• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &current_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)&currentstate);
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)&currentstate);
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)&currentstate);
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 }