0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于DWC2的USB驱动开发-0x0D PHY寄存器读写代码编写与测试

嵌入式USB开发 来源:嵌入式USB开发 作者:嵌入式USB开发 2023-06-06 13:03 次阅读

本文转自公众号,欢迎关注

基于DWC2的USB驱动开发-0x0D PHY寄存器读写代码编写与测试 (qq.com)

PHY寄存器读写

1.1前言

我们前面重点介绍了ULPI接口和PHY的寄存器,这一篇来进行PHY寄存器读写的代码编写与测试。从这一篇开始就正真进入了驱动编写的过程了。

1.2 GPVNDCTL寄存器介绍

DWC2提供了读写PHY寄存器的机制,对于应用来说就是操作一个寄存器GPVNDCTL:PHY供应商控制寄存器。能够读写PHY寄存器这在有些底层问题分析时很重要。

《DesignWare Cores USB 2.0 Hi-Speed On-TheGo (OTG) Databook》的P391 5.4.14 GPVNDCTL 有该寄存器的介绍。

IP必须配置OTG_VENDOR_CTL_INTERFACE = 1 才支持该功能。

GHWCFG3寄存器的b9查看该配置值。

图片

图片

对于UTMI+PHY,DWC_otg核心使用UTMI+供应商控制接口进行PHY寄存器访问。对于ULPI PHY,核心使用ULPI接口进行PHY寄存器访问。应用程序设置GPVNDCTL来访问PHY寄存器,并对PHY寄存器的访问进行计时,应用程序轮询此寄存器中的VStatus Done位来确认是否完成PHY寄存器的访问。

该寄存器的描述如下

偏移0x34 访问大小32位

image.png

image.png

image.png

图片

我们重点关注和PHY读写有关的位域,其他的位暂时用不到,先不管。

NewRegReq: 软件写1触发一次操作。

VStsDone: 当应用程序设置NewRegReq为1时,硬件清除该位,操作完成后硬件再置位该位。软件查询该位以判断是否完成,注意代码中需要考虑查询超时机制。

VStsBsy: 忙标志,正在进行操作时硬件置位该位,操作完成时硬件清零,可以认为是和VStsDone相反的标志。

RegWr: 0表示读PHY寄存器,1表示写PHY寄存器

RegAddr: PHY寄存器地址,PHY立即寄存器的6位地址。设置为6'h2F用于扩展PHY寄存器集访问。

VCtrl:UTMI+供应商控制寄存器地址(VCtrl)供应商定义的4位并行输出总线的4位寄存器地址。该字段的位11:8被置于utmi_vontrol[3:0]上。ULPI扩展寄存器地址(ExtRegAddr)PHY扩展寄存器地址。

RegData: 写寄存器时写入寄存器的数据。读寄存器时读到的寄存器内容,设置VStatus Done时有效。

DisUlpiDrvr:读写PHY寄存器无关,

应用程序在完成ULPI Carkit中断(GINTSTS.ULPICKINT)处理后设置此位。设置后,控制器将禁用输出信号驱动器,并屏蔽ULPI接口的输入信号。控制器在启用ULPI接口之前清除该位。

1.3 代码编写

读PHY寄存器

  1. RegWr设置为0
  2. RegAddr设置为立即寄存器的6位地址,如果是扩展寄存器则设置为0x2F且设置VCtrl为扩展寄存器的值。
  3. NewRegReq置1启动操作
  4. 等待VStsDone变为1
  5. 读出RegData

写PHY寄存器

  1. RegWr设置为1
  2. RegAddr设置为立即寄存器的6位地址,如果是扩展寄存器则设置为0x2F且设置VCtrl为扩展寄存器的值。
  3. RegData设置为待写入寄存器的值
  4. NewRegReq置1启动操作
  5. 等待VStsDone变为1

代码如下

