simplify code

pull/13/head
XIVN1987 3 years ago
parent 7d3e19af69
commit d84b28f1d9
  1. 2
      AT32F425/DAPLink.uvoptx
  2. 8
      AT32F425/src/hid_transfer.c
  3. 20
      AT32F425/src/vcom_serial.c
  4. 6
      AT32F425/src/vcom_serial.h
  5. 4
      M482/DAPLink.uvoptx
  6. 89
      M482/src/descriptors.c
  7. 74
      M482/src/hid_transfer.c
  8. 16
      M482/src/hid_transfer.h
  9. 10
      M482/src/main.c
  10. 180
      M482/src/vcom_serial.c
  11. 13
      M482/src/vcom_serial.h
  12. 8
      README.md

@ -226,7 +226,7 @@
<Group> <Group>
<GroupName>APP</GroupName> <GroupName>APP</GroupName>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>

@ -9,7 +9,6 @@
static usb_setup_type Setup; static usb_setup_type Setup;
static uint8_t hid_rx_buff[64]; static uint8_t hid_rx_buff[64];
uint8_t cdc_rx_buff[64];
/** /**
@ -37,7 +36,7 @@ static usb_sts_type class_init_handler(void *udev)
usbd_ept_open(usbd, CDC_BULK_IN_EP, EPT_BULK_TYPE, CDC_BULK_IN_SZ); usbd_ept_open(usbd, CDC_BULK_IN_EP, EPT_BULK_TYPE, CDC_BULK_IN_SZ);
usbd_ept_open(usbd, CDC_BULK_OUT_EP, EPT_BULK_TYPE, CDC_BULK_OUT_SZ); usbd_ept_open(usbd, CDC_BULK_OUT_EP, EPT_BULK_TYPE, CDC_BULK_OUT_SZ);
usbd_ept_recv(usbd, CDC_BULK_OUT_EP, cdc_rx_buff, CDC_BULK_OUT_SZ); usbd_ept_recv(usbd, CDC_BULK_OUT_EP, (uint8_t *)Vcom.out_buff, CDC_BULK_OUT_SZ);
return USB_OK; return USB_OK;
} }
@ -182,7 +181,7 @@ static usb_sts_type class_in_handler(void *udev, uint8_t ept_num)
break; break;
case CDC_BULK_IN_EP: case CDC_BULK_IN_EP:
VCOM_InComplete(); Vcom.in_ready = 1;
break; break;
} }
@ -212,7 +211,8 @@ static usb_sts_type class_out_handler(void *udev, uint8_t ept_num)
break; break;
case CDC_BULK_OUT_EP: case CDC_BULK_OUT_EP:
VCOM_GetOutData(cdc_rx_buff, recv_len); Vcom.out_bytes = recv_len;
Vcom.out_ready = 1;
break; break;
} }

@ -116,21 +116,6 @@ void USART2_IRQHandler(void)
} }
void VCOM_InComplete(void)
{
Vcom.in_ready = 1;
}
void VCOM_GetOutData(uint8_t * buf, uint32_t len)
{
Vcom.out_pbuf = buf;
Vcom.out_bytes = len;
Vcom.out_ready = 1;
}
extern otg_core_type Otg; extern otg_core_type Otg;
void VCOM_TransferData(void) void VCOM_TransferData(void)
@ -175,7 +160,7 @@ void VCOM_TransferData(void)
{ {
for(int i = 0; i < Vcom.out_bytes; i++) for(int i = 0; i < Vcom.out_bytes; i++)
{ {
Vcom.tx_buff[Vcom.tx_wrptr++] = Vcom.out_pbuf[i]; Vcom.tx_buff[Vcom.tx_wrptr++] = Vcom.out_buff[i];
if(Vcom.tx_wrptr >= TX_BUFF_SIZE) if(Vcom.tx_wrptr >= TX_BUFF_SIZE)
Vcom.tx_wrptr = 0; Vcom.tx_wrptr = 0;
} }
@ -187,8 +172,7 @@ void VCOM_TransferData(void)
Vcom.out_ready = 0; Vcom.out_ready = 0;
/* Ready for next BULK OUT */ /* Ready for next BULK OUT */
extern uint8_t cdc_rx_buff[64]; usbd_ept_recv(&Otg.dev, CDC_BULK_OUT_EP, (uint8_t *)Vcom.out_buff, CDC_BULK_OUT_SZ);
usbd_ept_recv(&Otg.dev, CDC_BULK_OUT_EP, cdc_rx_buff, CDC_BULK_OUT_SZ);
} }
if((Vcom.tx_bytes) && (USART2->ctrl1_bit.tdbeien == 0)) if((Vcom.tx_bytes) && (USART2->ctrl1_bit.tdbeien == 0))

