21IC电子工程师论坛

查看: 11419|回复: 38

STM32 USB-OTG-LIB 写得非常乱! [复制链接]

积分
104
帖子
27
本月在线
0小时0分
litop 发表于 2010-5-3 14:37:02 |显示全部楼层 |返回版面
STM32 USB-OTG-LIB 写得非常乱!好多寄存器的定义,在(STM32F107)芯片手册上找不到!!!叫人怎搞?
连基本的注释都没有!
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-7 11:56:20 |显示全部楼层 |返回版面
好像还有和数据手册上不对应的地方
积分
47720
帖子
14962
本月在线
7小时30分
香水城 发表于 2010-5-7 11:59:44 |显示全部楼层 |返回版面
STM32 USB-OTG-LIB 写得非常乱!好多寄存器的定义,在(STM32F107)芯片手册上找不到!!!叫人怎搞?
连基本的注释都没有!
litop 发表于 2010-5-3 14:37


哪些寄存器的定义在芯片手册上找不到?请指点一二,我还没有来得及看。

好像还有和数据手册上不对应的地方
yaohuitime 发表于 2010-5-7 11:56


哪些地方和数据手册上不对应?也请指点一二。

谢谢!
I do not teach, but I coach. I do not feed, but I seed.
欢迎访问我的博客:http://bbs.ednchina.com/BLOG_OWNER_199055.HTM
积分
25668
帖子
4137
本月在线
15小时30分
mcuisp 发表于 2010-5-7 12:46:11 |显示全部楼层 |返回版面
STM32 OTG是用的Synopsys的IP。
俺搞过几个月这个IP的驱动,呵呵。
这个IP是目前最好的USB IP,架构很好。
STM32的OTG库还不错的,作者对于USB架构和DWC IP领会很深。

DWC IP很容易扩展到High Speed,期待STM32出带HS USB的型号。
www.mcuisp.com
免费STM32 ISP软件
EP968手持烧录器,现场升级/生产线量产STM32,STM8S/L,FreeScale,LPC2000,LPC9xx,C8051F,AVR,PIC......
最新支持STM8S、L在线仿真和脱机下载
积分
2521
帖子
654
本月在线
0小时0分
vigia 发表于 2010-5-7 13:36:41 |显示全部楼层 |返回版面
那些寄存器不是没有列在参考手册中,而是名字和参考手册的略有不同。

据我所知,马上会有新版本的数据库了,把寄存器的名字都和参考手册的统一起来了。
积分
104
帖子
27
本月在线
0小时0分
litop 发表于 2010-5-7 15:36:06 |显示全部楼层 |返回版面
typedef struct _USB_OTG_common_regs  //000h
{

  __IO uint32_t otg_ctl;      /* USB_OTG Control and Status Register    000h*/
  __IO uint32_t otg_int;      /* USB_OTG Interrupt Register             004h*/
  __IO uint32_t ahb_cfg;      /*Core AHB Configuration Register    008h*/
  __IO uint32_t usb_cfg;      /*Core USB Configuration Register    00Ch*/
  __IO uint32_t rst_ctl;      /* Core Reset Register                010h*/
  __IO uint32_t int_sts;      /* Core Interrupt Register            014h*/
  __IO uint32_t int_msk;      /* Core Interrupt Mask Register       018h*/
  __IO uint32_t rx_stsr;      /*--Receive Sts Q Read Register        01Ch*/
  __IO uint32_t rx_stsp;      /* Receive Sts Q Read & POP Register  020h*/

                                                       
  __IO uint32_t rx_fifo_siz;          /*  Receive FIFO Size Register         024h*/
  __IO uint32_t np_tx_fifo_siz;  /* Non Periodic Tx FIFO Size Register 028h*/
  __IO uint32_t np_tx_sts;            /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/
  __IO uint32_t i2c_ctl;              /* (  数据手册没有) I2C Access Register                030h*/
  __IO uint32_t phy_vnd_ctl;          /* (  数据手册没有)PHY Vendor Control Register        034h*/
  
  __IO uint32_t gpio;                 /* General Purpose IO Register        038h*/
  __IO uint32_t usr_id;               /*  User ID Register                   03Ch*/
  
  __IO uint32_t snps_id;      /* Synopsys ID Register               040h*/
  __IO uint32_t hw_cfg1;      /*参考手册没有 User HW Config1 Register (RO)      044h*/
  __IO uint32_t hw_cfg2;      /*参考手册没有 User HW Config2 Register (RO)      048h*/
  __IO uint32_t hw_cfg3;      /*参考手册没有 User HW Config3 Register (RO)      04Ch*/
  __IO uint32_t hw_cfg4;      /*参考手册没有 User HW Config4 Register (RO)      050h*/
  uint32_t  reserved[43];          /* Reserved                      054h-0FFh*/
  __IO uint32_t host_p_tx_fifo_siz;                 /* OTG_FS_HPTXFSIZ----- Host Periodic Tx FIFO Size Reg     100h*/
  __IO uint32_t dev_p_tx_fsiz_dieptxf[15];        /* OTG_FS_DIEPTXF1~OTG_FS_DIEPTXF15--  dev Periodic Transmit FIFO */

}
USB_OTG_common_regs;