/**
 * \\fn static uint8_t hw_dwc2_is_vndctlsupt(void)
 * 判断是否支持供应商控制接口(VndctlSupt)
 * \\retval 0 不支持 供应商控制接口(VndctlSupt)
 * \\retval 1 支持
*/
static uint8_t hw_dwc2_is_vndctlsupt(void)
{
    return ((USB_OTG_READ_REG(CFG_GHWCFG3_ADDR) & VNDCTLSUPT_MASK) > > VNDCTLSUPT_OFFSET) & 0x01;
    //return (uint8_t)(s_dwc2_reg_t- >ghwcfg3._b.vndctlsupt);
}


/**
 * \\fn  int hw_dwc2_read_phyreg(uint8_t regaddr, uint8_t* regval, uint32_t timeout)
 * \\param[in] regaddr PHY寄存器,立即寄存器和扩展寄存器统一编码,高2位为0表示立即寄存器,
 * 高两位不为0表示扩展寄存器。
 * \\param[out] regval 存储读出的寄存器值
 * \\param[in] timeout 查询是否完成的次数
 * \\retval -1 不支持供应商控制接口(VndctlSupt)
 * \\retval -2 读超时
 * \\retval 0  读成功
*/
int hw_dwc2_read_phyreg(uint8_t regaddr, uint8_t* regval, uint32_t timeout)
{
    /* 判断是否支持供应商控制接口(VndctlSupt) */
    if(hw_dwc2_is_vndctlsupt() == 0)
    {
        return -1;
    }
#if 0
    s_dwc2_reg_t- >gpvndctl._b.regwr = 0; /* 读模式 */
    if((regaddr & 0xC0) != 0)
    {
        /* 扩展寄存器 */
        s_dwc2_reg_t- >gpvndctl._b.regaddr = 0x2F;
        s_dwc2_reg_t- >gpvndctl._b.vctrl = regaddr;
    }
    else
    {
        /* 立即寄存器 */
        s_dwc2_reg_t- >gpvndctl._b.regaddr = regaddr;
        s_dwc2_reg_t- >gpvndctl._b.vctrl = 0;    
    }
    s_dwc2_reg_t- >gpvndctl._b.newregreq = 1;  /* 启动操作 */
    while ((s_dwc2_reg_t- >gpvndctl._b.vstsdone == 0) && (timeout-- > 0));  /* 等待完成 */

    /* 根据标志返回值或者错误 */
    if(s_dwc2_reg_t- >gpvndctl._b.vstsdone != 0)
    {
        *regval = s_dwc2_reg_t- >gpvndctl._b.regdata;
        //s_dwc2_reg_t- >gpvndctl._b.vstsdone = 1;  /* newregreq =1时硬件清0,没必要手动清零 */
        return 0;
    }
    else
    {
        return -2;
    }
#else
    uint32_t tmp = 0;
    tmp &= ~REGWR_MASK; /* 读模式 */
    if((regaddr & 0xC0) != 0)
    {
        /* 扩展寄存器 */
        tmp |= ((uint32_t)0x2F < < REGADDR_OFFSET);
        tmp |= ((uint32_t)regaddr < < VCTRL_OFFSET);
    }
    else
    {
        /* 立即寄存器 */
        tmp |= ((uint32_t)regaddr < < REGADDR_OFFSET);
        tmp |= ((uint32_t)0 < < VCTRL_OFFSET);  
    }   
    tmp |= NEWREGREQ_MASK;                       /* 启动操作 */
    USB_OTG_WRITE_REG(CFG_GPVNDCTL_ADDR,tmp);


    while(((USB_OTG_READ_REG(CFG_GPVNDCTL_ADDR)&VSTSDONE_MASK) == 0) && (timeout-- > 0));  /* 等待完成 */
    if(((USB_OTG_READ_REG(CFG_GPVNDCTL_ADDR)&VSTSDONE_MASK) != 0))
    {
        *regval = (USB_OTG_READ_REG(CFG_GPVNDCTL_ADDR) > > REGDATA_OFFSET) & 0xFF; /* 读出寄存器的值 */
        USB_OTG_WRITE_REG(CFG_GPVNDCTL_ADDR,USB_OTG_READ_REG(CFG_GPVNDCTL_ADDR) | VSTSDONE_MASK);
        /* newregreq =1时硬件清0,没必要手动清零 */
        return 0;
    }
    else
    {
        return -2;
    }
#endif
}