@ -20,7 +20,7 @@ typedef struct {
uint8_t in_buff[64] __attribute__((aligned(4))); uint8_t in_buff[64] __attribute__((aligned(4)));
uint16_t in_bytes; uint16_t in_bytes;
uint16_t in_ready; uint16_t in_ready;
uint8_t *out_pbuf; uint8_t out_buff[64];
uint16_t out_bytes; uint16_t out_bytes;
uint16_t out_ready; uint16_t out_ready;
} VCOM; } VCOM;
@ -43,8 +43,4 @@ void VCOM_TransferData(void);
void VCOM_LineCoding(VCOM_LINE_CODING * LineCfgx); void VCOM_LineCoding(VCOM_LINE_CODING * LineCfgx);
void VCOM_InComplete(void);
void VCOM_GetOutData(uint8_t * buf, uint32_t len);
#endif // __VCOM_SERIAL_H__ #endif // __VCOM_SERIAL_H__

@ -269,7 +269,7 @@
<Group> <Group>
<GroupName>DAP</GroupName> <GroupName>DAP</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@ -425,7 +425,7 @@
<Group> <Group>
<GroupName>CSL/CMSIS</GroupName> <GroupName>CSL/CMSIS</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>

@ -53,9 +53,9 @@ uint8_t gu8ConfigDescriptor[] =
#else #else
#define TOTAL_LEN_0 (LEN_CONFIG + (LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT)) #define TOTAL_LEN_0 (LEN_CONFIG + (LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT))
#endif #endif
#define TOTAL_LEN (TOTAL_LEN_0 + (8 + LEN_INTERFACE + 5 + 5 + 4 + 5 + LEN_ENDPOINT + LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT) * VCOM_COUNT) #define TOTAL_LEN (TOTAL_LEN_0 + (8 + LEN_INTERFACE + 5 + 5 + 4 + 5 + LEN_ENDPOINT + LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT))
TOTAL_LEN & 0xFF, TOTAL_LEN >> 8, // wTotalLength TOTAL_LEN & 0xFF, TOTAL_LEN >> 8, // wTotalLength
(1 + 2*VCOM_COUNT), // bNumInterfaces (1 + 2), // bNumInterfaces
0x01, // bConfigurationValue 0x01, // bConfigurationValue
0x00, // iConfiguration 0x00, // iConfiguration
0x00, // bmAttributes, D6: self power D5: remote wake-up 0x00, // bmAttributes, D6: self power D5: remote wake-up
@ -194,91 +194,6 @@ uint8_t gu8ConfigDescriptor[] =
EP_BULK, // bmAttributes EP_BULK, // bmAttributes
EP6_MAX_PKT_SIZE, 0x00, // wMaxPacketSize EP6_MAX_PKT_SIZE, 0x00, // wMaxPacketSize
0x00, // bInterval 0x00, // bInterval
#if VCOM_COUNT > 1
// Interface Association Descriptor (IAD)
0x08, // bLength
0x0B, // bDescriptorType: IAD
0x03, // bFirstInterface
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol
0x00, // iFunction, ÃèÊö×Ö·û´®Ë÷Òý
// I/F descriptor: VCOM
LEN_INTERFACE, // bLength
DESC_INTERFACE, // bDescriptorType
0x03, // bInterfaceNumber
0x00, // bAlternateSetting
0x01, // bNumEndpoints
0x02, // bInterfaceClass
0x02, // bInterfaceSubClass
0x01, // bInterfaceProtocol
0x00, // iInterface
// Communication Class Specified INTERFACE descriptor
0x05, // Size of the descriptor, in bytes
0x24, // CS_INTERFACE descriptor type
0x00, // Header functional descriptor subtype
0x10, 0x01, // Communication device compliant to the communication spec. ver. 1.10
// Communication Class Specified INTERFACE descriptor
0x05, // Size of the descriptor, in bytes
0x24, // CS_INTERFACE descriptor type
0x01, // Call management functional descriptor
0x00, // BIT0: Whether device handle call management itself.
// BIT1: Whether device can send/receive call management information over a Data Class Interface 0
0x04, // Interface number of data class interface optionally used for call management
// Communication Class Specified INTERFACE descriptor
0x04, // Size of the descriptor, in bytes
0x24, // CS_INTERFACE descriptor type
0x02, // Abstract control management functional descriptor subtype
0x00, // bmCapabilities
// Communication Class Specified INTERFACE descriptor
0x05, // bLength
0x24, // bDescriptorType: CS_INTERFACE descriptor type
0x06, // bDescriptorSubType
0x03, // bMasterInterface
0x04, // bSlaveInterface0
// ENDPOINT descriptor
LEN_ENDPOINT, // bLength
DESC_ENDPOINT, // bDescriptorType
(EP_INPUT | CDC2_INT_IN_EP), // bEndpointAddress
EP_INT, // bmAttributes
EP7_MAX_PKT_SIZE, 0x00, // wMaxPacketSize
10, // bInterval
// I/F descriptor
LEN_INTERFACE, // bLength
DESC_INTERFACE, // bDescriptorType
0x04, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x0A, // bInterfaceClass
0x00, // bInterfaceSubClass
0x00, // bInterfaceProtocol
0x00, // iInterface
// ENDPOINT descriptor
LEN_ENDPOINT, // bLength
DESC_ENDPOINT, // bDescriptorType
(EP_INPUT | CDC2_BULK_IN_EP), // bEndpointAddress
EP_BULK, // bmAttributes
EP8_MAX_PKT_SIZE, 0x00, // wMaxPacketSize
0x00, // bInterval
// ENDPOINT descriptor
LEN_ENDPOINT, // bLength
DESC_ENDPOINT, // bDescriptorType
(EP_OUTPUT | CDC2_BULK_OUT_EP), // bEndpointAddress
EP_BULK, // bmAttributes
EP9_MAX_PKT_SIZE, 0x00, // wMaxPacketSize
0x00, // bInterval
#endif
}; };

