ChibiOS  0.0.0
hal_uart.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 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 /* Driver pre-compile time settings. */
48 /*===========================================================================*/
49 
50 /**
51  * @name UART configuration options
52  * @{
53  */
54 /**
55  * @brief Enables synchronous APIs.
56  * @note Disabling this option saves both code and data space.
57  */
58 #if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
59 #define UART_USE_WAIT FALSE
60 #endif
61 
62 /**
63  * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
64  * @note Disabling this option saves both code and data space.
65  */
66 #if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
67 #define UART_USE_MUTUAL_EXCLUSION FALSE
68 #endif
69 /** @} */
70 
71 /*===========================================================================*/
72 /* Derived constants and error checks. */
73 /*===========================================================================*/
74 
75 /*===========================================================================*/
76 /* Driver data structures and types. */
77 /*===========================================================================*/
78 
79 /**
80  * @brief Driver state machine possible states.
81  */
82 typedef enum {
83  UART_UNINIT = 0, /**< Not initialized. */
84  UART_STOP = 1, /**< Stopped. */
85  UART_READY = 2 /**< Ready. */
86 } uartstate_t;
87 
88 /**
89  * @brief Transmitter state machine states.
90  */
91 typedef enum {
92  UART_TX_IDLE = 0, /**< Not transmitting. */
93  UART_TX_ACTIVE = 1, /**< Transmitting. */
94  UART_TX_COMPLETE = 2 /**< Buffer complete. */
96 
97 /**
98  * @brief Receiver state machine states.
99  */
100 typedef enum {
101  UART_RX_IDLE = 0, /**< Not receiving. */
102  UART_RX_ACTIVE = 1, /**< Receiving. */
103  UART_RX_COMPLETE = 2 /**< Buffer complete. */
104 } uartrxstate_t;
105 
106 #include "hal_uart_lld.h"
107 
108 /*===========================================================================*/
109 /* Driver macros. */
110 /*===========================================================================*/
111 
112 /**
113  * @name Low level driver helper macros
114  * @{
115  */
116 #if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
117 /**
118  * @brief Wakes up the waiting thread in case of early TX complete.
119  *
120  * @param[in] uartp pointer to the @p UARTDriver object
121  *
122  * @notapi
123  */
124 #define _uart_wakeup_tx1_isr(uartp) { \
125  if ((uartp)->early == true) { \
126  osalSysLockFromISR(); \
127  osalThreadResumeI(&(uartp)->threadtx, MSG_OK); \
128  osalSysUnlockFromISR(); \
129  } \
130 }
131 #else /* !UART_USE_WAIT */
132 #define _uart_wakeup_tx1_isr(uartp)
133 #endif /* !UART_USE_WAIT */
134 
135 #if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
136 /**
137  * @brief Wakes up the waiting thread in case of late TX complete.
138  *
139  * @param[in] uartp pointer to the @p UARTDriver object
140  *
141  * @notapi
142  */
143 #define _uart_wakeup_tx2_isr(uartp) { \
144  if ((uartp)->early == false) { \
145  osalSysLockFromISR(); \
146  osalThreadResumeI(&(uartp)->threadtx, MSG_OK); \
147  osalSysUnlockFromISR(); \
148  } \
149 }
150 #else /* !UART_USE_WAIT */
151 #define _uart_wakeup_tx2_isr(uartp)
152 #endif /* !UART_USE_WAIT */
153 
154 #if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
155 /**
156  * @brief Wakes up the waiting thread in case of RX complete.
157  *
158  * @param[in] uartp pointer to the @p UARTDriver object
159  *
160  * @notapi
161  */
162 #define _uart_wakeup_rx_complete_isr(uartp) { \
163  osalSysLockFromISR(); \
164  osalThreadResumeI(&(uartp)->threadrx, MSG_OK); \
165  osalSysUnlockFromISR(); \
166 }
167 #else /* !UART_USE_WAIT */
168 #define _uart_wakeup_rx_complete_isr(uartp)
169 #endif /* !UART_USE_WAIT */
170 
171 #if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
172 /**
173  * @brief Wakes up the waiting thread in case of RX error.
174  *
175  * @param[in] uartp pointer to the @p UARTDriver object
176  *
177  * @notapi
178  */
179 #define _uart_wakeup_rx_error_isr(uartp) { \
180  osalSysLockFromISR(); \
181  osalThreadResumeI(&(uartp)->threadrx, MSG_RESET); \
182  osalSysUnlockFromISR(); \
183 }
184 #else /* !UART_USE_WAIT */
185 #define _uart_wakeup_rx_error_isr(uartp)
186 #endif /* !UART_USE_WAIT */
187 
188 #if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
189 /**
190  * @brief Wakes up the waiting thread in case of RX timeout.
191  *
192  * @param[in] uartp pointer to the @p UARTDriver object
193  *
194  * @notapi
195  */
196 #define _uart_wakeup_rx_timeout_isr(uartp) { \
197  osalSysLockFromISR(); \
198  osalThreadResumeI(&(uartp)->threadrx, MSG_TIMEOUT); \
199  osalSysUnlockFromISR(); \
200 }
201 #else /* !UART_USE_WAIT */
202 #define _uart_wakeup_rx_timeout_isr(uartp)
203 #endif /* !UART_USE_WAIT */
204 
205 /**
206  * @brief Common ISR code for early TX.
207  * @details This code handles the portable part of the ISR code:
208  * - Callback invocation.
209  * - Waiting thread wakeup, if any.
210  * - Driver state transitions.
211  * .
212  * @note This macro is meant to be used in the low level drivers
213  * implementation only.
214  *
215  * @param[in] uartp pointer to the @p UARTDriver object
216  *
217  * @notapi
218  */
219 #define _uart_tx1_isr_code(uartp) { \
220  (uartp)->txstate = UART_TX_COMPLETE; \
221  if ((uartp)->config->txend1_cb != NULL) { \
222  (uartp)->config->txend1_cb(uartp); \
223  } \
224  if ((uartp)->txstate == UART_TX_COMPLETE) { \
225  (uartp)->txstate = UART_TX_IDLE; \
226  } \
227  _uart_wakeup_tx1_isr(uartp); \
228 }
229 
230 /**
231  * @brief Common ISR code for late TX.
232  * @details This code handles the portable part of the ISR code:
233  * - Callback invocation.
234  * - Waiting thread wakeup, if any.
235  * - Driver state transitions.
236  * .
237  * @note This macro is meant to be used in the low level drivers
238  * implementation only.
239  *
240  * @param[in] uartp pointer to the @p UARTDriver object
241  *
242  * @notapi
243  */
244 #define _uart_tx2_isr_code(uartp) { \
245  if ((uartp)->config->txend2_cb != NULL) { \
246  (uartp)->config->txend2_cb(uartp); \
247  } \
248  _uart_wakeup_tx2_isr(uartp); \
249 }
250 
251 /**
252  * @brief Common ISR code for RX complete.
253  * @details This code handles the portable part of the ISR code:
254  * - Callback invocation.
255  * - Waiting thread wakeup, if any.
256  * - Driver state transitions.
257  * .
258  * @note This macro is meant to be used in the low level drivers
259  * implementation only.
260  *
261  * @param[in] uartp pointer to the @p UARTDriver object
262  *
263  * @notapi
264  */
265 #define _uart_rx_complete_isr_code(uartp) { \
266  (uartp)->rxstate = UART_RX_COMPLETE; \
267  if ((uartp)->config->rxend_cb != NULL) { \
268  (uartp)->config->rxend_cb(uartp); \
269  } \
270  if ((uartp)->rxstate == UART_RX_COMPLETE) { \
271  (uartp)->rxstate = UART_RX_IDLE; \
272  uart_enter_rx_idle_loop(uartp); \
273  } \
274  _uart_wakeup_rx_complete_isr(uartp); \
275 }
276 
277 /**
278  * @brief Common ISR code for RX error.
279  * @details This code handles the portable part of the ISR code:
280  * - Callback invocation.
281  * - Waiting thread wakeup, if any.
282  * - Driver state transitions.
283  * .
284  * @note This macro is meant to be used in the low level drivers
285  * implementation only.
286  *
287  * @param[in] uartp pointer to the @p UARTDriver object
288  * @param[in] errors mask of errors to be reported
289  *
290  * @notapi
291  */
292 #define _uart_rx_error_isr_code(uartp, errors) { \
293  if ((uartp)->config->rxerr_cb != NULL) { \
294  (uartp)->config->rxerr_cb(uartp, errors); \
295  } \
296  _uart_wakeup_rx_error_isr(uartp); \
297 }
298 
299 /**
300  * @brief Common ISR code for RX on idle.
301  * @details This code handles the portable part of the ISR code:
302  * - Callback invocation.
303  * - Waiting thread wakeup, if any.
304  * - Driver state transitions.
305  * .
306  * @note This macro is meant to be used in the low level drivers
307  * implementation only.
308  *
309  * @param[in] uartp pointer to the @p UARTDriver object
310  *
311  * @notapi
312  */
313 #define _uart_rx_idle_code(uartp) { \
314  if ((uartp)->config->rxchar_cb != NULL) \
315  (uartp)->config->rxchar_cb(uartp, (uartp)->rxbuf); \
316 }
317 
318 /**
319  * @brief Timeout ISR code for receiver.
320  * @details This code handles the portable part of the ISR code:
321  * - Callback invocation.
322  * - Waiting thread wakeup, if any.
323  * - Driver state transitions.
324  * .
325  * @note This macro is meant to be used in the low level drivers
326  * implementation only.
327  *
328  * @param[in] uartp pointer to the @p UARTDriver object
329  *
330  * @notapi
331  */
332 #define _uart_timeout_isr_code(uartp) { \
333  if ((uartp)->config->timeout_cb != NULL) { \
334  (uartp)->config->timeout_cb(uartp); \
335  } \
336  _uart_wakeup_rx_timeout_isr(uartp); \
337 }
338 
339 /** @} */
340 
341 /*===========================================================================*/
342 /* External declarations. */
343 /*===========================================================================*/
344 
345 #ifdef __cplusplus
346 extern "C" {
347 #endif
348  void uartInit(void);
349  void uartObjectInit(UARTDriver *uartp);
350  void uartStart(UARTDriver *uartp, const UARTConfig *config);
351  void uartStop(UARTDriver *uartp);
352  void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf);
353  void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf);
354  size_t uartStopSend(UARTDriver *uartp);
355  size_t uartStopSendI(UARTDriver *uartp);
356  void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf);
357  void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf);
358  size_t uartStopReceive(UARTDriver *uartp);
359  size_t uartStopReceiveI(UARTDriver *uartp);
360 #if UART_USE_WAIT == TRUE
361  msg_t uartSendTimeout(UARTDriver *uartp, size_t *np,
362  const void *txbuf, sysinterval_t timeout);
363  msg_t uartSendFullTimeout(UARTDriver *uartp, size_t *np,
364  const void *txbuf, sysinterval_t timeout);
365  msg_t uartReceiveTimeout(UARTDriver *uartp, size_t *np,
366  void *rxbuf, sysinterval_t timeout);
367 #endif
368 #if UART_USE_MUTUAL_EXCLUSION == TRUE
369  void uartAcquireBus(UARTDriver *uartp);
370  void uartReleaseBus(UARTDriver *uartp);
371 #endif
372 #ifdef __cplusplus
373 }
374 #endif
375 
376 #endif /* HAL_USE_UART == TRUE */
377 
378 #endif /* HAL_UART_H */
379 
380 /** @} */
PLATFORM UART subsystem low level driver header.
void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf)
Starts a transmission on the UART peripheral.
Definition: hal_uart.c:147
size_t uartStopReceive(UARTDriver *uartp)
Stops any ongoing receive operation.
Definition: hal_uart.c:301
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
void uartInit(void)
UART Driver initialization.
Definition: hal_uart.c:56
size_t uartStopSendI(UARTDriver *uartp)
Stops any ongoing transmission.
Definition: hal_uart.c:228
void uartStop(UARTDriver *uartp)
Deactivates the UART peripheral.
Definition: hal_uart.c:118
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:369
size_t uartStopReceiveI(UARTDriver *uartp)
Stops any ongoing receive operation.
Definition: hal_uart.c:334
uartstate_t
Driver state machine possible states.
Definition: hal_uart.h:82
size_t uartStopSend(UARTDriver *uartp)
Stops any ongoing transmission.
Definition: hal_uart.c:195
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:461
uarttxstate_t
Transmitter state machine states.
Definition: hal_uart.h:91
void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf)
Starts a transmission on the UART peripheral.
Definition: hal_uart.c:172
void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf)
Starts a receive operation on the UART peripheral.
Definition: hal_uart.c:278
void uartReleaseBus(UARTDriver *uartp)
Releases exclusive access to the UART bus.
Definition: hal_uart.c:514
void uartAcquireBus(UARTDriver *uartp)
Gains exclusive access to the UART bus.
Definition: hal_uart.c:498
void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf)
Starts a receive operation on the UART peripheral.
Definition: hal_uart.c:253
uartrxstate_t
Receiver state machine states.
Definition: hal_uart.h:100
void uartStart(UARTDriver *uartp, const UARTConfig *config)
Configures and activates the UART peripheral.
Definition: hal_uart.c:97
Driver configuration structure.
Definition: hal_uart_lld.h:100
void uartObjectInit(UARTDriver *uartp)
Initializes the standard part of a UARTDriver structure.
Definition: hal_uart.c:68
Structure representing an UART driver.
Definition: hal_uart_lld.h:129
int32_t msg_t
Definition: chtypes.h:51
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:414