请问,参考手册,数据手册上,那有里这几项?
这只是其中一个,很多这样的定义,在数据手册上都是注明“保留”的!
已有 1 人评分威望 收起 理由
zhangjunye + 1 我也遇见了这个问题

总评分: 威望 + 1   查看全部评分

积分
104
帖子
27
本月在线
0小时0分
litop 发表于 2010-5-7 15:42:38 |显示全部楼层 |返回版面
各位大侠熟悉USB-OTG吗,请教一个问题:
当用:
   USB_SIL_Write(EP2_IN,(uint8_t*)bbf,64);
来发数据时,当 上位机程序(VC++)不读对应的端口时,它会一直在USB 中断服务程序里转!!回不到main 函数中。 一但上位机程序读了,就正常了。
                   /* IN Endpoint interrupt */
#ifdef INTR_INEPINTR        /* IN 端点中断*/
    if (gintr_status.b.inepint)
    {
      retval |= OTGD_FS_Handle_InEP_ISR();<-------------------在这里转
    }
#endif /* INTR_INEPINTR */
请问一下,这是bug吗?
谢谢关注与帮助。
积分
47720
帖子
14962
本月在线
7小时30分
香水城 发表于 2010-5-7 15:50:36 |显示全部楼层 |返回版面
好多寄存器的定义,在(STM32F107)芯片手册上找不到,说明在STM32F107上没有实现这些寄存器。

