Contiki-NG
gpio-hal.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, George Oikonomou - http://www.spd.gr
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*---------------------------------------------------------------------------*/
32 /**
33  * \addtogroup dev
34  * @{
35  *
36  * \defgroup gpio-hal GPIO Hardware Abstraction Layer
37  *
38  * The GPIO HAL provides a set of common functions that can be used in a
39  * platform-independent fashion.
40  *
41  * Internally, the GPIO HAL handles edge detection handling and also provides
42  * fallback functions for GPIO pin toggling if the hardware does not have
43  * a direct method of toggling pins through direct register access.
44  *
45  * @{
46  *
47  * \file
48  * Header file for the GPIO HAL
49  */
50 /*---------------------------------------------------------------------------*/
51 #ifndef GPIO_HAL_H_
52 #define GPIO_HAL_H_
53 /*---------------------------------------------------------------------------*/
54 #include "contiki.h"
55 
56 #include <stdint.h>
57 /*---------------------------------------------------------------------------*/
58 /**
59  * \brief Specifies whether software-based pin toggle is required
60  *
61  * Some MCUs allow GPIO pin toggling via direct register access. For these
62  * MCUs, define GPIO_HAL_CONF_ARCH_SW_TOGGLE to 0 and then implement
63  * gpio_hal_arch_toggle_pin() and gpio_hal_arch_toggle_pins()
64  *
65  * \sa gpio_hal_arch_toggle_pin()
66  * \sa gpio_hal_arch_toggle_pins()
67  */
68 #ifdef GPIO_HAL_CONF_ARCH_SW_TOGGLE
69 #define GPIO_HAL_ARCH_SW_TOGGLE GPIO_HAL_CONF_ARCH_SW_TOGGLE
70 #else
71 #define GPIO_HAL_ARCH_SW_TOGGLE 1
72 #endif
73 /*---------------------------------------------------------------------------*/
74 /**
75  * \brief GPIO pin number representation
76  */
77 typedef uint8_t gpio_hal_pin_t;
78 
79 /**
80  * \brief GPIO pin configuration
81  *
82  * A logical representation of a pin's configuration. It is an OR combination
83  * of GPIO_HAL_PIN_CFG_xyz macros.
84  */
85 typedef uint8_t gpio_hal_pin_cfg_t;
86 
87 #ifdef GPIO_HAL_CONF_PIN_COUNT
88 #define GPIO_HAL_PIN_COUNT GPIO_HAL_CONF_PIN_COUNT
89 #else
90 #define GPIO_HAL_PIN_COUNT 32
91 #endif
92 
93 #if GPIO_HAL_PIN_COUNT > 32
94 typedef uint64_t gpio_hal_pin_mask_t;
95 #else
96 /**
97  * \brief GPIO pin mask representation
98  */
99 typedef uint32_t gpio_hal_pin_mask_t;
100 #endif
101 
102 typedef void (*gpio_hal_callback_t)(gpio_hal_pin_mask_t pin_mask);
103 /*---------------------------------------------------------------------------*/
104 #define GPIO_HAL_PIN_CFG_PULL_NONE 0x00
105 #define GPIO_HAL_PIN_CFG_PULL_UP 0x01
106 #define GPIO_HAL_PIN_CFG_PULL_DOWN 0x02
107 #define GPIO_HAL_PIN_CFG_PULL_MASK (GPIO_HAL_PIN_CFG_PULL_UP | \
108  GPIO_HAL_PIN_CFG_PULL_DOWN)
109 
110 #define GPIO_HAL_PIN_CFG_EDGE_NONE 0x00
111 #define GPIO_HAL_PIN_CFG_EDGE_RISING 0x04
112 #define GPIO_HAL_PIN_CFG_EDGE_FALLING 0x08
113 #define GPIO_HAL_PIN_CFG_EDGE_BOTH (GPIO_HAL_PIN_CFG_EDGE_RISING | \
114  GPIO_HAL_PIN_CFG_EDGE_FALLING)
115 
116 #define GPIO_HAL_PIN_CFG_INT_DISABLE 0x00
117 #define GPIO_HAL_PIN_CFG_INT_ENABLE 0x80
118 #define GPIO_HAL_PIN_CFG_INT_MASK 0x80
119 /*---------------------------------------------------------------------------*/
120 /**
121  * \brief Datatype for GPIO event handlers
122  *
123  * A GPIO event handler is a function that gets called whenever a pin triggers
124  * an event. The same handler can be registered to handle events for more than
125  * one pin by setting the respective pin's position but in \e pin_mask.
126  */
127 typedef struct gpio_hal_event_handler_s {
128  struct gpio_hal_event_handler_s *next;
129  gpio_hal_callback_t handler;
130  gpio_hal_pin_mask_t pin_mask;
132 /*---------------------------------------------------------------------------*/
133 /**
134  * \brief Unknown GPIO
135  *
136  * A default GPIO value for unknown GPIO
137  */
138 #define GPIO_HAL_PIN_UNKNOWN 0xFF
139 /*---------------------------------------------------------------------------*/
140 /**
141  * \name Core GPIO functions
142  *
143  * Functions implemented by the HAL itself
144  * @{
145  */
146 /**
147  * \brief Initialise the GPIO HAL
148  */
149 void gpio_hal_init(void);
150 
151 /**
152  * \brief Register a function to be called whenever a pin triggers an event
153  * \param handler The handler representation
154  *
155  * The handler must be pre-allocated statically by the caller.
156  *
157  * This function can be used to register a function to be called by the HAL
158  * whenever a GPIO interrupt occurs.
159  *
160  * \sa gpio_hal_event_handler
161  */
163 
164 /**
165  * \brief The platform-independent GPIO event handler
166  * \param pins OR mask of pins that generated an event
167  *
168  * Whenever a GPIO input interrupt occurs (edge or level detection) and an ISR
169  * is triggered, the ISR must call this function, passing as argument an ORd
170  * mask of the pins that triggered the interrupt. This function will then
171  * call the registered event handlers (if any) for the pins that triggered the
172  * event. The platform code should make no assumptions as to the order that
173  * the handlers will be called.
174  *
175  * If a pin set in the mask has an event handler registered, this function
176  * will call the registered handler.
177  *
178  * This function will not clear any CPU interrupt flags, this should be done
179  * by the calling ISR.
180  *
181  * \sa gpio_hal_register_handler
182  */
184 
185 /**
186  * \brief Convert a pin to a pin mask
187  * \param pin The pin
188  * \return The corresponding mask
189  */
190 #define gpio_hal_pin_to_mask(pin) (1 << (pin))
191 /** @} */
192 /*---------------------------------------------------------------------------*/
193 /**
194  * \name Functions to be provided by the platform
195  *
196  * All the functions below must be provided by the platform's developer. The
197  * HAL offers the developer a number of options of how to provide the required
198  * functionality.
199  *
200  * - The developer can provide a symbol. For example, the developer can create
201  * a .c file and implement a function called gpio_hal_arch_set_pin()
202  * - The developer can provide a function-like macro that has the same name as
203  * the function declared here. In this scenario, the declaration here will
204  * be removed by the pre-processor. For example, the developer can do
205  * something like:
206  *
207  * \code
208  * #define gpio_hal_arch_write_pin(p, v) platform_sdk_function(p, v)
209  * \endcode
210  *
211  * - The developer can provide a static inline implementation. For this to
212  * work, the developer can do something like:
213  *
214  * \code
215  * #define gpio_hal_arch_set_pin(p) set_pin(p)
216  * static inline void set_pin(gpio_hal_pin_t pin) { ... }
217  * \endcode
218  *
219  * In the latter two cases, the developer will likely provide implementations
220  * in a header file. In this scenario, one of the platform's configuration
221  * files must define GPIO_HAL_CONF_ARCH_HDR_PATH to the name of this header
222  * file. For example:
223  *
224  * \code
225  * #define GPIO_HAL_CONF_ARCH_HDR_PATH "dev/gpio-hal-arch.h"
226  * \endcode
227  *
228  * @{
229  */
230 /*---------------------------------------------------------------------------*/
231 /* Include Arch-Specific conf */
232 #ifdef GPIO_HAL_CONF_ARCH_HDR_PATH
233 #include GPIO_HAL_CONF_ARCH_HDR_PATH
234 #endif /* GPIO_HAL_CONF_ARCH_HDR_PATH */
235 /*---------------------------------------------------------------------------*/
236 #ifndef gpio_hal_arch_interrupt_enable
237 /**
238  * \brief Enable interrupts for a gpio pin
239  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
240  *
241  * It is the platform developer's responsibility to provide an implementation.
242  *
243  * The implementation can be provided as a global symbol, an inline function
244  * or a function-like macro, as described above.
245  */
247 #endif
248 /*---------------------------------------------------------------------------*/
249 #ifndef gpio_hal_arch_interrupt_disable
250 /**
251  * \brief Disable interrupts for a gpio pin
252  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
253  *
254  * It is the platform developer's responsibility to provide an implementation.
255  *
256  * The implementation can be provided as a global symbol, an inline function
257  * or a function-like macro, as described above.
258  */
260 #endif
261 /*---------------------------------------------------------------------------*/
262 #ifndef gpio_hal_arch_pin_cfg_set
263 /**
264  * \brief Configure a gpio pin
265  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
266  * \param cfg The configuration
267  *
268  * \e cfg is an OR mask of GPIO_HAL_PIN_CFG_xyz
269  *
270  * The implementation of this function also has to make sure that \e pin is
271  * configured as software-controlled GPIO.
272  *
273  * It is the platform developer's responsibility to provide an implementation.
274  *
275  * The implementation can be provided as a global symbol, an inline function
276  * or a function-like macro, as described above.
277  */
279 #endif
280 /*---------------------------------------------------------------------------*/
281 #ifndef gpio_hal_arch_pin_cfg_get
282 /**
283  * \brief Read the configuration of a GPIO pin
284  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
285  * \return An OR mask of GPIO_HAL_PIN_CFG_xyz
286  *
287  * It is the platform developer's responsibility to provide an implementation.
288  *
289  * The implementation can be provided as a global symbol, an inline function
290  * or a function-like macro, as described above.
291  */
293 #endif
294 /*---------------------------------------------------------------------------*/
295 #ifndef gpio_hal_arch_pin_set_input
296 /**
297  * \brief Configure a pin as GPIO input
298  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
299  *
300  * The implementation of this function also has to make sure that \e pin is
301  * configured as software-controlled GPIO.
302  *
303  * It is the platform developer's responsibility to provide an implementation.
304  *
305  * The implementation can be provided as a global symbol, an inline function
306  * or a function-like macro, as described above.
307  */
309 #endif
310 /*---------------------------------------------------------------------------*/
311 #ifndef gpio_hal_arch_pin_set_output
312 /**
313  * \brief Configure a pin as GPIO output
314  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
315  *
316  * The implementation of this function also has to make sure that \e pin is
317  * configured as software-controlled GPIO.
318  *
319  * It is the platform developer's responsibility to provide an implementation.
320  *
321  * The implementation can be provided as a global symbol, an inline function
322  * or a function-like macro, as described above.
323  */
325 #endif
326 /*---------------------------------------------------------------------------*/
327 #ifndef gpio_hal_arch_set_pin
328 /**
329  * \brief Set a GPIO pin to logical high
330  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
331  *
332  * It is the platform developer's responsibility to provide an implementation.
333  *
334  * The implementation can be provided as a global symbol, an inline function
335  * or a function-like macro, as described above.
336  */
338 #endif
339 /*---------------------------------------------------------------------------*/
340 #ifndef gpio_hal_arch_clear_pin
341 /**
342  * \brief Clear a GPIO pin (logical low)
343  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
344  *
345  * It is the platform developer's responsibility to provide an implementation.
346  *
347  * The implementation can be provided as a global symbol, an inline function
348  * or a function-like macro, as described above.
349  */
351 #endif
352 /*---------------------------------------------------------------------------*/
353 #ifndef gpio_hal_arch_toggle_pin
354 /**
355  * \brief Toggle a GPIO pin
356  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
357  *
358  * Some MCUs allow GPIO pin toggling directly via register access. In this
359  * case, it is a good idea to provide an implementation of this function.
360  * However, a default, software-based implementation is also provided by the
361  * HAL and can be used if the MCU does not have a pin toggle register. To use
362  * the HAL function, define GPIO_HAL_ARCH_SW_TOGGLE as 1. To provide your own
363  * implementation, define GPIO_HAL_ARCH_SW_TOGGLE as 0.
364  *
365  * The implementation can be provided as a global symbol, an inline function
366  * or a function-like macro, as described above.
367  */
369 #endif
370 /*---------------------------------------------------------------------------*/
371 #ifndef gpio_hal_arch_read_pin
372 /**
373  * \brief Read a GPIO pin
374  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
375  * \retval 0 The pin is logical low
376  * \retval 1 The pin is logical high
377  *
378  * It is the platform developer's responsibility to provide an implementation.
379  *
380  * The implementation can be provided as a global symbol, an inline function
381  * or a function-like macro, as described above.
382  */
384 #endif
385 /*---------------------------------------------------------------------------*/
386 #ifndef gpio_hal_arch_write_pin
387 /**
388  * \brief Write a GPIO pin
389  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
390  * \param value 0: Logical low; 1: Logical high
391  *
392  * It is the platform developer's responsibility to provide an implementation.
393  *
394  * The implementation can be provided as a global symbol, an inline function
395  * or a function-like macro, as described above.
396  */
397 void gpio_hal_arch_write_pin(gpio_hal_pin_t pin, uint8_t value);
398 #endif
399 /*---------------------------------------------------------------------------*/
400 #ifndef gpio_hal_arch_set_pins
401 /**
402  * \brief Set multiple pins to logical high
403  * \param pins An ORd pin mask of the pins to set
404  *
405  * A pin will be set to logical high if its position in \e pins is set. For
406  * example you can set pins 0 and 3 by passing 0x09.
407  *
408  * It is the platform developer's responsibility to provide an implementation.
409  *
410  * The implementation can be provided as a global symbol, an inline function
411  * or a function-like macro, as described above.
412  */
414 #endif
415 /*---------------------------------------------------------------------------*/
416 #ifndef gpio_hal_arch_clear_pins
417 /**
418  * \brief Clear multiple pins to logical low
419  * \param pins An ORd pin mask of the pins to clear
420  *
421  * A pin will be set to logical low if its position in \e pins is set. For
422  * example you can clear pins 0 and 3 by passing 0x09.
423  *
424  * It is the platform developer's responsibility to provide an implementation.
425  *
426  * The implementation can be provided as a global symbol, an inline function
427  * or a function-like macro, as described above.
428  */
430 #endif
431 /*---------------------------------------------------------------------------*/
432 #ifndef gpio_hal_arch_toggle_pins
433 /**
434  * \brief Toggle multiple pins
435  * \param pins An ORd pin mask of the pins to toggle
436  *
437  * A pin will be toggled if its position in \e pins is set. For example you
438  * can toggle pins 0 and 3 by passing 0x09.
439  *
440  * Some MCUs allow GPIO pin toggling directly via register access. In this
441  * case, it is a good idea to provide an implementation of this function.
442  * However, a default, software-based implementation is also provided by the
443  * HAL and can be used if the MCU does not have a pin toggle register. To use
444  * the HAL function, define GPIO_HAL_ARCH_SW_TOGGLE as 1. To provide your own
445  * implementation, define GPIO_HAL_ARCH_SW_TOGGLE as 0.
446  *
447  * The implementation can be provided as a global symbol, an inline function
448  * or a function-like macro, as described above.
449  */
451 #endif
452 /*---------------------------------------------------------------------------*/
453 #ifndef gpio_hal_arch_read_pins
454 /**
455  * \brief Read multiple pins
456  * \param pins An ORd pin mask of the pins to read
457  * \retval An ORd mask of the pins that are high
458  *
459  * If the position of the pin in \e pins is set and the pin is logical high
460  * then the position of the pin in the return value will be set. For example,
461  * if you pass 0x09 as the value of \e pins and the return value is 0x08 then
462  * pin 3 is logical high and pin 0 is logical low.
463  *
464  * It is the platform developer's responsibility to provide an implementation.
465  *
466  * The implementation can be provided as a global symbol, an inline function
467  * or a function-like macro, as described above.
468  */
470 #endif
471 /*---------------------------------------------------------------------------*/
472 #ifndef gpio_hal_arch_write_pins
473 /**
474  * \brief Write multiple pins
475  * \param pins An ORd pin mask of the pins to write
476  * \param value An ORd mask of the value to write
477  *
478  * The function will modify GPIO pins that have their position in the mask set.
479  * pins, the function will write the value specified in the corresponding
480  * position in \e value.
481 
482  * For example, you can set pin 3 and clear pin 0 by a single call to this
483  * function. To achieve this, \e pins must be 0x09 and \e value 0x08.
484  *
485  * It is the platform developer's responsibility to provide an implementation.
486  *
487  * There is no guarantee that this function will result in an atomic operation.
488  *
489  * The implementation can be provided as a global symbol, an inline function
490  * or a function-like macro, as described above.
491  */
493  gpio_hal_pin_mask_t value);
494 #endif
495 /** @} */
496 /*---------------------------------------------------------------------------*/
497 #endif /* GPIO_HAL_H_ */
498 /*---------------------------------------------------------------------------*/
499 /**
500  * @}
501  * @}
502  */
Datatype for GPIO event handlers.
Definition: gpio-hal.h:127
void gpio_hal_arch_interrupt_disable(gpio_hal_pin_t pin)
Disable interrupts for a gpio pin.
Definition: gpio-hal-arch.c:57
void gpio_hal_arch_write_pins(gpio_hal_pin_mask_t pins, gpio_hal_pin_mask_t value)
Write multiple pins.
void gpio_hal_arch_pin_set_input(gpio_hal_pin_t pin)
Configure a pin as GPIO input.
Definition: gpio-hal-arch.c:92
void gpio_hal_arch_interrupt_enable(gpio_hal_pin_t pin)
Enable interrupts for a gpio pin.
Definition: gpio-hal-arch.c:46
void gpio_hal_init()
Initialise the GPIO HAL.
Definition: gpio-hal.c:75
void gpio_hal_event_handler(gpio_hal_pin_mask_t pins)
The platform-independent GPIO event handler.
Definition: gpio-hal.c:61
void gpio_hal_register_handler(gpio_hal_event_handler_t *handler)
Register a function to be called whenever a pin triggers an event.
Definition: gpio-hal.c:55
uint8_t gpio_hal_pin_cfg_t
GPIO pin configuration.
Definition: gpio-hal.h:85
void gpio_hal_arch_set_pin(gpio_hal_pin_t pin)
Set a GPIO pin to logical high.
gpio_hal_pin_mask_t gpio_hal_arch_read_pins(gpio_hal_pin_mask_t pins)
Read multiple pins.
void gpio_hal_arch_clear_pin(gpio_hal_pin_t pin)
Clear a GPIO pin (logical low)
void gpio_hal_arch_toggle_pin(gpio_hal_pin_t pin)
Toggle a GPIO pin.
void gpio_hal_arch_toggle_pins(gpio_hal_pin_mask_t pins)
Toggle multiple pins.
uint8_t gpio_hal_pin_t
GPIO pin number representation.
Definition: gpio-hal.h:77
gpio_hal_pin_cfg_t gpio_hal_arch_pin_cfg_get(gpio_hal_pin_t pin)
Read the configuration of a GPIO pin.
Definition: gpio-hal-arch.c:97
uint32_t gpio_hal_pin_mask_t
GPIO pin mask representation.
Definition: gpio-hal.h:99
struct gpio_hal_event_handler_s gpio_hal_event_handler_t
Datatype for GPIO event handlers.
uint8_t gpio_hal_arch_read_pin(gpio_hal_pin_t pin)
Read a GPIO pin.
void gpio_hal_arch_pin_set_output(gpio_hal_pin_t pin)
Configure a pin as GPIO output.
void gpio_hal_arch_clear_pins(gpio_hal_pin_mask_t pins)
Clear multiple pins to logical low.
void gpio_hal_arch_write_pin(gpio_hal_pin_t pin, uint8_t value)
Write a GPIO pin.
void gpio_hal_arch_set_pins(gpio_hal_pin_mask_t pins)
Set multiple pins to logical high.
void gpio_hal_arch_pin_cfg_set(gpio_hal_pin_t pin, gpio_hal_pin_cfg_t cfg)
Configure a gpio pin.
Definition: gpio-hal-arch.c:48