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 uint32_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_HYSTERESIS 0x10
111 
112 #define GPIO_HAL_PIN_CFG_EDGE_NONE 0x00
113 #define GPIO_HAL_PIN_CFG_EDGE_RISING 0x04
114 #define GPIO_HAL_PIN_CFG_EDGE_FALLING 0x08
115 #define GPIO_HAL_PIN_CFG_EDGE_BOTH (GPIO_HAL_PIN_CFG_EDGE_RISING | \
116  GPIO_HAL_PIN_CFG_EDGE_FALLING)
117 
118 #define GPIO_HAL_PIN_CFG_INT_DISABLE 0x00
119 #define GPIO_HAL_PIN_CFG_INT_ENABLE 0x80
120 #define GPIO_HAL_PIN_CFG_INT_MASK 0x80
121 /*---------------------------------------------------------------------------*/
122 /**
123  * \brief Datatype for GPIO event handlers
124  *
125  * A GPIO event handler is a function that gets called whenever a pin triggers
126  * an event. The same handler can be registered to handle events for more than
127  * one pin by setting the respective pin's position but in \e pin_mask.
128  */
129 typedef struct gpio_hal_event_handler_s {
130  struct gpio_hal_event_handler_s *next;
131  gpio_hal_callback_t handler;
132  gpio_hal_pin_mask_t pin_mask;
134 /*---------------------------------------------------------------------------*/
135 /**
136  * \brief Unknown GPIO
137  *
138  * A default GPIO value for unknown GPIO
139  */
140 #define GPIO_HAL_PIN_UNKNOWN 0xFF
141 /*---------------------------------------------------------------------------*/
142 /**
143  * \name Core GPIO functions
144  *
145  * Functions implemented by the HAL itself
146  * @{
147  */
148 /**
149  * \brief Initialise the GPIO HAL
150  */
151 void gpio_hal_init(void);
152 
153 /**
154  * \brief Register a function to be called whenever a pin triggers an event
155  * \param handler The handler representation
156  *
157  * The handler must be pre-allocated statically by the caller.
158  *
159  * This function can be used to register a function to be called by the HAL
160  * whenever a GPIO interrupt occurs.
161  *
162  * \sa gpio_hal_event_handler
163  */
165 
166 /**
167  * \brief The platform-independent GPIO event handler
168  * \param pins OR mask of pins that generated an event
169  *
170  * Whenever a GPIO input interrupt occurs (edge or level detection) and an ISR
171  * is triggered, the ISR must call this function, passing as argument an ORd
172  * mask of the pins that triggered the interrupt. This function will then
173  * call the registered event handlers (if any) for the pins that triggered the
174  * event. The platform code should make no assumptions as to the order that
175  * the handlers will be called.
176  *
177  * If a pin set in the mask has an event handler registered, this function
178  * will call the registered handler.
179  *
180  * This function will not clear any CPU interrupt flags, this should be done
181  * by the calling ISR.
182  *
183  * \sa gpio_hal_register_handler
184  */
186 
187 /**
188  * \brief Convert a pin to a pin mask
189  * \param pin The pin
190  * \return The corresponding mask
191  */
192 #define gpio_hal_pin_to_mask(pin) ((gpio_hal_pin_mask_t)1 << (pin))
193 /** @} */
194 /*---------------------------------------------------------------------------*/
195 /**
196  * \name Functions to be provided by the platform
197  *
198  * All the functions below must be provided by the platform's developer. The
199  * HAL offers the developer a number of options of how to provide the required
200  * functionality.
201  *
202  * - The developer can provide a symbol. For example, the developer can create
203  * a .c file and implement a function called gpio_hal_arch_set_pin()
204  * - The developer can provide a function-like macro that has the same name as
205  * the function declared here. In this scenario, the declaration here will
206  * be removed by the pre-processor. For example, the developer can do
207  * something like:
208  *
209  * \code
210  * #define gpio_hal_arch_write_pin(p, v) platform_sdk_function(p, v)
211  * \endcode
212  *
213  * - The developer can provide a static inline implementation. For this to
214  * work, the developer can do something like:
215  *
216  * \code
217  * #define gpio_hal_arch_set_pin(p) set_pin(p)
218  * static inline void set_pin(gpio_hal_pin_t pin) { ... }
219  * \endcode
220  *
221  * In the latter two cases, the developer will likely provide implementations
222  * in a header file. In this scenario, one of the platform's configuration
223  * files must define GPIO_HAL_CONF_ARCH_HDR_PATH to the name of this header
224  * file. For example:
225  *
226  * \code
227  * #define GPIO_HAL_CONF_ARCH_HDR_PATH "dev/gpio-hal-arch.h"
228  * \endcode
229  *
230  * @{
231  */
232 /*---------------------------------------------------------------------------*/
233 /* Include Arch-Specific conf */
234 #ifdef GPIO_HAL_CONF_ARCH_HDR_PATH
235 #include GPIO_HAL_CONF_ARCH_HDR_PATH
236 #endif /* GPIO_HAL_CONF_ARCH_HDR_PATH */
237 /*---------------------------------------------------------------------------*/
238 #ifndef gpio_hal_arch_init
239 /**
240  * \brief Perform architecture specific gpio initaliaztion
241  *
242  * It is the platform developer's responsibility to provide an implementation.
243  *
244  * The implementation can be provided as a global symbol, an inline function
245  * or a function-like macro, as described above.
246  */
247 void gpio_hal_arch_init(void);
248 #endif
249 /*---------------------------------------------------------------------------*/
250 #ifndef gpio_hal_arch_interrupt_enable
251 /**
252  * \brief Enable interrupts for a gpio pin
253  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
254  *
255  * It is the platform developer's responsibility to provide an implementation.
256  *
257  * The implementation can be provided as a global symbol, an inline function
258  * or a function-like macro, as described above.
259  */
261 #endif
262 /*---------------------------------------------------------------------------*/
263 #ifndef gpio_hal_arch_interrupt_disable
264 /**
265  * \brief Disable interrupts for a gpio pin
266  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
267  *
268  * It is the platform developer's responsibility to provide an implementation.
269  *
270  * The implementation can be provided as a global symbol, an inline function
271  * or a function-like macro, as described above.
272  */
274 #endif
275 /*---------------------------------------------------------------------------*/
276 #ifndef gpio_hal_arch_pin_cfg_set
277 /**
278  * \brief Configure a gpio pin
279  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
280  * \param cfg The configuration
281  *
282  * \e cfg is an OR mask of GPIO_HAL_PIN_CFG_xyz
283  *
284  * The implementation of this function also has to make sure that \e pin is
285  * configured as software-controlled GPIO.
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_cfg_get
296 /**
297  * \brief Read the configuration of a GPIO pin
298  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
299  * \return An OR mask of GPIO_HAL_PIN_CFG_xyz
300  *
301  * It is the platform developer's responsibility to provide an implementation.
302  *
303  * The implementation can be provided as a global symbol, an inline function
304  * or a function-like macro, as described above.
305  */
307 #endif
308 /*---------------------------------------------------------------------------*/
309 #ifndef gpio_hal_arch_pin_set_input
310 /**
311  * \brief Configure a pin as GPIO input
312  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
313  *
314  * The implementation of this function also has to make sure that \e pin is
315  * configured as software-controlled GPIO.
316  *
317  * It is the platform developer's responsibility to provide an implementation.
318  *
319  * The implementation can be provided as a global symbol, an inline function
320  * or a function-like macro, as described above.
321  */
323 #endif
324 /*---------------------------------------------------------------------------*/
325 #ifndef gpio_hal_arch_pin_set_output
326 /**
327  * \brief Configure a pin as GPIO output
328  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
329  *
330  * The implementation of this function also has to make sure that \e pin is
331  * configured as software-controlled GPIO.
332  *
333  * It is the platform developer's responsibility to provide an implementation.
334  *
335  * The implementation can be provided as a global symbol, an inline function
336  * or a function-like macro, as described above.
337  */
339 #endif
340 /*---------------------------------------------------------------------------*/
341 #ifndef gpio_hal_arch_set_pin
342 /**
343  * \brief Set a GPIO pin to logical high
344  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
345  *
346  * It is the platform developer's responsibility to provide an implementation.
347  *
348  * The implementation can be provided as a global symbol, an inline function
349  * or a function-like macro, as described above.
350  */
352 #endif
353 /*---------------------------------------------------------------------------*/
354 #ifndef gpio_hal_arch_clear_pin
355 /**
356  * \brief Clear a GPIO pin (logical low)
357  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
358  *
359  * It is the platform developer's responsibility to provide an implementation.
360  *
361  * The implementation can be provided as a global symbol, an inline function
362  * or a function-like macro, as described above.
363  */
365 #endif
366 /*---------------------------------------------------------------------------*/
367 #ifndef gpio_hal_arch_toggle_pin
368 /**
369  * \brief Toggle a GPIO pin
370  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
371  *
372  * Some MCUs allow GPIO pin toggling directly via register access. In this
373  * case, it is a good idea to provide an implementation of this function.
374  * However, a default, software-based implementation is also provided by the
375  * HAL and can be used if the MCU does not have a pin toggle register. To use
376  * the HAL function, define GPIO_HAL_ARCH_SW_TOGGLE as 1. To provide your own
377  * implementation, define GPIO_HAL_ARCH_SW_TOGGLE as 0.
378  *
379  * The implementation can be provided as a global symbol, an inline function
380  * or a function-like macro, as described above.
381  */
383 #endif
384 /*---------------------------------------------------------------------------*/
385 #ifndef gpio_hal_arch_read_pin
386 /**
387  * \brief Read a GPIO pin
388  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
389  * \retval 0 The pin is logical low
390  * \retval 1 The pin is 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  */
398 #endif
399 /*---------------------------------------------------------------------------*/
400 #ifndef gpio_hal_arch_write_pin
401 /**
402  * \brief Write a GPIO pin
403  * \param pin The GPIO pin number (0...GPIO_HAL_PIN_COUNT - 1)
404  * \param value 0: Logical low; 1: Logical high
405  *
406  * It is the platform developer's responsibility to provide an implementation.
407  *
408  * The implementation can be provided as a global symbol, an inline function
409  * or a function-like macro, as described above.
410  */
411 void gpio_hal_arch_write_pin(gpio_hal_pin_t pin, uint8_t value);
412 #endif
413 /*---------------------------------------------------------------------------*/
414 #ifndef gpio_hal_arch_set_pins
415 /**
416  * \brief Set multiple pins to logical high
417  * \param pins An ORd pin mask of the pins to set
418  *
419  * A pin will be set to logical high if its position in \e pins is set. For
420  * example you can set pins 0 and 3 by passing 0x09.
421  *
422  * It is the platform developer's responsibility to provide an implementation.
423  *
424  * The implementation can be provided as a global symbol, an inline function
425  * or a function-like macro, as described above.
426  */
428 #endif
429 /*---------------------------------------------------------------------------*/
430 #ifndef gpio_hal_arch_clear_pins
431 /**
432  * \brief Clear multiple pins to logical low
433  * \param pins An ORd pin mask of the pins to clear
434  *
435  * A pin will be set to logical low if its position in \e pins is set. For
436  * example you can clear pins 0 and 3 by passing 0x09.
437  *
438  * It is the platform developer's responsibility to provide an implementation.
439  *
440  * The implementation can be provided as a global symbol, an inline function
441  * or a function-like macro, as described above.
442  */
444 #endif
445 /*---------------------------------------------------------------------------*/
446 #ifndef gpio_hal_arch_toggle_pins
447 /**
448  * \brief Toggle multiple pins
449  * \param pins An ORd pin mask of the pins to toggle
450  *
451  * A pin will be toggled if its position in \e pins is set. For example you
452  * can toggle pins 0 and 3 by passing 0x09.
453  *
454  * Some MCUs allow GPIO pin toggling directly via register access. In this
455  * case, it is a good idea to provide an implementation of this function.
456  * However, a default, software-based implementation is also provided by the
457  * HAL and can be used if the MCU does not have a pin toggle register. To use
458  * the HAL function, define GPIO_HAL_ARCH_SW_TOGGLE as 1. To provide your own
459  * implementation, define GPIO_HAL_ARCH_SW_TOGGLE as 0.
460  *
461  * The implementation can be provided as a global symbol, an inline function
462  * or a function-like macro, as described above.
463  */
465 #endif
466 /*---------------------------------------------------------------------------*/
467 #ifndef gpio_hal_arch_read_pins
468 /**
469  * \brief Read multiple pins
470  * \param pins An ORd pin mask of the pins to read
471  * \retval An ORd mask of the pins that are high
472  *
473  * If the position of the pin in \e pins is set and the pin is logical high
474  * then the position of the pin in the return value will be set. For example,
475  * if you pass 0x09 as the value of \e pins and the return value is 0x08 then
476  * pin 3 is logical high and pin 0 is logical low.
477  *
478  * It is the platform developer's responsibility to provide an implementation.
479  *
480  * The implementation can be provided as a global symbol, an inline function
481  * or a function-like macro, as described above.
482  */
484 #endif
485 /*---------------------------------------------------------------------------*/
486 #ifndef gpio_hal_arch_write_pins
487 /**
488  * \brief Write multiple pins
489  * \param pins An ORd pin mask of the pins to write
490  * \param value An ORd mask of the value to write
491  *
492  * The function will modify GPIO pins that have their position in the mask set.
493  * pins, the function will write the value specified in the corresponding
494  * position in \e value.
495 
496  * For example, you can set pin 3 and clear pin 0 by a single call to this
497  * function. To achieve this, \e pins must be 0x09 and \e value 0x08.
498  *
499  * It is the platform developer's responsibility to provide an implementation.
500  *
501  * There is no guarantee that this function will result in an atomic operation.
502  *
503  * The implementation can be provided as a global symbol, an inline function
504  * or a function-like macro, as described above.
505  */
507  gpio_hal_pin_mask_t value);
508 #endif
509 /** @} */
510 /*---------------------------------------------------------------------------*/
511 #endif /* GPIO_HAL_H_ */
512 /*---------------------------------------------------------------------------*/
513 /**
514  * @}
515  * @}
516  */
Datatype for GPIO event handlers.
Definition: gpio-hal.h:129
void gpio_hal_arch_init(void)
Perform architecture specific gpio initaliaztion.
Definition: gpio-hal-arch.c:46
void gpio_hal_arch_interrupt_disable(gpio_hal_pin_t pin)
Disable interrupts for a gpio pin.
Definition: gpio-hal-arch.c:63
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:98
void gpio_hal_arch_interrupt_enable(gpio_hal_pin_t pin)
Enable interrupts for a gpio pin.
Definition: gpio-hal-arch.c:52
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
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.
uint32_t gpio_hal_pin_cfg_t
GPIO pin configuration.
Definition: gpio-hal.h:85
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