18 :
UART(&_read_port, &_write_port),
19 id_(id),
20 _read_port(dma_rx.
size_),
21 _write_port(tx_queue_size, dma_tx.
size_ / 2),
22 dma_buff_rx_(dma_rx),
23 dma_buff_tx_(dma_tx),
24 instance_(CH32_UART_GetInstanceID(id)),
25 dma_rx_channel_(CH32_UART_RX_DMA_CHANNEL_MAP[id]),
26 dma_tx_channel_(CH32_UART_TX_DMA_CHANNEL_MAP[id])
27{
28 map[id] = this;
29
30 bool tx_enable = dma_tx.
size_ > 1;
31 bool rx_enable = dma_rx.
size_ > 0;
32
33 ASSERT(tx_enable || rx_enable);
34
35
36 GPIO_InitTypeDef gpio_init = {};
37 gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
38
39 if (tx_enable)
40 {
42 gpio_init.GPIO_Pin = tx_gpio_pin;
43 gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
44 GPIO_Init(tx_gpio_port, &gpio_init);
45 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(tx_gpio_port), ENABLE);
46 }
47
48 if (rx_enable)
49 {
51 gpio_init.GPIO_Pin = rx_gpio_pin;
52 gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
53 GPIO_Init(rx_gpio_port, &gpio_init);
54 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(rx_gpio_port), ENABLE);
55 }
56
57
58 if (pin_remap != 0)
59 {
60 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
61 GPIO_PinRemapConfig(pin_remap, ENABLE);
62 }
63
64
65 if (CH32_UART_APB_MAP[id] == 1)
66 {
67 RCC_APB1PeriphClockCmd(CH32_UART_RCC_PERIPH_MAP[id], ENABLE);
68 }
69 else if (CH32_UART_APB_MAP[id] == 2)
70 {
71 RCC_APB2PeriphClockCmd(CH32_UART_RCC_PERIPH_MAP[id], ENABLE);
72 }
73 else
74 {
75 ASSERT(false);
76 }
77 RCC_AHBPeriphClockCmd(CH32_UART_RCC_PERIPH_MAP_DMA[id], ENABLE);
78
79
80 USART_InitTypeDef usart_cfg = {};
81 usart_cfg.USART_BaudRate = config.
baudrate;
82 usart_cfg.USART_StopBits =
83 (config.
stop_bits == 2) ? USART_StopBits_2 : USART_StopBits_1;
85 {
87 usart_cfg.USART_Parity = USART_Parity_No;
88 usart_cfg.USART_WordLength = USART_WordLength_8b;
89 break;
91 usart_cfg.USART_Parity = USART_Parity_Even;
92 usart_cfg.USART_WordLength = USART_WordLength_9b;
93 break;
95 usart_cfg.USART_Parity = USART_Parity_Odd;
96 usart_cfg.USART_WordLength = USART_WordLength_9b;
97 break;
98 default:
99 ASSERT(false);
100 }
101
102 usart_cfg.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
103 usart_cfg.USART_Mode =
104 (tx_enable ? USART_Mode_Tx : 0) | (rx_enable ? USART_Mode_Rx : 0);
105 uart_mode_ = usart_cfg.USART_Mode;
106 USART_Init(instance_, &usart_cfg);
107
108
109 DMA_InitTypeDef dma_init = {};
110 dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
111 dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
112 dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
113 dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
114 dma_init.DMA_Priority = DMA_Priority_High;
115 dma_init.DMA_M2M = DMA_M2M_Disable;
116
117 if (rx_enable)
118 {
119 DMA_DeInit(dma_rx_channel_);
120 dma_init.DMA_PeripheralBaseAddr = (uint32_t)&instance_->DATAR;
121 dma_init.DMA_MemoryBaseAddr = (uint32_t)dma_buff_rx_.
addr_;
122 dma_init.DMA_DIR = DMA_DIR_PeripheralSRC;
123 dma_init.DMA_Mode = DMA_Mode_Circular;
124 dma_init.DMA_BufferSize = dma_buff_rx_.
size_;
125 DMA_Init(dma_rx_channel_, &dma_init);
126 DMA_Cmd(dma_rx_channel_, ENABLE);
127 USART_DMACmd(instance_, USART_DMAReq_Rx, ENABLE);
128 }
129
130 if (tx_enable)
131 {
132 DMA_DeInit(dma_tx_channel_);
133 dma_init.DMA_PeripheralBaseAddr = (u32)(&instance_->DATAR);
134 dma_init.DMA_MemoryBaseAddr = 0;
135 dma_init.DMA_DIR = DMA_DIR_PeripheralDST;
136 dma_init.DMA_Mode = DMA_Mode_Normal;
137 dma_init.DMA_BufferSize = 0;
138 DMA_Init(dma_tx_channel_, &dma_init);
139 DMA_ITConfig(dma_tx_channel_, DMA_IT_TC, ENABLE);
140 USART_DMACmd(instance_, USART_DMAReq_Tx, ENABLE);
141 }
142
143
144 USART_Cmd(instance_, ENABLE);
145
146 if (rx_enable)
147 {
148 USART_ITConfig(instance_, USART_IT_IDLE, ENABLE);
149 }
150
151 if (tx_enable)
152 {
153 NVIC_EnableIRQ(CH32_DMA_IRQ_MAP[CH32_DMA_GetID(dma_tx_channel_)]);
154 }
155
156 NVIC_EnableIRQ(CH32_UART_IRQ_MAP[id]);
157}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
@ NO_PARITY
无校验 / No parity
UART(ReadPortType *read_port, WritePortType *write_port)
UART 构造函数 / UART constructor.
ErrorCode(* ReadFun)(ReadPort &port)
Function pointer type for read operations.
ErrorCode(* WriteFun)(WritePort &port)
Function pointer type for write operations.
uint8_t stop_bits
停止位长度 / Number of stop bits
Parity parity
校验模式 / Parity mode
uint32_t baudrate
波特率 / Baud rate