打印

请教香主STM32关于USB控制端点4的问题

[复制链接]
10773|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dzh_fly|  楼主 | 2010-6-23 11:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问香主,STM32的datasheet中标明USB控制端点是有8个的,可是现在我一使用控制端点4会出现问题,具体描述如下:
1.使用官方版本STM32_USB_FS_Device_Lib_V3.1.1中的JoyStickMouse例程,运行正常。
2.将Dvice_Table中的EP_NUM改为5,将JoyStickReset()中ENDP1全部换成ENDP3,;usb_desc.c中配置描述符相应端点换成0x83,0x03,JoyStick_Send()中作相应更改,运行测试一切正常。
3.将上述更改为ENDP3的地方全部换成ENDP4,运行就会进入到HardFault_Handler()中断中,更改测试其它例程情况也一样现象。

使用的型号为STM32F103VC,因为我们的项目需要用到4路端点,所以急需解决此问题,在线等!谢谢!
沙发
vigia| | 2010-6-23 13:42 | 只看该作者
EP4初始化了没有?有没有为EP4开数据缓存区?

EP4没有问题的,如果有问题都是程序的问题。

使用特权

评论回复
板凳
dzh_fly|  楼主 | 2010-6-23 14:24 | 只看该作者
谢谢你的回答。
你所指的是JoyStickReset()中的配置吗?我已经说明了是在官方例程上改的,请看我第2点中注明更改的地方。贴出代码如下:
改动处1
#define EP_NUM     (5)  //(2)
改动处2
/* Initialize Endpoint 1 */
/*  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxCount(ENDP1, 4);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
*/
  /* Initialize Endpoint 1 */
  SetEPType(ENDP4, EP_INTERRUPT);
  SetEPTxAddr(ENDP4, ENDP1_TXADDR);
  SetEPTxCount(ENDP4, 4);
  SetEPRxStatus(ENDP4, EP_RX_DIS);
  SetEPTxStatus(ENDP4, EP_TX_NAK);

改动处3
   0x84,//0x81,          /*bEndpointAddress: Endpoint Address (IN)*/

改动处4
  /* prepare buffer to send */
  Mouse_Buffer[1] = X;
  Mouse_Buffer[2] = Y;
  /*copy mouse position info in ENDP1 Tx Packet Memory Area*/
//  UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 4);
  UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP4), 4);
  /* enable endpoint for transmission */
//  SetEPTxValid(ENDP1);
  SetEPTxValid(ENDP4);

运行以后按方向键会直接进入HardFault_Handler()中

使用特权

评论回复
地板
香水城| | 2010-6-23 14:33 | 只看该作者
关键是有没有为EP4开数据缓存区?

为什么要分配EP1的缓存区给EP4:SetEPTxAddr(ENDP4, ENDP1_TXADDR);

使用特权

评论回复
5
dzh_fly|  楼主 | 2010-6-23 14:43 | 只看该作者
请问不能把 ENDP1_TXADDR 赋给 ENDP4的吗?
我并没有使用到ENDP1啊
在这里只是测试,简单描述下现象,实际项目当然是都有缓冲区的
如果我把改动部分改为下面的,则完全正常,不知作何解释
改动处1
#define EP_NUM     (5)  //(2)
改动处2
/* Initialize Endpoint 1 */
/*  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxCount(ENDP1, 4);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
*/
  /* Initialize Endpoint 1 */
  SetEPType(ENDP3, EP_INTERRUPT);
  SetEPTxAddr(ENDP3, ENDP1_TXADDR);
  SetEPTxCount(ENDP3, 4);
  SetEPRxStatus(ENDP3, EP_RX_DIS);
  SetEPTxStatus(ENDP3, EP_TX_NAK);

改动处3
   0x83,//0x81,          /*bEndpointAddress: Endpoint Address (IN)*/

改动处4
  /* prepare buffer to send */
  Mouse_Buffer[1] = X;
  Mouse_Buffer[2] = Y;
  /*copy mouse position info in ENDP1 Tx Packet Memory Area*/
//  UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 4);
  UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP3), 4);
  /* enable endpoint for transmission */
//  SetEPTxValid(ENDP1);
  SetEPTxValid(ENDP3);

使用特权

评论回复
6
vigia| | 2010-6-23 14:47 | 只看该作者
初始化的时候加上这句看看
SetEPAddress(ENDP4, 4);

实际上所有的端点控制寄存器都是一样的,端点地址也是可以指定的,所以EP4和EP1完全没有区别。

一般初始化没做好,都是USB传输失败,导致FAULT的倒很少看到,你不如看看是什么语句导致的FAULT

使用特权

