ChibiOS 21.11.5
hal_uart.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 Giovanni Di Sirio.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file hal_uart.h
19 * @brief UART Driver macros and structures.
20 *
21 * @addtogroup UART
22 * @{
23 */
24
25#ifndef HAL_UART_H
26#define HAL_UART_H
27
28#if (HAL_USE_UART == TRUE) || defined(__DOXYGEN__)
29
30/*===========================================================================*/
31/* Driver constants. */
32/*===========================================================================*/
33
34/**
35 * @name UART status flags
36 * @{
37 */
38#define UART_NO_ERROR 0 /**< @brief No pending conditions. */
39#define UART_PARITY_ERROR 4 /**< @brief Parity error happened. */
40#define UART_FRAMING_ERROR 8 /**< @brief Framing error happened. */
41#define UART_OVERRUN_ERROR 16 /**< @brief Overflow happened. */
42#define UART_NOISE_ERROR 32 /**< @brief Noise on the line. */
43#define UART_BREAK_DETECTED 64 /**< @brief Break detected. */
44/** @} */
45
46/**
47 * @name UART error conditions
48 * @{
49 */
50#define UART_ERR_NOT_ACTIVE (size_t)-1
51/** @} */
52
53/*===========================================================================*/
54/* Driver pre-compile time settings. */
55/*===========================================================================*/
56
57/**
58 * @name UART configuration options
59 * @{
60 */
61/**
62 * @brief Enables synchronous APIs.
63 * @note Disabling this option saves both code and data space.
64 */
65#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
66#define UART_USE_WAIT FALSE
67#endif
68
69/**
70 * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
71 * @note Disabling this option saves both code and data space.
72 */
73#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
74#define UART_USE_MUTUAL_EXCLUSION FALSE
75#endif
76/** @} */
77
78/*===========================================================================*/
79/* Derived constants and error checks. */
80/*===========================================================================*/
81
82/*===========================================================================*/
83/* Driver data structures and types. */
84/*===========================================================================*/
85
86/**
87 * @brief Driver state machine possible states.
88 */
89typedef enum {
90 UART_UNINIT = 0, /**< Not initialized. */
91 UART_STOP = 1, /**< Stopped. */
92 UART_READY = 2 /**< Ready. */
94
95/**
96 * @brief Transmitter state machine states.
97 */
98typedef enum {
99 UART_TX_IDLE = 0, /**< Not transmitting. */
100 UART_TX_ACTIVE = 1 /**< Transmitting. */
102
103/**
104 * @brief Receiver state machine states.
105 */
106typedef enum {
107 UART_RX_IDLE = 0, /**< Not receiving. */
108 UART_RX_ACTIVE = 1 /**< Receiving. */
110
111#include "hal_uart_lld.h"
112
113/*===========================================================================*/
114/* Driver macros. */
115/*===========================================================================*/
116
117/**
118 * @name Low level driver helper macros
119 * @{
120 */
121#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
122/**
123 * @brief Wakes up the waiting thread in case of early TX complete.
124 *
125 * @param[in] uartp pointer to the @p UARTDriver object
126 *
127 * @notapi
128 */
129#define _uart_wakeup_tx1_isr(uartp) { \
130 if ((uartp)->early == true) { \
131 osalSysLockFromISR(); \
132 osalThreadResumeI(&(uartp)->threadtx, MSG_OK); \
133 osalSysUnlockFromISR(); \
134 } \
135}
136#else /* !UART_USE_WAIT */
137#define _uart_wakeup_tx1_isr(uartp)
138#endif /* !UART_USE_WAIT */
139
140#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
141/**
142 * @brief Wakes up the waiting thread in case of late TX complete.
143 *
144 * @param[in] uartp pointer to the @p UARTDriver object
145 *
146 * @notapi
147 */
148#define _uart_wakeup_tx2_isr(uartp) { \
149 if ((uartp)->early == false) { \
150 osalSysLockFromISR(); \
151 osalThreadResumeI(&(uartp)->threadtx, MSG_OK); \
152 osalSysUnlockFromISR(); \
153 } \
154}
155#else /* !UART_USE_WAIT */
156#define _uart_wakeup_tx2_isr(uartp)
157#endif /* !UART_USE_WAIT */
158
159#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
160/**
161 * @brief Wakes up the waiting thread in case of RX complete.
162 *
163 * @param[in] uartp pointer to the @p UARTDriver object
164 *
165 * @notapi
166 */
167#define _uart_wakeup_rx_complete_isr(uartp) { \
168 osalSysLockFromISR(); \
169 osalThreadResumeI(&(uartp)->threadrx, MSG_OK); \
170 osalSysUnlockFromISR(); \
171}
172#else /* !UART_USE_WAIT */
173#define _uart_wakeup_rx_complete_isr(uartp)
174#endif /* !UART_USE_WAIT */
175
176#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
177/**
178 * @brief Wakes up the waiting thread in case of RX error.
179 *
180 * @param[in] uartp pointer to the @p UARTDriver object
181 *
182 * @notapi
183 */
184#define _uart_wakeup_rx_error_isr(uartp) { \
185 osalSysLockFromISR(); \
186 osalThreadResumeI(&(uartp)->threadrx, MSG_RESET); \
187 osalSysUnlockFromISR(); \
188}
189#else /* !UART_USE_WAIT */
190#define _uart_wakeup_rx_error_isr(uartp)
191#endif /* !UART_USE_WAIT */
192
193#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
194/**
195 * @brief Wakes up the waiting thread in case of RX character match.
196 *
197 * @param[in] uartp pointer to the @p UARTDriver object
198 *
199 * @notapi
200 */
201#define _uart_wakeup_rx_cm_isr(uartp) { \
202 osalSysLockFromISR(); \
203 osalThreadResumeI(&(uartp)->threadrx, MSG_TIMEOUT); \
204 osalSysUnlockFromISR(); \
205}
206#else /* !UART_USE_WAIT */
207#define _uart_wakeup_rx_cm_isr(uartp)
208#endif /* !UART_USE_WAIT */
209
210#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
211/**
212 * @brief Wakes up the waiting thread in case of RX timeout.
213 *
214 * @param[in] uartp pointer to the @p UARTDriver object
215 *
216 * @notapi
217 */
218#define _uart_wakeup_rx_timeout_isr(uartp) { \
219 osalSysLockFromISR(); \
220 osalThreadResumeI(&(uartp)->threadrx, MSG_TIMEOUT); \
221 osalSysUnlockFromISR(); \
222}
223#else /* !UART_USE_WAIT */
224#define _uart_wakeup_rx_timeout_isr(uartp)
225#endif /* !UART_USE_WAIT */
226
227/**
228 * @brief Common ISR code for early TX.
229 * @details This code handles the portable part of the ISR code:
230 * - Callback invocation.
231 * - Waiting thread wakeup, if any.
232 * - Driver state transitions.
233 * .
234 * @note This macro is meant to be used in the low level drivers
235 * implementation only.
236 *
237 * @param[in] uartp pointer to the @p UARTDriver object
238 *
239 * @notapi
240 */
241#define _uart_tx1_isr_code(uartp) { \
242 (uartp)->txstate = UART_TX_IDLE; \
243 if ((uartp)->config->txend1_cb != NULL) { \
244 (uartp)->config->txend1_cb(uartp); \
245 } \
246 _uart_wakeup_tx1_isr(uartp); \
247}
248
249/**
250 * @brief Common ISR code for late TX.
251 * @details This code handles the portable part of the ISR code:
252 * - Callback invocation.
253 * - Waiting thread wakeup, if any.
254 * - Driver state transitions.
255 * .
256 * @note This macro is meant to be used in the low level drivers
257 * implementation only.
258 *
259 * @param[in] uartp pointer to the @p UARTDriver object
260 *
261 * @notapi
262 */
263#define _uart_tx2_isr_code(uartp) { \
264 if ((uartp)->config->txend2_cb != NULL) { \
265 (uartp)->config->txend2_cb(uartp); \
266 } \
267 _uart_wakeup_tx2_isr(uartp); \
268}
269
270/**
271 * @brief Common ISR code for RX complete.
272 * @details This code handles the portable part of the ISR code:
273 * - Callback invocation.
274 * - Waiting thread wakeup, if any.
275 * - Driver state transitions.
276 * .
277 * @note This macro is meant to be used in the low level drivers
278 * implementation only.
279 *
280 * @param[in] uartp pointer to the @p UARTDriver object
281 *
282 * @notapi
283 */
284#define _uart_rx_complete_isr_code(uartp) { \
285 (uartp)->rxstate = UART_RX_IDLE; \
286 uart_enter_rx_idle_loop(uartp); \
287 if ((uartp)->config->rxend_cb != NULL) { \
288 (uartp)->config->rxend_cb(uartp); \
289 } \
290 _uart_wakeup_rx_complete_isr(uartp); \
291}
292
293/**
294 * @brief Common ISR code for RX error.
295 * @details This code handles the portable part of the ISR code:
296 * - Callback invocation.
297 * - Waiting thread wakeup, if any.
298 * - Driver state transitions.
299 * .
300 * @note This macro is meant to be used in the low level drivers
301 * implementation only.
302 *
303 * @param[in] uartp pointer to the @p UARTDriver object
304 * @param[in] errors mask of errors to be reported
305 *
306 * @notapi
307 */
308#define _uart_rx_error_isr_code(uartp, errors) { \
309 if ((uartp)->config->rxerr_cb != NULL) { \
310 (uartp)->config->rxerr_cb(uartp, errors); \
311 } \
312 _uart_wakeup_rx_error_isr(uartp); \
313}
314
315/**
316 * @brief Common ISR code for RX on idle.
317 * @details This code handles the portable part of the ISR code:
318 * - Callback invocation.
319 * - Waiting thread wakeup, if any.
320 * - Driver state transitions.
321 * .
322 * @note This macro is meant to be used in the low level drivers
323 * implementation only.
324 *
325 * @param[in] uartp pointer to the @p UARTDriver object
326 *
327 * @notapi
328 */
329#define _uart_rx_idle_code(uartp) { \
330 if ((uartp)->config->rxchar_cb != NULL) \
331 (uartp)->config->rxchar_cb(uartp, (uartp)->rxbuf); \
332}
333
334/**
335 * @brief Timeout ISR code for receiver.
336 * @details This code handles the portable part of the ISR code:
337 * - Callback invocation.
338 * - Waiting thread wakeup, if any.
339 * - Driver state transitions.
340 * .
341 * @note This macro is meant to be used in the low level drivers
342 * implementation only.
343 *
344 * @param[in] uartp pointer to the @p UARTDriver object
345 *
346 * @notapi
347 */
348#define _uart_timeout_isr_code(uartp) { \
349 if ((uartp)->config->timeout_cb != NULL) { \
350 (uartp)->config->timeout_cb(uartp); \
351 } \
352 _uart_wakeup_rx_timeout_isr(uartp); \
353}
354
355/**
356 * @brief Character match ISR code for receiver.
357 * @details This code handles the portable part of the ISR code:
358 * - Callback invocation.
359 * - Waiting thread wakeup, if any.
360 * - Driver state transitions.
361 * .
362 * @note This macro is meant to be used in the low level drivers
363 * implementation only.
364 *
365 * @param[in] uartp pointer to the @p UARTDriver object
366 *
367 * @notapi
368 */
369#define _uart_rx_char_match_isr_code(uartp) { \
370 if ((uartp)->config->rx_cm_cb != NULL) { \
371 (uartp)->config->rx_cm_cb(uartp); \
372 } \
373 _uart_wakeup_rx_cm_isr(uartp); \
374}
375
376/** @} */
377
378/*===========================================================================*/
379/* External declarations. */
380/*===========================================================================*/
381
382#ifdef __cplusplus
383extern "C" {
384#endif
385 void uartInit(void);
386 void uartObjectInit(UARTDriver *uartp);
387 msg_t uartStart(UARTDriver *uartp, const UARTConfig *config);
388 void uartStop(UARTDriver *uartp);
389 void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf);
390 void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf);
391 size_t uartStopSend(UARTDriver *uartp);
392 size_t uartStopSendI(UARTDriver *uartp);
393 void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf);
394 void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf);
395 size_t uartStopReceive(UARTDriver *uartp);
396 size_t uartStopReceiveI(UARTDriver *uartp);
397#if UART_USE_WAIT == TRUE
398 msg_t uartSendTimeout(UARTDriver *uartp, size_t *np,
399 const void *txbuf, sysinterval_t timeout);
400 msg_t uartSendFullTimeout(UARTDriver *uartp, size_t *np,
401 const void *txbuf, sysinterval_t timeout);
402 msg_t uartReceiveTimeout(UARTDriver *uartp, size_t *np,
403 void *rxbuf, sysinterval_t timeout);
404#endif
405#if UART_USE_MUTUAL_EXCLUSION == TRUE
406 void uartAcquireBus(UARTDriver *uartp);
407 void uartReleaseBus(UARTDriver *uartp);
408#endif
409#ifdef __cplusplus
410}
411#endif
412
413#endif /* HAL_USE_UART == TRUE */
414
415#endif /* HAL_UART_H */
416
417/** @} */
struct hal_uart_config UARTConfig
Driver configuration structure.
void uartInit(void)
UART Driver initialization.
Definition hal_uart.c:56
void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf)
Starts a transmission on the UART peripheral.
Definition hal_uart.c:164
void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf)
Starts a transmission on the UART peripheral.
Definition hal_uart.c:189
void uartObjectInit(UARTDriver *uartp)
Initializes the standard part of a UARTDriver structure.
Definition hal_uart.c:68
uartstate_t
Driver state machine possible states.
Definition hal_uart.h:89
uartrxstate_t
Receiver state machine states.
Definition hal_uart.h:106
uarttxstate_t
Transmitter state machine states.
Definition hal_uart.h:98
void uartAcquireBus(UARTDriver *uartp)
Gains exclusive access to the UART bus.
Definition hal_uart.c:521
msg_t uartStart(UARTDriver *uartp, const UARTConfig *config)
Configures and activates the UART peripheral.
Definition hal_uart.c:98
void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf)
Starts a receive operation on the UART peripheral.
Definition hal_uart.c:295
msg_t uartReceiveTimeout(UARTDriver *uartp, size_t *np, void *rxbuf, sysinterval_t timeout)
Performs a receive operation on the UART peripheral.
Definition hal_uart.c:484
void uartReleaseBus(UARTDriver *uartp)
Releases exclusive access to the UART bus.
Definition hal_uart.c:537
msg_t uartSendFullTimeout(UARTDriver *uartp, size_t *np, const void *txbuf, sysinterval_t timeout)
Performs a transmission on the UART peripheral.
Definition hal_uart.c:435
void uartStop(UARTDriver *uartp)
Deactivates the UART peripheral.
Definition hal_uart.c:135
void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf)
Starts a receive operation on the UART peripheral.
Definition hal_uart.c:270
size_t uartStopSend(UARTDriver *uartp)
Stops any ongoing transmission.
Definition hal_uart.c:212
size_t uartStopReceive(UARTDriver *uartp)
Stops any ongoing receive operation.
Definition hal_uart.c:318
size_t uartStopSendI(UARTDriver *uartp)
Stops any ongoing transmission.
Definition hal_uart.c:245
size_t uartStopReceiveI(UARTDriver *uartp)
Stops any ongoing receive operation.
Definition hal_uart.c:351
msg_t uartSendTimeout(UARTDriver *uartp, size_t *np, const void *txbuf, sysinterval_t timeout)
Performs a transmission on the UART peripheral.
Definition hal_uart.c:388
struct hal_uart_driver UARTDriver
Type of structure representing an UART driver.
@ UART_READY
Definition hal_uart.h:92
@ UART_UNINIT
Definition hal_uart.h:90
@ UART_STOP
Definition hal_uart.h:91
@ UART_RX_ACTIVE
Definition hal_uart.h:108
@ UART_RX_IDLE
Definition hal_uart.h:107
@ UART_TX_IDLE
Definition hal_uart.h:99
@ UART_TX_ACTIVE
Definition hal_uart.h:100
int32_t msg_t
Definition chearly.h:87
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:118
PLATFORM UART subsystem low level driver header.