/**
 * \\fn  int hw_dwc2_write_phyreg(uint8_t regaddr, uint8_t regval, uint32_t timeout)
 * \\param[in] regaddr PHY寄存器,立即寄存器和扩展寄存器统一编码,高2位为0表示立即寄存器,
 * 高两位不为0表示扩展寄存器。
 * \\param[out] regval 写入寄存器的值
 * \\param[in] timeout 查询是否完成的次数
 * \\retval -1 不支持供应商控制接口(VndctlSupt)
 * \\retval -2 读超时
 * \\retval 0  读成功
*/
int hw_dwc2_write_phyreg(uint8_t regaddr, uint8_t regval, uint32_t timeout)
{
    /* 判断是否支持供应商控制接口(VndctlSupt) */
    if(hw_dwc2_is_vndctlsupt() == 0)
    {
        return -1;
    }


#if 0
    /* 不能使用结构体单位域操作,因为regdata需要vstsdone=1才能访问
     * 且vstsdone是W1C,所以单位域读-修改-写时vstsdone写入1导致清0,导致后面regdata不能写入
    */
    s_dwc2_reg_t- >gpvndctl._b.regwr = 1; /* 写模式 */
    if((regaddr & 0xC0) != 0)
    {
        /* 扩展寄存器 */
        s_dwc2_reg_t- >gpvndctl._b.regaddr = 0x2F;
        s_dwc2_reg_t- >gpvndctl._b.vctrl = regaddr;
    }
    else
    {
        /* 立即寄存器 */
        s_dwc2_reg_t- >gpvndctl._b.regaddr = regaddr;
        s_dwc2_reg_t- >gpvndctl._b.vctrl = 0;    
    }
    s_dwc2_reg_t- >gpvndctl._b.regdata = regval; /* 写入寄存器的值 */
    s_dwc2_reg_t- >gpvndctl._b.newregreq = 1;    /* 启动操作 此时regdata回读未0,导致回写为0 不对*/
    while ((s_dwc2_reg_t- >gpvndctl._b.vstsdone == 0) && (timeout-- > 0));  /* 等待完成 */

    /* 根据标志返回值或者错误 */
    if(s_dwc2_reg_t- >gpvndctl._b.vstsdone != 0)
    {
        // s_dwc2_reg_t- >gpvndctl._b.vstsdone = 1;  /* newregreq =1时硬件清0,没必要手动清零 */
        return 0;
    }
    else
    {
        return -2;
    }
#else
    uint32_t tmp = 0;
    tmp |= REGWR_MASK; /* 写模式 */
    if((regaddr & 0xC0) != 0)
    {
        /* 扩展寄存器 */
        tmp |= ((uint32_t)0x2F < < REGADDR_OFFSET);
        tmp |= ((uint32_t)regaddr < < VCTRL_OFFSET);
    }
    else
    {
        /* 立即寄存器 */
        tmp |= ((uint32_t)regaddr < < REGADDR_OFFSET);
        tmp |= ((uint32_t)0 < < VCTRL_OFFSET);  
    }   
    tmp |= ((uint32_t)regval < < REGDATA_OFFSET); /* 写入寄存器的值 */
    tmp |= NEWREGREQ_MASK;                       /* 启动操作 */
    USB_OTG_WRITE_REG(CFG_GPVNDCTL_ADDR,tmp);


    while(((USB_OTG_READ_REG(CFG_GPVNDCTL_ADDR)&VSTSDONE_MASK) == 0) && (timeout-- > 0));  /* 等待完成 */
    if(((USB_OTG_READ_REG(CFG_GPVNDCTL_ADDR)&VSTSDONE_MASK) != 0))
    {
        USB_OTG_WRITE_REG(CFG_GPVNDCTL_ADDR,USB_OTG_READ_REG(CFG_GPVNDCTL_ADDR) | VSTSDONE_MASK);
        /* newregreq =1时硬件清0,没必要手动清零 */
        return 0;
    }
    else
    {
        return -2;
    }
#endif
}

