打印
[STM32]

請問 GetEPRxAddr(ENDP0) * 2 => 為什要乘 2 ( usb_core.c )

[复制链接]
2203|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
u012801|  楼主 | 2013-12-21 07:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 u012801 于 2013-12-21 08:33 编辑

#define RegBase  (0x40005C00L)  /* USB_IP Peripheral Registers base address */
#define PMAAddr  (0x40006000L)  /* USB_IP Packet Memory Area base address   */

#define BTABLE  ((volatile unsigned *)(RegBase + 0x50))
#define _GetBTABLE() ((u16) *BTABLE)
#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr))
#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum))





u8 Setup0_Process(void)
{

  union
  {
    u8* b;
    u16* w;
  } pBuf;

  pBuf.b = PMAAddr + (u8 *)(_GetEPRxAddr(ENDP0) * 2);           /* *2 for 32 bits addr */

  if (pInformation->ControlState != PAUSE)
  {
    pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
    pInformation->USBbRequest = *pBuf.b++; /* bRequest */
    pBuf.w++;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
    pBuf.w++;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwIndex  = ByteSwap(*pBuf.w++); /* wIndex */
    pBuf.w++;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwLength = *pBuf.w; /* wLength */
  }

  pInformation->ControlState = SETTING_UP;
  if (pInformation->USBwLength == 0)
  {
    /* Setup with no data stage */
    NoData_Setup0();
  }
  else
  {
    /* Setup with data stage */
    Data_Setup0();
  }
  return Post0_Process();
}

相关帖子

沙发
ayb_ice| | 2013-12-21 08:26 | 只看该作者
可能是
强制指针转换了
本来是指向32位变量的,现在指向16位变量

使用特权

评论回复
板凳
u012801|  楼主 | 2013-12-21 08:35 | 只看该作者
還是不懂,如果有例子說明會更清楚
:)

使用特权

评论回复
地板
huangxz| | 2013-12-21 10:07 | 只看该作者
看看芯片资料应该好理解一点

使用特权

评论回复
5
u012801|  楼主 | 2013-12-21 10:47 | 只看该作者
沒資料了,這是固件庫

使用特权

评论回复
6
efen| | 2013-12-21 14:10 | 只看该作者
嘻,芯片手册上提及。
"STM32的USB缓冲区是一个双端口的RAM,CPU一端需要使用32位方式访问,但USB模块一端使用16位方式访问,每个USB模块中的地址*2才能对应到控制器中的实际地址"

使用特权

评论回复
7
u012801|  楼主 | 2013-12-21 16:58 | 只看该作者
虽然缓冲区描述表位于分组缓冲区内,但还是可以将它看作是特殊的寄存器,用以配置USB
模块和微控制器内核共享的分组缓冲区的地址和大小。由于APB1总线按32位寻址,所以所
有的分组缓冲区地址都使用32位。USB模块的USB_BTABLE寄存器指示了缓冲区描述表的
起始地址,缓冲区描述表则给出了分组缓冲区的确定地址。后面的章节介绍了两种地址表示
方式:一种是应用程序访问分组缓冲区时使用的,另一种是相对于USB模块的本地地址。供
应用程序使用的分组缓冲区地址需要乘以2才能得到缓冲区在微控制器中的真正地址。分组
缓冲区的首地址为0xC0008800。
下面将描述与USB_EpnR寄存器相关的缓冲区描述表。完整的分组缓冲区的说明和缓冲区描
述表的用法请参考分组缓冲区的结构和用途章节。
发送缓冲区地址寄存器 n()
地址偏移:[USB_BTABLE] ×2 + n×16
USB本地地址:[USB_BTABLE] + n×8

使用特权

评论回复
8
u012801|  楼主 | 2013-12-21 17:00 | 只看该作者
上面這段望高手解釋一下
有圖就更好了

使用特权

评论回复
9
u012801|  楼主 | 2013-12-21 17:15 | 只看该作者
amobbs.com/thread-3843061-1-1.html[/url][/url]

看了 為什要 乘 2 啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

7

帖子

0

粉丝