评论回复
7
dzh_fly|  楼主 | 2010-6-23 15:02 | 只看该作者
谢谢!我开始写错了一点,是 STM32_USB_FS_Device_Lib_V3.0.1 中的JoyStickMouse例程,我其它地方完全没动过。加了SetEPAddress(ENDP4, 4);没有效果。
很奇怪的是,我把#define EP_NUM     (5)  //(2) 改到#define EP_NUM    (6) //(5)  //(2)  使用端点5又是正常的,端点2,3也正常,只是一到4就挂了,因为我处于开发阶段,还没量产没有批量机器测试,不知道是不是个别现象,好象这种可能性也不大。
单步跟踪,可以看到问题出在UserToPMABufferCopy中的for循环中,出不来了
希望哪位可以测试一下,谢谢了!

使用特权

评论回复
8
vigia| | 2010-6-23 15:05 | 只看该作者
你的ENDP1_TXADDR是多少?

使用特权

评论回复
9
vigia| | 2010-6-23 15:06 | 只看该作者
还有那个EP_NUM 是你用了几个EP不是你用到了第几个EP吧。

使用特权

评论回复
10
dzh_fly|  楼主 | 2010-6-23 15:19 | 只看该作者
EP_NUM 的意思确实是用到几个啊,比如你只用到了端点0和端点5,那么必须为6才行啊。
#define ENDP1_TXADDR        (0x100)

使用特权

评论回复
11
dzh_fly|  楼主 | 2010-6-23 15:23 | 只看该作者
现在已查到是运行到UserToPMABufferCopy中
    pdwVal++; //此语句执行时出错,
    pbUsrBuf++;
端点4时 pdwVal = 0x40017F1F   //错误
端点5时 pdwVal = 0x40006200  //正常
不知为何相差如此之大,还在找原因

使用特权

评论回复
12
vigia| | 2010-6-23 15:28 | 只看该作者
确实蛮奇怪的,找到原因一定要来说一下哦

使用特权

评论回复
13
dzh_fly|  楼主 | 2010-6-23 17:36 | 只看该作者
本帖最后由 dzh_fly 于 2010-6-23 17:38 编辑

经过一下午的调试,分析,问题解决了,为使大家也少走弯路,分享一下。
解释如下:
#define BTABLE_ADDRESS      (0x00)  //说明端点描述符表从0x00开始
每个端点描述符会占用4个uint32_t型,即16个字节
如果使用到端点4,需要将
#define ENDP0_RXADDR        (0x18)
#define ENDP0_TXADDR        (0x58)
改为
#define ENDP0_RXADDR        (0x50)  端点0-4  占用16*5=80个字节
#define ENDP0_TXADDR        (0x90)  端点0缓冲区占用字节Device_Property.MaxPacketSize=0x40;

以下端点分配需从 ENDP0_TXADDR + 0x40开始
EP1_RXBUF 等的大小根据需要自行定义,不贴出了。

#define         ENDP1_TXADDR                ((uint16_t)(0xD0))
#define         ENDP1_RXADDR                ((uint16_t)((ENDP1_TXADDR+EP1_TXBUF+1)/2*2)) //按字对齐

#define         ENDP2_TXADDR                ((uint16_t)((ENDP1_RXADDR+EP1_RXBUF+1)/2*2))
#define         ENDP2_RXADDR                ((uint16_t)((ENDP2_TXADDR+EP2_TXBUF+1)/2*2))

#define         ENDP3_TXADDR                ((uint16_t)((ENDP2_RXADDR+EP2_RXBUF+1)/2*2))
#define         ENDP3_RXADDR                ((uint16_t)((ENDP3_TXADDR+EP3_TXBUF+1)/2*2))

#define         ENDP4_TXADDR                ((uint16_t)((ENDP3_RXADDR+EP3_RXBUF+1)/2*2))
#define         ENDP4_RXADDR                ((uint16_t)((ENDP4_TXADDR+EP4_TXBUF+1)/2*2))

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
lxyppc + 1
14
xsgy123| | 2010-6-23 21:30 | 只看该作者
很好,问题解决了就应该分享的

使用特权

评论回复
15
sinadz| | 2010-6-23 21:44 | 只看该作者
还不是非常理解,再琢磨下

使用特权

评论回复
16
vigia| | 2010-6-23 21:52 | 只看该作者
确实如此,我前面忘记问你ep0了。

你研究的很透彻阿。

使用特权

评论回复
17
demeng| | 2010-6-24 13:16 | 只看该作者
受益了,楼主真强

使用特权

评论回复
18
pjdu| | 2010-9-26 11:32 | 只看该作者
学习了。

使用特权

评论回复
19
junsi| | 2011-8-28 23:16 | 只看该作者
被这个问题困扰了几天,看到lz的帖才得以解决,非常感谢

使用特权

评论回复
20
ljp123gl| | 2011-12-31 14:32 | 只看该作者
谢谢楼主分享。我也是被这个问题困扰了好长时间。

使用特权

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

本版积分规则

0

主题

22

帖子

2

粉丝