1.4 测试

1.4.1 立即寄存器读VID PID

这里使用的PHY型号是USB3343

VID PID寄存器值如下

图片

测试代码如下

uint8_t regval;
    int res = 0;


    /* 读VID PID */
    res = hw_dwc2_read_phyreg(0x00,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    usb_hal_info("[VIDL]:0x%x\\r\\n",regval);
    res = hw_dwc2_read_phyreg(0x01,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    usb_hal_info("[VIDH]:0x%x\\r\\n",regval);
    res = hw_dwc2_read_phyreg(0x02,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    usb_hal_info("[PIDL]:0x%x\\r\\n",regval);
    res = hw_dwc2_read_phyreg(0x03,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    usb_hal_info("[PIDH]:0x%x\\r\\n",regval);

打印如下,可以看到读出的值是正确的

image.png

也可以直接使用仿真器修改寄存器操作

(gdb) set (unsigned int )0x03000034=0x02000000 // 读0寄存器

(gdb) x /1xw 0x03000034

0x3000034: 0x08000024

(gdb) set (unsigned int )0x03000034=0x02010000 // 读1寄存器

(gdb) x /1xw 0x03000034

0x3000034: 0x08010004

(gdb) set (unsigned int )0x03000034=0x02020000 // 读2寄存器

(gdb) x /1xw 0x03000034

0x3000034: 0x08020009

(gdb) set (unsigned int )0x03000034=0x02030000 // 读3寄存器

(gdb) x /1xw 0x03000034

0x3000034: 0x08030000

1.4.2 立即寄存器读写寄存器

图片

0x16处的Scratch寄存器是用户可以自由使用的寄存器,可以使用该寄存器测试

0x16对应读写

0x17对应Set

0x18对应Clr

测试代码如下

/* 读Scratch Register初始值 */
    res = hw_dwc2_read_phyreg(0x16,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    usb_hal_info("[Scratch Register]:0x%x\\r\\n",regval);


    /* 写入0x55回读是否正确 */
    hw_dwc2_write_phyreg(0x16,0x55,1000);
    if(res != 0)
    {
        return res;
    }
    res = hw_dwc2_read_phyreg(0x16,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    if(regval != 0x55)
    {
        usb_hal_info("[Scratch Register Write Err]:0x%x\\r\\n",regval);
    }
    else
    {
        usb_hal_info("[Scratch Register Write OK]:0x%x\\r\\n",regval);
    }


    /* 0x55置位0xAA变为0xFF */
    hw_dwc2_write_phyreg(0x17,0xAA,1000);
    if(res != 0)
    {
        return res;
    }
    res = hw_dwc2_read_phyreg(0x16,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    if(regval != 0xFF)
    {
        usb_hal_info("[Scratch Register Set Err]:0x%x\\r\\n",regval);
    }
    else
    {
        usb_hal_info("[Scratch Register Set OK]:0x%x\\r\\n",regval);
    }


    /* 0xFF清除0x55变为0xAA */
    hw_dwc2_write_phyreg(0x18,0x55,1000);
    if(res != 0)
    {
        return res;
    }
    res = hw_dwc2_read_phyreg(0x16,&regval,1000);
    if(res != 0)
    {
        return res;
    }
    if(regval != 0xAA)
    {
        usb_hal_info("[Scratch Register Clr Err]:0x%x\\r\\n",regval);
    }
    else
    {
        usb_hal_info("[Scratch Register Clr OK]:0x%x\\r\\n",regval);
    }

打印如下

图片

直接使用仿真器操作

(gdb) set (unsigned int )0x03000034=0x02560055 //写0x16寄存器为0x55

(gdb) set (unsigned int )0x03000034=0x02160000 //读0x16寄存器

(gdb) x /1xw 0x03000034 //查看读回来的值为0x55 正确

0x3000034: 0x08160055

(gdb) set (unsigned int )0x03000034=0x025700AA //设置0x16寄存器,即操作0x17置位0xAA位

(gdb) set (unsigned int )0x03000034=0x02160000 //读0x16寄存器

(gdb) x /1xw 0x03000034

0x3000034: 0x081600ff //查看读回来的值为0xFF 正确

(gdb)

1.4.3 问题

位域操作和宏操作

  1. 写regwr时 done标志被清零了,因为是读-修改-写的方式,VstsDone读出来为1再修改其他位回写时VstsDone写入1,但是该位为W1C,写1清0,所以回写时会清除标志。虽然这里不会有什么问题,但是这里有编程者未意料到的副作用,在其他地方可能会导致问题,所以不建议使用位域一步步的操作。
  2. 位域的操作可能被优化,比如这里位于regdata等因为是字节对齐的,所以使用了字节操作指令,但是按照DWC2手册应该要求都是按照32位访问的,所以这里带来了未预料的问题。
  3. 写入regdata后,实际上回读的值是0,所以最后s_dwc2_reg_t->gpvndctl._b.newregreq = 1;读-写0修改后读出regdata是0,再写入就是0了,而不是上一步写入的s_dwc2_reg_t->gpvndctl._b.regdata = regval;了,所以不能使用这种位域一步步设置的方式。

以下验证regdata写入是不能回读的,写入0x55回读是0

图片

所以regdata在手册中描述的rw不完全是可读可写,而是写时只写不可读,读时只有Vstsdone才能读。

  1. 位域操作有太多的副作用,比如上面的W1C,写入不能回读,位域访问宽度被优化修改,等等都可能导致问题,而且位域一步步操作都需要读-修改-写,所以效率也低,最好使用直接的寄存器宏一次读出,临时变量存储修改,最后一次写入的方式。

图片

所以不能使用结构体一步一步修改的方式,而是使用宏,一次性修改整个寄存器。

图片

图片

1.5总结

以上测试了PHY立即寄存器的读写,由于使用的PHY USB3343没有扩展寄存器,所以扩展寄存器读写没有测试。注意上面也介绍了尽量使用宏的方式进行寄存器操作,而不要使用位域的方式,位域的方式存在诸多副作用。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5290

    浏览量

    119787
  • usb
    usb
    +关注

    关注

    60

    文章

    7872

    浏览量

    263655
  • PHY
    PHY
    +关注

    关注

    2

    文章

    301

    浏览量

    51657
  • 驱动开发
    +关注

    关注

    0

    文章

    130

    浏览量

    12059
  • DWC2
    +关注

    关注

    0

    文章

    35

    浏览量

    118
收藏 人收藏

    评论

    相关推荐

    基于DWC2USB驱动开发-0x06 DWC2 USB2.0 IP 头文件与寄存器读写操作

    上一篇我们介绍了控制寄存器,而驱动编写底层无非就是配置各种寄存器,所以第一步先要准备寄存器
    的头像 发表于 05-16 14:04 2348次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>0x</b>06 <b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0 IP 头文件与<b class='flag-5'>寄存器</b>的<b class='flag-5'>读写</b>操作

    STM32串口接收不定长数据:采用标志位(比如0X0D,0X0A)结束法

    缺点:有些情况下会导致数据丢失(可能返回数据中0x0d0a本身为有效数据)
    的头像 发表于 09-23 14:06 5374次阅读

    基于DWC2USB驱动开发-0x01开篇介绍与新思DWC2 USB2.0控制简介

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-0x01开篇介绍与新思DWC2
    的头像 发表于 05-08 18:10 4453次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>0x</b>01开篇介绍与新思<b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0控制<b class='flag-5'>器</b>简介

    基于DWC2USB驱动开发-0x02 DWC2 USB2.0 IP功能特征介绍

    DWC2即新思(Synopsys )的DesignWare® Cores USB 2.0 HiSpeed On-The-Go (OTG)控制IP,被大量使用。从linux的内核源码驱动
    的头像 发表于 05-09 10:09 8897次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>0x</b>02 <b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0 IP功能特征介绍

    基于DWC2USB驱动开发-0x05 DWC2 USB2.0 IP 寄存器介绍

    本文对控制寄存器有了一个整体上的概览,先了解个大概,了解寄存器的组织结构,大致了解一下常用的寄存器。后面编程时再一个个对照每一个寄存器
    的头像 发表于 05-16 12:50 3107次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>0x</b>05 <b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0 IP <b class='flag-5'>寄存器</b>介绍

    基于DWC2USB驱动开发-0x0B ULPI接口寄存器介绍

    以上详细介绍了PHY相关的寄存器内容,标准部分是所有PHY都需要按照该规范实现的,还有厂商自定义部分可以自定义。正是因为规范对寄存器功能进行了规范所以LINK部分的IP才能做到兼容通用
    的头像 发表于 06-05 15:36 3950次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>0x0</b>B ULPI接口<b class='flag-5'>寄存器</b>介绍

    基于DWC2USB驱动开发-USB复位详解

    本文转自公众号欢迎关注 基于DWC2USB驱动开发-USB复位详解 (qq.com) 一.前言          上一篇我们详细介绍了
    的头像 发表于 07-07 11:18 5.3w次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>USB</b>复位详解

    基于DWC2USB驱动开发-USB连接详解

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-USB连接详解 (qq.com) 一.前言   之前一直在阅读手册,规格书,练习招式
    的头像 发表于 07-07 08:46 3492次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-<b class='flag-5'>USB</b>连接详解

    基于DWC2USB驱动开发-设备类驱动框架

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-设备类驱动框架 (qq.com) 一.前言 从软件顶层,从数据流的角度来看
    的头像 发表于 07-16 15:56 1251次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-设备类<b class='flag-5'>驱动</b>框架

    基于DWC2USB驱动开发-发送相关的寄存器DMA寄存器详解

    本文转自公众号,欢迎关注 基于DWC2USB驱动开发-发送相关的寄存器DMA寄存器详解 (qq
    的头像 发表于 07-16 16:42 1547次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-发送相关的<b class='flag-5'>寄存器</b>DMA<b class='flag-5'>寄存器</b>详解

    基于DWC2USB驱动开发-DOEP接收相关的DMA寄存器详解

    前面我们详细介绍了发送即DIEP相关的一些寄存器,这一篇我们来看看接收即DOEP相关的一些寄存器。形式上DOEP和DIEP寄存器是类似的。不过我们看寄存器列表会发现DOEP会少一个
    的头像 发表于 07-19 09:00 1176次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-DOEP接收相关的DMA<b class='flag-5'>寄存器</b>详解

    基于DWC2USB驱动开发-控制传输中断相关寄存器

    本篇讲解Scatter/Gather DMA模式下控制传输相关的寄存器。控制传输是USB驱动的核心部分,控制传输调通了驱动就完成了一大半,而驱动
    的头像 发表于 07-24 00:07 2294次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-控制传输中断相关<b class='flag-5'>寄存器</b>

    基于DWC2USB驱动开发-数据不能发送问题分析案例

    本文转自公众号欢迎关注 基于DWC2USB驱动开发-数据不能发送问题分析案例 (qq.com)   一.前言        对于驱动
    的头像 发表于 08-08 09:43 2047次阅读
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-数据不能发送问题分析案例

    基于DWC_ether_qos的以太网驱动开发-MDIO驱动编写测试

    本文转自公众号欢迎关注 基于DWC_ether_qos的以太网驱动开发-MDIO驱动编写测试
    的头像 发表于 08-30 09:37 3551次阅读
    基于<b class='flag-5'>DWC</b>_ether_qos的以太网<b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-MDIO<b class='flag-5'>驱动</b><b class='flag-5'>编写</b>与<b class='flag-5'>测试</b>

    RK3399平台上USB控制PHY的连接方式和配置说明

    判断切换为何种模式,ID脚的电平变化触发控制ID脚中断,然后由软件切换到对应模式。目前使用两种驱动版本,一个是upstream 版,驱动dwc2目录下,主要从upstream开源项
    发表于 05-12 17:46