1. 修改EP数量,用到EP0,EP1,EP2,EP3共4个端点
#define EP_NUM (4)
2. 修改端点的PMA分配
/* EP0 */
/* rx/tx buffer base address */
#define ENDP0_RXADDR (0x40) //0x80-0x40 = 0x40 = 64字节
#define ENDP0_TXADDR (0x80) //0xC0 - 0x80 = 0x40 = 64字节
/* EP1 */
/* tx buffer base address */
#define ENDP1_TXADDR (0xC0) //
#define ENDP2_TXADDR (0x100)
#define ENDP3_RXADDR (0x110)
3. 初始化端点,主要是EP1,EP2,EP3的初始化改动
/* Initialize Endpoint 1 */
SetEPType(ENDP1, EP_BULK);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxStatus(ENDP1, EP_RX_DIS);
/* Initialize Endpoint 2 */
SetEPType(ENDP2, EP_INTERRUPT);
SetEPTxAddr(ENDP2, ENDP2_TXADDR);
SetEPRxStatus(ENDP2, EP_RX_DIS);
SetEPTxStatus(ENDP2, EP_TX_NAK);
/* Initialize Endpoint 3 */
SetEPType(ENDP3, EP_BULK);
SetEPRxAddr(ENDP3, ENDP3_RXADDR);
SetEPRxCount(ENDP3, VIRTUAL_COM_PORT_DATA_SIZE);
SetEPRxStatus(ENDP3, EP_RX_VALID);
SetEPTxStatus(ENDP3, EP_TX_DIS);
4. 修改EP的回调函数
在USB的中断中要增加一个SOF的回调函数。
if (wIstr & ISTR_SOF & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_SOF);
//USB_ISTR_INFO(Printf("USB SOF\r\n"));
bIntPackSOF++;
#ifdef SOF_CALLBACK
SOF_Callback();
#endif
}
EP1是数据IN,即设备发送数据给USB主机,串口输入,从串口读入数据,判断是否大于端点1的缓冲区大小,如果大于就只发送缓冲区大小的数据到端点。
void EP1_IN_Callback(void)
{
uint8_t buf[USB_VIRTUAL_COM_PORT_DATA_LEN];
uint16_t uartRxLen = uartGetQueueStatus(UART_VCOM);
if( uartRxLen > 0)
{
uint8_t count = (uartRxLen > USB_VIRTUAL_COM_PORT_DATA_LEN) ?
USB_VIRTUAL_COM_PORT_DATA_LEN : uartRxLen;
uartReadBytes(UART_VCOM, buf, count);
UserToPMABufferCopy(buf, ENDP1_TXADDR, count);
SetEPTxCount(ENDP1, count);
SetEPTxValid(ENDP1);
}
}
EP3是数据OUT,即USB主机发送数据给设备,串口输出,从缓冲区读入数据,UART发送即可
void EP3_OUT_Callback(void)
{
uint8_t buf[USB_VIRTUAL_COM_PORT_DATA_LEN];
uint16_t uartTxLen = USB_SIL_Read(EP3_OUT, buf);
uartWriteBytes(UART_VCOM, buf, uartTxLen);
SetEPRxValid(ENDP3);
}
在端点1 IN中可能会出现串口并没有完全发送完,这里是在SOF中断中继续发送串口数据。
void SOF_Callback(void)
{
static uint8_t FrameCount = 0;
if(gbUsbDeviceState == CONFIGURED)
{
FrameCount++;
if(FrameCount >= 5)
{
FrameCount = 0;
EP1_IN_Callback();
}
}
}