@ -42,23 +42,6 @@ void HID_Init(void)
USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE); USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE);
/* trigger receive OUT data */ /* trigger receive OUT data */
USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE); USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE);
#if VCOM_COUNT > 1
/*****************************************************/
/* EP7 ==> Interrupt IN endpoint, address 4 */
USBD_CONFIG_EP(EP7, USBD_CFG_EPMODE_IN | CDC2_INT_IN_EP);
USBD_SET_EP_BUF_ADDR(EP7, EP7_BUF_BASE);
/* EP8 ==> Bulk IN endpoint, address 5 */
USBD_CONFIG_EP(EP8, USBD_CFG_EPMODE_IN | CDC2_BULK_IN_EP);
USBD_SET_EP_BUF_ADDR(EP8, EP8_BUF_BASE);
/* EP9 ==> Bulk Out endpoint, address 5 */
USBD_CONFIG_EP(EP9, USBD_CFG_EPMODE_OUT | CDC2_BULK_OUT_EP);
USBD_SET_EP_BUF_ADDR(EP9, EP9_BUF_BASE);
/* trigger receive OUT data */
USBD_SET_PAYLOAD_LEN(EP9, EP9_MAX_PKT_SIZE);
#endif
} }
@ -149,16 +132,7 @@ void USBD_IRQHandler(void)
extern uint8_t g_usbd_SetupPacket[]; extern uint8_t g_usbd_SetupPacket[];
if(g_usbd_SetupPacket[1] == SET_LINE_CODE) if(g_usbd_SetupPacket[1] == SET_LINE_CODE)
{ {
switch(g_usbd_SetupPacket[4]) // Interface number VCOM_LineCoding(&LineCfg);
{
case 1:
VCOM_LineCoding(UART2, &LineCfg, &Vcom);
break;
case 3:
VCOM_LineCoding(UART1, &LineCfg2, &Vcom2);
break;
}
} }
} }
@ -193,25 +167,6 @@ void USBD_IRQHandler(void)
USBD_CLR_INT_FLAG(USBD_INTSTS_EP6); USBD_CLR_INT_FLAG(USBD_INTSTS_EP6);
EP6_Handler(); EP6_Handler();
}
if(u32IntSts & USBD_INTSTS_EP7)
{
USBD_CLR_INT_FLAG(USBD_INTSTS_EP7);
}
if(u32IntSts & USBD_INTSTS_EP8) // Bulk IN
{
USBD_CLR_INT_FLAG(USBD_INTSTS_EP8);
EP8_Handler();
}
if(u32IntSts & USBD_INTSTS_EP9) // Bulk OUT
{
USBD_CLR_INT_FLAG(USBD_INTSTS_EP9);
EP9_Handler();
} }
} }
} }
@ -234,16 +189,7 @@ void HID_ClassRequest(void)
break; break;
case GET_LINE_CODE: case GET_LINE_CODE:
switch(buf[4]) // Interface number
{
case 1:
USBD_PrepareCtrlIn((uint8_t *)&LineCfg, 7); USBD_PrepareCtrlIn((uint8_t *)&LineCfg, 7);
break;
case 3:
USBD_PrepareCtrlIn((uint8_t *)&LineCfg2, 7);
break;
}
/* Status stage */ /* Status stage */
USBD_PrepareCtrlOut(0,0); USBD_PrepareCtrlOut(0,0);
@ -279,16 +225,7 @@ void HID_ClassRequest(void)
break; break;
case SET_LINE_CODE: case SET_LINE_CODE:
switch(buf[4]) // Interface number
{
case 1:
USBD_PrepareCtrlOut((uint8_t *)&LineCfg, 7); USBD_PrepareCtrlOut((uint8_t *)&LineCfg, 7);
break;
case 3:
USBD_PrepareCtrlOut((uint8_t *)&LineCfg2, 7);
break;
}
/* Status stage */ /* Status stage */
USBD_SET_DATA1(EP0); USBD_SET_DATA1(EP0);
@ -296,16 +233,7 @@ void HID_ClassRequest(void)
break; break;
case SET_CONTROL_LINE: case SET_CONTROL_LINE:
switch(buf[4]) // Interface number
{
case 1:
Vcom.hw_flow = (buf[3] << 8) | buf[2]; Vcom.hw_flow = (buf[3] << 8) | buf[2];
break;
case 3:
Vcom2.hw_flow = (buf[3] << 8) | buf[2];
break;
}
/* Status stage */ /* Status stage */
USBD_SET_DATA1(EP0); USBD_SET_DATA1(EP0);

