基于STM32F103的USB学习笔记17 - 初始化端点

72 篇文章 36 订阅

USB 端点n寄存器(USB_EPnR), n=[0..7],其结构如下图:

CTR_RX: 正确接收标志位,由硬件置位,只能写0。

DTOG_RX: 用于数据接收的数据翻转位,此位应用程序可读可写,但写0无效,写1可以翻转此位。

STAT_RX[1:0]:用于数据接收的状态位,此位用于指示端点当前的状态,这些位也是写0无效,写1翻转

SETUP:SETUP分组传输完成标志位,硬件置位并且只有控制端点才使用。此位应用程序只读。

EP_TPYE[1:0]:端点类型位

EP_KIND:端点特殊类型位
此位的需要和EP_TYPE位配合使用

CTR_TX:正确发送标志位,由硬件置位,只能写0。

DTOG_TX:发送数据翻转位,与DTOG_RX功能类似

STAT_TX[1:0]:用于发送数据的状态位,与STAT_RX功能类似

EA[3:0]:端点地址,应用程序必需设置此4位,在使能一个端点前为它定义一个地址。

初始化步骤

1. 设置端点类型

void SetEPType(uint8_t bEpNum, uint16_t wType)

STM32F103支持8个EP:

#define ENDP0       ((uint8_t)0)
#define ENDP1       ((uint8_t)1)
#define ENDP2       ((uint8_t)2)
#define ENDP3       ((uint8_t)3)
#define ENDP4       ((uint8_t)4)
#define ENDP5       ((uint8_t)5)
#define ENDP6       ((uint8_t)6)
#define ENDP7       ((uint8_t)7)

4种EP类型:

#define EP_BULK        (0x0000) /* EndPoint BULK */
#define EP_CONTROL     (0x0200) /* EndPoint CONTROL */
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
#define EP_INTERRUPT   (0x0600) /* EndPoint INTERRUPT */

例如端点0都是EP_CONTROL:

SetEPType(ENDP0, EP_CONTROL);

2.  设置端点的状态,如果是单向,需要把不使用的方向设置为EP_RX_DIS或EP_TX_DIS

void SetEPTxStatus(uint8_t bEpNum, uint16_t wState),对应的宏定义:
#define _SetEPTxStatus(bEpNum,wState) {\
    register uint16_t _wRegVal;       \
    _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
    /* toggle first bit ? */     \
    if((EPTX_DTOG1 & wState)!= 0)      \
      _wRegVal ^= EPTX_DTOG1;        \
    /* toggle second bit ?  */         \
    if((EPTX_DTOG2 & wState)!= 0)      \
      _wRegVal ^= EPTX_DTOG2;        \
    _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX));    \
  } /* _SetEPTxStatus */

注意这些bits是写1翻转,所以写的有点复杂。

3. 设置端点的PMA地址

    SetEPRxAddr(ENDP0, ENDP0_RXADDR);
    SetEPTxAddr(ENDP0, ENDP0_TXADDR);

4. 设置EP_KIND

Clear_Status_Out(ENDP0); //清除Status Out状态,仅EP0

5. 设置Count值

根据端点的方向设置对应的Count值。

6. 如果是RX,使能端点RX有效

SetEPRxValid(ENDP0);

#define _SetEPRxStatus(bEpNum,wState) {\
    register uint16_t _wRegVal;   \
    \
    _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
    /* toggle first bit ? */  \
    if((EPRX_DTOG1 & wState)!= 0) \
      _wRegVal ^= EPRX_DTOG1;  \
    /* toggle second bit ? */  \
    if((EPRX_DTOG2 & wState)!= 0) \
      _wRegVal ^= EPRX_DTOG2;  \
    _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX)); \
  } /* _SetEPRxStatus */

7. 设置EP地址

  /* set address in every used endpoint */
  for (i = 0; i < nEP; i++)
  {
    _SetEPAddress((uint8_t)i, (uint8_t)i);
  }

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值