ChibiOS/HAL 9.0.0
hal_sio.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_sio.h
19 * @brief SIO Driver macros and structures.
20 *
21 * @addtogroup SIO
22 * @{
23 */
24
25#ifndef HAL_SIO_H
26#define HAL_SIO_H
27
28#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__)
29
30/*===========================================================================*/
31/* Driver constants. */
32/*===========================================================================*/
33
34/**
35 * @name SIO masks offsets
36 * @{
37 */
38#define SIO_EV_RXNOTEMPY_POS 2 /* CHN_INPUT_AVAILABLE */
39#define SIO_EV_TXNOTFULL_POS 3 /* CHN_OUTPUT_EMPTY */
40#define SIO_EV_TXDONE_POS 4 /* CHN_TRANSMISSION_END */
41#define SIO_EV_ALL_ERRORS_POS SIO_EV_PARITY_ERR_POS
42#define SIO_EV_PARITY_ERR_POS 5 /* CHN_PARITY_ERROR */
43#define SIO_EV_FRAMING_ERR_POS 6 /* CHN_FRAMING_ERROR */
44#define SIO_EV_NOISE_ERR_POS 7 /* CHN_NOISE_ERROR */
45#define SIO_EV_OVERRUN_ERR_POS 8 /* CHN_OVERRUN_ERROR */
46#define SIO_EV_RXIDLE_POS 9 /* CHN_IDLE_DETECTED */
47#define SIO_EV_RXBREAK_POS 10 /* CHN_BREAK_DETECTED */
48/** @} */
49
50/**
51 * @name Event flags (compatible with channel and serial events)
52 * @{
53 */
54/*lint -save -e9053 [12.2] MISRA seems to assume that the underlying type
55 is 8 bits wide, it is not.*/
56#define SIO_EV_NONE 0U
57#define SIO_EV_RXNOTEMPY (1U << SIO_EV_RXNOTEMPY_POS)
58#define SIO_EV_TXNOTFULL (1U << SIO_EV_TXNOTFULL_POS)
59#define SIO_EV_ALL_DATA (SIO_EV_RXNOTEMPY | SIO_EV_TXNOTFULL)
60#define SIO_EV_TXDONE (1U << SIO_EV_TXDONE_POS)
61#define SIO_EV_PARITY_ERR (1U << SIO_EV_PARITY_ERR_POS)
62#define SIO_EV_FRAMING_ERR (1U << SIO_EV_FRAMING_ERR_POS)
63#define SIO_EV_NOISE_ERR (1U << SIO_EV_NOISE_ERR_POS)
64#define SIO_EV_OVERRUN_ERR (1U << SIO_EV_OVERRUN_ERR_POS)
65#define SIO_EV_RXIDLE (1U << SIO_EV_RXIDLE_POS)
66#define SIO_EV_RXBREAK (1U << SIO_EV_RXBREAK_POS)
67#define SIO_EV_ALL_ERRORS (SIO_EV_PARITY_ERR | \
68 SIO_EV_FRAMING_ERR | \
69 SIO_EV_OVERRUN_ERR | \
70 SIO_EV_NOISE_ERR | \
71 SIO_EV_RXBREAK)
72#define SIO_EV_ALL_EVENTS (SIO_EV_ALL_DATA | \
73 SIO_EV_ALL_ERRORS | \
74 SIO_EV_TXDONE | \
75 SIO_EV_RXIDLE)
76/*lint -restore*/
77/** @} */
78
79/**
80 * @name Additional messages
81 * @{
82 */
83#define SIO_MSG_ERRORS (msg_t)1
84/** @} */
85
86/*===========================================================================*/
87/* Driver pre-compile time settings. */
88/*===========================================================================*/
89
90/**
91 * @name SIO configuration options
92 * @{
93 */
94/**
95 * @brief Default bit rate.
96 * @details Configuration parameter, this is the baud rate selected for the
97 * default configuration.
98 */
99#if !defined(SIO_DEFAULT_BITRATE) || defined(__DOXYGEN__)
100#define SIO_DEFAULT_BITRATE 38400
101#endif
102
103/**
104 * @brief Support for thread synchronization API.
105 */
106#if !defined(SIO_USE_SYNCHRONIZATION) || defined(__DOXYGEN__)
107#define SIO_USE_SYNCHRONIZATION TRUE
108#endif
109
110/**
111 * @brief Support for streams interfacwe.
112 */
113#if !defined(SIO_USE_STREAMS_INTERFACE) || defined(__DOXYGEN__)
114#define SIO_USE_STREAMS_INTERFACE SIO_USE_SYNCHRONIZATION
115#endif
116/** @} */
117
118/*===========================================================================*/
119/* Derived constants and error checks. */
120/*===========================================================================*/
121
122#if (SIO_USE_STREAMS_INTERFACE == TRUE) && (SIO_USE_SYNCHRONIZATION == FALSE)
123#error "SIO_USE_STREAMS_INTERFACE requires SIO_USE_SYNCHRONIZATION"
124#endif
125
126/*===========================================================================*/
127/* Driver data structures and types. */
128/*===========================================================================*/
129
130/**
131 * @brief Type of event flags.
132 */
134
135/**
136 * @brief Type of structure representing a SIO driver.
137 */
139
140/**
141 * @brief Type of structure representing a SIO configuration.
142 */
144
145/**
146 * @brief Generic SIO notification callback type.
147 *
148 * @param[in] siop pointer to the @p SIODriver object
149 */
150typedef void (*siocb_t)(SIODriver *siop);
151
152/**
153 * @brief Driver state machine possible states.
154 */
155typedef enum {
156 SIO_UNINIT = 0, /**< Not initialized. */
157 SIO_STOP = 1, /**< Stopped. */
158 SIO_READY = 2 /**< Ready. */
159} siostate_t;
160
161#include "hal_sio_lld.h"
162
163/**
164 * @brief Driver configuration structure.
165 * @note Implementations may extend this structure to contain more,
166 * architecture dependent, fields.
167 */
169 /* End of the mandatory fields.*/
171#if defined(SIO_CONFIG_EXT_FIELS)
172 SIO_CONFIG_EXT_FIELDS
173#endif
174};
175
176/**
177 * @brief @p SIODriver specific methods.
178 */
179#define _sio_driver_methods \
180 _base_channel_methods
181
182/**
183 * @extends BaseChannelVMT
184 *
185 * @brief @p SIODriver virtual methods table.
186 */
190
191/**
192 * @brief Structure representing a SIO driver.
193 * @note Implementations may extend this structure to contain more,
194 * architecture dependent, fields.
195 */
197#if (SIO_USE_STREAMS_INTERFACE == TRUE) || defined(__DOXYGEN__)
198 /**
199 * @brief Virtual Methods Table.
200 */
201 const struct sio_driver_vmt *vmt;
202#endif
203 /**
204 * @brief Driver state.
205 */
207 /**
208 * @brief Current configuration data.
209 */
211 /**
212 * @brief Enabled event flags.
213 */
215 /**
216 * @brief Events callback.
217 * @note Can be @p NULL.
218 */
220 /**
221 * @brief User argument.
222 * @note Can be retrieved through the @p siop argument of the callback.
223 */
224 void *arg;
225#if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
226 /**
227 * @brief Synchronization point for RX.
228 */
230 /**
231 * @brief Synchronization point for RX idle.
232 */
234 /**
235 * @brief Synchronization point for TX.
236 */
238 /**
239 * @brief Synchronization point for TX-end.
240 */
242#endif /* SIO_USE_SYNCHRONIZATION == TRUE */
243#if defined(SIO_DRIVER_EXT_FIELS)
244 SIO_DRIVER_EXT_FIELDS
245#endif
246 /* End of the mandatory fields.*/
248};
249
250/*===========================================================================*/
251/* Driver macros. */
252/*===========================================================================*/
253
254/**
255 * @brief Associates a callback to the SIO instance.
256 *
257 * @param[in] siop pointer to the @p SIODriver object
258 * @param[in] f callback to be associated
259 */
260#define sioSetCallbackX(siop, f) (siop)->cb = (f)
261
262/**
263 * @brief Determines the state of the RX FIFO.
264 *
265 * @param[in] siop pointer to the @p SIODriver object
266 * @return The RX FIFO state.
267 * @retval false if RX FIFO is not empty.
268 * @retval true if RX FIFO is empty.
269 *
270 * @xclass
271 */
272#define sioIsRXEmptyX(siop) sio_lld_is_rx_empty(siop)
273
274/**
275 * @brief Determines the activity state of the receiver.
276 *
277 * @param[in] siop pointer to the @p SIODriver object
278 * @return The RX activity state.
279 * @retval false if RX is in active state.
280 * @retval true if RX is in idle state.
281 *
282 * @xclass
283 */
284#define sioIsRXIdleX(siop) sio_lld_is_rx_idle(siop)
285
286/**
287 * @brief Determines if RX has pending errors to be read and cleared.
288 * @note Only errors are handled, data and idle events are not considered.
289 *
290 * @param[in] siop pointer to the @p SIODriver object
291 * @return The RX error events.
292 * @retval false if RX has no pending events.
293 * @retval true if RX has pending events.
294 *
295 * @xclass
296 */
297#define sioHasRXErrorsX(siop) sio_lld_has_rx_errors(siop)
298
299/**
300 * @brief Determines the state of the TX FIFO.
301 *
302 * @param[in] siop pointer to the @p SIODriver object
303 * @return The TX FIFO state.
304 * @retval false if TX FIFO is not full.
305 * @retval true if TX FIFO is full.
306 *
307 * @xclass
308 */
309#define sioIsTXFullX(siop) sio_lld_is_tx_full(siop)
310
311/**
312 * @brief Determines the transmission state.
313 *
314 * @param[in] siop pointer to the @p SIODriver object
315 * @return The TX FIFO state.
316 * @retval false if transmission is over.
317 * @retval true if transmission is ongoing.
318 *
319 * @xclass
320 */
321#define sioIsTXOngoingX(siop) sio_lld_is_tx_ongoing(siop)
322
323/**
324 * @brief Writes the enabled events mask.
325 *
326 * @param[in] siop pointer to the @p SIODriver object
327 * @param[in] mask enabled events mask to be written
328 *
329 * @xclass
330 */
331#define sioWriteEnableFlagsX(siop, mask) do { \
332 (siop)->enabled = (mask); \
333 sio_lld_update_enable_flags(siop); \
334} while (false)
335
336/**
337 * @brief Sets flags into the enabled events flags mask.
338 *
339 * @param[in] siop pointer to the @p SIODriver object
340 * @param[in] mask enabled events mask to be set
341 *
342 * @xclass
343 */
344#define sioSetEnableFlagsX(siop, mask) do { \
345 (siop)->enabled |= (mask); \
346 sio_lld_update_enable_flags(siop); \
347} while (false)
348
349/**
350 * @brief Clears flags from the enabled events flags mask.
351 *
352 * @param[in] siop pointer to the @p SIODriver object
353 * @param[in] mask enabled events mask to be cleared
354 *
355 * @xclass
356 */
357#define sioClearEnableFlagsX(siop, mask) do { \
358 (siop)->enabled &= ~(mask); \
359 sio_lld_update_enable_flags(siop); \
360} while (false)
361
362/**
363 * @brief Return the enabled condition flags mask.
364 *
365 * @param[in] siop pointer to the @p SIODriver object
366 *
367 * @xclass
368 */
369#define sioGetEnableFlagsX(siop) (siop)->enabled
370
371/**
372 * @brief Get and clears SIO error event flags.
373 *
374 * @param[in] siop pointer to the @p SIODriver object
375 * @return The pending error event flags.
376 *
377 * @xclass
378 */
379#define sioGetAndClearErrorsX(siop) sio_lld_get_and_clear_errors(siop)
380
381/**
382 * @brief Get and clears SIO event flags.
383 *
384 * @param[in] siop pointer to the @p SIODriver object
385 * @return The pending event flags.
386 *
387 * @xclass
388 */
389#define sioGetAndClearEventsX(siop) sio_lld_get_and_clear_events(siop)
390
391/**
392 * @brief Returns the pending SIO event flags.
393 *
394 * @param[in] siop pointer to the @p SIODriver object
395 * @return The pending event flags.
396 *
397 * @xclass
398 */
399#define sioGetEventsX(siop) sio_lld_get_events(siop)
400
401/**
402 * @brief Returns one frame from the RX FIFO.
403 * @note If the FIFO is empty then the returned value is unpredictable.
404 *
405 * @param[in] siop pointer to the @p SIODriver object
406 * @return The frame from RX FIFO.
407 *
408 * @xclass
409 */
410#define sioGetX(siop) sio_lld_get(siop)
411
412/**
413 * @brief Pushes one frame into the TX FIFO.
414 * @note If the FIFO is full then the behavior is unpredictable.
415 *
416 * @param[in] siop pointer to the @p SIODriver object
417 * @param[in] data frame to be written
418 *
419 * @xclass
420 */
421#define sioPutX(siop, data) sio_lld_put(siop, data)
422
423/**
424 * @brief Reads data from the RX FIFO.
425 * @details This function is non-blocking, data is read if present and the
426 * effective amount is returned.
427 * @note This function can be called from any context but it is meant to
428 * be called from the @p rxne_cb callback handler.
429 *
430 * @param[in] siop pointer to the @p SIODriver object
431 * @param[in] size maximum number of frames to read
432 * @param[in] buffer buffer for the received data
433 * @return The number of received frames.
434 *
435 * @xclass
436 */
437#define sioAsyncReadX(siop, size, buffer) sio_lld_read(siop, size, buffer)
438
439/**
440 * @brief Writes data into the TX FIFO.
441 * @details This function is non-blocking, data is written if there is space
442 * in the FIFO and the effective amount is returned.
443 * @note This function can be called from any context but it is meant to
444 * be called from the @p txnf_cb callback handler.
445 *
446 * @param[in] siop pointer to the @p SIODriver object
447 * @param[in] size maximum number of frames to read
448 * @param[out] buffer buffer containing the data to be transmitted
449 * @return The number of transmitted frames.
450 *
451 * @xclass
452 */
453#define sioAsyncWriteX(siop, size, buffer) sio_lld_write(siop, size, buffer)
454
455/**
456 * @brief Control operation on a serial port.
457 *
458 * @param[in] siop pointer to the @p SIODriver object
459 * @param[in] operation control operation code
460 * @param[in,out] arg operation argument
461 *
462 * @return The control operation status.
463 * @retval MSG_OK in case of success.
464 * @retval MSG_TIMEOUT in case of operation timeout.
465 * @retval MSG_RESET in case of operation reset.
466 *
467 * @xclass
468 */
469#define sioControlX(siop, operation, arg) sio_lld_control(siop, operation, arg)
470
471/**
472 * @name Low level driver helper macros
473 * @{
474 */
475/**
476 * @brief SIO callback.
477 *
478 * @param[in] siop pointer to the @p SIODriver object
479 *
480 * @notapi
481 */
482#define __sio_callback(siop) do { \
483 if ((siop)->cb != NULL) { \
484 (siop)->cb(siop); \
485 } \
486} while (false)
487
488#if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
489/**
490 * @brief Wakes up because RX errors.
491 *
492 * @param[in] siop pointer to the @p SIODriver object
493 *
494 * @notapi
495 */
496#define __sio_wakeup_errors(siop) do { \
497 osalSysLockFromISR(); \
498 osalThreadResumeI(&(siop)->sync_rx, SIO_MSG_ERRORS); \
499 osalThreadResumeI(&(siop)->sync_rxidle, SIO_MSG_ERRORS); \
500 osalSysUnlockFromISR(); \
501} while (false)
502
503/**
504 * @brief Wakes up the RX-waiting thread.
505 *
506 * @param[in] siop pointer to the @p SIODriver object
507 *
508 * @notapi
509 */
510#define __sio_wakeup_rx(siop) do { \
511 osalSysLockFromISR(); \
512 osalThreadResumeI(&(siop)->sync_rx, MSG_OK); \
513 osalSysUnlockFromISR(); \
514} while (false)
515
516/**
517 * @brief Wakes up the RX-idle-waiting thread.
518 *
519 * @param[in] siop pointer to the @p SIODriver object
520 *
521 * @notapi
522 */
523#define __sio_wakeup_rxidle(siop) do { \
524 osalSysLockFromISR(); \
525 osalThreadResumeI(&(siop)->sync_rxidle, MSG_OK); \
526 osalSysUnlockFromISR(); \
527} while (false)
528
529/**
530 * @brief Wakes up the TX-waiting thread.
531 *
532 * @param[in] siop pointer to the @p SIODriver object
533 *
534 * @notapi
535 */
536#define __sio_wakeup_tx(siop) do { \
537 osalSysLockFromISR(); \
538 osalThreadResumeI(&(siop)->sync_tx, MSG_OK); \
539 osalSysUnlockFromISR(); \
540} while (false)
541
542/**
543 * @brief Wakes up the TXend-waiting thread.
544 *
545 * @param[in] siop pointer to the @p SIODriver object
546 *
547 * @notapi
548 */
549#define __sio_wakeup_txend(siop) do { \
550 osalSysLockFromISR(); \
551 osalThreadResumeI(&(siop)->sync_txend, MSG_OK); \
552 osalSysUnlockFromISR(); \
553} while (false)
554#else /* !SIO_USE_SYNCHRONIZATION */
555#define __sio_wakeup_errors(siop)
556#define __sio_wakeup_rx(siop)
557#define __sio_wakeup_rxidle(siop)
558#define __sio_wakeup_tx(siop)
559#define __sio_wakeup_txend(siop)
560#endif /* !SIO_USE_SYNCHRONIZATION */
561/** @} */
562
563/**
564 * @brief Relocates a bit field.
565 *
566 * @param[in] v value
567 * @param[in] m mask of the bit field
568 * @param[in] s source bit offset
569 * @param[in] d destination bit offset
570 */
571#define __sio_reloc_field(v, m, s, d) ((((v) & m) >> (s)) << (d))
572
573/*===========================================================================*/
574/* External declarations. */
575/*===========================================================================*/
576
577#ifdef __cplusplus
578extern "C" {
579#endif
580 void sioInit(void);
581 void sioObjectInit(SIODriver *siop);
582 msg_t sioStart(SIODriver *siop, const SIOConfig *config);
583 void sioStop(SIODriver *siop);
584 void sioWriteEnableFlags(SIODriver *siop, sioevents_t mask);
585 void sioSetEnableFlags(SIODriver *siop, sioevents_t mask);
586 void sioClearEnableFlags(SIODriver *siop, sioevents_t mask);
590 size_t sioAsyncRead(SIODriver *siop, uint8_t *buffer, size_t n);
591 size_t sioAsyncWrite(SIODriver *siop, const uint8_t *buffer, size_t n);
592#if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
597#endif
598#ifdef __cplusplus
599}
600#endif
601
602#endif /* HAL_USE_SIO == TRUE */
603
604#endif /* HAL_SIO_H */
605
606/** @} */
uint32_t eventflags_t
Type of an event flags mask.
Definition osal.h:191
int32_t msg_t
Type of a message.
Definition osal.h:159
uint32_t sysinterval_t
Type of system time interval.
Definition osal.h:169
void * thread_reference_t
Type of a thread reference.
Definition osal.h:186
struct hal_sio_config SIOConfig
Type of structure representing a SIO configuration.
Definition hal_sio.h:143
void(* siocb_t)(SIODriver *siop)
Generic SIO notification callback type.
Definition hal_sio.h:150
msg_t sioSynchronizeRX(SIODriver *siop, sysinterval_t timeout)
Synchronizes with RX FIFO data availability.
Definition hal_sio.c:529
msg_t sioSynchronizeRXIdle(SIODriver *siop, sysinterval_t timeout)
Synchronizes with RX going idle.
Definition hal_sio.c:574
msg_t sioSynchronizeTXEnd(SIODriver *siop, sysinterval_t timeout)
Synchronizes with TX completion.
Definition hal_sio.c:659
msg_t sioSynchronizeTX(SIODriver *siop, sysinterval_t timeout)
Synchronizes with TX FIFO space availability.
Definition hal_sio.c:621
void sioWriteEnableFlags(SIODriver *siop, sioevents_t mask)
Writes the enabled events flags mask.
Definition hal_sio.c:327
sioevents_t sioGetAndClearErrors(SIODriver *siop)
Get and clears SIO error event flags.
Definition hal_sio.c:390
struct hal_sio_driver SIODriver
Type of structure representing a SIO driver.
Definition hal_sio.h:138
void sioInit(void)
SIO Driver initialization.
Definition hal_sio.c:204
size_t sioAsyncRead(SIODriver *siop, uint8_t *buffer, size_t n)
Reads data from the RX FIFO.
Definition hal_sio.c:468
#define _sio_driver_methods
SIODriver specific methods.
Definition hal_sio.h:179
size_t sioAsyncWrite(SIODriver *siop, const uint8_t *buffer, size_t n)
Writes data into the TX FIFO.
Definition hal_sio.c:497
void sioObjectInit(SIODriver *siop)
Initializes the standard part of a SIODriver structure.
Definition hal_sio.c:216
msg_t sioStart(SIODriver *siop, const SIOConfig *config)
Configures and activates the SIO peripheral.
Definition hal_sio.c:249
sioevents_t sioGetAndClearEvents(SIODriver *siop)
Get and clears SIO event flags.
Definition hal_sio.c:414
void sioSetEnableFlags(SIODriver *siop, sioevents_t mask)
Sets flags into the enabled events flags mask.
Definition hal_sio.c:348
eventflags_t sioevents_t
Type of event flags.
Definition hal_sio.h:133
void sioStop(SIODriver *siop)
Deactivates the SIO peripheral.
Definition hal_sio.c:292
#define sio_lld_driver_fields
Low level fields of the SIO driver structure.
Definition hal_sio_lld.h:67
siostate_t
Driver state machine possible states.
Definition hal_sio.h:155
sioevents_t sioGetEvents(SIODriver *siop)
Returns the pending SIO event flags.
Definition hal_sio.c:438
#define sio_lld_config_fields
Low level fields of the SIO configuration structure.
Definition hal_sio_lld.h:73
void sioClearEnableFlags(SIODriver *siop, sioevents_t mask)
Clears flags from the enabled events flags mask.
Definition hal_sio.c:369
@ SIO_UNINIT
Definition hal_sio.h:156
@ SIO_READY
Definition hal_sio.h:158
@ SIO_STOP
Definition hal_sio.h:157
PLATFORM SIO subsystem low level driver header.
Driver configuration structure.
Definition hal_sio.h:168
Structure representing a SIO driver.
Definition hal_sio.h:196
thread_reference_t sync_rxidle
Synchronization point for RX idle.
Definition hal_sio.h:233
siostate_t state
Driver state.
Definition hal_sio.h:206
sioevents_t enabled
Enabled event flags.
Definition hal_sio.h:214
siocb_t cb
Events callback.
Definition hal_sio.h:219
thread_reference_t sync_rx
Synchronization point for RX.
Definition hal_sio.h:229
thread_reference_t sync_txend
Synchronization point for TX-end.
Definition hal_sio.h:241
const struct sio_driver_vmt * vmt
Virtual Methods Table.
Definition hal_sio.h:201
thread_reference_t sync_tx
Synchronization point for TX.
Definition hal_sio.h:237
void * arg
User argument.
Definition hal_sio.h:224
const SIOConfig * config
Current configuration data.
Definition hal_sio.h:210
SIODriver virtual methods table.
Definition hal_sio.h:187