@ -2,14 +2,11 @@
#define __HID_TRANSFER_H__ #define __HID_TRANSFER_H__
#define VCOM_COUNT 1 // 1 or 2
#define USBD_VID 0x0416 #define USBD_VID 0x0416
#ifdef DAP_FW_V1 #ifdef DAP_FW_V1
#define USBD_PID (0x5021 + (VCOM_COUNT - 1)) #define USBD_PID 0x5021
#else #else
#define USBD_PID (0x7687 + (VCOM_COUNT - 1)) #define USBD_PID 0x7687
#endif #endif
@ -22,9 +19,6 @@
#define CDC_INT_IN_EP 2 #define CDC_INT_IN_EP 2
#define CDC_BULK_IN_EP 3 #define CDC_BULK_IN_EP 3
#define CDC_BULK_OUT_EP 3 #define CDC_BULK_OUT_EP 3
#define CDC2_INT_IN_EP 4
#define CDC2_BULK_IN_EP 5
#define CDC2_BULK_OUT_EP 5
/* Define EP maximum packet size */ /* Define EP maximum packet size */
@ -35,9 +29,6 @@
#define EP4_MAX_PKT_SIZE 8 #define EP4_MAX_PKT_SIZE 8
#define EP5_MAX_PKT_SIZE 64 #define EP5_MAX_PKT_SIZE 64
#define EP6_MAX_PKT_SIZE 64 #define EP6_MAX_PKT_SIZE 64
#define EP7_MAX_PKT_SIZE 8
#define EP8_MAX_PKT_SIZE 64
#define EP9_MAX_PKT_SIZE 64
#define SETUP_BUF_BASE 0 #define SETUP_BUF_BASE 0
#define SETUP_BUF_SIZE 8 #define SETUP_BUF_SIZE 8
@ -48,9 +39,6 @@
#define EP4_BUF_BASE (EP3_BUF_BASE + EP3_MAX_PKT_SIZE) #define EP4_BUF_BASE (EP3_BUF_BASE + EP3_MAX_PKT_SIZE)
#define EP5_BUF_BASE (EP4_BUF_BASE + EP4_MAX_PKT_SIZE) #define EP5_BUF_BASE (EP4_BUF_BASE + EP4_MAX_PKT_SIZE)
#define EP6_BUF_BASE (EP5_BUF_BASE + EP5_MAX_PKT_SIZE) #define EP6_BUF_BASE (EP5_BUF_BASE + EP5_MAX_PKT_SIZE)
#define EP7_BUF_BASE (EP6_BUF_BASE + EP6_MAX_PKT_SIZE)
#define EP8_BUF_BASE (EP7_BUF_BASE + EP7_MAX_PKT_SIZE)
#define EP9_BUF_BASE (EP8_BUF_BASE + EP8_MAX_PKT_SIZE)
/* HID Class Specific Request */ /* HID Class Specific Request */

