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

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

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

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

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

基于STM32F103的USB学习笔记17 - 初始化端点_第1张图片

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

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

基于STM32F103的USB学习笔记17 - 初始化端点_第2张图片

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

基于STM32F103的USB学习笔记17 - 初始化端点_第3张图片

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

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

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

基于STM32F103的USB学习笔记17 - 初始化端点_第4张图片

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);
  }

 

 

 

你可能感兴趣的:(MCU编程,USB)