正如4楼所说,这个模块的设计是买来的,在放到STM32F107中的时候,把一些不必要的寄存器去掉了,这没有什么奇怪的。
I do not teach, but I coach. I do not feed, but I seed.
欢迎访问我的博客:http://bbs.ednchina.com/BLOG_OWNER_199055.HTM
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 15:38:46 |显示全部楼层 |返回版面
原来是买的
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 15:45:30 |显示全部楼层 |返回版面
USB_OTG_Status USB_OTG_CoreInitHost(USB_OTG_CORE_DEVICE *pdev)
{
  USB_OTG_Status              status = USB_OTG_OK;
  USB_OTG_fifo_size_data    nptxfifosize;
  USB_OTG_fifo_size_data  ptxfifosize;
  USB_OTG_OTG_ctl_data         gotgctl;
  USB_OTG_hc_char_data  hcchar;
  USB_OTG_host_cfg_data       hcfg;
  uint32_t               num_channels, i;
  gotgctl.d32 = 0;
  /* Restart the Phy Clock */
  WRITE_REG32(pdev->regs.pcgcctl, 0);
  /* Initialize Host Configuration Register */
  InitFSLSPClkSel(pdev);
  hcfg.d32 = READ_REG32(&pdev->regs.host_regs->host_cfg);
  hcfg.b.fslssupp = 1;
  WRITE_REG32(&pdev->regs.host_regs->host_cfg, hcfg.d32);
  /* Configure data FIFO sizes */
  /* Rx FIFO */
  WRITE_REG32(&pdev->regs.common_regs->rx_fifo_siz, 160);
  /* Non-periodic Tx FIFO */
  nptxfifosize.b.depth  = 160;
  nptxfifosize.b.startaddr = 160;
  WRITE_REG32(&pdev->regs.common_regs->np_tx_fifo_siz, nptxfifosize.d32);
  /* Periodic Tx FIFO */
  ptxfifosize.b.depth  = 128;
  ptxfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
  WRITE_REG32(&pdev->regs.common_regs->host_p_tx_fifo_siz, ptxfifosize.d32);
#ifdef DUAL_ROLE_MODE_ENABLED
  /* Clear Host Set HNP Enable in the USB_OTG Control Register */
  gotgctl.b.hstsethnpen = 1;
  MODIFY_REG32( &pdev->regs.common_regs->otg_ctl, gotgctl.d32, 0);
#endif
  /* Make sure the FIFOs are flushed. */
  USB_OTG_FlushTxFifo(pdev, 0x10 );         /* all Tx FIFOs */
  USB_OTG_FlushRxFifo(pdev);
  /* Flush out any leftover queued requests. */
  num_channels = 8;
  for (i = 0; i < num_channels; i++)
  {
    hcchar.d32 = READ_REG32(&pdev->regs.hc_regs[i]->hc_char);
    hcchar.b.chen = 0;
    hcchar.b.chdis = 1;
    hcchar.b.epdir = 0;
    WRITE_REG32(&pdev->regs.hc_regs[i]->hc_char, hcchar.d32);
  }
  /* Halt all channels to put them into a known state. */
  for (i = 0; i < num_channels; i++)
  {
    hcchar.d32 = READ_REG32(&pdev->regs.hc_regs[i]->hc_char);
    hcchar.b.chen = 1;
    hcchar.b.chdis = 1;
    hcchar.b.epdir = 0;
    WRITE_REG32(&pdev->regs.hc_regs[i]->hc_char, hcchar.d32);
    do
    {
      hcchar.d32 = READ_REG32(&pdev->regs.hc_regs[i]->hc_char);
      uDELAY (20);
    }
    while (hcchar.b.chen);
  }
  /* Disable HALT interrupt Masks */
  for (i = 0; i < num_channels; i++)
  {
    USB_OTG_hc_int_msk_data hcintmsk;
    hcintmsk.d32 = READ_REG32(&pdev->regs.hc_regs[i]->hc_int_msk);
    hcintmsk.b.chhltd = 0;
    WRITE_REG32(&pdev->regs.hc_regs[i]->hc_int_msk , hcintmsk.d32);
  }
#ifndef DUAL_ROLE_MODE_ENABLED
  USB_OTG_DriveVbus(pdev, 1);      
#endif
  USB_OTG_EnableHostInt(pdev);
  return status;
}
看代码知道 接收 周期发送 非周期发送 一共是1.5K
但“总共1.25K字节的USB数据RAM区”
不能理解???
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 15:50:37 |显示全部楼层 |返回版面
USB_OTG_Status USB_OTG_WritePacket(USB_OTG_CORE_DEVICE *pdev, uint8_t *src, uint8_t ch_ep_num, uint16_t bytes)
{
  USB_OTG_Status status = USB_OTG_OK;
  uint32_t dword_count , i;
  vuint32_t *fifo;
  uint32_t *data_buff = (uint32_t *)src;
  /* Find the DWORD length, padded by extra bytes as neccessary if MPS
   * is not a multiple of DWORD */
  dword_count =  (bytes + 3) / 4;
  fifo = pdev->regs.data_fifo[ch_ep_num];
  for (i = 0; i < dword_count; i++, data_buff++)
  {
    WRITE_REG32( fifo, *data_buff );
  }
  return status;
}
其中代码
for (i = 0; i < dword_count; i++, data_buff++)
  {
    WRITE_REG32( fifo, *data_buff );
  }
在这个循环中 fifo 的地址是不变的 但手册中

图281  CSR存储器映像 中 每个端点FIFO  最大4k

