bleSDK_expansion_board/examples/usb2uart/src/cdc_uart.c

232 lines
6.7 KiB
C
Raw Normal View History

#include "usbd.h"
#include "usbd_cdc.h"
#include "uart.h"
#define USBD_BCD USB_2_0 // Version
#define USBD_VID 0xFFFF // Vendor ID
#define USBD_PID 0xFFFF // Product ID
#define USBD_MAX_POWER 100 // unit in mA
#define USBD_LANGID_STRING 0x0409 // English(US)
#define ENB_CDC_CNT 1
#if (ENB_CDC_CNT == 0 || ENB_CDC_CNT > 3)
#error "The count of USB-Serial be 1 ~ 3."
#endif
/*
* Descriptor
****************************************************************************
*/
#define CDC0_IN_EP 0x81
#define CDC0_OUT_EP 0x01
#define CDC0_INT_EP 0x81+ENB_CDC_CNT
#define CDC0_INTF_NUM 0
#if (ENB_CDC_CNT > 1)
#define CDC1_IN_EP 0x82
#define CDC1_OUT_EP 0x02
#define CDC1_INT_EP 0x82+ENB_CDC_CNT
#define CDC1_INTF_NUM 2
#endif
#if (ENB_CDC_CNT > 2)
#define CDC2_IN_EP 0x83
#define CDC2_OUT_EP 0x03
#define CDC2_INT_EP 0x83+ENB_CDC_CNT
#define CDC2_INTF_NUM 4
#endif
#define USB_CDC_INTF_CNT (2 * ENB_CDC_CNT) // Cmd Intf + Data Intf
#define USB_CDC_INTF_END (USB_CDC_INTF_CNT - 1)
#define USB_CDC_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN * ENB_CDC_CNT)
/*!< cdc device descriptor */
static const uint8_t cdc_descriptor[] = {
/* Descriptor - Device (Size:18) */
USB_DEVICE_DESCRIPTOR_INIT(USBD_BCD, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
/* Descriptor - Configuration (Total Size:9+Intf_Size) */
USB_CONFIG_DESCRIPTOR_INIT(USB_CDC_CONFIG_SIZE, USB_CDC_INTF_CNT, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/* Descriptor - CDC Interface (Size:66) */
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC0_INT_EP, CDC0_OUT_EP, CDC0_IN_EP, 0x02),
#if (ENB_CDC_CNT > 1)
CDC_ACM_DESCRIPTOR_INIT(0x02, CDC1_INT_EP, CDC1_OUT_EP, CDC1_IN_EP, 0x02),
#endif
#if (ENB_CDC_CNT > 2)
CDC_ACM_DESCRIPTOR_INIT(0x04, CDC2_INT_EP, CDC2_OUT_EP, CDC2_IN_EP, 0x02),
#endif
/* Descriptor - String */
// String0 - Language ID (Size:4)
USB_LANGID_INIT(USBD_LANGID_STRING),
// String1 - iManufacturer
0x02, /* bLength */
USB_DESC_TYPE_STRING, /* bDescriptorType */
// String2 - iProduct
0x16, /* bLength */
USB_DESC_TYPE_STRING, /* bDescriptorType */
WCHAR('U'),
WCHAR('S'),
WCHAR('B'),
WCHAR('-'),
WCHAR('S'),
WCHAR('e'),
WCHAR('r'),
WCHAR('i'),
WCHAR('a'),
WCHAR('l'),
// String3 - iSerialNumber
// 0x10, /* bLength */
// USB_DESC_TYPE_STRING, /* bDescriptorType */
// WCHAR('6'),
// WCHAR('.'),
// WCHAR('2'),
// WCHAR('2'),
// WCHAR('.'),
// WCHAR('0'),
// WCHAR('7'),
/* Descriptor - Device Qualifier (Size:10) */
#if (USBD_BCD == USB_2_0)
USB_QUALIFIER_INIT(0x01),
#endif
/* Descriptor - EOF */
0x00
};
/*
* Configuration
****************************************************************************
*/
static const usbd_ep_t endpoint_tab[] = {
USBD_EP_T(CDC0_INT_EP, USB_EP_TYPE_INTERRUPT, CDC_INT_EP_MPS, NULL),
USBD_EP_T(CDC0_OUT_EP, USB_EP_TYPE_BULK, CDC_BULK_EP_MPS, &usbd_cdc_bulk_out_handler),
USBD_EP_T(CDC0_IN_EP, USB_EP_TYPE_BULK, CDC_BULK_EP_MPS, &usbd_cdc_bulk_in_handler),
#if (ENB_CDC_CNT > 1)
USBD_EP_T(CDC1_INT_EP, USB_EP_TYPE_INTERRUPT, CDC_INT_EP_MPS, NULL),
USBD_EP_T(CDC1_OUT_EP, USB_EP_TYPE_BULK, CDC_BULK_EP_MPS, &usbd_cdc_bulk_out_handler),
USBD_EP_T(CDC1_IN_EP, USB_EP_TYPE_BULK, CDC_BULK_EP_MPS, &usbd_cdc_bulk_in_handler),
#endif
#if (ENB_CDC_CNT > 2)
USBD_EP_T(CDC2_INT_EP, USB_EP_TYPE_INTERRUPT, CDC_INT_EP_MPS, NULL),
USBD_EP_T(CDC2_OUT_EP, USB_EP_TYPE_BULK, CDC_BULK_EP_MPS, &usbd_cdc_bulk_out_handler),
USBD_EP_T(CDC2_IN_EP, USB_EP_TYPE_BULK, CDC_BULK_EP_MPS, &usbd_cdc_bulk_in_handler),
#endif
};
static const usbd_class_t class_tab[] = {
USBD_CLASS_T(0, USB_CDC_INTF_END, &usbd_cdc_class_handler),
};
static const usbd_config_t cdc_configuration[] = {
USBD_CONFIG_T(1, USB_CDC_INTF_CNT, class_tab, endpoint_tab)
};
/*
* Handlers
****************************************************************************
*/
volatile uint8_t dtr_enable = 0;
void usbd_cdc_updated(usbd_cdc_t *cdc, uint8_t type)
{
if (type == CDC_LINE_STATE) {
USB_LOG_RAW("CDC Update(ep:0x%02X,<DTR:0x%x,RTS:0x%x>)\r\n", cdc->ep_in, (cdc->line_state & 0x01), (cdc->line_state & 0x02));
dtr_enable = cdc->line_state;
} else {
USB_LOG_RAW("CDC Update(ep:0x%02X,<Rate:%d,DataBits:%d,Parity:%d,StopBits:%d>)\r\n", cdc->ep_in,
cdc->line_coding.dwDTERate, cdc->line_coding.bDataBits,
cdc->line_coding.bParityType, cdc->line_coding.bCharFormat);
}
}
void usbd_cdc_bulk_out_handler(uint8_t ep)
{
uint16_t read_byte;
uint8_t data[CDC_BULK_EP_MPS];
read_byte = usbd_ep_read(ep, CDC_BULK_EP_MPS, data);
USB_LOG_RAW("CDC Bulk Out(ep:%d,len:%d)\r\n", ep, read_byte);
/*!< here you can output data to hardware */
for (uint8_t i = 0; i < read_byte; i++) {
uart_putc(0, data[i]);
}
}
__USBIRQ void usbd_notify_handler(uint8_t event, void *arg)
{
switch (event) {
case USBD_EVENT_RESET:
usbd_cdc_reset();
break;
default:
break;
}
}
/*
* Test Functions
****************************************************************************
*/
#define CDC_BULK_TX_SIZE (CDC_BULK_EP_MPS-1)
uint8_t cdc_bulk_buff[CDC_BULK_TX_SIZE];
void usbdInit(void)
{
usbd_init();
usbd_register(cdc_descriptor, cdc_configuration);
usbd_cdc_init(0, CDC0_INTF_NUM, CDC0_IN_EP);
#if (ENB_CDC_CNT > 1)
usbd_cdc_init(1, CDC1_INTF_NUM, CDC1_IN_EP);
#endif
#if (ENB_CDC_CNT > 2)
usbd_cdc_init(2, CDC2_INTF_NUM, CDC2_IN_EP);
#endif
for (uint8_t i = 0; i < CDC_BULK_TX_SIZE; i++) {
cdc_bulk_buff[i] = '0' + i;
}
}
void usbdTest(void)
{
if (!usbd_is_configured())
return;
if (dtr_enable)
{
uint8_t status;
status = usbd_cdc_ep_send(CDC0_IN_EP, CDC_BULK_TX_SIZE, cdc_bulk_buff);
USB_LOG_RAW("CDC0 Send(sta:%d,len:%d)\r\n", status, CDC_BULK_TX_SIZE);
#if (ENB_CDC_CNT > 1)
status = usbd_cdc_ep_send(CDC1_IN_EP, CDC_BULK_TX_SIZE, cdc_bulk_buff);
USB_LOG_RAW("CDC1 Send(sta:%d,len:%d)\r\n", status, CDC_BULK_TX_SIZE);
#endif
#if (ENB_CDC_CNT > 2)
status = usbd_cdc_ep_send(CDC2_IN_EP, CDC_BULK_TX_SIZE, cdc_bulk_buff);
USB_LOG_RAW("CDC2 Send(sta:%d,len:%d)\r\n", status, CDC_BULK_TX_SIZE);
#endif
}
}