ChibiOS 21.11.4
hal_buffered_sio.c
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_buffered_sio.c
19 * @brief Buffered SIO Driver code.
20 *
21 * @addtogroup HAL_BUFFERED_SIO
22 * @{
23 */
24
25#include "hal.h"
26
27#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__)
28
29#include "hal_buffered_sio.h"
30
31/*===========================================================================*/
32/* Driver local definitions. */
33/*===========================================================================*/
34
35/*===========================================================================*/
36/* Driver exported variables. */
37/*===========================================================================*/
38
39/*===========================================================================*/
40/* Driver local variables and types. */
41/*===========================================================================*/
42
43/*===========================================================================*/
44/* Driver local functions. */
45/*===========================================================================*/
46
48
49 while (!sioIsTXFullX(bsiop->siop)) {
50 msg_t msg;
51
52 msg = oqGetI(&bsiop->oqueue);
53 if (msg < MSG_OK) {
55 return;
56 }
57 sioPutX(bsiop->siop, (uint_fast16_t)msg);
58 }
59}
60
62
63 /* RX FIFO needs to be fully emptied or SIO will not generate more RX FIFO
64 events.*/
65 while (!sioIsRXEmptyX(bsiop->siop)) {
66 bsIncomingDataI((BufferedSerial *)bsiop, sioGetX(bsiop->siop));
67 }
68}
69
70static void __bsio_default_cb(SIODriver *siop) {
71 BufferedSIODriver *bsiop = (BufferedSIODriver *)siop->arg;
72 sioevents_t events;
73
75
76 /* Posting the non-data SIO events as channel event flags, the masks are
77 made to match.*/
78 events = sioGetAndClearEventsX(siop);
79 chnAddFlagsI(bsiop, (eventflags_t)(events & ~SIO_EV_ALL_DATA));
80
81 /* RX FIFO event.*/
82 if ((events & SIO_EV_RXNOTEMPY) != (sioevents_t)0) {
83
84 __bsio_pop_data(bsiop);
85 }
86
87 /* TX FIFO event.*/
88 if ((events & SIO_EV_TXNOTFULL) != (sioevents_t)0) {
89
90 __bsio_push_data(bsiop);
91 }
92
94}
95
100
101/*
102 * Interface implementation.
103 */
104static size_t __bsio_write(void *ip, const uint8_t *bp, size_t n) {
105
106 return __buffered_serial_write_impl(ip, bp, n);
107}
108
109static size_t __bsio_read(void *ip, uint8_t *bp, size_t n) {
110
111 return __buffered_serial_read_impl(ip, bp, n);
112}
113
114static msg_t __bsio_put(void *ip, uint8_t b) {
115
116 return __buffered_serial_put_impl(ip, b);
117}
118
119static msg_t __bsio_get(void *ip) {
120
122}
123
124static msg_t __bsio_putt(void *ip, uint8_t b, sysinterval_t timeout) {
125
126 return __buffered_serial_put_timeout_impl(ip, b, timeout);
127}
128
129static msg_t __bsio_gett(void *ip, sysinterval_t timeout) {
130
131 return __buffered_serial_get_timeout_impl(ip, timeout);
132}
133
134static size_t __bsio_writet(void *ip, const uint8_t *bp, size_t n,
135 sysinterval_t timeout) {
136
137 return __buffered_serial_write_timeout_impl(ip, bp, n, timeout);
138}
139
140static size_t __bsio_readt(void *ip, uint8_t *bp, size_t n,
141 sysinterval_t timeout) {
142
143 return __buffered_serial_read_timeout_impl(ip, bp, n, timeout);
144}
145
146static msg_t __bsio_ctl(void *ip, unsigned int operation, void *arg) {
147
148 return sioControlX(((BufferedSIODriver *)ip)->siop, operation, arg);
149}
150
157
158/*===========================================================================*/
159/* Driver exported functions. */
160/*===========================================================================*/
161
162/**
163 * @brief Initializes a generic serial driver object.
164 * @details The HW dependent part of the initialization has to be performed
165 * outside, usually in the hardware initialization code.
166 *
167 * @param[out] bsiop pointer to a @p BufferedSIODriver structure
168 * @param[in] siop pointer to the @p SIODriver object
169 * @param[in] ib pointer to the input buffer
170 * @param[in] ibsize size of the input buffer
171 * @param[in] ob pointer to the output buffer
172 * @param[in] obsize size of the output buffer
173 *
174 * @init
175 */
177 uint8_t *ib, size_t ibsize,
178 uint8_t *ob, size_t obsize) {
179
180 __buffered_serial_objinit_impl((void *)bsiop, (const void *)&vmt,
181 ib, ibsize, NULL, NULL,
182 ob, obsize, __bsio_onotify, (void *)bsiop);
183 bsiop->siop = siop;
184 siop->arg = (void *)bsiop;
185}
186
187/**
188 * @brief Configures and starts the driver.
189 *
190 * @param[out] bsiop pointer to a @p BufferedSIODriver structure
191 * @param[in] config the architecture-dependent serial driver configuration.
192 * If this parameter is set to @p NULL then a default
193 * configuration is used.
194 * @return The operation status.
195 *
196 * @api
197 */
199 msg_t msg;
200
201 osalDbgCheck(bsiop != NULL);
202
203 osalDbgAssert((bsiop->state == BS_STOP) || (bsiop->state == BS_READY),
204 "invalid state");
205
206 msg = sioStart(bsiop->siop, config);
207 if (msg == HAL_RET_SUCCESS) {
208 osalSysLock();
209 sioSetCallbackX(bsiop->siop, &__bsio_default_cb);
211 bsiop->state = BS_READY;
213 }
214 else {
215 bsiop->state = BS_STOP;
216 }
217
218 return msg;
219}
220
221/**
222 * @brief Stops the driver.
223 * @details Any thread waiting on the driver's queues will be awakened with
224 * the message @p MSG_RESET.
225 *
226 * @param[out] bsiop pointer to a @p BufferedSIODriver structure
227 *
228 * @api
229 */
231
232 osalDbgCheck(bsiop != NULL);
233
234 osalDbgAssert((bsiop->state == BS_STOP) || (bsiop->state == BS_READY),
235 "invalid state");
236
237 /* Stopping undelying SIO driver.*/
238 sioStop(bsiop->siop);
239
240 bsiop->state = BS_STOP;
241
242 osalSysLock();
243 oqResetI(&bsiop->oqueue); /* TODO should go in the upper class.*/
244 iqResetI(&bsiop->iqueue);
247}
248
249#endif /* HAL_USE_SIO == TRUE */
250
251/** @} */
static CC_FORCE_INLINE size_t __buffered_serial_read_timeout_impl(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout)
static CC_FORCE_INLINE msg_t __buffered_serial_put_impl(void *ip, uint8_t b)
static CC_FORCE_INLINE size_t __buffered_serial_write_impl(void *ip, const uint8_t *bp, size_t n)
static CC_FORCE_INLINE msg_t __buffered_serial_get_timeout_impl(void *ip, sysinterval_t timeout)
static CC_FORCE_INLINE msg_t __buffered_serial_get_impl(void *ip)
static CC_FORCE_INLINE size_t __buffered_serial_read_impl(void *ip, uint8_t *bp, size_t n)
struct hal_buffered_serial BufferedSerial
Structure representing a buffered serial class.
static CC_FORCE_INLINE size_t __buffered_serial_write_timeout_impl(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout)
static CC_FORCE_INLINE msg_t __buffered_serial_put_timeout_impl(void *ip, uint8_t b, sysinterval_t timeout)
void bsIncomingDataI(BufferedSerial *bsp, uint8_t b)
Handles incoming data.
static CC_FORCE_INLINE void __buffered_serial_objinit_impl(void *ip, const void *vmt, uint8_t *ib, size_t ibsize, qnotify_t inotify, void *iarg, uint8_t *ob, size_t obsize, qnotify_t onotify, void *oarg)
Object initialization implementation.
static msg_t __bsio_putt(void *ip, uint8_t b, sysinterval_t timeout)
static void __bsio_onotify(io_queue_t *qp)
static void __bsio_push_data(BufferedSIODriver *bsiop)
static msg_t __bsio_gett(void *ip, sysinterval_t timeout)
struct hal_buffered_siol_driver BufferedSIODriver
Buffered SIO driver class.
static size_t __bsio_writet(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout)
SIOConfig BufferedSIOConfig
Type of a buffered SIO configuration.
static msg_t __bsio_get(void *ip)
static void __bsio_default_cb(SIODriver *siop)
static size_t __bsio_read(void *ip, uint8_t *bp, size_t n)
static size_t __bsio_readt(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout)
void bsioObjectInit(BufferedSIODriver *bsiop, SIODriver *siop, uint8_t *ib, size_t ibsize, uint8_t *ob, size_t obsize)
Initializes a generic serial driver object.
static void __bsio_pop_data(BufferedSIODriver *bsiop)
void bsioStop(BufferedSIODriver *bsiop)
Stops the driver.
static size_t __bsio_write(void *ip, const uint8_t *bp, size_t n)
msg_t bsioStart(BufferedSIODriver *bsiop, const BufferedSIOConfig *config)
Configures and starts the driver.
static msg_t __bsio_put(void *ip, uint8_t b)
static msg_t __bsio_ctl(void *ip, unsigned int operation, void *arg)
static const struct EFlashDriverVMT vmt
Definition hal_efl.c:71
void iqResetI(input_queue_t *iqp)
Resets an input queue.
Definition hal_queues.c:201
void oqResetI(output_queue_t *oqp)
Resets an output queue.
Definition hal_queues.c:467
msg_t oqGetI(output_queue_t *oqp)
Output queue read.
Definition hal_queues.c:576
struct io_queue io_queue_t
Type of a generic I/O queue structure.
Definition hal_queues.h:58
#define HAL_RET_SUCCESS
Definition hal.h:93
#define CHN_OUTPUT_EMPTY
Output queue empty.
#define chnAddFlagsI(ip, flags)
Adds status flags to the listeners's flags mask.
static void osalSysLock(void)
Enters a critical zone from thread context.
Definition osal.h:601
static void osalSysUnlock(void)
Leaves a critical zone from thread context.
Definition osal.h:611
static void osalSysLockFromISR(void)
Enters a critical zone from ISR context.
Definition osal.h:621
void osalOsRescheduleS(void)
Checks if a reschedule is required and performs it.
Definition osal.c:119
static void osalSysUnlockFromISR(void)
Leaves a critical zone from ISR context.
Definition osal.h:631
#define osalDbgAssert(c, remark)
Condition assertion.
Definition osal.h:264
#define osalDbgCheck(c)
Function parameters check.
Definition osal.h:284
#define sioPutX(siop, data)
Pushes one frame into the TX FIFO.
Definition hal_sio.h:421
#define SIO_EV_ALL_DATA
Definition hal_sio.h:59
#define sioGetX(siop)
Returns one frame from the RX FIFO.
Definition hal_sio.h:410
struct hal_sio_driver SIODriver
Type of structure representing a SIO driver.
Definition hal_sio.h:138
#define sioSetCallbackX(siop, f)
Associates a callback to the SIO instance.
Definition hal_sio.h:260
#define sioWriteEnableFlagsX(siop, mask)
Writes the enabled events mask.
Definition hal_sio.h:331
#define sioIsTXFullX(siop)
Determines the state of the TX FIFO.
Definition hal_sio.h:309
msg_t sioStart(SIODriver *siop, const SIOConfig *config)
Configures and activates the SIO peripheral.
Definition hal_sio.c:249
#define sioGetAndClearEventsX(siop)
Get and clears SIO event flags.
Definition hal_sio.h:389
#define sioControlX(siop, operation, arg)
Control operation on a serial port.
Definition hal_sio.h:469
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_EV_TXNOTFULL
Definition hal_sio.h:58
#define SIO_EV_RXNOTEMPY
Definition hal_sio.h:57
#define sioIsRXEmptyX(siop)
Determines the state of the RX FIFO.
Definition hal_sio.h:272
#define SIO_EV_ALL_EVENTS
Definition hal_sio.h:72
uint32_t eventflags_t
Definition chearly.h:91
int32_t msg_t
Definition chearly.h:88
#define MSG_OK
Normal wakeup message.
Definition chschd.h:39
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:119
HAL subsystem header.
Buffered SIO Driver macros and structures.
BufferedSIODriver virtual methods table.
void * arg
User argument.
Definition hal_sio.h:224
void * q_link
Application defined field.
Definition hal_queues.h:84