ChibiOS  21.6.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 status flags
36  * @{
37  */
38 #define SIO_NO_ERROR 0 /**< @brief No pending conditions. */
39 #define SIO_PARITY_ERROR 4 /**< @brief Parity error happened. */
40 #define SIO_FRAMING_ERROR 8 /**< @brief Framing error happened. */
41 #define SIO_OVERRUN_ERROR 16 /**< @brief Overflow happened. */
42 #define SIO_NOISE_ERROR 32 /**< @brief Noise on the line. */
43 #define SIO_BREAK_DETECTED 64 /**< @brief Break detected. */
44 /** @} */
45 
46 /**
47  * @name SIO additional messages
48  * @{
49  */
50 #define SIO_MSG_IDLE 1
51 #define SIO_MSG_ERRORS 2
52 /** @} */
53 
54 /*===========================================================================*/
55 /* Driver pre-compile time settings. */
56 /*===========================================================================*/
57 
58 /**
59  * @name SIO configuration options
60  * @{
61  */
62 /**
63  * @brief Default bit rate.
64  * @details Configuration parameter, this is the baud rate selected for the
65  * default configuration.
66  */
67 #if !defined(SIO_DEFAULT_BITRATE) || defined(__DOXYGEN__)
68 #define SIO_DEFAULT_BITRATE 38400
69 #endif
70 
71 /**
72  * @brief Support for thread synchronization API.
73  */
74 #if !defined(SIO_USE_SYNCHRONIZATION) || defined(__DOXYGEN__)
75 #define SIO_USE_SYNCHRONIZATION TRUE
76 #endif
77 /** @} */
78 
79 /*===========================================================================*/
80 /* Derived constants and error checks. */
81 /*===========================================================================*/
82 
83 /*===========================================================================*/
84 /* Driver data structures and types. */
85 /*===========================================================================*/
86 
87 /**
88  * @brief SIO driver condition flags type.
89  */
90 typedef uint_fast8_t sioflags_t;
91 
92 /**
93  * @brief Type of structure representing a SIO driver.
94  */
95 typedef struct hal_sio_driver SIODriver;
96 
97 /**
98  * @brief Type of structure representing a SIO configuration.
99  */
100 typedef struct hal_sio_config SIOConfig;
101 
102 /**
103  * @brief Type of structure representing a SIO operation.
104  */
106 
107 /**
108  * @brief Generic SIO notification callback type.
109  *
110  * @param[in] siop pointer to the @p SIODriver object
111  */
112 typedef void (*siocb_t)(SIODriver *siop);
113 
114 /**
115  * @brief Driver state machine possible states.
116  */
117 typedef enum {
118  SIO_UNINIT = 0, /**< Not initialized. */
119  SIO_STOP = 1, /**< Stopped. */
120  SIO_READY = 2, /**< Ready. */
121  SIO_ACTIVE = 3 /**< Operation ongoing. */
122 } siostate_t;
123 
124 #include "hal_sio_lld.h"
125 
126 /**
127  * @brief Driver configuration structure.
128  * @note Implementations may extend this structure to contain more,
129  * architecture dependent, fields.
130  */
132  /* End of the mandatory fields.*/
133  sio_lld_config_fields;
134 };
135 
136 /**
137  * @brief @p SIODriver specific methods.
138  */
139 #define _sio_driver_methods \
140  _base_channel_methods
141 
142 /**
143  * @extends BaseChannelVMT
144  *
145  * @brief @p SIODriver virtual methods table.
146  */
149 };
150 
151 /**
152  * @brief Structure representing a SIO driver.
153  * @note Implementations may extend this structure to contain more,
154  * architecture dependent, fields.
155  */
157 #if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
158  /**
159  * @brief Virtual Methods Table.
160  */
161  const struct sio_driver_vmt *vmt;
162 #endif
163  /**
164  * @brief Driver state.
165  */
167  /**
168  * @brief Current configuration data.
169  */
171  /**
172  * @brief Current configuration data.
173  */
175 #if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
176  /**
177  * @brief Synchronization point for RX.
178  */
180  /**
181  * @brief Synchronization point for TX.
182  */
184  /**
185  * @brief Synchronization point for TX-end.
186  */
188 #endif /* SIO_USE_SYNCHRONIZATION == TRUE */
189 #if defined(SIO_DRIVER_EXT_FIELDS)
190  SIO_DRIVER_EXT_FIELDS
191 #endif
192  /* End of the mandatory fields.*/
194 };
195 
196 /**
197  * @brief Structure representing a SIO operation.
198  */
200  /**
201  * @brief Receive non-empty callback.
202  * @note Can be @p NULL.
203  */
205  /**
206  * @brief Receive idle callback.
207  * @note Can be @p NULL.
208  */
210  /**
211  * @brief Transmission buffer non-full callback.
212  * @note Can be @p NULL.
213  */
215  /**
216  * @brief Physical end of transmission callback.
217  * @note Can be @p NULL.
218  */
220  /**
221  * @brief Receive event callback.
222  * @note Can be @p NULL.
223  */
225 };
226 
227 /*===========================================================================*/
228 /* Driver macros. */
229 /*===========================================================================*/
230 
231 /**
232  * @brief Returns the current set of flags and clears it.
233  */
234 #define sioGetFlagsX(siop) sio_lld_get_flags(siop)
235 
236 /**
237  * @brief Determines the state of the RX FIFO.
238  *
239  * @param[in] siop pointer to the @p SIODriver object
240  * @return The RX FIFO state.
241  * @retval false if RX FIFO is not empty
242  * @retval true if RX FIFO is empty
243  *
244  * @xclass
245  */
246 #define sioIsRXEmptyX(siop) sio_lld_is_rx_empty(siop)
247 
248 /**
249  * @brief Determines the state of the TX FIFO.
250  *
251  * @param[in] siop pointer to the @p SIODriver object
252  * @return The TX FIFO state.
253  * @retval false if TX FIFO is not full
254  * @retval true if TX FIFO is full
255  *
256  * @xclass
257  */
258 #define sioIsTXFullX(siop) sio_lld_is_tx_full(siop)
259 
260 /**
261  * @brief Return the pending SIO events flags.
262  *
263  * @param[in] siop pointer to the @p SIODriver object
264  * @return The pending event flags.
265  *
266  * @iclass
267  */
268 #define sioGetAndClearEventsI(siop) sio_lld_get_and_clear_events(siop)
269 
270 /**
271  * @brief Returns one frame from the RX FIFO.
272  * @note If the FIFO is empty then the returned value is unpredictable.
273  *
274  * @param[in] siop pointer to the @p SIODriver object
275  * @return The frame from RX FIFO.
276  *
277  * @xclass
278  */
279 #define sioGetX(siop) sio_lld_get(siop)
280 
281 /**
282  * @brief Pushes one frame into the TX FIFO.
283  * @note If the FIFO is full then the behavior is unpredictable.
284  *
285  * @param[in] siop pointer to the @p SIODriver object
286  * @param[in] data frame to be written
287  *
288  * @xclass
289  */
290 #define sioPutX(siop, data) sio_lld_put(siop, data)
291 
292 /**
293  * @brief Reads data from the RX FIFO.
294  * @details This function is non-blocking, data is read if present and the
295  * effective amount is returned.
296  * @note This function can be called from any context but it is meant to
297  * be called from the @p rxne_cb callback handler.
298  *
299  * @param[in] siop pointer to the @p SIODriver object
300  * @param[in] size maximum number of frames to read
301  * @param[in] buffer buffer for the received data
302  * @return The number of received frames.
303  *
304  * @iclass
305  */
306 #define sioAsyncReadI(siop, size, buffer) sio_lld_read(siop, size, buffer)
307 
308 /**
309  * @brief Writes data into the TX FIFO.
310  * @details This function is non-blocking, data is written if there is space
311  * in the FIFO and the effective amount is returned.
312  * @note This function can be called from any context but it is meant to
313  * be called from the @p txnf_cb callback handler.
314  *
315  * @param[in] siop pointer to the @p SIODriver object
316  * @param[in] size maximum number of frames to read
317  * @param[out] buffer buffer containing the data to be transmitted
318  * @return The number of transmitted frames.
319  *
320  * @iclass
321  */
322 #define sioAsyncWriteI(siop, size, buffer) sio_lld_write(siop, size, buffer)
323 
324 /**
325  * @brief Control operation on a serial port.
326  *
327  * @param[in] siop pointer to the @p SIODriver object
328  * @param[in] operation control operation code
329  * @param[in,out] arg operation argument
330  *
331  * @return The control operation status.
332  * @retval MSG_OK in case of success.
333  * @retval MSG_TIMEOUT in case of operation timeout.
334  * @retval MSG_RESET in case of operation reset.
335  *
336  * @xclass
337  */
338 #define sioControlX(siop, operation, arg) sio_lld_control(siop, operation, arg)
339 
340 /**
341  * @name Low level driver helper macros
342  * @{
343  */
344 /**
345  * @brief RX callback.
346  *
347  * @param[in] siop pointer to the @p SIODriver object
348  *
349  * @notapi
350  */
351 #define __sio_callback_rx(siop) { \
352  if ((siop)->operation->rx_cb != NULL) { \
353  (siop)->operation->rx_cb(siop); \
354  } \
355 }
356 
357 /**
358  * @brief RX idle callback.
359  *
360  * @param[in] siop pointer to the @p SIODriver object
361  *
362  * @notapi
363  */
364 #define __sio_callback_rx_idle(siop) { \
365  if ((siop)->operation->rx_idle_cb != NULL) { \
366  (siop)->operation->rx_idle_cb(siop); \
367  } \
368 }
369 
370 /**
371  * @brief TX callback.
372  *
373  * @param[in] siop pointer to the @p SIODriver object
374  *
375  * @notapi
376  */
377 #define __sio_callback_tx(siop) { \
378  if ((siop)->operation->tx_cb != NULL) { \
379  (siop)->operation->tx_cb(siop); \
380  } \
381 }
382 
383 /**
384  * @brief TX end callback.
385  *
386  * @param[in] siop pointer to the @p SIODriver object
387  *
388  * @notapi
389  */
390 #define __sio_callback_tx_end(siop) { \
391  if ((siop)->operation->tx_end_cb != NULL) { \
392  (siop)->operation->tx_end_cb(siop); \
393  } \
394 }
395 
396 /**
397  * @brief RX event callback.
398  *
399  * @param[in] siop pointer to the @p SIODriver object
400  *
401  * @notapi
402  */
403 #define __sio_callback_rx_evt(siop) { \
404  if ((siop)->operation->rx_evt_cb != NULL) { \
405  (siop)->operation->rx_evt_cb(siop); \
406  } \
407 }
408 
409 #if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
410 /**
411  * @brief Wakes up the RX-waiting thread.
412  *
413  * @param[in] siop pointer to the @p SIODriver object
414  * @param[in] msg the wake up message
415  *
416  * @notapi
417  */
418 #define __sio_wakeup_rx(siop, msg) { \
419  osalSysLockFromISR(); \
420  osalThreadResumeI(&(siop)->sync_rx, msg); \
421  osalSysUnlockFromISR(); \
422 }
423 
424 /**
425  * @brief Wakes up the TX-waiting thread.
426  *
427  * @param[in] siop pointer to the @p SIODriver object
428  * @param[in] msg the wake up message
429  *
430  * @notapi
431  */
432 #define __sio_wakeup_tx(siop, msg) { \
433  osalSysLockFromISR(); \
434  osalThreadResumeI(&(siop)->sync_tx, msg); \
435  osalSysUnlockFromISR(); \
436 }
437 
438 /**
439  * @brief Wakes up the TXend-waiting thread.
440  *
441  * @param[in] siop pointer to the @p SIODriver object
442  * @param[in] msg the wake up message
443  *
444  * @notapi
445  */
446 #define __sio_wakeup_txend(siop, msg) { \
447  osalSysLockFromISR(); \
448  osalThreadResumeI(&(siop)->sync_txend, msg); \
449  osalSysUnlockFromISR(); \
450 }
451 #else /* !SIO_USE_SYNCHRONIZATION */
452 #define __sio_wakeup_rx(siop, msg)
453 #define __sio_wakeup_tx(siop, msg)
454 #define __sio_wakeup_txend(siop, msg)
455 #endif /* !SIO_USE_SYNCHRONIZATION */
456 /** @} */
457 
458 /*===========================================================================*/
459 /* External declarations. */
460 /*===========================================================================*/
461 
462 #ifdef __cplusplus
463 extern "C" {
464 #endif
465  void sioInit(void);
466  void sioObjectInit(SIODriver *siop);
467  bool sioStart(SIODriver *siop, const SIOConfig *config);
468  void sioStop(SIODriver *siop);
469  void sioStartOperation(SIODriver *siop, const SIOOperation *operation);
470  void sioStopOperation(SIODriver *siop);
472  size_t sioAsyncRead(SIODriver *siop, uint8_t *buffer, size_t n);
473  size_t sioAsyncWrite(SIODriver *siop, const uint8_t *buffer, size_t n);
474 #if (SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
478 #endif
479 #ifdef __cplusplus
480 }
481 #endif
482 
483 #endif /* HAL_USE_SIO == TRUE */
484 
485 #endif /* HAL_SIO_H */
486 
487 /** @} */
sio_lld_driver_fields
#define sio_lld_driver_fields
Low level fields of the SIO driver structure.
Definition: hal_sio_lld.h:72
hal_sio_operation::rx_evt_cb
siocb_t rx_evt_cb
Receive event callback.
Definition: hal_sio.h:224
hal_sio_driver::sync_tx
thread_reference_t sync_tx
Synchronization point for TX.
Definition: hal_sio.h:183
sioStop
void sioStop(SIODriver *siop)
Deactivates the SIO peripheral.
Definition: hal_sio.c:277
sioAsyncRead
size_t sioAsyncRead(SIODriver *siop, uint8_t *buffer, size_t n)
Reads data from the RX FIFO.
Definition: hal_sio.c:392
sioStartOperation
void sioStartOperation(SIODriver *siop, const SIOOperation *operation)
Starts a SIO operation.
Definition: hal_sio.c:303
SIO_READY
@ SIO_READY
Definition: hal_sio.h:120
hal_sio_operation::rx_idle_cb
siocb_t rx_idle_cb
Receive idle callback.
Definition: hal_sio.h:209
msg_t
int32_t msg_t
Definition: chearly.h:88
SIO_ACTIVE
@ SIO_ACTIVE
Definition: hal_sio.h:121
hal_sio_driver::operation
const SIOOperation * operation
Current configuration data.
Definition: hal_sio.h:174
_sio_driver_methods
#define _sio_driver_methods
SIODriver specific methods.
Definition: hal_sio.h:139
sioStart
bool sioStart(SIODriver *siop, const SIOConfig *config)
Configures and activates the SIO peripheral.
Definition: hal_sio.c:251
sioSynchronizeRX
msg_t sioSynchronizeRX(SIODriver *siop, sysinterval_t timeout)
Synchronizes with RX FIFO data availability.
Definition: hal_sio.c:448
hal_sio_driver::config
const SIOConfig * config
Current configuration data.
Definition: hal_sio.h:170
hal_sio_operation
Structure representing a SIO operation.
Definition: hal_sio.h:199
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
hal_sio_driver::sync_txend
thread_reference_t sync_txend
Synchronization point for TX-end.
Definition: hal_sio.h:187
hal_sio_operation::tx_end_cb
siocb_t tx_end_cb
Physical end of transmission callback.
Definition: hal_sio.h:219
sioObjectInit
void sioObjectInit(SIODriver *siop)
Initializes the standard part of a SIODriver structure.
Definition: hal_sio.c:225
hal_sio_config
Driver configuration structure.
Definition: hal_sio.h:131
sioSynchronizeTX
msg_t sioSynchronizeTX(SIODriver *siop, sysinterval_t timeout)
Synchronizes with TX FIFO space availability.
Definition: hal_sio.c:483
sioflags_t
uint_fast8_t sioflags_t
SIO driver condition flags type.
Definition: hal_sio.h:90
siostate_t
siostate_t
Driver state machine possible states.
Definition: hal_sio.h:117
hal_sio_driver::state
siostate_t state
Driver state.
Definition: hal_sio.h:166
SIO_STOP
@ SIO_STOP
Definition: hal_sio.h:119
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
sioSynchronizeTXEnd
msg_t sioSynchronizeTXEnd(SIODriver *siop, sysinterval_t timeout)
Synchronizes with TX completion.
Definition: hal_sio.c:515
sioStopOperation
void sioStopOperation(SIODriver *siop)
Stops an ongoing SIO operation, if any.
Definition: hal_sio.c:333
hal_sio_driver::vmt
const struct sio_driver_vmt * vmt
Virtual Methods Table.
Definition: hal_sio.h:161
sioAsyncWrite
size_t sioAsyncWrite(SIODriver *siop, const uint8_t *buffer, size_t n)
Writes data into the TX FIFO.
Definition: hal_sio.c:419
hal_sio_operation::tx_cb
siocb_t tx_cb
Transmission buffer non-full callback.
Definition: hal_sio.h:214
sioInit
void sioInit(void)
SIO Driver initialization.
Definition: hal_sio.c:213
hal_sio_operation::rx_cb
siocb_t rx_cb
Receive non-empty callback.
Definition: hal_sio.h:204
hal_sio_lld.h
PLATFORM SIO subsystem low level driver header.
hal_sio_driver
Structure representing a SIO driver.
Definition: hal_sio.h:156
sio_driver_vmt
SIODriver virtual methods table.
Definition: hal_sio.h:147
hal_sio_driver::sync_rx
thread_reference_t sync_rx
Synchronization point for RX.
Definition: hal_sio.h:179
sioGetAndClearEvents
sio_events_mask_t sioGetAndClearEvents(SIODriver *siop)
Return the pending SIO events flags.
Definition: hal_sio.c:364
SIO_UNINIT
@ SIO_UNINIT
Definition: hal_sio.h:118
siocb_t
void(* siocb_t)(SIODriver *siop)
Generic SIO notification callback type.
Definition: hal_sio.h:112
sio_events_mask_t
uint32_t sio_events_mask_t
Type of a SIO events mask.
Definition: hal_sio_lld.h:63