基于STM32F103的USB学习笔记29 - 虚拟串口之端点

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

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