CH32V203 UART DMA enable

This commit is contained in:
XIVN1987
2023-06-03 19:53:49 +08:00
parent 51cea28e9d
commit 208aa3d8d6
9 changed files with 183 additions and 113 deletions
-1
View File
@@ -1 +0,0 @@
ENTRY( _start )
+26
View File
@@ -7,6 +7,9 @@
extern uint8_t usbd_hid_process(void);
volatile uint32_t SysTick_ms = 0;
void SysTick_Config(uint32_t ticks);
void USB_Config(void);
int main(void)
@@ -16,6 +19,8 @@ int main(void)
VCOM_Init();
USB_Config();
SysTick_Config(SystemCoreClock / 1000);
while(1)
{
@@ -26,6 +31,27 @@ int main(void)
}
void SysTick_Config(uint32_t ticks)
{
SysTick->CTLR= 0;
SysTick->SR = 0;
SysTick->CNT = 0;
SysTick->CMP = ticks;
SysTick->CTLR= 0x0F;
NVIC_EnableIRQ(SysTicK_IRQn);
}
void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void SysTick_Handler(void)
{
SysTick->SR = 0;
SysTick_ms++;
}
void USB_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
+70 -85
View File
@@ -1,3 +1,4 @@
#include <string.h>
#include "ch32v20x.h"
#include "usb_lib.h"
#include "usb_regs.h"
@@ -10,35 +11,71 @@ volatile VCOM Vcom = {.in_ready = 1};
VCOM_LINE_CODING LineCfg = {115200, 0, 0, 8}; // Baud rate, stop bits, parity bits, data bits
#define RXDMA_SZ (CDC_BULK_IN_SZ * 2)
uint8_t RXBuffer[RXDMA_SZ] __attribute__((aligned(4)));
uint8_t TXBuffer[CDC_BULK_OUT_SZ] __attribute__((aligned(4)));
void VCOM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
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
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DATAR;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)TXBuffer;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel7, ENABLE);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DATAR;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RXBuffer;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_BufferSize = RXDMA_SZ;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel6, ENABLE);
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_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
USART_DMACmd(USART2, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
NVIC_EnableIRQ(USART2_IRQn);
USART_Cmd(USART2, ENABLE);
}
@@ -71,88 +108,46 @@ void VCOM_LineCoding(VCOM_LINE_CODING * LineCfgx)
}
USART_InitStructure.USART_BaudRate = LineCfgx->u32DTERate;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
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);
}
}
}
extern volatile uint32_t SysTick_ms;
void VCOM_TransferData(void)
{
static uint32_t last_ms = 0;
static uint32_t last_pos = 0;
if(Vcom.in_ready) // 可以向主机发送数据
{
if(Vcom.rx_bytes) // 有新的数据可以发送
uint32_t pos = RXDMA_SZ - DMA_GetCurrDataCounter(DMA1_Channel6);
if((pos - last_pos >= CDC_BULK_IN_SZ) || ((pos != last_pos) && (SysTick_ms != last_ms)))
{
Vcom.in_bytes = Vcom.rx_bytes;
if(Vcom.in_bytes > CDC_BULK_IN_SZ)
Vcom.in_bytes = CDC_BULK_IN_SZ;
if(pos < last_pos)
pos = RXDMA_SZ;
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;
}
if(pos - last_pos > CDC_BULK_IN_SZ)
pos = last_pos + CDC_BULK_IN_SZ;
__disable_irq();
Vcom.rx_bytes -= Vcom.in_bytes;
__enable_irq();
Vcom.in_bytes = pos - last_pos;
Vcom.in_ready = 0;
USB_SIL_Write(EP3_IN, (uint8_t *)Vcom.in_buff, Vcom.in_bytes);
USB_SIL_Write(EP3_IN, &RXBuffer[last_pos], Vcom.in_bytes);
SetEPTxValid(ENDP3);
last_pos = pos % RXDMA_SZ;
last_ms = SysTick_ms;
}
else
{
@@ -161,35 +156,25 @@ void VCOM_TransferData(void)
if(Vcom.in_bytes == CDC_BULK_IN_SZ)
{
Vcom.in_bytes = 0;
USB_SIL_Write(EP3_IN, (uint8_t *)Vcom.in_buff, 0);
USB_SIL_Write(EP3_IN, (uint8_t *)0, 0);
SetEPTxValid(ENDP3);
}
}
}
/* 从主机接收到数据,且 tx_buff 能够装下它们 */
if(Vcom.out_ready && (Vcom.out_bytes <= TX_BUFF_SIZE - Vcom.tx_bytes))
/* 从主机接收到数据,且前面的数据 DMA 已发送完 */
if(Vcom.out_ready && (DMA_GetCurrDataCounter(DMA1_Channel7) == 0))
{
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;
memcpy(TXBuffer, (uint8_t *)Vcom.out_buff, Vcom.out_bytes);
DMA_Cmd(DMA1_Channel7, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel7, Vcom.out_bytes);
DMA_Cmd(DMA1_Channel7, ENABLE);
/* Ready for next BULK OUT */
SetEPRxValid(ENDP3);
}
if(Vcom.tx_bytes && ((USART2->CTLR1 & USART_CTLR1_TXEIE) == 0))
{
USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
}
}