@ -22,8 +22,6 @@ int main(void)
USB_Config(); USB_Config();
SysTick_Config(CyclesPerUs * 1000); // 1ms interrupt
GPIO_SetMode(PC, (1 << 0), GPIO_MODE_OUTPUT); // PC0 => UART RXD ״ָ̬ʾ GPIO_SetMode(PC, (1 << 0), GPIO_MODE_OUTPUT); // PC0 => UART RXD ״ָ̬ʾ
GPIO_SetMode(PC, (1 << 1), GPIO_MODE_OUTPUT); // PC1 => UART TXD ״ָ̬ʾ GPIO_SetMode(PC, (1 << 1), GPIO_MODE_OUTPUT); // PC1 => UART TXD ״ָ̬ʾ
@ -89,11 +87,3 @@ void USB_Config(void)
NVIC_EnableIRQ(USBD_IRQn); NVIC_EnableIRQ(USBD_IRQn);
} }
uint32_t SysTick_Count = 0;
void SysTick_Handler(void)
{
SysTick_Count++;
}

@ -20,60 +20,28 @@ void VCOM_Init(void)
UART_ENABLE_INT(UART2, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk)); UART_ENABLE_INT(UART2, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
NVIC_EnableIRQ(UART2_IRQn); NVIC_EnableIRQ(UART2_IRQn);
#if VCOM_COUNT > 1
GPIO_SetPullCtl(PB, BIT2, GPIO_PUSEL_PULL_UP);
SYS->GPB_MFPL &= ~(SYS_GPB_MFPL_PB2MFP_Msk | SYS_GPB_MFPL_PB3MFP_Msk);
SYS->GPB_MFPL |= (SYS_GPB_MFPL_PB2MFP_UART1_RXD | SYS_GPB_MFPL_PB3MFP_UART1_TXD);
CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_HXT, CLK_CLKDIV0_UART1(1));
CLK_EnableModuleClock(UART1_MODULE);
UART_Open(UART1, 115200);
UART1->FIFO = (UART1->FIFO & (~UART_FIFO_RFITL_Msk)) | UART_FIFO_RFITL_8BYTES;
UART_SetTimeoutCnt(UART1, 50);
UART_ENABLE_INT(UART1, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
NVIC_EnableIRQ(UART1_IRQn);
#endif
} }
volatile VCOM Vcom, Vcom2; volatile VCOM Vcom = {.in_ready = 1};
void EP5_Handler(void) // Bulk IN void EP5_Handler(void) // Bulk IN
{ {
Vcom.in_bytes = 0; Vcom.in_ready = 1;
} }
void EP6_Handler(void) // Bulk OUT void EP6_Handler(void) // Bulk OUT
{ {
Vcom.out_bytes = USBD_GET_PAYLOAD_LEN(EP6); Vcom.out_bytes = USBD_GET_PAYLOAD_LEN(EP6);
Vcom.out_ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP6)); USBD_MemCopy((uint8_t *)Vcom.out_buff, (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP6)), Vcom.out_bytes);
Vcom.out_ready = 1; Vcom.out_ready = 1;
} }
void EP8_Handler(void) // Bulk IN
{
Vcom2.in_bytes = 0;
}
void EP9_Handler(void) // Bulk OUT
{
Vcom2.out_bytes = USBD_GET_PAYLOAD_LEN(EP9);
Vcom2.out_ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP9));
Vcom2.out_ready = 1;
}
VCOM_LINE_CODING LineCfg = {115200, 0, 0, 8}; // Baud rate, stop bits, parity bits, data bits VCOM_LINE_CODING LineCfg = {115200, 0, 0, 8}; // Baud rate, stop bits, parity bits, data bits
VCOM_LINE_CODING LineCfg2 = {115200, 0, 0, 8};
void VCOM_LineCoding(UART_T * UARTx, VCOM_LINE_CODING * LineCfgx, volatile VCOM * Vcomx) void VCOM_LineCoding(VCOM_LINE_CODING * LineCfgx)
{ {
uint32_t data_len, parity, stop_len; uint32_t data_len, parity, stop_len;
@ -107,50 +75,47 @@ void VCOM_LineCoding(UART_T * UARTx, VCOM_LINE_CODING * LineCfgx, volatile VCOM
__disable_irq(); __disable_irq();
// Reset software FIFO // Reset software FIFO
Vcomx->rx_bytes = 0; Vcom.rx_bytes = 0;
Vcomx->rx_head = 0; Vcom.rx_head = 0;
Vcomx->rx_tail = 0; Vcom.rx_tail = 0;
Vcomx->tx_bytes = 0; Vcom.tx_bytes = 0;
Vcomx->tx_head = 0; Vcom.tx_head = 0;
Vcomx->tx_tail = 0; Vcom.tx_tail = 0;
// Reset hardware FIFO // Reset hardware FIFO
UARTx->FIFO |= (UART_FIFO_RXRST_Msk | UART_FIFO_TXRST_Msk); UART2->FIFO |= (UART_FIFO_RXRST_Msk | UART_FIFO_TXRST_Msk);
UART_SetLineConfig(UARTx, LineCfgx->u32DTERate, data_len, parity, stop_len); UART_SetLineConfig(UART2, LineCfgx->u32DTERate, data_len, parity, stop_len);
__enable_irq(); __enable_irq();
} }
void UARTX_IRQHandler(UART_T * UARTx, volatile VCOM * Vcomx) void UART2_IRQHandler(void)
{ {
uint8_t chr; if((UART2->INTSTS & UART_INTSTS_RDAIF_Msk) || (UART2->INTSTS & UART_INTSTS_RXTOIF_Msk))
int32_t size;
if((UARTx->INTSTS & UART_INTSTS_RDAIF_Msk) || (UARTx->INTSTS & UART_INTSTS_RXTOIF_Msk))
{ {
while((UARTx->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0) while((UART2->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0)
{ {
chr = UARTx->DAT; uint8_t chr = UART2->DAT;
if(Vcomx->rx_bytes < RX_BUFF_SIZE) // Check if buffer full if(Vcom.rx_bytes < RX_BUFF_SIZE) // Check if buffer full
{ {
Vcomx->rx_buff[Vcomx->rx_tail++] = chr; Vcom.rx_buff[Vcom.rx_tail++] = chr;
if(Vcomx->rx_tail >= RX_BUFF_SIZE) if(Vcom.rx_tail >= RX_BUFF_SIZE)
Vcomx->rx_tail = 0; Vcom.rx_tail = 0;
Vcomx->rx_bytes++; Vcom.rx_bytes++;
} }
} }
} }
if(UARTx->INTSTS & UART_INTSTS_THREIF_Msk) if(UART2->INTSTS & UART_INTSTS_THREIF_Msk)
{ {
if(Vcomx->tx_bytes) if(Vcom.tx_bytes)
{ {
/* Fill the Tx FIFO */ /* Fill the Tx FIFO */
size = Vcomx->tx_bytes; int size = Vcom.tx_bytes;
if(size >= TX_FIFO_SIZE) if(size >= TX_FIFO_SIZE)
{ {
size = TX_FIFO_SIZE; size = TX_FIFO_SIZE;
@ -158,119 +123,96 @@ void UARTX_IRQHandler(UART_T * UARTx, volatile VCOM * Vcomx)
while(size) while(size)
{ {
UARTx->DAT = Vcomx->tx_buff[Vcomx->tx_head++]; UART2->DAT = Vcom.tx_buff[Vcom.tx_head++];
if(Vcomx->tx_head >= TX_BUFF_SIZE) if(Vcom.tx_head >= TX_BUFF_SIZE)
Vcomx->tx_head = 0; Vcom.tx_head = 0;
Vcomx->tx_bytes--; Vcom.tx_bytes--;
size--; size--;
} }
} }
else else
{ {
/* No more data, just stop Tx (Stop work) */ /* No more data, just stop Tx (Stop work) */
UARTx->INTEN &= ~UART_INTEN_THREIEN_Msk; UART2->INTEN &= ~UART_INTEN_THREIEN_Msk;
}
} }
} }
void UART2_IRQHandler(void)
{
UARTX_IRQHandler(UART2, &Vcom);
}
void UART1_IRQHandler(void)
{
UARTX_IRQHandler(UART1, &Vcom2);
} }
void VCOM_TransferData(void)
void VCOMX_TransferData(volatile VCOM * Vcomx, UART_T * UARTx, uint32_t InEP, uint32_t InEP_MAX_PKT_SIZE, uint32_t OutEP, uint32_t OutEP_MAX_PKT_SIZE)
{ {
int32_t i, len;
/* Check whether USB is ready for next packet or not */ /* Check whether USB is ready for next packet or not */
if(Vcomx->in_bytes == 0) if(Vcom.in_ready)
{ {
/* Check whether we have new COM Rx data to send to USB or not */ /* Check whether we have new COM Rx data to send to USB or not */
if(Vcomx->rx_bytes) if(Vcom.rx_bytes)
{ {
len = Vcomx->rx_bytes; Vcom.in_bytes = Vcom.rx_bytes;
if(len > InEP_MAX_PKT_SIZE) if(Vcom.in_bytes > EP5_MAX_PKT_SIZE)
len = InEP_MAX_PKT_SIZE; Vcom.in_bytes = EP5_MAX_PKT_SIZE;
for(i = 0; i < len; i++) for(int i = 0; i < Vcom.in_bytes; i++)
{ {
Vcomx->in_buff[i] = Vcomx->rx_buff[Vcomx->rx_head++]; Vcom.in_buff[i] = Vcom.rx_buff[Vcom.rx_head++];
if(Vcomx->rx_head >= RX_BUFF_SIZE) if(Vcom.rx_head >= RX_BUFF_SIZE)
Vcomx->rx_head = 0; Vcom.rx_head = 0;
} }
__disable_irq(); __disable_irq();
Vcomx->rx_bytes -= len; Vcom.rx_bytes -= Vcom.in_bytes;
__enable_irq(); __enable_irq();
Vcomx->in_bytes = len; Vcom.in_ready = 0;
USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(InEP)), (uint8_t *)Vcomx->in_buff, len); USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5)), (uint8_t *)Vcom.in_buff, Vcom.in_bytes);
USBD_SET_PAYLOAD_LEN(InEP, len); USBD_SET_PAYLOAD_LEN(EP5, Vcom.in_bytes);
} }
else else
{ {
/* Prepare a zero packet if previous packet size is InEP_MAX_PKT_SIZE and /* Prepare a zero packet if previous packet size is InEP_MAX_PKT_SIZE and
no more data to send at this moment to note Host the transfer has been done */ no more data to send at this moment to note Host the transfer has been done */
len = USBD_GET_PAYLOAD_LEN(InEP); if(Vcom.in_bytes == EP5_MAX_PKT_SIZE)
if(len == InEP_MAX_PKT_SIZE) USBD_SET_PAYLOAD_LEN(EP5, 0);
USBD_SET_PAYLOAD_LEN(InEP, 0);
} }
} }
/* Process the Bulk out data when bulk out data is ready. */ /* Process the Bulk out data when bulk out data is ready. */
if(Vcomx->out_ready && (Vcomx->out_bytes <= TX_BUFF_SIZE - Vcomx->tx_bytes)) if(Vcom.out_ready && (Vcom.out_bytes <= TX_BUFF_SIZE - Vcom.tx_bytes))
{ {
for(i = 0; i < Vcomx->out_bytes; i++) for(int i = 0; i < Vcom.out_bytes; i++)
{ {
Vcomx->tx_buff[Vcomx->tx_tail++] = Vcomx->out_ptr[i]; Vcom.tx_buff[Vcom.tx_tail++] = Vcom.out_buff[i];
if(Vcomx->tx_tail >= TX_BUFF_SIZE) if(Vcom.tx_tail >= TX_BUFF_SIZE)
Vcomx->tx_tail = 0; Vcom.tx_tail = 0;
} }
__disable_irq(); __disable_irq();
Vcomx->tx_bytes += Vcomx->out_bytes; Vcom.tx_bytes += Vcom.out_bytes;
__enable_irq(); __enable_irq();
Vcomx->out_bytes = 0; Vcom.out_bytes = 0;
Vcomx->out_ready = 0; /* Clear bulk out ready flag */ Vcom.out_ready = 0; /* Clear bulk out ready flag */
/* Ready to get next BULK out */ /* Ready to get next BULK out */
USBD_SET_PAYLOAD_LEN(OutEP, OutEP_MAX_PKT_SIZE); USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE);
} }
/* Process the software Tx FIFO */ /* Process the software Tx FIFO */
if(Vcomx->tx_bytes) if(Vcom.tx_bytes)
{ {
/* Check if Tx is working */ /* Check if Tx is working */
if((UARTx->INTEN & UART_INTEN_THREIEN_Msk) == 0) if((UART2->INTEN & UART_INTEN_THREIEN_Msk) == 0)
{ {
/* Send one bytes out */ /* Send one bytes out */
UARTx->DAT = Vcomx->tx_buff[Vcomx->tx_head++]; UART2->DAT = Vcom.tx_buff[Vcom.tx_head++];
if(Vcomx->tx_head >= TX_BUFF_SIZE) if(Vcom.tx_head >= TX_BUFF_SIZE)
Vcomx->tx_head = 0; Vcom.tx_head = 0;
__disable_irq(); __disable_irq();
Vcomx->tx_bytes--; Vcom.tx_bytes--;
__enable_irq(); __enable_irq();
/* Enable Tx Empty Interrupt. (Trigger first one) */ /* Enable Tx Empty Interrupt. (Trigger first one) */
UARTx->INTEN |= UART_INTEN_THREIEN_Msk; UART2->INTEN |= UART_INTEN_THREIEN_Msk;
}
} }
} }
void VCOM_TransferData(void)
{
VCOMX_TransferData(&Vcom, UART2, EP5, EP5_MAX_PKT_SIZE, EP6, EP6_MAX_PKT_SIZE);
VCOMX_TransferData(&Vcom2, UART1, EP8, EP8_MAX_PKT_SIZE, EP9, EP9_MAX_PKT_SIZE);
} }