不理解代码   请指教
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 15:57:50 |显示全部楼层 |返回版面
"总共1.25K字节的USB数据RAM区 "这个区域到底在哪里?
数据FIFO(DFIFO)访问寄存器址映射
这组寄存器列在主机模式和设备模式下都有效,用于读写指定方向的特殊端点或通道的FIFO。
如果一个主机模式下的通道是IN类型的,相对应的FIFO只能进行读操作。同样地,如果一个主
机模式下的通道是OUT类型的,相对应的FIFO只能进行写操作。
表186 数据FIFO(DFIFO)访问寄存器图
数据FIFO(DFIFO)访问寄存器段  地址范围  访问方式
设备模式下IN端点0/主机模式下OUT通道0:DFIFO 只写  写操作
0x1000~0x1FFC
设备模式下OUT端点0/主机模式下IN通道0:DFIFO 只读  读操作
设备模式下IN端点1/主机模式下OUT通道1:DFIFO 只写  写操作
0x2000~0x2FFC
设备模式下OUT端点1/主机模式下IN通道1:DFIFO 只读  读操作
……  ……  ……
设备模式下IN端点x/主机模式下OUT通道x:DFIFO 只写  写操作
0xX000~0xXFFC
设备模式下OUT端点x/主机模式下IN通道x:DFIFO 只读  读操作
表中的x在设备模式下为3,在主机模式下为7


不知道怎么和特定的端点联系起来的??
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 16:24:32 |显示全部楼层 |返回版面
USB_OTG_Status USB_OTG_CoreInitDev (USB_OTG_CORE_DEVICE *pdev)
{
  USB_OTG_Status status = USB_OTG_OK;
  USB_OTG_dev_ep_ctl_data   depctl;
  uint32_t i;
  USB_OTG_dev_cfg_data   dcfg;
  USB_OTG_fifo_size_data nptxfifosize;
  USB_OTG_fifo_size_data txfifosize;
  USB_OTG_dev_in_ep_msk_data msk;
  dcfg.d32 = 0;
  /* Set device speed */
  InitDevSpeed (pdev);
  /* Restart the Phy Clock */
  WRITE_REG32(pdev->regs.pcgcctl, 0);
  /* Device configuration register */
  dcfg.d32 = READ_REG32( &pdev->regs.dev_regs->dev_cfg);
  dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80;
  WRITE_REG32( &pdev->regs.dev_regs->dev_cfg, dcfg.d32 );
  /* set Rx FIFO size */
  WRITE_REG32( &pdev->regs.common_regs->rx_fifo_siz, 160/*pdev->cfgs->host_rx_fifo_size*/);
  /* Non-periodic Tx FIFO */
  nptxfifosize.b.depth     = DEV_NP_TX_FIFO_SIZE;
  nptxfifosize.b.startaddr = RX_FIFO_SIZE;
  WRITE_REG32( &pdev->regs.common_regs->np_tx_fifo_siz, nptxfifosize.d32 );
  txfifosize.b.depth = DEV_NP_TX_FIFO_SIZE;
  WRITE_REG32( &pdev->regs.common_regs->dev_p_tx_fsiz_dieptxf[0], txfifosize.d32 );
  txfifosize.b.startaddr += txfifosize.b.depth;
  txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
  /* Flush the FIFOs */
  USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */
  USB_OTG_FlushRxFifo(pdev);
  /* Clear all pending Device Interrupts */
  WRITE_REG32( &pdev->regs.dev_regs->dev_in_ep_msk, 0 );
  WRITE_REG32( &pdev->regs.dev_regs->dev_out_ep_msk, 0 );
  WRITE_REG32( &pdev->regs.dev_regs->dev_all_int, 0xFFFFFFFF );
  WRITE_REG32( &pdev->regs.dev_regs->dev_all_int_msk, 0 );
  for (i = 0; i <= MAX_TX_FIFOS; i++)
  {
    depctl.d32 = READ_REG32(&pdev->regs.inep_regs[i]->dev_in_ep_ctl);
    if (depctl.b.epena)
    {
      depctl.d32 = 0;
      depctl.b.epdis = 1;
      depctl.b.snak = 1;
    }
    else
    {
      depctl.d32 = 0;
    }
    WRITE_REG32( &pdev->regs.inep_regs[i]->dev_in_ep_ctl, depctl.d32);
    WRITE_REG32( &pdev->regs.inep_regs[i]->dev_in_ep_txfer_siz, 0);
    WRITE_REG32( &pdev->regs.inep_regs[i]->dev_in_ep_int, 0xFF);
  }
  for (i = 0; i < 1/* NUM_OUT_EPS*/; i++)
  {
    USB_OTG_dev_ep_ctl_data depctl;
    depctl.d32 = READ_REG32(&pdev->regs.outep_regs[i]->dev_out_ep_ctl);
    if (depctl.b.epena)
    {
      depctl.d32 = 0;
      depctl.b.epdis = 1;
      depctl.b.snak = 1;
    }
    else
    {
      depctl.d32 = 0;
    }
    WRITE_REG32( &pdev->regs.outep_regs[i]->dev_out_ep_ctl, depctl.d32);
    WRITE_REG32( &pdev->regs.outep_regs[i]->dev_out_ep_txfer_siz, 0);
    WRITE_REG32( &pdev->regs.outep_regs[i]->dev_out_ep_int, 0xFF);
  }
  msk.d32 = 0;
  msk.b.txfifoundrn = 1;
  MODIFY_REG32(&pdev->regs.dev_regs->dev_in_ep_msk, msk.d32, msk.d32);
  USB_OTG_EnableDevInt(pdev);
  return status;
}

