ChibiOS  21.6.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  */
90 void 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  */
113 void 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  */
148 void palSetLineCallbackI(ioline_t line, palcallback_t cb, void *arg) {
149 
150  palevent_t *pep = pal_lld_get_line_event(line);
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  * .
167  * @returns The operation state.
168  * @retval MSG_OK if an edge has been detected.
169  * @retval MSG_TIMEOUT if a timeout occurred before an edge could be detected.
170  * @retval MSG_RESET if the event has been disabled while the thread was
171  * waiting for an edge.
172  *
173  * @sclass
174  */
176  iopadid_t pad,
177  sysinterval_t timeout) {
178 
179  palevent_t *pep = pal_lld_get_pad_event(port, pad);
180  return osalThreadEnqueueTimeoutS(&pep->threads, timeout);
181 }
182 
183 /**
184  * @brief Waits for an edge on the specified port/pad.
185  *
186  * @param[in] port port identifier
187  * @param[in] pad pad number within the port
188  * @param[in] timeout the number of ticks before the operation timeouts,
189  * the following special values are allowed:
190  * - @a TIME_IMMEDIATE immediate timeout.
191  * - @a TIME_INFINITE no timeout.
192  * .
193  * @returns The operation state.
194  * @retval MSG_OK if an edge has been detected.
195  * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
196  * @retval MSG_RESET if the event has been disabled while the thread was
197  * waiting for an edge.
198  *
199  * @api
200  */
202  iopadid_t pad,
203  sysinterval_t timeout) {
204  msg_t msg;
205 
206  osalSysLock();
207  msg = palWaitPadTimeoutS(port, pad, timeout);
208  osalSysUnlock();
209  return msg;
210 }
211 
212 /**
213  * @brief Waits for an edge on the specified line.
214  *
215  * @param[in] line line identifier
216  * @param[in] timeout operation timeout
217  * @returns The operation state.
218  * @retval MSG_OK if an edge has been detected.
219  * @retval MSG_TIMEOUT if a timeout occurred before an edge could be detected.
220  * @retval MSG_RESET if the event has been disabled while the thread was
221  * waiting for an edge.
222  *
223  * @sclass
224  */
226  sysinterval_t timeout) {
227 
228  palevent_t *pep = pal_lld_get_line_event(line);
229  return osalThreadEnqueueTimeoutS(&pep->threads, timeout);
230 }
231 
232 /**
233  * @brief Waits for an edge on the specified line.
234  *
235  * @param[in] line line identifier
236  * @param[in] timeout operation timeout
237  * @returns The operation state.
238  * @retval MSG_OK if an edge has been detected.
239  * @retval MSG_TIMEOUT if a timeout occurred before an edge cound be detected.
240  * @retval MSG_RESET if the event has been disabled while the thread was
241  * waiting for an edge.
242  *
243  * @api
244  */
246  msg_t msg;
247 
248  osalSysLock();
249  msg = palWaitLineTimeoutS(line, timeout);
250  osalSysUnlock();
251  return msg;
252 }
253 #endif /* PAL_USE_WAIT == TRUE */
254 
255 #endif /* HAL_USE_PAL == TRUE */
256 
257 /** @} */
ioportid_t
uint32_t ioportid_t
Port Identifier.
Definition: hal_pal_lld.h:122
hal.h
HAL subsystem header.
pal_lld_get_line_event
#define pal_lld_get_line_event(line)
Returns a PAL event structure associated to a line.
Definition: hal_pal_lld.h:420
IOBus::portid
ioportid_t portid
Port identifier.
Definition: hal_pal.h:187
iopadid_t
uint32_t iopadid_t
Type of an pad identifier.
Definition: hal_pal_lld.h:127
osalSysUnlock
static void osalSysUnlock(void)
Leaves a critical zone from thread context.
Definition: osal.h:611
iomode_t
uint32_t iomode_t
Digital I/O modes.
Definition: hal_pal_lld.h:109
palWaitPadTimeout
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:201
palSetPadCallbackI
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
msg_t
int32_t msg_t
Definition: chearly.h:88
ioportmask_t
uint32_t ioportmask_t
Digital I/O port sized unsigned type.
Definition: hal_pal_lld.h:104
palSetBusMode
void palSetBusMode(const IOBus *bus, iomode_t mode)
Programs a bus with the specified mode.
Definition: hal_pal.c:113
palevent_t::arg
void * arg
Event callback argument.
Definition: hal_pal.h:169
palevent_t::cb
palcallback_t cb
Event callback.
Definition: hal_pal.h:165
palWaitLineTimeoutS
msg_t palWaitLineTimeoutS(ioline_t line, sysinterval_t timeout)
Waits for an edge on the specified line.
Definition: hal_pal.c:225
palReadBus
ioportmask_t palReadBus(const IOBus *bus)
Read from an I/O bus.
Definition: hal_pal.c:65
palWriteBus
void palWriteBus(const IOBus *bus, ioportmask_t bits)
Write to an I/O bus.
Definition: hal_pal.c:90
ioline_t
uint32_t ioline_t
Type of an I/O line.
Definition: hal_pal_lld.h:114
osalThreadEnqueueTimeoutS
msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread.
Definition: osal.c:277
osalDbgCheck
#define osalDbgCheck(c)
Function parameters check.
Definition: osal.h:284
palWriteGroup
#define palWriteGroup(port, mask, offset, bits)
Writes a group of bits.
Definition: hal_pal.h:524
palWaitPadTimeoutS
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:175
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
osalSysLock
static void osalSysLock(void)
Enters a critical zone from thread context.
Definition: osal.h:601
palevent_t::threads
threads_queue_t threads
Threads queued for an event.
Definition: hal_pal.h:159
palSetGroupMode
#define palSetGroupMode(port, mask, offset, mode)
Pads group mode setup.
Definition: hal_pal.h:551
IOBus
I/O bus descriptor.
Definition: hal_pal.h:183
palevent_t
Type of a PAL event record.
Definition: hal_pal.h:154
palReadGroup
#define palReadGroup(port, mask, offset)
Reads a group of bits.
Definition: hal_pal.h:500
palcallback_t
void(* palcallback_t)(void *arg)
Type of a PAL event callback.
Definition: hal_pal.h:148
PAL_IOPORTS_WIDTH
#define PAL_IOPORTS_WIDTH
Width, in bits, of an I/O port.
Definition: hal_pal_lld.h:49
palSetLineCallbackI
void palSetLineCallbackI(ioline_t line, palcallback_t cb, void *arg)
Associates a callback to a line.
Definition: hal_pal.c:148
IOBus::mask
ioportmask_t mask
Bus mask aligned to port bit 0.
Definition: hal_pal.h:193
IOBus::offset
uint_fast8_t offset
Offset, within the port, of the least significant bit of the bus.
Definition: hal_pal.h:197
palWaitLineTimeout
msg_t palWaitLineTimeout(ioline_t line, sysinterval_t timeout)
Waits for an edge on the specified line.
Definition: hal_pal.c:245
pal_lld_get_pad_event
#define pal_lld_get_pad_event(port, pad)
Returns a PAL event structure associated to a pad.
Definition: hal_pal_lld.h:410