@ -16,7 +16,7 @@ typedef struct __attribute__((packed)) {
uint8_t u8DataBits; // data bits: 5, 6, 7, 8, 16 uint8_t u8DataBits; // data bits: 5, 6, 7, 8, 16
} VCOM_LINE_CODING; } VCOM_LINE_CODING;
extern VCOM_LINE_CODING LineCfg, LineCfg2; extern VCOM_LINE_CODING LineCfg;
@ -38,12 +38,13 @@ typedef struct {
uint8_t in_buff[64]; uint8_t in_buff[64];
uint16_t in_bytes; uint16_t in_bytes;
uint8_t *out_ptr; uint8_t in_ready;
uint8_t out_buff[64];
uint16_t out_bytes; uint16_t out_bytes;
uint16_t out_ready; uint8_t out_ready;
} VCOM; } VCOM;
extern volatile VCOM Vcom, Vcom2; extern volatile VCOM Vcom;
@ -51,10 +52,8 @@ void VCOM_Init(void);
void EP5_Handler(void); void EP5_Handler(void);
void EP6_Handler(void); void EP6_Handler(void);
void EP8_Handler(void);
void EP9_Handler(void);
void VCOM_LineCoding(UART_T * UARTx, VCOM_LINE_CODING * LineCfgx, volatile VCOM * Vcomx); void VCOM_LineCoding(VCOM_LINE_CODING * LineCfgx);
void VCOM_TransferData(void); void VCOM_TransferData(void);

@ -28,7 +28,7 @@ DAPLink (CMSIS-DAP) based on WCH CH32V203 (support crystal-less USB), supports S
| LED_SWD | PA.4 | | LED_SWD | PA.4 |
## DAPLink-M480 ## DAPLink-M480
DAPLink (CMSIS-DAP) based on Nuvoton M480, supports SWD and CDC (1 or 2). DAPLink (CMSIS-DAP) based on Nuvoton M480, supports SWD and CDC.
In the C/C++ page of Keil Option Window: In the C/C++ page of Keil Option Window:
* Define `DAP_FW_V1`: generate CMSIS-DAP V1 firmware, using HID transport protocol. * Define `DAP_FW_V1`: generate CMSIS-DAP V1 firmware, using HID transport protocol.
@ -45,9 +45,3 @@ In the C/C++ page of Keil Option Window:
| LED_SWD | PA.2 | | LED_SWD | PA.2 |
| LED_TXD | PC.1 | | LED_TXD | PC.1 |
| LED_RXD | PC.0 | | LED_RXD | PC.0 |
### Optional CDC2
| FUNC | Pin |
| :---- | :---- |
| CDC2_TXD | PB.3 |
| CDC2_RXD | PB.2 |

Loading…
Cancel
Save