这个函数是设备模式下初始函数
/* Non-periodic Tx FIFO */
  nptxfifosize.b.depth     = DEV_NP_TX_FIFO_SIZE;
  nptxfifosize.b.startaddr = RX_FIFO_SIZE;
  WRITE_REG32( &pdev->regs.common_regs->np_tx_fifo_siz, nptxfifosize.d32 );
  txfifosize.b.depth = DEV_NP_TX_FIFO_SIZE;
  WRITE_REG32( &pdev->regs.common_regs->dev_p_tx_fsiz_dieptxf[0], txfifosize.d32 );
  txfifosize.b.startaddr += txfifosize.b.depth;
  txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
  这段代码好像有问题
积分
2521
帖子
654
本月在线
0小时0分
vigia 发表于 2010-5-13 16:54:48 |显示全部楼层 |返回版面
本帖最后由 vigia 于 2010-5-13 16:56 编辑

你把问题总结下吧,这么长,我没看懂唉。。。。。。


那个FIFO地址是个PUSH/POP寄存器,所以写和读的地址是不变的。
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 17:26:03 |显示全部楼层 |返回版面
其中代码
for (i = 0; i < dword_count; i++, data_buff++)
  {
    WRITE_REG32( fifo, *data_buff );
  }
在这个循环中 fifo 的地址是不变的 但手册中

图281  CSR存储器映像 中 每个端点FIFO  最大4k

不理解代码   请指教
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 17:27:32 |显示全部楼层 |返回版面
我认为fifo 和data_buff 循环都应该地址是增加的

不知???
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 17:28:48 |显示全部楼层 |返回版面
谢谢 明白点了
积分
454
帖子
47
本月在线
0小时0分
yaohuitime 发表于 2010-5-13 17:33:28 |显示全部楼层 |返回版面
数据FIFO(DFIFO)访问寄存器址映射

还想请教 每个 fifo 地址是怎样和特定端点 联系起来的 ?
比如是不是 端点0  (不管什么模式下)就对应相应的 PUSH POP 地址
积分
2521
帖子
654
本月在线
0小时0分
vigia 发表于 2010-5-13 17:35:18 |显示全部楼层 |返回版面
data_buff是你自己的数组,要读数据,地址总归要增加的。

DFIFO不是通过写和读来操作的,是通过push和pop来操作的,向同一个地址push数据,会把前一个数据顶上去的。
积分
2521
帖子
654
本月在线
0小时0分
vigia 发表于 2010-5-13 17:38:45 |显示全部楼层 |返回版面
数据FIFO(DFIFO)访问寄存器址映射

还想请教 每个 fifo 地址是怎样和特定端点 联系起来的 ?
比如是不是 端点0  (不管什么模式下)就对应相应的 PUSH POP 地址 ...
yaohuitime 发表于 2010-5-13 17:33



参考手册上有个CSR寄存器的地址列表,上面很清楚的写了每个端点所对应到的DFIFO地址。
您需要登录后才可以回帖 登录 | 注册