gpio_ll.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Gunar Schorcht
3  * 2021 Otto-von-Guericke-Universität Magdeburg
4  *
5  * This file is subject to the terms and conditions of the GNU Lesser
6  * General Public License v2.1. See the file LICENSE in the top level
7  * directory for more details.
8  */
9 
69 #ifndef PERIPH_GPIO_LL_H
70 #define PERIPH_GPIO_LL_H
71 
72 #include <assert.h>
73 #include <stdbool.h>
74 #include <stdint.h>
75 
76 #include "architecture.h"
77 #include "periph/gpio.h"
78 #include "periph_cpu.h"
79 
80 #ifdef __cplusplus
81 extern "C" {
82 #endif
83 
87 typedef uintptr_t gpio_port_t;
88 
89 #if !defined(GPIO_PORT_UNDEF) || defined(DOXYGEN)
93 #define GPIO_PORT_UNDEF UINTPTR_MAX
94 #endif
95 
96 #if defined(DOXYGEN)
106 # define GPIO_PORT_NUMBERING_ALPHABETIC implementation_specific
107 #endif
108 
109 
110 #ifdef DOXYGEN
122 #define GPIO_PORT_0 implementation_specific
123 
137 
152 #endif /* DOXYGEN */
153 
154 #if !defined(HAVE_GPIO_STATE_T) || defined(DOXYGEN)
158 typedef enum {
243 } gpio_state_t;
244 #endif
245 
246 #if !defined(HAVE_GPIO_PULL_T) || defined(DOXYGEN)
250 typedef enum {
256 } gpio_pull_t;
257 #endif
258 
259 #if !defined(HAVE_GPIO_PULL_STRENGTH_T) || defined(DOXYGEN)
268 typedef enum {
274 #endif
275 
286 #define GPIO_PULL_NUMOF (1U + (GPIO_PULL_WEAKEST != GPIO_PULL_WEAK) \
287  + (GPIO_PULL_WEAK != GPIO_PULL_STRONG) \
288  + (GPIO_PULL_STRONG != GPIO_PULL_STRONGEST))
289 
290 #if !defined(HAVE_GPIO_DRIVE_STRENGTH_T) || defined(DOXYGEN)
299 typedef enum {
305 #endif
306 
315 #define GPIO_DRIVE_NUMOF (1U + (GPIO_DRIVE_WEAKEST != GPIO_DRIVE_WEAK) \
316  + (GPIO_DRIVE_WEAK != GPIO_DRIVE_STRONG) \
317  + (GPIO_DRIVE_STRONG != GPIO_DRIVE_STRONGEST))
318 
319 #if !defined(HAVE_GPIO_SLEW_T) || defined(DOXYGEN)
332 typedef enum {
339 } gpio_slew_t;
340 #endif
341 
350 #define GPIO_SLEW_NUMOF (1U + (GPIO_SLEW_SLOWEST != GPIO_SLEW_SLOW) \
351  + (GPIO_SLEW_SLOW != GPIO_SLEW_FAST) \
352  + (GPIO_SLEW_FAST != GPIO_SLEW_FASTEST))
353 
372  uint8_t bits;
373  struct {
395  bool initial_value : 1;
396  uint8_t : 2; /*< padding */
397  };
398 };
399 
400 #if !defined(HAVE_GPIO_CONF_T) && !defined(DOXYGEN)
401 typedef union gpio_conf_minimal gpio_conf_t;
402 #endif
403 
404 #ifdef DOXYGEN
416 typedef /* implementation specific */ gpio_conf_t;
417 #endif
418 
419 #ifndef __cplusplus
442 static const gpio_conf_t gpio_ll_in = {
443  .state = GPIO_INPUT,
444  .pull = GPIO_FLOATING,
445 };
446 
451 static const gpio_conf_t gpio_ll_in_pd = {
452  .state = GPIO_INPUT,
453  .pull = GPIO_PULL_DOWN,
454 };
455 
460 static const gpio_conf_t gpio_ll_in_pu = {
461  .state = GPIO_INPUT,
462  .pull = GPIO_PULL_UP,
463 };
464 
475 static const gpio_conf_t gpio_ll_in_pk = {
476  .state = GPIO_INPUT,
477  .pull = GPIO_PULL_KEEP,
478 };
479 
485 static const gpio_conf_t gpio_ll_out = {
486  .state = GPIO_OUTPUT_PUSH_PULL,
487  .initial_value = false,
488 };
489 
496 static const gpio_conf_t gpio_ll_od = {
497  .state = GPIO_OUTPUT_OPEN_DRAIN,
498  .pull = GPIO_FLOATING,
499  .initial_value = true,
500 };
501 
509 static const gpio_conf_t gpio_ll_od_pu = {
510  .state = GPIO_OUTPUT_OPEN_DRAIN,
511  .pull = GPIO_PULL_UP,
512  .initial_value = true,
513 };
515 #endif
516 
524 static inline bool is_gpio_port_num_valid(uint_fast8_t num);
525 
563 int gpio_ll_init(gpio_port_t port, uint8_t pin, gpio_conf_t conf);
564 
580 
590 
596 
612 static inline uword_t gpio_ll_read(gpio_port_t port);
613 
630 
646 static inline void gpio_ll_set(gpio_port_t port, uword_t mask);
647 
663 static inline void gpio_ll_clear(gpio_port_t port, uword_t mask);
664 
680 static inline void gpio_ll_toggle(gpio_port_t port, uword_t mask);
681 
682 #if defined(DOXYGEN) || !defined(HAVE_GPIO_LL_PREPARE_WRITE_ALL_PINS)
706  uword_t value)
707 {
708  (void)port;
709  return value;
710 }
711 #endif
712 
713 #if defined(DOXYGEN) || !defined(HAVE_GPIO_LL_PREPARE_WRITE)
728  uword_t value)
729 {
730  return value | (gpio_ll_read_output(port) & (~mask));
731 }
732 #endif
733 
734 #if defined(DOXYGEN) || !defined(HAVE_GPIO_LL_PREPARE_SWITCH_DIR)
744 {
745  return mask;
746 }
747 #endif
748 
759 static inline void gpio_ll_switch_dir_output(gpio_port_t port, uword_t pins);
760 
779 static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t pins);
780 
822 static inline void gpio_ll_write(gpio_port_t port, uword_t state);
823 
827 static inline gpio_port_t gpio_get_port(gpio_t pin);
828 
832 static inline uint8_t gpio_get_pin_num(gpio_t pin);
833 
845 static inline gpio_port_t gpio_port_pack_addr(void *addr);
846 
859 static inline void * gpio_port_unpack_addr(gpio_port_t port);
860 
861 #ifndef DOXYGEN
862 #if !MODULE_PERIPH_GPIO_LL_SWITCH_DIR
863 static inline void gpio_ll_switch_dir_output(gpio_port_t port, uword_t outputs)
864 {
865  (void)port;
866  (void)outputs;
867  /* Hack: If this function is only used guarded by some
868  *
869  * if (IS_USED(MODULE_PERIPH_GPIO_LL_SWITCH_DIR)) {
870  * ...
871  * }
872  *
873  * as intended, all calls to the following fake function will be optimized
874  * due to the elimination of dead branches. If used incorrectly, a linking
875  * failure will be the result. The error message will not be ideal, but a
876  * compile time error is much better than a runtime error.
877  */
878  extern void gpio_ll_switch_dir_output_used_but_feature_gpio_ll_switch_dir_is_not_provided(void);
879  gpio_ll_switch_dir_output_used_but_feature_gpio_ll_switch_dir_is_not_provided();
880 }
881 
882 static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t inputs)
883 {
884  (void)port;
885  (void)inputs;
886  /* Same hack as above */
887  extern void gpio_ll_switch_dir_input_used_but_feature_gpio_ll_switch_dir_is_not_provided(void);
888  gpio_ll_switch_dir_input_used_but_feature_gpio_ll_switch_dir_is_not_provided();
889 }
890 
891 #endif /* !MODULE_PERIPH_GPIO_LL_SWITCH_DIR */
892 #endif /* !DOXYGEN */
893 
894 #ifdef __cplusplus
895 }
896 #endif
897 
898 /* the hardware specific implementation relies on the types such as gpio_port_t
899  * to be provided */
900 #include "gpio_ll_arch.h" /* IWYU pragma: export */
901 
902 #if !defined(DOXYGEN) && !defined(GPIO_PORT_NUMBERING_ALPHABETIC)
903 # define GPIO_PORT_NUMBERING_ALPHABETIC 0
904 #endif
905 
910 #if defined(GPIO_PORT_0) || defined(DOXYGEN)
914 # define GPIO_PORT_A GPIO_PORT_0
915 #endif
916 #if defined(GPIO_PORT_1) || defined(DOXYGEN)
920 # define GPIO_PORT_B GPIO_PORT_1
921 #endif
922 #if defined(GPIO_PORT_2) || defined(DOXYGEN)
926 # define GPIO_PORT_C GPIO_PORT_2
927 #endif
928 #if defined(GPIO_PORT_3) || defined(DOXYGEN)
932 # define GPIO_PORT_D GPIO_PORT_3
933 #endif
934 #if defined(GPIO_PORT_4) || defined(DOXYGEN)
938 # define GPIO_PORT_E GPIO_PORT_4
939 #endif
940 #if defined(GPIO_PORT_5) || defined(DOXYGEN)
944 # define GPIO_PORT_F GPIO_PORT_5
945 #endif
946 #if defined(GPIO_PORT_6) || defined(DOXYGEN)
950 # define GPIO_PORT_G GPIO_PORT_6
951 #endif
952 #if defined(GPIO_PORT_7) || defined(DOXYGEN)
956 # define GPIO_PORT_H GPIO_PORT_7
957 #endif
958 #if defined(GPIO_PORT_8) || defined(DOXYGEN)
962 # define GPIO_PORT_I GPIO_PORT_8
963 #endif
964 #if defined(GPIO_PORT_9) || defined(DOXYGEN)
968 # define GPIO_PORT_J GPIO_PORT_9
969 #endif
970 #if defined(GPIO_PORT_10) || defined(DOXYGEN)
974 # define GPIO_PORT_K GPIO_PORT_10
975 #endif
976 #if defined(GPIO_PORT_11) || defined(DOXYGEN)
980 # define GPIO_PORT_L GPIO_PORT_11
981 #endif
982 #if defined(GPIO_PORT_12) || defined(DOXYGEN)
986 # define GPIO_PORT_M GPIO_PORT_12
987 #endif
988 #if defined(GPIO_PORT_13) || defined(DOXYGEN)
992 # define GPIO_PORT_N GPIO_PORT_13
993 #endif
994 #if defined(GPIO_PORT_14) || defined(DOXYGEN)
998 # define GPIO_PORT_O GPIO_PORT_14
999 #endif
1000 #if defined(GPIO_PORT_15) || defined(DOXYGEN)
1004 # define GPIO_PORT_P GPIO_PORT_15
1005 #endif
1008 #endif /* PERIPH_GPIO_LL_H */
Platform-independent access to architecture details.
POSIX.1-2008 compliant version of the assert macro.
Low-level GPIO peripheral driver interface definitions.
static const gpio_conf_t gpio_ll_in_pk
A standard configuration for a generic input pin with pull resistor to keep signal at bus level.
Definition: gpio_ll.h:475
static uint8_t gpio_get_pin_num(gpio_t pin)
Extract the pin number from a gpio_t
static void * gpio_port_unpack_addr(gpio_port_t port)
Extract a data pointer that was packed by gpio_port_pack_addr.
static void gpio_ll_set(gpio_port_t port, uword_t mask)
Perform an reg |= mask operation on the I/O register of the port.
gpio_pull_t
Enumeration of pull resistor configurations.
Definition: gpio_ll.h:250
gpio_pull_strength_t
Enumeration of pull resistor values.
Definition: gpio_ll.h:268
static const gpio_conf_t gpio_ll_in_pd
A standard configuration for a generic input pin with pull down resistor.
Definition: gpio_ll.h:451
static const gpio_conf_t gpio_ll_out
A standard configuration for a generic push-pull output pin.
Definition: gpio_ll.h:485
gpio_state_t
Enumeration of GPIO states (direction)
Definition: gpio_ll.h:158
gpio_port_t gpio_port(uword_t num)
Get the gpio_port_t value of the port number num.
gpio_slew_t
Enumeration of slew rate settings.
Definition: gpio_ll.h:332
int gpio_ll_init(gpio_port_t port, uint8_t pin, gpio_conf_t conf)
Initialize the given GPIO pin as specified.
static uword_t gpio_ll_prepare_write(gpio_port_t port, uword_t mask, uword_t value)
Helper to use gpio_ll_write side-effect free.
Definition: gpio_ll.h:727
static gpio_port_t gpio_port_pack_addr(void *addr)
Pack a pointer into a gpio_port_t.
static void gpio_ll_switch_dir_output(gpio_port_t port, uword_t pins)
Turn GPIO pins specified by pins (obtained from gpio_ll_prepare_switch_dir) to outputs.
gpio_conf_t gpio_ll_query_conf(gpio_port_t port, uint8_t pin)
Retrieve the current configuration of a GPIO pin.
void gpio_ll_print_conf_common(const gpio_conf_t conf)
INTERNAL, use gpio_ll_print_conf instead.
gpio_drive_strength_t
Enumeration of drive strength options.
Definition: gpio_ll.h:299
static const gpio_conf_t gpio_ll_in_pu
A standard configuration for a generic input pin with pull up resistor.
Definition: gpio_ll.h:460
static void gpio_ll_switch_dir_input(gpio_port_t port, uword_t pins)
Turn GPIO pins specified by pins (obtained from gpio_ll_prepare_switch_dir) to inputs.
static uword_t gpio_ll_read(gpio_port_t port)
Get the current input value of all GPIO pins of the given port as bitmask.
static gpio_port_t gpio_get_port(gpio_t pin)
Extract the gpio_port_t from a gpio_t
static uword_t gpio_ll_prepare_write_all_outputs(gpio_port_t port, uword_t value)
Same as gpio_ll_prepare_write(port, UWORD_MAX, value), but faster.
Definition: gpio_ll.h:705
typedef gpio_conf_t
GPIO pin configuration.
Definition: gpio_ll.h:416
static const gpio_conf_t gpio_ll_in
A standard configuration for a generic floating input pin.
Definition: gpio_ll.h:442
uword_t gpio_port_num(gpio_port_t port)
Get the number of the GPIO port port refers to.
static uword_t gpio_ll_prepare_switch_dir(uword_t mask)
Prepare bitmask for use with gpio_ll_switch_dir_output and gpio_ll_switch_dir_input.
Definition: gpio_ll.h:743
static const gpio_conf_t gpio_ll_od_pu
A standard configuration for a generic open drain output with pull up.
Definition: gpio_ll.h:509
static bool is_gpio_port_num_valid(uint_fast8_t num)
Check if the given number is a valid argument for gpio_port.
static uword_t gpio_ll_read_output(gpio_port_t port)
Get the current output value of all GPIO pins of the given port as bitmask.
static void gpio_ll_clear(gpio_port_t port, uword_t mask)
Perform an reg &= ~mask operation on the I/O register of the port.
static void gpio_ll_toggle(gpio_port_t port, uword_t mask)
Perform an reg ^= mask operation on the I/O register of the port.
static void gpio_ll_write(gpio_port_t port, uword_t state)
Perform a masked write operation on the I/O register of the port.
static const gpio_conf_t gpio_ll_od
A standard configuration for a generic floating open drain output.
Definition: gpio_ll.h:496
uintptr_t gpio_port_t
GPIO port type.
Definition: gpio_ll.h:87
void gpio_ll_print_conf(const gpio_conf_t conf)
Utility function to print a given GPIO configuration to stdio.
@ GPIO_FLOATING
No pull ups nor pull downs enabled.
Definition: gpio_ll.h:251
@ GPIO_PULL_KEEP
Keep the signal at current logic level with pull up/down resistors.
Definition: gpio_ll.h:254
@ GPIO_PULL_DOWN
Pull down resistor enabled.
Definition: gpio_ll.h:253
@ GPIO_PULL_UP
Pull up resistor enabled.
Definition: gpio_ll.h:252
@ GPIO_PULL_WEAKEST
Use the weakest (highest Ohm value) resistor.
Definition: gpio_ll.h:269
@ GPIO_PULL_WEAK
Use a weak pull resistor.
Definition: gpio_ll.h:270
@ GPIO_PULL_STRONG
Use a strong pull resistor.
Definition: gpio_ll.h:271
@ GPIO_PULL_STRONGEST
Use the strongest pull resistor.
Definition: gpio_ll.h:272
@ GPIO_OUTPUT_OPEN_SOURCE
Use pin as output in open emitter configuration.
Definition: gpio_ll.h:195
@ GPIO_USED_BY_PERIPHERAL
The GPIO pin is used by a peripheral.
Definition: gpio_ll.h:214
@ GPIO_OUTPUT_OPEN_DRAIN
Use pin as output in open collector configuration.
Definition: gpio_ll.h:182
@ GPIO_OUTPUT_PUSH_PULL
Use pin as output in push-pull configuration.
Definition: gpio_ll.h:169
@ GPIO_DISCONNECT
Disconnect pin from all peripherals.
Definition: gpio_ll.h:242
@ GPIO_INPUT
Use pin as input.
Definition: gpio_ll.h:201
@ GPIO_SLEW_SLOWEST
let the output voltage level rise/fall as slow as possible
Definition: gpio_ll.h:333
@ GPIO_SLEW_FAST
let the output voltage level rise/fall fast
Definition: gpio_ll.h:336
@ GPIO_SLEW_SLOW
let the output voltage level rise/fall slowly
Definition: gpio_ll.h:335
@ GPIO_SLEW_FASTEST
let the output voltage level rise/fall as fast as possible
Definition: gpio_ll.h:337
@ GPIO_DRIVE_STRONG
Use a strong drive strength.
Definition: gpio_ll.h:302
@ GPIO_DRIVE_WEAK
Use a weak drive strength.
Definition: gpio_ll.h:301
@ GPIO_DRIVE_STRONGEST
Use the strongest drive strength.
Definition: gpio_ll.h:303
@ GPIO_DRIVE_WEAKEST
Use the weakest drive strength.
Definition: gpio_ll.h:300
uint< NUM > _t uword_t
Word sized unsigned integer.
Definition: architecture.h:70
Public members of gpio_conf_t
Definition: gpio_ll.h:371
uint8_t bits
The raw bits of the configuration.
Definition: gpio_ll.h:372
gpio_pull_t pull
Pull resistor configuration.
Definition: gpio_ll.h:381
bool initial_value
Initial value of the output.
Definition: gpio_ll.h:395
gpio_state_t state
State of the pin.
Definition: gpio_ll.h:377