diff --git a/DAPLink.uvoptx b/DAPLink.uvoptx index 0f9e9b7..366d30f 100644 --- a/DAPLink.uvoptx +++ b/DAPLink.uvoptx @@ -120,7 +120,7 @@ 0 DLGUARM - ?}wé³»??}wé³»? + 0 @@ -269,7 +269,7 @@ DAP - 1 + 0 0 0 0 diff --git a/README.md b/README.md index f767067..12b3aad 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,24 @@ ## DAPLink -DAPLink (CMSIS-DAP) based on Nuvoton M480, supports SWD and CDC. +DAPLink (CMSIS-DAP) based on Nuvoton M480, supports SWD and CDC (1 or 2). In the C/C++ page of Keil Option Window: * Define `DAP_FW_V1`: generate CMSIS-DAP V1 firmware, using HID transport protocol. * Do not define `DAP_FW_V1`: Generate CMSIS-DAP V2 firmware, using WINUSB transfer protocol. ### Pin map -| FUNC | Pin | -| :---- | :---- | -| SWD_CLK | PA.1 | -| SWD_DIO | PA.0 | -| SWD_RST | PF.4 | -| CDC_TXD | PB.1 | -| CDC_RXD | PB.0 | -| LED_SWD | PA.2 | -| LED_TXD | PC.1 | -| LED_RXD | PC.0 | +| FUNC | Pin | +| :---- | :---- | +| SWD_CLK | PA.1 | +| SWD_DIO | PA.0 | +| SWD_RST | PF.4 | +| CDC_TXD | PB.1 | +| CDC_RXD | PB.0 | +| LED_SWD | PA.2 | +| LED_TXD | PC.1 | +| LED_RXD | PC.0 | + +### Optional CDC2 +| FUNC | Pin | +| :---- | :---- | +| CDC2_TXD | PB.3 | +| CDC2_RXD | PB.2 | diff --git a/doc/DAPLink.pcapng b/doc/DAPLink.pcapng deleted file mode 100644 index e6526da..0000000 Binary files a/doc/DAPLink.pcapng and /dev/null differ diff --git a/src/descriptors.c b/src/descriptors.c index 51e9f92..b8a7291 100644 --- a/src/descriptors.c +++ b/src/descriptors.c @@ -53,9 +53,9 @@ uint8_t gu8ConfigDescriptor[] = #else #define TOTAL_LEN_0 (LEN_CONFIG + (LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT)) #endif -#define TOTAL_LEN (TOTAL_LEN_0 + (8 + LEN_INTERFACE + 5 + 5 + 4 + 5 + LEN_ENDPOINT + LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT)) +#define TOTAL_LEN (TOTAL_LEN_0 + (8 + LEN_INTERFACE + 5 + 5 + 4 + 5 + LEN_ENDPOINT + LEN_INTERFACE + LEN_ENDPOINT + LEN_ENDPOINT) * VCOM_COUNT) TOTAL_LEN & 0xFF, TOTAL_LEN >> 8, // wTotalLength - 0x03, // bNumInterfaces + (1 + 2*VCOM_COUNT), // bNumInterfaces 0x01, // bConfigurationValue 0x00, // iConfiguration 0x00, // bmAttributes, D6: self power D5: remote wake-up @@ -194,6 +194,91 @@ uint8_t gu8ConfigDescriptor[] = EP_BULK, // bmAttributes EP6_MAX_PKT_SIZE, 0x00, // wMaxPacketSize 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 }; diff --git a/src/hid_transfer.c b/src/hid_transfer.c index ce2e717..db080a3 100644 --- a/src/hid_transfer.c +++ b/src/hid_transfer.c @@ -42,6 +42,23 @@ void HID_Init(void) USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE); /* trigger receive OUT data */ 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 } @@ -132,7 +149,16 @@ void USBD_IRQHandler(void) extern uint8_t g_usbd_SetupPacket[]; if(g_usbd_SetupPacket[1] == SET_LINE_CODE) { - VCOM_LineCoding(); + switch(g_usbd_SetupPacket[4]) // Interface number + { + case 1: + VCOM_LineCoding(UART2, &LineCfg, &Vcom); + break; + + case 3: + VCOM_LineCoding(UART1, &LineCfg2, &Vcom2); + break; + } } } @@ -167,6 +193,25 @@ void USBD_IRQHandler(void) USBD_CLR_INT_FLAG(USBD_INTSTS_EP6); 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(); } } } @@ -189,7 +234,16 @@ void HID_ClassRequest(void) break; case GET_LINE_CODE: - USBD_PrepareCtrlIn((uint8_t *)&LineCfg, 7); + switch(buf[4]) // Interface number + { + case 1: + USBD_PrepareCtrlIn((uint8_t *)&LineCfg, 7); + break; + + case 3: + USBD_PrepareCtrlIn((uint8_t *)&LineCfg2, 7); + break; + } /* Status stage */ USBD_PrepareCtrlOut(0,0); @@ -225,7 +279,16 @@ void HID_ClassRequest(void) break; case SET_LINE_CODE: - USBD_PrepareCtrlOut((uint8_t *)&LineCfg, 7); + switch(buf[4]) // Interface number + { + case 1: + USBD_PrepareCtrlOut((uint8_t *)&LineCfg, 7); + break; + + case 3: + USBD_PrepareCtrlOut((uint8_t *)&LineCfg2, 7); + break; + } /* Status stage */ USBD_SET_DATA1(EP0); @@ -233,7 +296,16 @@ void HID_ClassRequest(void) break; case SET_CONTROL_LINE: - Vcom.hw_flow = (buf[3] << 8) | buf[2]; + switch(buf[4]) // Interface number + { + case 1: + Vcom.hw_flow = (buf[3] << 8) | buf[2]; + break; + + case 3: + Vcom2.hw_flow = (buf[3] << 8) | buf[2]; + break; + } /* Status stage */ USBD_SET_DATA1(EP0); diff --git a/src/hid_transfer.h b/src/hid_transfer.h index 6e65543..f4bd82f 100644 --- a/src/hid_transfer.h +++ b/src/hid_transfer.h @@ -2,11 +2,14 @@ #define __HID_TRANSFER_H__ +#define VCOM_COUNT 1 // 1 or 2 + + #define USBD_VID 0x0416 #ifdef DAP_FW_V1 -#define USBD_PID 0x5021 +#define USBD_PID (0x5021 + (VCOM_COUNT - 1)) #else -#define USBD_PID 0x7687 +#define USBD_PID (0x7687 + (VCOM_COUNT - 1)) #endif @@ -19,6 +22,9 @@ #define CDC_INT_IN_EP 2 #define CDC_BULK_IN_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 */ @@ -29,7 +35,9 @@ #define EP4_MAX_PKT_SIZE 8 #define EP5_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_SIZE 8 @@ -40,6 +48,9 @@ #define EP4_BUF_BASE (EP3_BUF_BASE + EP3_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 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 */ diff --git a/src/vcom_serial.c b/src/vcom_serial.c index eaa5bd9..5f97a96 100644 --- a/src/vcom_serial.c +++ b/src/vcom_serial.c @@ -20,10 +20,28 @@ void VCOM_Init(void) UART_ENABLE_INT(UART2, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk)); 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; +volatile VCOM Vcom, Vcom2; void EP5_Handler(void) // Bulk IN { @@ -38,14 +56,28 @@ void EP6_Handler(void) // Bulk OUT 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 LineCfg2 = {115200, 0, 0, 8}; -void VCOM_LineCoding(void) +void VCOM_LineCoding(UART_T * UARTx, VCOM_LINE_CODING * LineCfgx, volatile VCOM * Vcomx) { - uint32_t data_len, parity, stop_len; + uint32_t data_len, parity, stop_len; - switch(LineCfg.u8DataBits) + switch(LineCfgx->u8DataBits) { case 5: data_len = UART_WORD_LEN_5; break; case 6: data_len = UART_WORD_LEN_6; break; @@ -54,7 +86,7 @@ void VCOM_LineCoding(void) default: data_len = UART_WORD_LEN_8; break; } - switch(LineCfg.u8ParityType) + switch(LineCfgx->u8ParityType) { case 0: parity = UART_PARITY_NONE; break; case 1: parity = UART_PARITY_ODD; break; @@ -64,7 +96,7 @@ void VCOM_LineCoding(void) default: parity = UART_PARITY_NONE; break; } - switch(LineCfg.u8CharFormat) + switch(LineCfgx->u8CharFormat) { case 0: stop_len = UART_STOP_BIT_1; break; case 1: stop_len = UART_STOP_BIT_1_5; break; @@ -72,53 +104,53 @@ void VCOM_LineCoding(void) default: stop_len = UART_STOP_BIT_1; break; } - NVIC_DisableIRQ(UART2_IRQn); + __disable_irq(); // Reset software FIFO - Vcom.rx_bytes = 0; - Vcom.rx_head = 0; - Vcom.rx_tail = 0; + Vcomx->rx_bytes = 0; + Vcomx->rx_head = 0; + Vcomx->rx_tail = 0; - Vcom.tx_bytes = 0; - Vcom.tx_head = 0; - Vcom.tx_tail = 0; + Vcomx->tx_bytes = 0; + Vcomx->tx_head = 0; + Vcomx->tx_tail = 0; // Reset hardware FIFO - UART2->FIFO |= (UART_FIFO_RXRST_Msk | UART_FIFO_TXRST_Msk); + UARTx->FIFO |= (UART_FIFO_RXRST_Msk | UART_FIFO_TXRST_Msk); - UART_SetLineConfig(UART2, LineCfg.u32DTERate, data_len, parity, stop_len); + UART_SetLineConfig(UARTx, LineCfgx->u32DTERate, data_len, parity, stop_len); - NVIC_EnableIRQ(UART2_IRQn); + __enable_irq(); } -void UART2_IRQHandler(void) +void UARTX_IRQHandler(UART_T * UARTx, volatile VCOM * vcomx) { uint8_t chr; int32_t size; - if((UART2->INTSTS & UART_INTSTS_RDAIF_Msk) || (UART2->INTSTS & UART_INTSTS_RXTOIF_Msk)) + if((UARTx->INTSTS & UART_INTSTS_RDAIF_Msk) || (UARTx->INTSTS & UART_INTSTS_RXTOIF_Msk)) { - while((UART2->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0) + while((UARTx->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0) { - chr = UART2->DAT; + chr = UARTx->DAT; - if(Vcom.rx_bytes < RX_BUFF_SIZE) // Check if buffer full + if(vcomx->rx_bytes < RX_BUFF_SIZE) // Check if buffer full { - Vcom.rx_buff[Vcom.rx_tail++] = chr; - if(Vcom.rx_tail >= RX_BUFF_SIZE) - Vcom.rx_tail = 0; - Vcom.rx_bytes++; + vcomx->rx_buff[vcomx->rx_tail++] = chr; + if(vcomx->rx_tail >= RX_BUFF_SIZE) + vcomx->rx_tail = 0; + vcomx->rx_bytes++; } } } - if(UART2->INTSTS & UART_INTSTS_THREIF_Msk) + if(UARTx->INTSTS & UART_INTSTS_THREIF_Msk) { - if(Vcom.tx_bytes) + if(vcomx->tx_bytes) { /* Fill the Tx FIFO */ - size = Vcom.tx_bytes; + size = vcomx->tx_bytes; if(size >= TX_FIFO_SIZE) { size = TX_FIFO_SIZE; @@ -126,104 +158,119 @@ void UART2_IRQHandler(void) while(size) { - UART2->DAT = Vcom.tx_buff[Vcom.tx_head++]; - if(Vcom.tx_head >= TX_BUFF_SIZE) - Vcom.tx_head = 0; - Vcom.tx_bytes--; + UARTx->DAT = vcomx->tx_buff[vcomx->tx_head++]; + if(vcomx->tx_head >= TX_BUFF_SIZE) + vcomx->tx_head = 0; + vcomx->tx_bytes--; size--; } } else { /* No more data, just stop Tx (Stop work) */ - UART2->INTEN &= ~UART_INTEN_THREIEN_Msk; + UARTx->INTEN &= ~UART_INTEN_THREIEN_Msk; } } } -extern uint32_t SysTick_Count; -static uint32_t SysTick_Count_Save; +void UART2_IRQHandler(void) +{ + UARTX_IRQHandler(UART2, &Vcom); +} -void VCOM_TransferData(void) + +void UART1_IRQHandler(void) +{ + UARTX_IRQHandler(UART1, &Vcom2); +} + + + +void VCOMX_TransferData(volatile VCOM * vcomx, UART_T * UARTx, uint32_t INEP, uint32_t INEP_PKT_SIZE, uint32_t OUTEP, uint32_t OUTEP_PKT_SIZE) { int32_t i, len; /* Check whether USB is ready for next packet or not */ - if(Vcom.in_bytes == 0) + if(vcomx->in_bytes == 0) { /* Check whether we have new COM Rx data to send to USB or not */ - if(Vcom.rx_bytes && ((Vcom.rx_bytes >= EP5_MAX_PKT_SIZE) || (SysTick_Count_Save != SysTick_Count))) + if(vcomx->rx_bytes) { - SysTick_Count_Save = SysTick_Count; - - len = Vcom.rx_bytes; - if(len > EP5_MAX_PKT_SIZE) - len = EP5_MAX_PKT_SIZE; + len = vcomx->rx_bytes; + if(len > INEP_PKT_SIZE) + len = INEP_PKT_SIZE; for(i = 0; i < len; i++) { - Vcom.in_buff[i] = Vcom.rx_buff[Vcom.rx_head++]; - if(Vcom.rx_head >= RX_BUFF_SIZE) - Vcom.rx_head = 0; + vcomx->in_buff[i] = vcomx->rx_buff[vcomx->rx_head++]; + if(vcomx->rx_head >= RX_BUFF_SIZE) + vcomx->rx_head = 0; } __disable_irq(); - Vcom.rx_bytes -= len; + vcomx->rx_bytes -= len; __enable_irq(); - Vcom.in_bytes = len; - USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5)), (uint8_t *)Vcom.in_buff, len); - USBD_SET_PAYLOAD_LEN(EP5, len); + vcomx->in_bytes = len; + USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(INEP)), (uint8_t *)vcomx->in_buff, len); + USBD_SET_PAYLOAD_LEN(INEP, len); } else { - /* Prepare a zero packet if previous packet size is EP5_MAX_PKT_SIZE and + /* Prepare a zero packet if previous packet size is EP2_MAX_PKT_SIZE and no more data to send at this moment to note Host the transfer has been done */ - len = USBD_GET_PAYLOAD_LEN(EP5); - if(len == EP5_MAX_PKT_SIZE) - USBD_SET_PAYLOAD_LEN(EP5, 0); + len = USBD_GET_PAYLOAD_LEN(INEP); + if(len == INEP_PKT_SIZE) + USBD_SET_PAYLOAD_LEN(INEP, 0); } } /* Process the Bulk out data when bulk out data is ready. */ - if(Vcom.out_ready && (Vcom.out_bytes <= TX_BUFF_SIZE - Vcom.tx_bytes)) + if(vcomx->out_ready && (vcomx->out_bytes <= TX_BUFF_SIZE - vcomx->tx_bytes)) { - for(i = 0; i < Vcom.out_bytes; i++) + for(i = 0; i < vcomx->out_bytes; i++) { - Vcom.tx_buff[Vcom.tx_tail++] = Vcom.out_ptr[i]; - if(Vcom.tx_tail >= TX_BUFF_SIZE) - Vcom.tx_tail = 0; + vcomx->tx_buff[vcomx->tx_tail++] = vcomx->out_ptr[i]; + if(vcomx->tx_tail >= TX_BUFF_SIZE) + vcomx->tx_tail = 0; } __disable_irq(); - Vcom.tx_bytes += Vcom.out_bytes; + vcomx->tx_bytes += vcomx->out_bytes; __enable_irq(); - Vcom.out_bytes = 0; - Vcom.out_ready = 0; + vcomx->out_bytes = 0; + vcomx->out_ready = 0; /* Clear bulk out ready flag */ /* Ready to get next BULK out */ - USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE); + USBD_SET_PAYLOAD_LEN(OUTEP, OUTEP_PKT_SIZE); } /* Process the software Tx FIFO */ - if(Vcom.tx_bytes) + if(vcomx->tx_bytes) { /* Check if Tx is working */ - if((UART2->INTEN & UART_INTEN_THREIEN_Msk) == 0) + if((UARTx->INTEN & UART_INTEN_THREIEN_Msk) == 0) { /* Send one bytes out */ - UART2->DAT = Vcom.tx_buff[Vcom.tx_head++]; - if(Vcom.tx_head >= TX_BUFF_SIZE) - Vcom.tx_head = 0; + UARTx->DAT = vcomx->tx_buff[vcomx->tx_head++]; + if(vcomx->tx_head >= TX_BUFF_SIZE) + vcomx->tx_head = 0; __disable_irq(); - Vcom.tx_bytes--; + vcomx->tx_bytes--; __enable_irq(); /* Enable Tx Empty Interrupt. (Trigger first one) */ - UART2->INTEN |= UART_INTEN_THREIEN_Msk; + UARTx->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); +} diff --git a/src/vcom_serial.h b/src/vcom_serial.h index 9f752c1..a8e3bc3 100644 --- a/src/vcom_serial.h +++ b/src/vcom_serial.h @@ -16,7 +16,7 @@ typedef struct __attribute__((packed)) { uint8_t u8DataBits; // data bits: 5, 6, 7, 8, 16 } VCOM_LINE_CODING; -extern VCOM_LINE_CODING LineCfg; +extern VCOM_LINE_CODING LineCfg, LineCfg2; @@ -43,7 +43,7 @@ typedef struct { uint16_t out_ready; } VCOM; -extern volatile VCOM Vcom; +extern volatile VCOM Vcom, Vcom2; @@ -51,8 +51,10 @@ void VCOM_Init(void); void EP5_Handler(void); void EP6_Handler(void); +void EP8_Handler(void); +void EP9_Handler(void); -void VCOM_LineCoding(void); +void VCOM_LineCoding(UART_T * UARTx, VCOM_LINE_CODING * LineCfgx, volatile VCOM * Vcomx); void VCOM_TransferData(void);