DAPLink (CMSIS-DAP) porting to Artery AT32F425, WCH CH32V203 and WCH CH32V305.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

199 lines
6.0 KiB

#include <string.h>
#include "ch32v30x.h"
#include "ch32v30x_usb.h"
#include "ch32v30x_usbhs_device.h"
#include "usb_desc.h"
#include "vcom_serial.h"
volatile VCOM Vcom = {.in_ready = 1};
VCOM_LINE_CODING LineCfg = {115200, 0, 0, 8}; // Baud rate, stop bits, parity bits, data bits
void VCOM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure); // PA2 => USART2_TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure); // PA3 => USART2_RX
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
NVIC_EnableIRQ(USART2_IRQn);
}
void VCOM_LineCoding(VCOM_LINE_CODING * LineCfgx)
{
USART_InitTypeDef USART_InitStructure;
switch(LineCfgx->u8DataBits)
{
case 8: USART_InitStructure.USART_WordLength = USART_WordLength_8b; break;
default: USART_InitStructure.USART_WordLength = USART_WordLength_8b; break;
}
switch(LineCfgx->u8ParityType)
{
case 0: USART_InitStructure.USART_Parity = USART_Parity_No; break;
case 1: USART_InitStructure.USART_Parity = USART_Parity_Odd;
USART_InitStructure.USART_WordLength = USART_WordLength_9b; break;
case 2: USART_InitStructure.USART_Parity = USART_Parity_Even;
USART_InitStructure.USART_WordLength = USART_WordLength_9b; break;
default: USART_InitStructure.USART_Parity = USART_Parity_No; break;
}
switch(LineCfgx->u8CharFormat)
{
case 0: USART_InitStructure.USART_StopBits = USART_StopBits_1; break;
case 1: USART_InitStructure.USART_StopBits = USART_StopBits_1_5; break;
case 2: USART_InitStructure.USART_StopBits = USART_StopBits_2; break;
default: USART_InitStructure.USART_StopBits = USART_StopBits_1; break;
}
USART_InitStructure.USART_BaudRate = LineCfgx->u32DTERate;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
__disable_irq();
// Reset software FIFO
Vcom.rx_bytes = 0;
Vcom.rx_wrptr = 0;
Vcom.rx_rdptr = 0;
Vcom.tx_bytes = 0;
Vcom.tx_wrptr = 0;
Vcom.tx_rdptr = 0;
USART_Init(USART2, &USART_InitStructure);
__enable_irq();
}
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
uint16_t chr = USART_ReceiveData(USART2);
if(Vcom.rx_bytes < RX_BUFF_SIZE)
{
Vcom.rx_buff[Vcom.rx_wrptr++] = chr;
if(Vcom.rx_wrptr == RX_BUFF_SIZE)
Vcom.rx_wrptr = 0;
Vcom.rx_bytes++;
}
}
if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET)
{
if(Vcom.tx_bytes)
{
USART_SendData(USART2, Vcom.tx_buff[Vcom.tx_rdptr++]);
if(Vcom.tx_rdptr == TX_BUFF_SIZE)
Vcom.tx_rdptr = 0;
Vcom.tx_bytes--;
}
else
{
/* No more data, just stop Tx (Stop work) */
USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
}
}
}
void VCOM_TransferData(void)
{
if(Vcom.in_ready) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if(Vcom.rx_bytes) // <EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD>
{
Vcom.in_bytes = Vcom.rx_bytes;
if(Vcom.in_bytes > CDC_BULK_IN_SZ_HS)
Vcom.in_bytes = CDC_BULK_IN_SZ_HS;
for(int i = 0; i < Vcom.in_bytes; i++)
{
Vcom.in_buff[i] = Vcom.rx_buff[Vcom.rx_rdptr++];
if(Vcom.rx_rdptr >= RX_BUFF_SIZE)
Vcom.rx_rdptr = 0;
}
__disable_irq();
Vcom.rx_bytes -= Vcom.in_bytes;
__enable_irq();
Vcom.in_ready = 0;
memcpy(USBHS_EP3_Tx_Buf, (uint8_t *)Vcom.in_buff, Vcom.in_bytes);
USBHSD->UEP3_TX_LEN = Vcom.in_bytes;
USBHSD->UEP3_TX_CTRL = (USBHSD->UEP3_TX_CTRL & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_ACK;
}
else
{
/* Prepare a zero packet if previous packet size is CDC_BULK_IN_SZ and
no more data to send at this moment to note Host the transfer has been done */
if(Vcom.in_bytes == CDC_BULK_IN_SZ_HS)
{
Vcom.in_bytes = 0;
USBHSD->UEP3_TX_LEN = 0;
USBHSD->UEP3_TX_CTRL = (USBHSD->UEP3_TX_CTRL & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_ACK;
}
}
}
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD> tx_buff <EFBFBD>ܹ<EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if(Vcom.out_ready && (Vcom.out_bytes <= TX_BUFF_SIZE - Vcom.tx_bytes))
{
for(int i = 0; i < Vcom.out_bytes; i++)
{
Vcom.tx_buff[Vcom.tx_wrptr++] = Vcom.out_buff[i];
if(Vcom.tx_wrptr >= TX_BUFF_SIZE)
Vcom.tx_wrptr = 0;
}
__disable_irq();
Vcom.tx_bytes += Vcom.out_bytes;
__enable_irq();
Vcom.out_ready = 0;
/* Ready for next BULK OUT */
USBHSD->UEP3_RX_CTRL = (USBHSD->UEP3_RX_CTRL & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_ACK;
}
if(Vcom.tx_bytes && ((USART2->CTLR1 & USART_CTLR1_TXEIE) == 0))
{
USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
}
}