STM32 USB-OTG-LIB 写得非常乱!好多寄存器的定义,在(STM32F107)芯片手册上找不到!!!叫人怎搞?
连基本的注释都没有!
STM32 USB-OTG-LIB 写得非常乱!好多寄存器的定义,在(STM32F107)芯片手册上找不到!!!叫人怎搞?
连基本的注释都没有!
哪些寄存器的定义在芯片手册上找不到?请指点一二,我还没有来得及看。
哪些地方和数据手册上不对应?也请指点一二。
谢谢!
STM32 OTG是用的Synopsys的IP。
俺搞过几个月这个IP的驱动,呵呵。
这个IP是目前最好的USB IP,架构很好。
STM32的OTG库还不错的,作者对于USB架构和DWC IP领会很深。
DWC IP很容易扩展到High Speed,期待STM32出带HS USB的型号。
那些寄存器不是没有列在参考手册中,而是名字和参考手册的略有不同。
据我所知,马上会有新版本的数据库了,把寄存器的名字都和参考手册的统一起来了。
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;
请问,参考手册,数据手册上,那有里这几项?
这只是其中一个,很多这样的定义,在数据手册上都是注明“保留”的!
好多寄存器的定义,在(STM32F107)芯片手册上找不到,说明在STM32F107上没有实现这些寄存器。
正如4楼所说,这个模块的设计是买来的,在放到STM32F107中的时候,把一些不必要的寄存器去掉了,这没有什么奇怪的。
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区”
不能理解???
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
不理解代码 请指教
"总共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
不知道怎么和特定的端点联系起来的??
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;
这段代码好像有问题
你把问题总结下吧,这么长,我没看懂唉。。。。。。
那个FIFO地址是个PUSH/POP寄存器,所以写和读的地址是不变的。
其中代码
for (i = 0; i < dword_count; i++, data_buff++)
{
WRITE_REG32( fifo, *data_buff );
}
在这个循环中 fifo 的地址是不变的 但手册中
图281 CSR存储器映像 中 每个端点FIFO 最大4k
不理解代码 请指教
我认为fifo 和data_buff 循环都应该地址是增加的
不知???
数据FIFO(DFIFO)访问寄存器址映射
还想请教 每个 fifo 地址是怎样和特定端点 联系起来的 ?
比如是不是 端点0 (不管什么模式下)就对应相应的 PUSH POP 地址
data_buff是你自己的数组,要读数据,地址总归要增加的。
DFIFO不是通过写和读来操作的,是通过push和pop来操作的,向同一个地址push数据,会把前一个数据顶上去的。
数据FIFO(DFIFO)访问寄存器址映射
还想请教 每个 fifo 地址是怎样和特定端点 联系起来的 ?
比如是不是 端点0 (不管什么模式下)就对应相应的 PUSH POP 地址 ...
参考手册上有个CSR寄存器的地址列表,上面很清楚的写了每个端点所对应到的DFIFO地址。
谢谢 vigia
还有个问题就是
/* 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);
看代码知道 接收 周期发送 非周期发送 一共是1.5K
但“总共1.25K字节的USB数据RAM区”
不能理解???
"总共1.25K字节的USB数据RAM区 "这个区域到底在哪里?