1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Description: Provides uart driver source \n
16 *
17 * History: \n
18 * 2022-06-09, Create file. \n
19 */
20 #include "uart.h"
21 #include <stdbool.h>
22 #include "common_def.h"
23 #include "soc_osal.h"
24 #include "securec.h"
25 #if defined(CONFIG_UART_SUPPORT_DMA)
26 #include "dma_porting.h"
27 #include "dma.h"
28 #endif
29
30 /**
31 * @brief Maximum number of fragments per uart for transmission.
32 * Configurable field that specifies the maximum numbers of transmissions the driver can queue
33 * before it returns false on the write requests.
34 */
35 #define UART_MAX_NUMBER_OF_FRAGMENTS 4
36
37 /**
38 * @brief Uart parity error bit mask
39 */
40 #define UART_PARITY_ERROR_MASK BIT(8)
41
42 /**
43 * @brief Uart frame error bit mask.
44 */
45 #define UART_FRAME_ERROR_MASK BIT(7)
46
47 #if defined(CONFIG_UART_SUPPORT_TX)
48 /**
49 * @brief A fragment of data that is to be transmitted.
50 */
51 typedef struct {
52 uint8_t *data;
53 void *params;
54 uart_tx_callback_t release_func;
55 uint32_t data_length;
56 } uart_tx_fragment_t;
57
58 /**
59 * @brief The UART transmission configuration parameters.
60 */
61 typedef struct {
62 uart_tx_fragment_t *current_tx_fragment; /*!< Current TX fragment being transmitted. */
63 uart_tx_fragment_t *free_tx_fragment; /*!< The unused TX fragment admin blocks available
64 for re-use/freeing. */
65 uint16_t fragments_to_process; /*!< Number of fragments to process including the current one. */
66 uint16_t current_tx_fragment_pos; /*!< Index of the current position of the next byte to be
67 transmitted in the current TX fragment
68 current_tx_fragment_pos == 0 means
69 the first byte is yet to be sent for transmission */
70 uart_tx_fragment_t fragment_buffer[UART_MAX_NUMBER_OF_FRAGMENTS]; /*!< Fragments buffer pointer. */
71 } uart_tx_state_t;
72
73 /**
74 * @brief Internal UART TX configuration.
75 */
76 #if defined(CONFIG_UART_SUPPORT_TX_INT)
77 static uart_tx_state_t g_uart_tx_state_array[UART_BUS_MAX_NUM];
78 #endif
79
80 #if defined(CONFIG_UART_SUPPORT_DMA)
81 #define DMA_UART_TRANSFER_TIMEOUT_MS 1000
82 #define UART_DMA_TRANS_MEMORY_TO_PERIPHERAL_DMA 1
83 #define UART_DMA_TRANS_PERIPHERAL_TO_MEMORY_DMA 2
84 #define UART_DMA_TRANSFER_DIR_MEM_TO_PERIPHERAL 0
85 #define UART_DMA_TRANSFER_DIR_PERIPHERAL_TO_MEM 1
86 #define UART_DMA_ADDRESS_INC_INCREMENT 0
87 #define UART_DMA_ADDRESS_INC_NO_CHANGE 2
88 #define UART_DMA_PROTECTION_CONTROL_BUFFERABLE 1
89
90 typedef struct uart_dma_trans_inf {
91 bool inited;
92 bool trans_succ;
93 uint8_t channel;
94 uint8_t reserved;
95 osal_semaphore dma_sem;
96 } uart_dma_trans_inf_t;
97
98 static uart_dma_trans_inf_t g_dma_trans[UART_BUS_MAX_NUM] = { 0 };
99
100 static void uart_dma_set_config(uart_bus_t bus, const uart_extra_attr_t *extra_attr);
101 #endif /* CONFIG_UART_SUPPORT_DMA */
102
103 #endif /* CONFIG_UART_SUPPORT_TX */
104
105 #if defined(CONFIG_UART_SUPPORT_RX)
106 /**
107 * @brief The UART reception configuration parameters.
108 */
109 typedef struct {
110 uart_rx_callback_t rx_callback; /*!< The RX callback to make when the condition is met. */
111 uart_error_callback_t parity_error_callback; /*!< The parity error callback. */
112 uart_error_callback_t frame_error_callback; /*!< The frame error callback. */
113 uint8_t *rx_buffer; /*!< The RX data buffer. */
114 uint16_t rx_buffer_size; /*!< The size of the receive buffer. */
115 uint16_t rx_condition_size; /*!< The size relating the condition. */
116 uint16_t new_rx_pos; /*!< Index to the position in the RX buffer that is where new data
117 should be put if (new_rx_pos == 0) the buffer is empty. */
118 uart_rx_condition_t rx_condition; /*!< The condition under which an RX callback is made. */
119 } uart_rx_state_t;
120
121 /**
122 * @brief Internal UART RX configuration.
123 */
124 static uart_rx_state_t g_uart_rx_state_array[UART_BUS_MAX_NUM];
125
126 #endif /* CONFIG_UART_SUPPORT_RX */
127
128 static bool g_uart_inited[UART_BUS_MAX_NUM] = { false };
129
130 #if defined(CONFIG_UART_SUPPORT_RX)
131 static bool uart_config_rx_state(uart_bus_t bus, const uart_buffer_config_t *uart_buffer_config);
132 #endif /* CONFIG_UART_SUPPORT_RX */
133
134 #if defined(CONFIG_UART_SUPPORT_TX)
135 #if defined(CONFIG_UART_SUPPORT_TX_INT)
136 static void uart_config_tx_state(uart_bus_t bus);
137 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
138 #endif /* CONFIG_UART_SUPPORT_TX */
139
140 #if defined(CONFIG_UART_SUPPORT_RX) || defined(CONFIG_UART_SUPPORT_TX)
141 static void uart_deconfig_state(uart_bus_t bus);
142 #endif /* defined(CONFIG_UART_SUPPORT_RX) || defined(CONFIG_UART_SUPPORT_TX) */
143
144 #if defined(CONFIG_UART_SUPPORT_TX)
145 #if defined(CONFIG_UART_SUPPORT_TX_INT)
146 static bool uart_helper_add_fragment(uart_bus_t bus, const uint8_t *buffer,
147 uint32_t length, void *params,
148 uart_tx_callback_t finished_with_buffer_func);
149 static inline bool uart_helper_is_the_current_fragment_the_last_to_process(uart_bus_t bus);
150
151 static inline bool uart_helper_are_there_fragments_to_process(uart_bus_t bus);
152
153 static inline bool uart_helper_send_next_char(uart_bus_t bus);
154
155 static inline void uart_helper_invoke_current_fragment_callback(uart_bus_t bus);
156
157 static inline void uart_helper_move_to_next_fragment(uart_bus_t bus);
158 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
159 #endif /* CONFIG_UART_SUPPORT_TX */
160
161 #if defined(CONFIG_UART_SUPPORT_RX)
162 static inline void uart_rx_buffer_release(uart_bus_t bus);
163
164 static inline bool uart_rx_buffer_has_free_space(uart_bus_t bus);
165
166 static inline uint16_t uart_rx_buffer_data_available(uart_bus_t bus);
167 #endif /* CONFIG_UART_SUPPORT_RX */
168
169 static int32_t uart_check_params_attr(const uart_attr_t *attr);
170
171 static int32_t uart_init_check_params(uart_bus_t bus, const uart_pin_config_t *pins, const uart_attr_t *attr);
172
173 static void uart_claim_pins(uart_bus_t bus, const uart_pin_config_t *pins);
174
175 static void uart_release_pins(uart_bus_t bus);
176
177 #if defined(CONFIG_UART_SUPPORT_RX)
178 static void uart_idle_isr(uart_bus_t bus);
179
180 static void uart_rx_isr(uart_bus_t bus);
181
182 static void uart_error_isr(uart_bus_t bus);
183 #endif /* CONFIG_UART_SUPPORT_RX */
184
185 #if defined(CONFIG_UART_SUPPORT_TX_INT)
186 static void uart_tx_isr(uart_bus_t bus);
187 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
188
189 #if defined(CONFIG_UART_SUPPORT_LPM)
190 static bool g_uart_suspend_flag[UART_BUS_MAX_NUM] = { false };
191 static uart_pin_config_t g_uart_pins[UART_BUS_MAX_NUM] = { 0 };
192 static uart_attr_t g_uart_attr[UART_BUS_MAX_NUM] = { 0 };
193 static uart_extra_attr_t g_uart_extra_attr[UART_BUS_MAX_NUM] = { 0 };
194 static uart_buffer_config_t g_uart_buffer_config[UART_BUS_MAX_NUM] = { 0 };
195 static uart_rx_condition_t g_uart_condition[UART_BUS_MAX_NUM] = { 0 };
196 static uint32_t g_uart_size[UART_BUS_MAX_NUM] = { 0 };
197 static uart_rx_callback_t g_uart_callback[UART_BUS_MAX_NUM] = { 0 };
198 #endif /* CONFIG_UART_SUPPORT_LPM */
199
200 static errcode_t uart_evt_callback(uart_bus_t bus, hal_uart_evt_id_t evt, uintptr_t param);
201
uapi_uart_init(uart_bus_t bus,const uart_pin_config_t * pins,const uart_attr_t * attr,const uart_extra_attr_t * extra_attr,uart_buffer_config_t * uart_buffer_config)202 errcode_t uapi_uart_init(uart_bus_t bus, const uart_pin_config_t *pins, const uart_attr_t *attr,
203 const uart_extra_attr_t *extra_attr, uart_buffer_config_t *uart_buffer_config)
204 {
205 unused(uart_buffer_config);
206 if (uart_init_check_params(bus, pins, attr) != 0) {
207 return ERRCODE_INVALID_PARAM;
208 }
209 if (g_uart_inited[bus]) { return ERRCODE_SUCC; }
210 #if defined(CONFIG_UART_SUPPORT_LPM)
211 if (g_uart_suspend_flag[bus] == false) {
212 (void)memcpy_s(&g_uart_pins[bus], sizeof(uart_pin_config_t), pins, sizeof(uart_pin_config_t));
213 (void)memcpy_s(&g_uart_attr[bus], sizeof(uart_attr_t), attr, sizeof(uart_attr_t));
214 (void)memcpy_s(&g_uart_extra_attr[bus], sizeof(uart_extra_attr_t), extra_attr, sizeof(uart_extra_attr_t));
215 (void)memcpy_s(&g_uart_buffer_config[bus], sizeof(uart_buffer_config_t), uart_buffer_config,
216 sizeof(uart_buffer_config_t));
217 }
218 #endif /* CONFIG_UART_SUPPORT_LPM */
219 #if defined(CONFIG_UART_SUPPORT_LPC)
220 uart_port_clock_enable(bus, true);
221 #endif
222 uart_claim_pins(bus, pins);
223
224 #if defined(CONFIG_UART_SUPPORT_RX)
225 if (uart_config_rx_state(bus, uart_buffer_config) == false) {
226 return ERRCODE_UART_INIT_TRX_STATE_FAIL;
227 }
228 #endif /* CONFIG_UART_SUPPORT_RX */
229 #if defined(CONFIG_UART_SUPPORT_TX)
230 #if defined(CONFIG_UART_SUPPORT_TX_INT)
231 uart_config_tx_state(bus);
232 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
233 #endif /* CONFIG_UART_SUPPORT_TX */
234 uint8_t flow_ctrl = UART_FLOW_CTRL_SOFT;
235 #if defined(CONFIG_UART_SUPPORT_FLOW_CTRL)
236 flow_ctrl = attr->flow_ctrl;
237 #endif /* CONFIG_UART_SUPPORT_FLOW_CTRL */
238 errcode_t ret = hal_uart_init(bus, uart_evt_callback, (hal_uart_pin_config_t *)pins, (hal_uart_attr_t *)attr,
239 (hal_uart_flow_ctrl_t)flow_ctrl);
240 if (ret != ERRCODE_SUCC) { return ret; }
241
242 #if defined(CONFIG_UART_SUPPORT_DMA)
243 if ((extra_attr != NULL) && (extra_attr->tx_dma_enable || extra_attr->rx_dma_enable)) {
244 uart_dma_set_config(bus, extra_attr);
245 }
246 #else
247 unused(extra_attr);
248 #endif /* CONFIG_UART_SUPPORT_DMA */
249 g_uart_inited[bus] = true;
250 uart_port_register_irq(bus);
251 return ret;
252 }
253
uapi_uart_deinit(uart_bus_t bus)254 errcode_t uapi_uart_deinit(uart_bus_t bus)
255 {
256 errcode_t ret = ERRCODE_FAIL;
257 if (bus >= UART_BUS_MAX_NUM) {
258 return ERRCODE_INVALID_PARAM;
259 }
260 if (!g_uart_inited[bus]) {
261 return ERRCODE_SUCC;
262 }
263 ret = hal_uart_deinit(bus);
264
265 uart_port_unregister_irq(bus);
266
267 #if defined(CONFIG_UART_SUPPORT_RX) || defined(CONFIG_UART_SUPPORT_TX)
268 uart_deconfig_state(bus);
269 #endif /* defined(CONFIG_UART_SUPPORT_RX) || defined(CONFIG_UART_SUPPORT_TX) */
270
271 uart_release_pins(bus);
272
273 #if defined(CONFIG_UART_SUPPORT_DMA)
274 if (g_dma_trans[bus].inited) {
275 osal_sem_destroy(&(g_dma_trans[bus].dma_sem));
276 g_dma_trans[bus].inited = false;
277 }
278 #endif /* CONFIG_UART_SUPPORT_DMA */
279 #if defined(CONFIG_UART_SUPPORT_LPC)
280 uart_port_clock_enable(bus, false);
281 #endif
282 g_uart_inited[bus] = false;
283 return ret;
284 }
285
uapi_uart_set_attr(uart_bus_t bus,const uart_attr_t * attr)286 errcode_t uapi_uart_set_attr(uart_bus_t bus, const uart_attr_t *attr)
287 {
288 if (bus >= UART_BUS_MAX_NUM) {
289 return ERRCODE_INVALID_PARAM;
290 }
291 if ((uart_check_params_attr(attr)) != 0) {
292 return ERRCODE_INVALID_PARAM;
293 }
294 uint32_t irq_sts = uart_porting_lock(bus);
295 errcode_t ret = hal_uart_ctrl(bus, UART_CTRL_SET_ATTR, (uintptr_t)attr);
296 uart_porting_unlock(bus, irq_sts);
297 return ret;
298 }
299
uapi_uart_get_attr(uart_bus_t bus,const uart_attr_t * attr)300 errcode_t uapi_uart_get_attr(uart_bus_t bus, const uart_attr_t *attr)
301 {
302 if (bus >= UART_BUS_MAX_NUM || attr == NULL) {
303 return ERRCODE_INVALID_PARAM;
304 }
305 uint32_t irq_sts = uart_porting_lock(bus);
306 errcode_t ret = hal_uart_ctrl(bus, UART_CTRL_GET_ATTR, (uintptr_t)attr);
307 uart_porting_unlock(bus, irq_sts);
308 return ret;
309 }
310
311 #if defined(CONFIG_UART_SUPPORT_RX)
uapi_uart_register_rx_callback(uart_bus_t bus,uart_rx_condition_t condition,uint32_t size,uart_rx_callback_t callback)312 errcode_t uapi_uart_register_rx_callback(uart_bus_t bus, uart_rx_condition_t condition,
313 uint32_t size, uart_rx_callback_t callback)
314 {
315 errcode_t ret = ERRCODE_FAIL;
316
317 if (bus >= UART_BUS_MAX_NUM || callback == NULL) {
318 return ERRCODE_INVALID_PARAM;
319 }
320
321 #if defined(CONFIG_UART_SUPPORT_LPM)
322 if (g_uart_suspend_flag[bus] == false) {
323 memcpy_s(&g_uart_condition[bus], sizeof(uart_rx_condition_t), &condition, sizeof(uart_rx_condition_t));
324 memcpy_s(&g_uart_size[bus], sizeof(uint32_t), &size, sizeof(uint32_t));
325 memcpy_s(&g_uart_callback[bus], sizeof(uart_rx_callback_t), &callback, sizeof(uart_rx_callback_t));
326 }
327 #endif /* CONFIG_UART_SUPPORT_LPM */
328
329 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
330 uint32_t irq_sts = uart_porting_lock(bus);
331 rx_state->rx_callback = callback;
332 rx_state->rx_condition = condition;
333 #if !defined(CONFIG_UART_NOT_SUPPORT_RX_CONDITON_SIZE_OPTIMIZE)
334 uint32_t uart_rx_fifo_thresh = 0;
335 ret = hal_uart_ctrl(bus, UART_CTRL_GET_RX_FIFO_THRESHOLD, (uintptr_t)&uart_rx_fifo_thresh);
336 size = size > uart_rx_fifo_thresh ? uart_rx_fifo_thresh : size;
337 #endif
338 rx_state->rx_condition_size = (uint16_t)size;
339 ret = hal_uart_ctrl(bus, UART_CTRL_EN_RX_INT, 1);
340 ret = hal_uart_ctrl(bus, UART_CTRL_EN_FRAME_ERR_INT, 1);
341 ret = hal_uart_ctrl(bus, UART_CTRL_EN_PARITY_ERR_INT, 1);
342 ret = hal_uart_ctrl(bus, UART_CTRL_EN_IDLE_INT, 1);
343 uart_porting_unlock(bus, irq_sts);
344
345 return ret;
346 }
347
uapi_uart_register_parity_error_callback(uart_bus_t bus,uart_error_callback_t callback)348 errcode_t uapi_uart_register_parity_error_callback(uart_bus_t bus, uart_error_callback_t callback)
349 {
350 errcode_t ret = ERRCODE_FAIL;
351
352 if (bus >= UART_BUS_MAX_NUM || callback == NULL) {
353 return ERRCODE_INVALID_PARAM;
354 }
355 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
356 uint32_t irq_sts = uart_porting_lock(bus);
357 rx_state->parity_error_callback = callback;
358 ret = hal_uart_ctrl(bus, UART_CTRL_EN_PARITY_ERR_INT, 0);
359 uart_porting_unlock(bus, irq_sts);
360
361 return ret;
362 }
363
uapi_uart_register_frame_error_callback(uart_bus_t bus,uart_error_callback_t callback)364 errcode_t uapi_uart_register_frame_error_callback(uart_bus_t bus, uart_error_callback_t callback)
365 {
366 errcode_t ret = ERRCODE_FAIL;
367
368 if (bus >= UART_BUS_MAX_NUM || callback == NULL) {
369 return ERRCODE_INVALID_PARAM;
370 }
371 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
372 uint32_t irq_sts = uart_porting_lock(bus);
373 rx_state->frame_error_callback = callback;
374 ret = hal_uart_ctrl(bus, UART_CTRL_EN_FRAME_ERR_INT, 0);
375 uart_porting_unlock(bus, irq_sts);
376
377 return ret;
378 }
379 #endif /* CONFIG_UART_SUPPORT_RX */
380
uapi_uart_param_check(uart_bus_t bus,const uint8_t * buffer,uint32_t length)381 static int32_t uapi_uart_param_check(uart_bus_t bus, const uint8_t *buffer, uint32_t length)
382 {
383 if (bus >= UART_BUS_MAX_NUM || buffer == NULL || length == 0) {
384 return ERRCODE_INVALID_PARAM;
385 }
386 if (!g_uart_inited[bus]) {
387 return ERRCODE_UART_NOT_INIT;
388 }
389
390 return ERRCODE_SUCC;
391 }
392
393 #if defined(CONFIG_UART_SUPPORT_TX)
uapi_uart_write(uart_bus_t bus,const uint8_t * buffer,uint32_t length,uint32_t timeout)394 int32_t uapi_uart_write(uart_bus_t bus, const uint8_t *buffer, uint32_t length, uint32_t timeout)
395 {
396 unused(timeout);
397 bool tx_fifo_full = false;
398 uint8_t *data_buffer = (uint8_t *)buffer;
399 int32_t write_count = 0;
400 uint32_t len = length;
401
402 int32_t ret = uapi_uart_param_check(bus, buffer, length);
403 if (ret != ERRCODE_SUCC) {
404 return ret;
405 }
406
407 uint32_t irq_sts = uart_porting_lock(bus);
408 while (len > 0) {
409 hal_uart_ctrl(bus, UART_CTRL_CHECK_TX_FIFO_FULL, (uintptr_t)&tx_fifo_full);
410 if (tx_fifo_full == false) {
411 hal_uart_write(bus, data_buffer++, 1);
412 len--;
413 write_count++;
414 }
415 }
416 uart_porting_unlock(bus, irq_sts);
417
418 return write_count;
419 }
420
421 #if defined(CONFIG_UART_SUPPORT_TX_INT)
uapi_uart_data_send(uart_bus_t bus)422 static void uapi_uart_data_send(uart_bus_t bus)
423 {
424 bool tx_fifo_full = false;
425 hal_uart_ctrl(bus, UART_CTRL_CHECK_TX_FIFO_FULL, (uintptr_t)&tx_fifo_full);
426
427 /* Populate the UART TX FIFO if there is data to send */
428 while (tx_fifo_full == false) {
429 /* There is some data to transmit so provide another byte to the UART */
430 bool end_of_fragment = uart_helper_send_next_char(bus);
431 if (end_of_fragment) {
432 /* If it is the end of the fragment invoke the callback and move to the next one */
433 uart_helper_invoke_current_fragment_callback(bus);
434 uart_helper_move_to_next_fragment(bus);
435 /* As it was the only fragment leave */
436 break;
437 }
438
439 hal_uart_ctrl(bus, UART_CTRL_CHECK_TX_FIFO_FULL, (uintptr_t)&tx_fifo_full);
440 }
441 }
442
uapi_uart_write_int(uart_bus_t bus,const uint8_t * buffer,uint32_t length,void * params,uart_tx_callback_t finished_with_buffer_func)443 errcode_t uapi_uart_write_int(uart_bus_t bus, const uint8_t *buffer, uint32_t length,
444 void *params, uart_tx_callback_t finished_with_buffer_func)
445 {
446 errcode_t ret = (errcode_t)uapi_uart_param_check(bus, buffer, length);
447 if (ret != ERRCODE_SUCC) {
448 return ret;
449 }
450
451 uint32_t irq_sts = uart_porting_lock(bus);
452 if (uart_helper_are_there_fragments_to_process(bus) == true) {
453 uapi_uart_data_send(bus);
454 }
455
456 bool fragment_added = uart_helper_add_fragment(bus, buffer, length, params, finished_with_buffer_func);
457 if (!fragment_added) {
458 uart_porting_unlock(bus, irq_sts);
459 return ERRCODE_UART_ADD_QUEUE_FAIL;
460 }
461 /* If it is the first on the list process it */
462 if (uart_helper_is_the_current_fragment_the_last_to_process(bus) ==
463 true) { /* No other fragments require transmission so start the transmission */
464 uapi_uart_data_send(bus);
465 /* if we have not finished transmitting it enable the interrupts */
466 if (uart_helper_are_there_fragments_to_process(bus) == true) { /* if it is not finished transmitting it */
467 hal_uart_ctrl(bus, UART_CTRL_EN_TX_INT, true);
468 }
469 }
470 uart_porting_unlock(bus, irq_sts);
471 return ERRCODE_SUCC;
472 }
473 #endif
474
475 #if defined(CONFIG_UART_SUPPORT_DMA)
uart_dma_set_config(uart_bus_t bus,const uart_extra_attr_t * extra_attr)476 static void uart_dma_set_config(uart_bus_t bus, const uart_extra_attr_t *extra_attr)
477 {
478 hal_uart_set_dma_config(bus, (hal_uart_extra_attr_t *)extra_attr);
479 (void)memset_s(&(g_dma_trans[bus].dma_sem), sizeof(g_dma_trans[bus].dma_sem), 0, sizeof(g_dma_trans[bus].dma_sem));
480 (void)osal_sem_init(&(g_dma_trans[bus].dma_sem), 0);
481 g_dma_trans[bus].inited = true;
482 }
483
uart_dma_isr(uint8_t int_type,uint8_t ch,uintptr_t arg)484 static void uart_dma_isr(uint8_t int_type, uint8_t ch, uintptr_t arg)
485 {
486 unused(arg);
487 uint8_t bus = UART_BUS_MAX_NUM;
488 for (uint8_t i = UART_BUS_0; i < UART_BUS_MAX_NUM; i++) {
489 /* channel default value is 0, means not used. channel > 0 means used.
490 So ch + 1 will not misjudgment with channel value 0. */
491 if (g_dma_trans[i].channel == ch + 1) {
492 bus = i;
493 break;
494 }
495 }
496
497 if (bus != UART_BUS_MAX_NUM) {
498 if (int_type == 0) {
499 g_dma_trans[bus].trans_succ = true;
500 }
501 osal_sem_up(&(g_dma_trans[bus].dma_sem));
502 }
503 }
504
uart_write_by_dma_config(uart_bus_t bus,const void * buffer,uint32_t length,uart_write_dma_config_t * dma_cfg,dma_ch_user_peripheral_config_t * user_cfg)505 static int32_t uart_write_by_dma_config(uart_bus_t bus, const void *buffer, uint32_t length,
506 uart_write_dma_config_t *dma_cfg,
507 dma_ch_user_peripheral_config_t *user_cfg)
508 {
509 uint32_t uart_data_addr = 0;
510 errcode_t ret = hal_uart_ctrl(bus, UART_CTRL_GET_DMA_DATA_ADDR, (uintptr_t)&uart_data_addr);
511 if (ret != ERRCODE_SUCC) {
512 return -1;
513 }
514 user_cfg->src = (uint32_t)(uintptr_t)buffer;
515 user_cfg->dest = uart_data_addr;
516 user_cfg->transfer_num = (uint16_t)(length >> dma_cfg->src_width);
517 user_cfg->src_handshaking = 0;
518 user_cfg->trans_type = UART_DMA_TRANS_MEMORY_TO_PERIPHERAL_DMA;
519 user_cfg->trans_dir = UART_DMA_TRANSFER_DIR_MEM_TO_PERIPHERAL;
520 user_cfg->priority = dma_cfg->priority;
521 user_cfg->src_width = dma_cfg->src_width;
522 user_cfg->dest_width = dma_cfg->dest_width;
523 user_cfg->burst_length = dma_cfg->burst_length;
524 user_cfg->src_increment = UART_DMA_ADDRESS_INC_INCREMENT;
525 user_cfg->dest_increment = UART_DMA_ADDRESS_INC_NO_CHANGE;
526 user_cfg->protection = UART_DMA_PROTECTION_CONTROL_BUFFERABLE;
527 user_cfg->dest_handshaking = uart_port_get_dma_trans_dest_handshaking(bus);
528 return ERRCODE_SUCC;
529 }
530
uapi_uart_dma_check(uart_bus_t bus,const void * buffer,uint32_t length,const uart_write_dma_config_t * dma_cfg)531 static int32_t uapi_uart_dma_check(uart_bus_t bus, const void *buffer, uint32_t length,
532 const uart_write_dma_config_t *dma_cfg)
533 {
534 if ((bus >= UART_BUS_MAX_NUM) || (dma_cfg == NULL)) {
535 return UART_DMA_CFG_PARAM_INVALID;
536 }
537 if ((buffer == NULL) || (length == 0)) {
538 return UART_DMA_BUFF_NULL;
539 }
540 if (length % bit(dma_cfg->src_width) != 0) {
541 return UART_DMA_CFG_PARAM_INVALID;
542 }
543 return 0;
544 }
545
uapi_uart_write_by_dma(uart_bus_t bus,const void * buffer,uint32_t length,uart_write_dma_config_t * dma_cfg)546 int32_t uapi_uart_write_by_dma(uart_bus_t bus, const void *buffer, uint32_t length, uart_write_dma_config_t *dma_cfg)
547 {
548 int32_t ret = uapi_uart_dma_check(bus, buffer, length, dma_cfg);
549 if (ret != 0) {
550 return ret;
551 }
552
553 dma_ch_user_peripheral_config_t user_cfg = {0};
554
555 ret = uart_write_by_dma_config(bus, buffer, length, dma_cfg, &user_cfg);
556 if (ret != ERRCODE_SUCC || user_cfg.dest_handshaking == HAL_DMA_HANDSHAKING_MAX_NUM) {
557 return UART_DMA_SHAKING_INVALID_OR_UART_FUNCS_NULL;
558 }
559
560 uint8_t dma_ch;
561 if (uapi_dma_configure_peripheral_transfer_single(&user_cfg, &dma_ch,
562 uart_dma_isr, (uintptr_t)NULL) != ERRCODE_SUCC) {
563 return UART_DMA_CONFIGURE_FAIL;
564 }
565
566 g_dma_trans[bus].channel = dma_ch + 1;
567 g_dma_trans[bus].trans_succ = false;
568
569 if (uapi_dma_start_transfer(dma_ch) != ERRCODE_SUCC) {
570 g_dma_trans[bus].channel = 0;
571 return UART_DMA_START_TRANSFER_FAIL;
572 }
573
574 if (osal_sem_down_timeout(&(g_dma_trans[bus].dma_sem), DMA_UART_TRANSFER_TIMEOUT_MS) != OSAL_SUCCESS) {
575 g_dma_trans[bus].channel = 0;
576 return UART_DMA_TRANSFER_TIMEOUT;
577 }
578
579 g_dma_trans[bus].channel = 0;
580
581 if (!g_dma_trans[bus].trans_succ) {
582 return UART_DMA_TRANSFER_ERROR;
583 }
584
585 return (int32_t)uapi_dma_get_block_ts(dma_ch);
586 }
587
uart_read_by_dma_config(uart_bus_t bus,const void * buffer,uint32_t length,uart_write_dma_config_t * dma_cfg,dma_ch_user_peripheral_config_t * user_cfg)588 static int32_t uart_read_by_dma_config(uart_bus_t bus, const void *buffer, uint32_t length,
589 uart_write_dma_config_t *dma_cfg,
590 dma_ch_user_peripheral_config_t *user_cfg)
591 {
592 uint32_t uart_data_addr = 0;
593 errcode_t ret = hal_uart_ctrl(bus, UART_CTRL_GET_DMA_DATA_ADDR, (uintptr_t)&uart_data_addr);
594 if (ret != ERRCODE_SUCC) {
595 return -1;
596 }
597 user_cfg->src = uart_data_addr;
598 user_cfg->dest = (uint32_t)(uintptr_t)buffer;
599 user_cfg->transfer_num = (uint16_t)(length >> dma_cfg->src_width);
600 user_cfg->dest_handshaking = 0;
601 user_cfg->trans_type = UART_DMA_TRANS_PERIPHERAL_TO_MEMORY_DMA;
602 user_cfg->trans_dir = UART_DMA_TRANSFER_DIR_PERIPHERAL_TO_MEM;
603 user_cfg->priority = dma_cfg->priority;
604 user_cfg->src_width = dma_cfg->src_width;
605 user_cfg->dest_width = dma_cfg->dest_width;
606 user_cfg->burst_length = dma_cfg->burst_length;
607 user_cfg->src_increment = UART_DMA_ADDRESS_INC_NO_CHANGE;
608 user_cfg->dest_increment = UART_DMA_ADDRESS_INC_INCREMENT;
609 user_cfg->protection = UART_DMA_PROTECTION_CONTROL_BUFFERABLE;
610 user_cfg->src_handshaking = uart_port_get_dma_trans_src_handshaking(bus);
611 return ERRCODE_SUCC;
612 }
613
uapi_uart_read_by_dma(uart_bus_t bus,const void * buffer,uint32_t length,uart_write_dma_config_t * dma_cfg)614 int32_t uapi_uart_read_by_dma(uart_bus_t bus, const void *buffer, uint32_t length, uart_write_dma_config_t *dma_cfg)
615 {
616 int32_t ret = uapi_uart_dma_check(bus, buffer, length, dma_cfg);
617 if (ret != 0) {
618 return ret;
619 }
620
621 dma_ch_user_peripheral_config_t user_cfg = {0};
622 uint8_t dma_ch;
623
624 ret = uart_read_by_dma_config(bus, buffer, length, dma_cfg, &user_cfg);
625 if (ret != ERRCODE_SUCC || user_cfg.src_handshaking == HAL_DMA_HANDSHAKING_MAX_NUM) {
626 return -1;
627 }
628
629 if (uapi_dma_configure_peripheral_transfer_single(&user_cfg, &dma_ch,
630 uart_dma_isr, (uintptr_t)NULL) != ERRCODE_SUCC) {
631 return -1;
632 }
633
634 g_dma_trans[bus].channel = dma_ch + 1;
635 g_dma_trans[bus].trans_succ = false;
636
637 if (uapi_dma_start_transfer(dma_ch) != ERRCODE_SUCC) {
638 g_dma_trans[bus].channel = 0;
639 return -1;
640 }
641
642 if (osal_sem_down(&(g_dma_trans[bus].dma_sem)) != OSAL_SUCCESS) {
643 g_dma_trans[bus].channel = 0;
644 return -1;
645 }
646
647 g_dma_trans[bus].channel = 0;
648
649 if (!g_dma_trans[bus].trans_succ) {
650 return -1;
651 }
652
653 return (int32_t)uapi_dma_get_block_ts(dma_ch);
654 }
655 #endif /* CONFIG_UART_SUPPORT_DMA */
656 #endif /* CONFIG_UART_SUPPORT_TX */
657
658 #if defined(CONFIG_UART_SUPPORT_RX)
uapi_uart_read(uart_bus_t bus,const uint8_t * buffer,uint32_t length,uint32_t timeout)659 int32_t uapi_uart_read(uart_bus_t bus, const uint8_t *buffer, uint32_t length, uint32_t timeout)
660 {
661 int32_t ret = uapi_uart_param_check(bus, buffer, length);
662 if (ret != ERRCODE_SUCC) {
663 return ret;
664 }
665
666 unused(timeout);
667 bool rx_fifo_empty = false;
668 uint8_t *data_buffer = (uint8_t *)buffer;
669 int32_t read_count = 0;
670 uint32_t len = length;
671
672 uint32_t irq_sts = uart_porting_lock(bus);
673 while (len > 0) {
674 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
675 if (rx_fifo_empty == false) {
676 hal_uart_read(bus, data_buffer++, 1);
677 len--;
678 read_count++;
679 }
680 }
681 uart_porting_unlock(bus, irq_sts);
682
683 return read_count;
684 }
685 #endif /* CONFIG_UART_SUPPORT_RX */
686
687 #if defined(CONFIG_UART_SUPPORT_RX)
uart_config_rx_state(uart_bus_t bus,const uart_buffer_config_t * uart_buffer_config)688 static bool uart_config_rx_state(uart_bus_t bus, const uart_buffer_config_t *uart_buffer_config)
689 {
690 if ((uart_buffer_config == NULL) ||
691 (uart_buffer_config->rx_buffer == NULL) ||
692 (uart_buffer_config->rx_buffer_size == 0)) { /* No RX buffer specified */
693 return false;
694 }
695 /* Configure RX state structure */
696 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
697 rx_state->rx_buffer = uart_buffer_config->rx_buffer;
698 rx_state->rx_buffer_size = (uint16_t)uart_buffer_config->rx_buffer_size;
699
700 return true;
701 }
702 #endif /* CONFIG_UART_SUPPORT_RX */
703
704 #if defined(CONFIG_UART_SUPPORT_TX)
705 #if defined(CONFIG_UART_SUPPORT_TX_INT)
uart_config_tx_state(uart_bus_t bus)706 static void uart_config_tx_state(uart_bus_t bus)
707 {
708 /* Configure TX state structure */
709 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
710 tx_state->current_tx_fragment = tx_state->fragment_buffer; /* the queue is empty */
711 tx_state->free_tx_fragment = tx_state->fragment_buffer; /* the queue is empty */
712 }
713 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
714 #endif /* CONFIG_UART_SUPPORT_TX */
715
716 #if defined(CONFIG_UART_SUPPORT_RX) || (CONFIG_UART_SUPPORT_TX)
uart_deconfig_state(uart_bus_t bus)717 static void uart_deconfig_state(uart_bus_t bus)
718 {
719 unused(bus);
720 #if defined(CONFIG_UART_SUPPORT_RX)
721 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
722 (void)memset_s(rx_state, sizeof(uart_rx_state_t), 0, sizeof(uart_rx_state_t));
723 #endif /* CONFIG_UART_SUPPORT_RX */
724 #if defined(CONFIG_UART_SUPPORT_TX)
725 #if defined(CONFIG_UART_SUPPORT_TX_INT)
726 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
727 (void)memset_s(tx_state, sizeof(uart_tx_state_t), 0, sizeof(uart_tx_state_t));
728 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
729 #endif /* CONFIG_UART_SUPPORT_TX */
730 }
731 #endif /* defined(CONFIG_UART_SUPPORT_RX) || (CONFIG_UART_SUPPORT_TX) */
732
733 #if defined(CONFIG_UART_SUPPORT_TX)
734 #if defined(CONFIG_UART_SUPPORT_TX_INT)
uart_helper_add_fragment(uart_bus_t bus,const uint8_t * buffer,uint32_t length,void * params,uart_tx_callback_t finished_with_buffer_func)735 static bool uart_helper_add_fragment(uart_bus_t bus, const uint8_t *buffer,
736 uint32_t length, void *params,
737 uart_tx_callback_t finished_with_buffer_func)
738 {
739 uart_tx_fragment_t *fragment;
740
741 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
742 /* If we have fragments left add it */
743 if (tx_state->fragments_to_process >= UART_MAX_NUMBER_OF_FRAGMENTS) {
744 return false;
745 }
746
747 /* Put it on the queue */
748 fragment = tx_state->free_tx_fragment;
749 /* Populate the fragment */
750 fragment->data = (uint8_t *)buffer;
751 fragment->params = params;
752 fragment->data_length = length;
753 fragment->release_func = finished_with_buffer_func;
754
755 /* Update the counters */
756 tx_state->free_tx_fragment++;
757 if (tx_state->free_tx_fragment >=
758 tx_state->fragment_buffer + UART_MAX_NUMBER_OF_FRAGMENTS) {
759 tx_state->free_tx_fragment = tx_state->fragment_buffer; /* wrapping */
760 }
761 tx_state->fragments_to_process++;
762 return true;
763 }
764
uart_helper_is_the_current_fragment_the_last_to_process(uart_bus_t bus)765 static inline bool uart_helper_is_the_current_fragment_the_last_to_process(uart_bus_t bus)
766 {
767 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
768 return (tx_state->fragments_to_process == 1);
769 }
770
uart_helper_are_there_fragments_to_process(uart_bus_t bus)771 static inline bool uart_helper_are_there_fragments_to_process(uart_bus_t bus)
772 {
773 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
774 return (tx_state->fragments_to_process > 0);
775 }
776
uart_helper_send_next_char(uart_bus_t bus)777 static bool uart_helper_send_next_char(uart_bus_t bus)
778 {
779 uart_tx_fragment_t *current_fragment;
780 uint16_t current_fragment_pos;
781
782 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
783 current_fragment = tx_state->current_tx_fragment;
784 current_fragment_pos = tx_state->current_tx_fragment_pos;
785 hal_uart_write(bus, ¤t_fragment->data[current_fragment_pos], 1);
786 /* update the counters */
787 tx_state->current_tx_fragment_pos++;
788
789 return (tx_state->current_tx_fragment_pos >= current_fragment->data_length);
790 }
791
uart_helper_invoke_current_fragment_callback(uart_bus_t bus)792 static inline void uart_helper_invoke_current_fragment_callback(uart_bus_t bus)
793 {
794 uart_tx_fragment_t *current_fragment;
795 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
796 current_fragment = tx_state->current_tx_fragment;
797 /* Call any TX data release call-back */
798 if (current_fragment->release_func != NULL) {
799 current_fragment->release_func(current_fragment->data, current_fragment->data_length, current_fragment->params);
800 }
801 }
802
uart_helper_move_to_next_fragment(uart_bus_t bus)803 static inline void uart_helper_move_to_next_fragment(uart_bus_t bus)
804 {
805 /* Move onto the next fragment and re-set the position to zero */
806 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
807 tx_state->current_tx_fragment++;
808 if (tx_state->current_tx_fragment >=
809 tx_state->fragment_buffer + UART_MAX_NUMBER_OF_FRAGMENTS) {
810 tx_state->current_tx_fragment = tx_state->fragment_buffer; /* wrapping */
811 }
812 tx_state->current_tx_fragment_pos = 0; /* reset the current fragment */
813 tx_state->fragments_to_process--; /* one fragment less to process */
814 }
815 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
816 #endif /* CONFIG_UART_SUPPORT_TX */
817
818 #if defined(CONFIG_UART_SUPPORT_RX)
uart_rx_buffer_release(uart_bus_t bus)819 static inline void uart_rx_buffer_release(uart_bus_t bus)
820 {
821 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
822 rx_state->new_rx_pos = 0;
823 }
824
uart_rx_buffer_has_free_space(uart_bus_t bus)825 static inline bool uart_rx_buffer_has_free_space(uart_bus_t bus)
826 {
827 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
828 return (rx_state->new_rx_pos < rx_state->rx_buffer_size);
829 }
830
uart_rx_buffer_data_available(uart_bus_t bus)831 static inline uint16_t uart_rx_buffer_data_available(uart_bus_t bus)
832 {
833 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
834 return rx_state->new_rx_pos;
835 }
836 #endif /* CONFIG_UART_SUPPORT_RX */
837
838 #if defined(CONFIG_UART_SUPPORT_LPM)
uapi_uart_suspend(uintptr_t arg)839 errcode_t uapi_uart_suspend(uintptr_t arg)
840 {
841 errcode_t ret = ERRCODE_SUCC;
842 unused(arg);
843 for (uint32_t i = 0; i < UART_BUS_MAX_NUM; i++) {
844 if (g_uart_inited[i] == false) {
845 continue;
846 }
847 g_uart_suspend_flag[i] = true;
848 #if defined(CONFIG_UART_SUPPORT_DMA)
849 uapi_dma_suspend(arg);
850 #endif
851 }
852 return ret;
853 }
854
uapi_uart_resume(uintptr_t arg)855 errcode_t uapi_uart_resume(uintptr_t arg)
856 {
857 errcode_t ret = ERRCODE_SUCC;
858 unused(arg);
859 for (uint32_t i = 0; i < UART_BUS_MAX_NUM; i++) {
860 if (g_uart_suspend_flag[i] == false) {
861 continue;
862 }
863 ret |= uapi_uart_deinit(i);
864 ret |= uapi_uart_init(i, &g_uart_pins[i], &g_uart_attr[i], &g_uart_extra_attr[i], &g_uart_buffer_config[i]);
865 if (g_uart_callback[i] != NULL) {
866 ret |= uapi_uart_register_rx_callback(i, g_uart_condition[i], g_uart_size[i], g_uart_callback[i]);
867 }
868 #if defined(CONFIG_UART_SUPPORT_DMA)
869 uapi_dma_resume(arg);
870 #endif
871 g_uart_suspend_flag[i] = false;
872 }
873 return ret;
874 }
875 #endif /* CONFIG_UART_SUPPORT_LPM */
876
uart_check_params_attr(const uart_attr_t * attr)877 static int32_t uart_check_params_attr(const uart_attr_t *attr)
878 {
879 if (attr == NULL || attr->data_bits > UART_DATA_BIT_8) {
880 return -1;
881 }
882
883 if (attr->parity > UART_PARITY_EVEN) {
884 return -1;
885 }
886
887 if (attr->stop_bits != UART_STOP_BIT_1 && attr->stop_bits != UART_STOP_BIT_2) {
888 return -1;
889 }
890
891 return 0;
892 }
893
uart_init_check_params(uart_bus_t bus,const uart_pin_config_t * pins,const uart_attr_t * attr)894 static int32_t uart_init_check_params(uart_bus_t bus, const uart_pin_config_t *pins, const uart_attr_t *attr)
895 {
896 if (bus >= UART_BUS_MAX_NUM || pins == NULL) {
897 return -1;
898 }
899
900 #if defined(CONFIG_UART_SUPPORT_RX)
901 if (pins->rx_pin >= PIN_NONE) {
902 return -1;
903 }
904 #endif
905 #if defined(CONFIG_UART_SUPPORT_TX)
906 if (pins->tx_pin >= PIN_NONE) {
907 return -1;
908 }
909 #endif
910
911 return uart_check_params_attr(attr);
912 }
913
uart_claim_pins(uart_bus_t bus,const uart_pin_config_t * pins)914 static void uart_claim_pins(uart_bus_t bus, const uart_pin_config_t *pins)
915 {
916 unused(pins);
917 uart_port_config_pinmux(bus);
918 }
919
uart_release_pins(uart_bus_t bus)920 static void uart_release_pins(uart_bus_t bus)
921 {
922 unused(bus);
923 }
924
925 #if defined(CONFIG_UART_SUPPORT_RX)
uart_idle_isr(uart_bus_t bus)926 static void uart_idle_isr(uart_bus_t bus)
927 {
928 uint16_t char_recv_cnt = 0;
929 uint16_t uart_rx_isr_available = 0;
930 uint8_t uart_rx_isr_data = 0 ;
931 bool rx_fifo_empty = false;
932
933 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
934 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
935 while (rx_fifo_empty != true) {
936 /* Read the data out of the UART to clear the interrupt */
937 /* using a volatile variable to ensure the read always happens */
938 hal_uart_read(bus, &uart_rx_isr_data, 1);
939 char_recv_cnt++;
940 /* Only bother to try and record UART data it there is an RX callback registered */
941 if (rx_state->rx_callback == NULL) {
942 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
943 continue;
944 }
945 /* There is some space in the RX buffer so put the data in and move the pointers */
946 rx_state->rx_buffer[rx_state->new_rx_pos] = uart_rx_isr_data;
947 rx_state->new_rx_pos++;
948 /* When the rx buffer is full, callback should be invoked */
949 if (uart_rx_buffer_has_free_space(bus) == false) {
950 if (rx_state->rx_callback != NULL) {
951 uart_rx_isr_available = uart_rx_buffer_data_available(bus);
952 rx_state->rx_callback(rx_state->rx_buffer, uart_rx_isr_available, false);
953 }
954 uart_rx_buffer_release(bus);
955 }
956
957 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
958 }
959 /**
960 * Is the RX callback an exact size condition or
961 * it has already been determined that a callback must be made.
962 */
963 uart_rx_isr_available = uart_rx_buffer_data_available(bus);
964 if (uart_rx_isr_available > 0 &&
965 ((((uint8_t)rx_state->rx_condition & UART_RX_CONDITION_MASK_IDLE) != 0) ||
966 (((uint8_t)rx_state->rx_condition & UART_RX_CONDITION_MASK_SUFFICIENT_DATA) != 0 &&
967 char_recv_cnt >= rx_state->rx_condition_size))) {
968 if (rx_state->rx_callback != NULL) {
969 rx_state->rx_callback(rx_state->rx_buffer, uart_rx_isr_available, false);
970 }
971 uart_rx_buffer_release(bus);
972 }
973 }
974
uart_rx_isr(uart_bus_t bus)975 static void uart_rx_isr(uart_bus_t bus)
976 {
977 uint16_t uart_rx_isr_available;
978 uint8_t uart_rx_isr_data = 0;
979 bool rx_fifo_empty = false;
980 uint16_t char_recv_cnt = 0;
981
982 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
983 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
984 /* Check that the UART is opened */
985 while (rx_fifo_empty != true) {
986 /* Read the data out of the UART to clear the interrupt */
987 /* Using a volatile variable to ensure the read always happens */
988 hal_uart_read(bus, &uart_rx_isr_data, 1);
989 char_recv_cnt++;
990 /* Only bother to try and record UART data it there is an RX callback registered */
991 if (rx_state->rx_callback == NULL) {
992 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
993 continue;
994 }
995 /* There is some space in the RX buffer so put the data in and move the pointers */
996 rx_state->rx_buffer[rx_state->new_rx_pos] = uart_rx_isr_data;
997 rx_state->new_rx_pos++;
998 /* When the rx buffer is full, callback should be invoked */
999 if (uart_rx_buffer_has_free_space(bus) == false) {
1000 uart_rx_isr_available = uart_rx_buffer_data_available(bus);
1001 rx_state->rx_callback(rx_state->rx_buffer, uart_rx_isr_available, false);
1002 uart_rx_buffer_release(bus);
1003 }
1004
1005 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
1006 }
1007 /* Check to see if the callback should be invoked */
1008 uart_rx_isr_available = uart_rx_buffer_data_available(bus);
1009 if (uart_rx_isr_available > 0 &&
1010 (((uint8_t)rx_state->rx_condition & UART_RX_CONDITION_MASK_SUFFICIENT_DATA) != 0 &&
1011 char_recv_cnt >= rx_state->rx_condition_size)) {
1012 if (rx_state->rx_callback != NULL) {
1013 rx_state->rx_callback(rx_state->rx_buffer, uart_rx_isr_available, false);
1014 }
1015 uart_rx_buffer_release(bus);
1016 }
1017 }
1018
uart_error_isr(uart_bus_t bus)1019 static void uart_error_isr(uart_bus_t bus)
1020 {
1021 uint16_t uart_rx_isr_available;
1022 uint8_t uart_rx_isr_data = 0;
1023 bool rx_fifo_empty = false;
1024
1025 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
1026 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
1027 while (rx_fifo_empty != true) {
1028 /* Read the data out of the UART FIFO */
1029 hal_uart_read(bus, &uart_rx_isr_data, 1);
1030 /* There is some space in the RX buffer so put the data in and move the pointers */
1031 rx_state->rx_buffer[rx_state->new_rx_pos] = (uint8_t)uart_rx_isr_data;
1032 rx_state->new_rx_pos++;
1033 /* Only bother to try and record UART data if there is an RX callback registered */
1034 if (uart_rx_buffer_has_free_space(bus) == false) {
1035 if (rx_state->rx_callback != NULL) {
1036 /* Calculate the amount of available data */
1037 uart_rx_isr_available = uart_rx_buffer_data_available(bus);
1038 /* Callback should be invoked in any case */
1039 rx_state->rx_callback(rx_state->rx_buffer, uart_rx_isr_available, true);
1040 }
1041 uart_rx_buffer_release(bus);
1042 }
1043 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
1044 }
1045 uart_rx_isr_available = uart_rx_buffer_data_available(bus);
1046 if (uart_rx_isr_available > 0 && rx_state->rx_callback != NULL) {
1047 rx_state->rx_callback(rx_state->rx_buffer, uart_rx_isr_available, true);
1048 uart_rx_buffer_release(bus);
1049 }
1050 }
1051 #endif /* CONFIG_UART_SUPPORT_RX */
1052
1053 #if defined(CONFIG_UART_SUPPORT_TX_INT)
uart_tx_isr(uart_bus_t bus)1054 static void uart_tx_isr(uart_bus_t bus)
1055 {
1056 bool tx_fifo_full = false;
1057
1058 /* if there are fragments to process do it */
1059 if (!uart_helper_are_there_fragments_to_process(bus)) {
1060 /* No data to transmit so disable the TX interrupt */
1061 hal_uart_ctrl(bus, UART_CTRL_EN_TX_INT, false);
1062 return;
1063 }
1064
1065 hal_uart_ctrl(bus, UART_CTRL_CHECK_TX_FIFO_FULL, (uintptr_t)&tx_fifo_full);
1066 /* Populate the UART TX FIFO if there is data to send */
1067 while (tx_fifo_full != true) {
1068 /* There is some data to transmit so provide another byte to the UART */
1069 bool end_of_fragment = uart_helper_send_next_char(bus);
1070 if (end_of_fragment) {
1071 /* If it is the end of the fragment invoke the callback and move to the next one */
1072 uart_helper_invoke_current_fragment_callback(bus);
1073 uart_helper_move_to_next_fragment(bus);
1074 /* If it was the last fragment disable the TX interrupts and leave */
1075 if (uart_helper_are_there_fragments_to_process(bus) == false) {
1076 /* No data to transmit so disable the TX interrupt */
1077 hal_uart_ctrl(bus, UART_CTRL_EN_TX_INT, false);
1078 break;
1079 }
1080 }
1081
1082 hal_uart_ctrl(bus, UART_CTRL_CHECK_TX_FIFO_FULL, (uintptr_t)&tx_fifo_full);
1083 }
1084 }
1085 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
1086
uart_evt_callback(uart_bus_t bus,hal_uart_evt_id_t evt,uintptr_t param)1087 static errcode_t uart_evt_callback(uart_bus_t bus, hal_uart_evt_id_t evt, uintptr_t param)
1088 {
1089 unused(param);
1090 unused(bus);
1091 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
1092 switch (evt) {
1093 #if defined(CONFIG_UART_SUPPORT_TX_INT)
1094 case UART_EVT_TX_ISR:
1095 uart_tx_isr(bus);
1096 break;
1097 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
1098
1099 #if defined(CONFIG_UART_SUPPORT_RX)
1100 case UART_EVT_RX_ISR:
1101 uart_rx_isr(bus);
1102 break;
1103
1104 case UART_EVT_IDLE_ISR:
1105 uart_idle_isr(bus);
1106 break;
1107
1108 case UART_EVT_PARITY_ERR_ISR:
1109 if (rx_state->parity_error_callback != NULL) {
1110 rx_state->parity_error_callback(NULL, 0);
1111 }
1112 uart_error_isr(bus);
1113 break;
1114
1115 case UART_EVT_FRAME_ERR_ISR:
1116 if (rx_state->frame_error_callback != NULL) {
1117 rx_state->frame_error_callback(NULL, 0);
1118 }
1119 uart_error_isr(bus);
1120 break;
1121
1122 case UART_EVT_BREAK_ERR_ISR:
1123 uart_error_isr(bus);
1124 break;
1125
1126 #endif /* CONFIG_UART_SUPPORT_RX */
1127 default :
1128 /* 为保证UT覆盖到default分支,UART_EVT_OVERRUN_ERR_ISR分支与default分支合并 */
1129 #if defined(CONFIG_UART_SUPPORT_RX)
1130 uart_error_isr(bus);
1131 #endif /* CONFIG_UART_SUPPORT_RX */
1132 break;
1133 }
1134 return ERRCODE_SUCC;
1135 }
1136
uapi_uart_has_pending_transmissions(uart_bus_t bus)1137 bool uapi_uart_has_pending_transmissions(uart_bus_t bus)
1138 {
1139 if (bus >= UART_BUS_MAX_NUM) {
1140 return false;
1141 }
1142 if (!g_uart_inited[bus]) {
1143 return false;
1144 }
1145
1146 bool currentstate = false;
1147
1148 hal_uart_ctrl(bus, UART_CTRL_CHECK_UART_BUSY, (uintptr_t)¤tstate);
1149
1150 #if defined(CONFIG_UART_SUPPORT_TX)
1151 #if defined(CONFIG_UART_SUPPORT_TX_INT)
1152 uart_tx_state_t *tx_state = &g_uart_tx_state_array[bus];
1153 return ((tx_state->fragments_to_process > 0) || currentstate);
1154 #else
1155 return currentstate;
1156 #endif /* CONFIG_UART_SUPPORT_TX_INIT */
1157 #else
1158 return currentstate;
1159 #endif /* CONFIG_UART_SUPPORT_TX */
1160 }
1161
uapi_uart_rx_fifo_is_empty(uart_bus_t bus)1162 bool uapi_uart_rx_fifo_is_empty(uart_bus_t bus)
1163 {
1164 if (bus >= UART_BUS_MAX_NUM) {
1165 return false;
1166 }
1167 if (!g_uart_inited[bus]) {
1168 return false;
1169 }
1170
1171 bool currentstate = false;
1172
1173 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)¤tstate);
1174
1175 return currentstate;
1176 }
1177
uapi_uart_tx_fifo_is_empty(uart_bus_t bus)1178 bool uapi_uart_tx_fifo_is_empty(uart_bus_t bus)
1179 {
1180 if (bus >= UART_BUS_MAX_NUM) {
1181 return false;
1182 }
1183 if (!g_uart_inited[bus]) {
1184 return false;
1185 }
1186
1187 bool currentstate = false;
1188
1189 hal_uart_ctrl(bus, UART_CTRL_CHECK_TX_BUSY, (uintptr_t)¤tstate);
1190
1191 return currentstate;
1192 }
1193
uapi_uart_unregister_rx_callback(uart_bus_t bus)1194 void uapi_uart_unregister_rx_callback(uart_bus_t bus)
1195 {
1196 bool rx_fifo_empty = false;
1197 uint8_t uart_rx_isr_data;
1198 uint32_t fifo_depth = CONFIG_UART_FIFO_DEPTH;
1199 if (bus >= UART_BUS_MAX_NUM) {
1200 return;
1201 }
1202 uint32_t irq_sts = uart_porting_lock(bus);
1203 uart_rx_state_t *rx_state = &g_uart_rx_state_array[bus];
1204 rx_state->rx_callback = NULL;
1205 hal_uart_ctrl(bus, UART_CTRL_EN_RX_INT, 0);
1206 hal_uart_ctrl(bus, UART_CTRL_EN_FRAME_ERR_INT, 0);
1207 hal_uart_ctrl(bus, UART_CTRL_EN_PARITY_ERR_INT, 0);
1208 hal_uart_ctrl(bus, UART_CTRL_EN_IDLE_INT, 0);
1209 /* Flush the data on the RX FIFO */
1210 while (fifo_depth > 0) {
1211 hal_uart_ctrl(bus, UART_CTRL_CHECK_RX_FIFO_EMPTY, (uintptr_t)&rx_fifo_empty);
1212 if (rx_fifo_empty) {
1213 break;
1214 }
1215 hal_uart_read(bus, &uart_rx_isr_data, 1);
1216 fifo_depth--;
1217 unused(uart_rx_isr_data);
1218 }
1219 uart_porting_unlock(bus, irq_sts);
1220 }