ChibiOS/HAL 9.0.0
hal_pal.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_pal.c
19 * @brief I/O Ports Abstraction Layer code.
20 *
21 * @addtogroup PAL
22 * @{
23 */
24
25#include "hal.h"
26
27#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
28
29/*===========================================================================*/
30/* Driver local definitions. */
31/*===========================================================================*/
32
33/*===========================================================================*/
34/* Driver exported variables. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Driver local variables and types. */
39/*===========================================================================*/
40
41/*===========================================================================*/
42/* Driver local functions. */
43/*===========================================================================*/
44
45/*===========================================================================*/
46/* Driver exported functions. */
47/*===========================================================================*/
48
49/**
50 * @brief Read from an I/O bus.
51 * @note The operation is not guaranteed to be atomic on all the
52 * architectures, for atomicity and/or portability reasons you may
53 * need to enclose port I/O operations between @p osalSysLock() and
54 * @p osalSysUnlock().
55 * @note The function internally uses the @p palReadGroup() macro. The use
56 * of this function is preferred when you value code size, readability
57 * and error checking over speed.
58 * @note The function can be called from any context.
59 *
60 * @param[in] bus the I/O bus, pointer to a @p IOBus structure
61 * @return The bus logical states.
62 *
63 * @special
64 */
66
67 osalDbgCheck((bus != NULL) && (bus->offset < PAL_IOPORTS_WIDTH));
68
69 return palReadGroup(bus->portid, bus->mask, bus->offset);
70}
71
72/**
73 * @brief Write to an I/O bus.
74 * @note The operation is not guaranteed to be atomic on all the
75 * architectures, for atomicity and/or portability reasons you may
76 * need to enclose port I/O operations between @p osalSysLock() and
77 * @p osalSysUnlock().
78 * @note The default implementation is non atomic and not necessarily
79 * optimal. Low level drivers may optimize the function by using
80 * specific hardware or coding.
81 * @note The function can be called from any context.
82 *
83 * @param[in] bus the I/O bus, pointer to a @p IOBus structure
84 * @param[in] bits the bits to be written on the I/O bus. Values exceeding
85 * the bus width are masked so most significant bits are
86 * lost.
87 *
88 * @special
89 */
90void palWriteBus(const IOBus *bus, ioportmask_t bits) {
91
92 osalDbgCheck((bus != NULL) && (bus->offset < PAL_IOPORTS_WIDTH));
93
94 palWriteGroup(bus->portid, bus->mask, bus->offset, bits);
95}
96
97/**
98 * @brief Programs a bus with the specified mode.
99 * @note The operation is not guaranteed to be atomic on all the
100 * architectures, for atomicity and/or portability reasons you may
101 * need to enclose port I/O operations between @p osalSysLock() and
102 * @p osalSysUnlock().
103 * @note The default implementation is non atomic and not necessarily
104 * optimal. Low level drivers may optimize the function by using
105 * specific hardware or coding.
106 * @note The function can be called from any context.
107 *
108 * @param[in] bus the I/O bus, pointer to a @p IOBus structure
109 * @param[in] mode the mode
110 *
111 * @special
112 */
113void palSetBusMode(const IOBus *bus, iomode_t mode) {
114
115 osalDbgCheck((bus != NULL) && (bus->offset < PAL_IOPORTS_WIDTH));
116
117 palSetGroupMode(bus->portid, bus->mask, bus->offset, mode);
118}
119
120#if (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
121/**
122 * @brief Associates a callback to a port/pad.
123 *
124 * @param[in] port port identifier
125 * @param[in] pad pad number within the port
126 * @param[in] cb event callback function
127 * @param[in] arg callback argument
128 *
129 * @iclass
130 */
132 palcallback_t cb, void *arg) {
133
134 palevent_t *pep = pal_lld_get_pad_event(port, pad);
135 pep->cb = cb;
136 pep->arg = arg;
137}
138
139/**
140 * @brief Associates a callback to a line.
141 *
142 * @param[in] line line identifier
143 * @param[in] cb event callback function
144 * @param[in] arg callback argument
145 *
146 * @iclass
147 */
148void palSetLineCallbackI(ioline_t line, palcallback_t cb, void *arg) {
149
151 pep->cb = cb;
152 pep->arg = arg;
153}
154#endif /* PAL_USE_CALLBACKS == TRUE */
155
156#if (PAL_USE_WAIT == TRUE) || defined(__DOXYGEN__)
157/**
158 * @brief Waits for an edge on the specified port/pad.
159 *
160 * @param[in] port port identifier
161 * @param[in] pad pad number within the port
162 * @param[in] timeout the number of ticks before the operation timeouts,
163 * the following special values are allowed:
164 * - @a TIME_IMMEDIATE immediate timeout.
165 * - @a TIME_INFINITE no timeout.
166 * @returns The operation state.
167 * @retval MSG_OK if an edge has been detected.
168 * @retval MSG_TIMEOUT if a timeout occurred before an edge could be detected.
169 * @retval MSG_RESET if the event has been disabled while the thread was
170 * waiting for an edge.
171 *
172 * @sclass
173 */
175 iopadid_t pad,
176 sysinterval_t timeout) {
177
178 palevent_t *pep = pal_lld_get_pad_event(port, pad);
179 return osalThreadEnqueueTimeoutS(&pep->threads, timeout);
180}
181
182/**
183 * @brief Waits for an edge on the specified port/pad.
184 *
185 * @param[in] port port identifier
186 * @param[in] pad pad number within the port
187 * @param[in] timeout the number of ticks before the operation timeouts,
188 * the following special values are allowed:
189 * - @a TIME_IMMEDIATE immediate timeout.
190 * - @a TIME_INFINITE no timeout.
191 * @returns The operation state.
192 * @retval MSG_OK if an edge has been detected.
193 * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
194 * @retval MSG_RESET if the event has been disabled while the thread was
195 * waiting for an edge.
196 *
197 * @api
198 */
200 iopadid_t pad,
201 sysinterval_t timeout) {
202 msg_t msg;
203
204 osalSysLock();
205 msg = palWaitPadTimeoutS(port, pad, timeout);
207 return msg;
208}
209
210/**
211 * @brief Waits for an edge on the specified line.
212 *
213 * @param[in] line line identifier
214 * @param[in] timeout operation timeout
215 * @returns The operation state.
216 * @retval MSG_OK if an edge has been detected.
217 * @retval MSG_TIMEOUT if a timeout occurred before an edge could be detected.
218 * @retval MSG_RESET if the event has been disabled while the thread was
219 * waiting for an edge.
220 *
221 * @sclass
222 */
224 sysinterval_t timeout) {
225
227 return osalThreadEnqueueTimeoutS(&pep->threads, timeout);
228}
229
230/**
231 * @brief Waits for an edge on the specified line.
232 *
233 * @param[in] line line identifier
234 * @param[in] timeout operation timeout
235 * @returns The operation state.
236 * @retval MSG_OK if an edge has been detected.
237 * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
238 * @retval MSG_RESET if the event has been disabled while the thread was
239 * waiting for an edge.
240 *
241 * @api
242 */
244 msg_t msg;
245
246 osalSysLock();
247 msg = palWaitLineTimeoutS(line, timeout);
249 return msg;
250}
251#endif /* PAL_USE_WAIT == TRUE */
252
253#endif /* HAL_USE_PAL == TRUE */
254
255/** @} */
msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread.
Definition osal.c:273
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
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
#define osalDbgCheck(c)
Function parameters check.
Definition osal.h:284
#define PAL_IOPORTS_WIDTH
Width, in bits, of an I/O port.
Definition hal_pal_lld.h:49
void palSetPadCallbackI(ioportid_t port, iopadid_t pad, palcallback_t cb, void *arg)
Associates a callback to a port/pad.
Definition hal_pal.c:131
void palWriteBus(const IOBus *bus, ioportmask_t bits)
Write to an I/O bus.
Definition hal_pal.c:90
void palSetLineCallbackI(ioline_t line, palcallback_t cb, void *arg)
Associates a callback to a line.
Definition hal_pal.c:148
msg_t palWaitLineTimeout(ioline_t line, sysinterval_t timeout)
Waits for an edge on the specified line.
Definition hal_pal.c:243
msg_t palWaitPadTimeout(ioportid_t port, iopadid_t pad, sysinterval_t timeout)
Waits for an edge on the specified port/pad.
Definition hal_pal.c:199
msg_t palWaitPadTimeoutS(ioportid_t port, iopadid_t pad, sysinterval_t timeout)
Waits for an edge on the specified port/pad.
Definition hal_pal.c:174
uint32_t ioportid_t
Port Identifier.
ioportmask_t palReadBus(const IOBus *bus)
Read from an I/O bus.
Definition hal_pal.c:65
uint32_t ioportmask_t
Digital I/O port sized unsigned type.
#define pal_lld_get_pad_event(port, pad)
Returns a PAL event structure associated to a pad.
msg_t palWaitLineTimeoutS(ioline_t line, sysinterval_t timeout)
Waits for an edge on the specified line.
Definition hal_pal.c:223
#define pal_lld_get_line_event(line)
Returns a PAL event structure associated to a line.
void(* palcallback_t)(void *arg)
Type of a PAL event callback.
Definition hal_pal.h:148
uint32_t iomode_t
Digital I/O modes.
void palSetBusMode(const IOBus *bus, iomode_t mode)
Programs a bus with the specified mode.
Definition hal_pal.c:113
#define palWriteGroup(port, mask, offset, bits)
Writes a group of bits.
Definition hal_pal.h:543
#define palReadGroup(port, mask, offset)
Reads a group of bits.
Definition hal_pal.h:500
#define palSetGroupMode(port, mask, offset, mode)
Pads group mode setup.
Definition hal_pal.h:570
uint32_t iopadid_t
Type of an pad identifier.
uint32_t ioline_t
Type of an I/O line.
HAL subsystem header.
I/O bus descriptor.
Definition hal_pal.h:183
uint_fast8_t offset
Offset, within the port, of the least significant bit of the bus.
Definition hal_pal.h:197
ioportid_t portid
Port identifier.
Definition hal_pal.h:187
ioportmask_t mask
Bus mask aligned to port bit 0.
Definition hal_pal.h:193
Type of a PAL event record.
Definition hal_pal.h:154
void * arg
Event callback argument.
Definition hal_pal.h:169
palcallback_t cb
Event callback.
Definition hal_pal.h:165
threads_queue_t threads
Threads queued for an event.
Definition hal_pal.h:159