Loading...
Searching...
No Matches
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
10#pragma once
11
79
80#include <assert.h>
81#include <stdbool.h>
82#include <stdint.h>
83
84#include "architecture.h"
85#include "periph/gpio.h"
86#include "periph_cpu.h"
87
88#ifdef __cplusplus
89extern "C" {
90#endif
91
95typedef uintptr_t gpio_port_t;
96
97#if !defined(GPIO_PORT_UNDEF) || defined(DOXYGEN)
101#define GPIO_PORT_UNDEF UINTPTR_MAX
102#endif
103
104#if defined(DOXYGEN)
114# define GPIO_PORT_NUMBERING_ALPHABETIC implementation_specific
115#endif
116
117#ifdef DOXYGEN
129#define GPIO_PORT_0 implementation_specific
130
144
159#endif /* DOXYGEN */
160
161#if !defined(HAVE_GPIO_STATE_T) || defined(DOXYGEN)
251#endif
252
253#if !defined(HAVE_GPIO_PULL_T) || defined(DOXYGEN)
264#endif
265
266#if !defined(HAVE_GPIO_PULL_STRENGTH_T) || defined(DOXYGEN)
281#endif
282
293#define GPIO_PULL_NUMOF (1U + (GPIO_PULL_WEAKEST != GPIO_PULL_WEAK) \
294 + (GPIO_PULL_WEAK != GPIO_PULL_STRONG) \
295 + (GPIO_PULL_STRONG != GPIO_PULL_STRONGEST))
296
297#if !defined(HAVE_GPIO_DRIVE_STRENGTH_T) || defined(DOXYGEN)
312#endif
313
322#define GPIO_DRIVE_NUMOF (1U + (GPIO_DRIVE_WEAKEST != GPIO_DRIVE_WEAK) \
323 + (GPIO_DRIVE_WEAK != GPIO_DRIVE_STRONG) \
324 + (GPIO_DRIVE_STRONG != GPIO_DRIVE_STRONGEST))
325
326#if !defined(HAVE_GPIO_SLEW_T) || defined(DOXYGEN)
347#endif
348
357#define GPIO_SLEW_NUMOF (1U + (GPIO_SLEW_SLOWEST != GPIO_SLEW_SLOW) \
358 + (GPIO_SLEW_SLOW != GPIO_SLEW_FAST) \
359 + (GPIO_SLEW_FAST != GPIO_SLEW_FASTEST))
360
379 uint8_t bits;
380 struct {
403 uint8_t : 2;
404 };
405};
406
407#if !defined(HAVE_GPIO_CONF_T) && !defined(DOXYGEN)
408typedef union gpio_conf_minimal gpio_conf_t;
409#endif
410
411#ifdef DOXYGEN
423typedef /* implementation specific */ gpio_conf_t;
424#endif
425
426#ifndef __cplusplus
449static const gpio_conf_t gpio_ll_in = {
450 .state = GPIO_INPUT,
451 .pull = GPIO_FLOATING,
452};
453
459 .state = GPIO_INPUT,
460 .pull = GPIO_PULL_DOWN,
461};
462
468 .state = GPIO_INPUT,
469 .pull = GPIO_PULL_UP,
470};
471
483 .state = GPIO_INPUT,
484 .pull = GPIO_PULL_KEEP,
485};
486
492static const gpio_conf_t gpio_ll_out = {
493 .state = GPIO_OUTPUT_PUSH_PULL,
494 .initial_value = false,
495};
496
503static const gpio_conf_t gpio_ll_od = {
504 .state = GPIO_OUTPUT_OPEN_DRAIN,
505 .pull = GPIO_FLOATING,
506 .initial_value = true,
507};
508
517 .state = GPIO_OUTPUT_OPEN_DRAIN,
518 .pull = GPIO_PULL_UP,
519 .initial_value = true,
520};
521
522#endif
523
531static inline bool is_gpio_port_num_valid(uint_fast8_t num);
532
570int gpio_ll_init(gpio_port_t port, uint8_t pin, gpio_conf_t conf);
571
587
597
603
619static inline uword_t gpio_ll_read(gpio_port_t port);
620
637
653static inline void gpio_ll_set(gpio_port_t port, uword_t mask);
654
670static inline void gpio_ll_clear(gpio_port_t port, uword_t mask);
671
687static inline void gpio_ll_toggle(gpio_port_t port, uword_t mask);
688
689#if defined(DOXYGEN) || !defined(HAVE_GPIO_LL_PREPARE_WRITE_ALL_PINS)
713 uword_t value)
714{
715 (void)port;
716 return value;
717}
718#endif
719
720#if defined(DOXYGEN) || !defined(HAVE_GPIO_LL_PREPARE_WRITE)
735 uword_t value)
736{
737 return value | (gpio_ll_read_output(port) & (~mask));
738}
739#endif
740
741#if defined(DOXYGEN) || !defined(HAVE_GPIO_LL_PREPARE_SWITCH_DIR)
751{
752 return mask;
753}
754#endif
755
766static inline void gpio_ll_switch_dir_output(gpio_port_t port, uword_t pins);
767
786static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t pins);
787
829static inline void gpio_ll_write(gpio_port_t port, uword_t state);
830
842static inline gpio_port_t gpio_get_port(gpio_t pin);
843
859static inline uint8_t gpio_get_pin_num(gpio_t pin);
860
872static inline gpio_port_t gpio_port_pack_addr(void *addr);
873
886static inline void * gpio_port_unpack_addr(gpio_port_t port);
887
888#ifndef DOXYGEN
889#if !MODULE_PERIPH_GPIO_LL_SWITCH_DIR
890static inline void gpio_ll_switch_dir_output(gpio_port_t port, uword_t outputs)
891{
892 (void)port;
893 (void)outputs;
894 /* Hack: If this function is only used guarded by some
895 *
896 * if (IS_USED(MODULE_PERIPH_GPIO_LL_SWITCH_DIR)) {
897 * ...
898 * }
899 *
900 * as intended, all calls to the following fake function will be optimized
901 * due to the elimination of dead branches. If used incorrectly, a linking
902 * failure will be the result. The error message will not be ideal, but a
903 * compile time error is much better than a runtime error.
904 */
905 extern void gpio_ll_switch_dir_output_used_but_feature_gpio_ll_switch_dir_is_not_provided(void);
906 gpio_ll_switch_dir_output_used_but_feature_gpio_ll_switch_dir_is_not_provided();
907}
908
909static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t inputs)
910{
911 (void)port;
912 (void)inputs;
913 /* Same hack as above */
914 extern void gpio_ll_switch_dir_input_used_but_feature_gpio_ll_switch_dir_is_not_provided(void);
915 gpio_ll_switch_dir_input_used_but_feature_gpio_ll_switch_dir_is_not_provided();
916}
917
918#endif /* !MODULE_PERIPH_GPIO_LL_SWITCH_DIR */
919#endif /* !DOXYGEN */
920
921#ifdef __cplusplus
922}
923#endif
924
925/* the hardware specific implementation relies on the types such as gpio_port_t
926 * to be provided */
927#include "gpio_ll_arch.h" /* IWYU pragma: export */
928
929#if !defined(DOXYGEN) && !defined(GPIO_PORT_NUMBERING_ALPHABETIC)
930# define GPIO_PORT_NUMBERING_ALPHABETIC 0
931#endif
932
937#if defined(GPIO_PORT_0) || defined(DOXYGEN)
941# define GPIO_PORT_A GPIO_PORT_0
942#endif
943#if defined(GPIO_PORT_1) || defined(DOXYGEN)
947# define GPIO_PORT_B GPIO_PORT_1
948#endif
949#if defined(GPIO_PORT_2) || defined(DOXYGEN)
953# define GPIO_PORT_C GPIO_PORT_2
954#endif
955#if defined(GPIO_PORT_3) || defined(DOXYGEN)
959# define GPIO_PORT_D GPIO_PORT_3
960#endif
961#if defined(GPIO_PORT_4) || defined(DOXYGEN)
965# define GPIO_PORT_E GPIO_PORT_4
966#endif
967#if defined(GPIO_PORT_5) || defined(DOXYGEN)
971# define GPIO_PORT_F GPIO_PORT_5
972#endif
973#if defined(GPIO_PORT_6) || defined(DOXYGEN)
977# define GPIO_PORT_G GPIO_PORT_6
978#endif
979#if defined(GPIO_PORT_7) || defined(DOXYGEN)
983# define GPIO_PORT_H GPIO_PORT_7
984#endif
985#if defined(GPIO_PORT_8) || defined(DOXYGEN)
989# define GPIO_PORT_I GPIO_PORT_8
990#endif
991#if defined(GPIO_PORT_9) || defined(DOXYGEN)
995# define GPIO_PORT_J GPIO_PORT_9
996#endif
997#if defined(GPIO_PORT_10) || defined(DOXYGEN)
1001# define GPIO_PORT_K GPIO_PORT_10
1002#endif
1003#if defined(GPIO_PORT_11) || defined(DOXYGEN)
1007# define GPIO_PORT_L GPIO_PORT_11
1008#endif
1009#if defined(GPIO_PORT_12) || defined(DOXYGEN)
1013# define GPIO_PORT_M GPIO_PORT_12
1014#endif
1015#if defined(GPIO_PORT_13) || defined(DOXYGEN)
1019# define GPIO_PORT_N GPIO_PORT_13
1020#endif
1021#if defined(GPIO_PORT_14) || defined(DOXYGEN)
1025# define GPIO_PORT_O GPIO_PORT_14
1026#endif
1027#if defined(GPIO_PORT_15) || defined(DOXYGEN)
1031# define GPIO_PORT_P GPIO_PORT_15
1032#endif
1034
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:482
static uint8_t gpio_get_pin_num(gpio_t pin)
Extract the pin number from a gpio_t
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:257
gpio_pull_strength_t
Enumeration of pull resistor values.
Definition gpio_ll.h:275
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:458
static const gpio_conf_t gpio_ll_out
A standard configuration for a generic push-pull output pin.
Definition gpio_ll.h:492
gpio_state_t
Enumeration of GPIO states (direction)
Definition gpio_ll.h:165
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:339
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:734
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:306
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:467
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:712
typedef gpio_conf_t
GPIO pin configuration.
Definition gpio_ll.h:423
static const gpio_conf_t gpio_ll_in
A standard configuration for a generic floating input pin.
Definition gpio_ll.h:449
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:750
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:516
static void * gpio_port_unpack_addr(gpio_port_t port)
Extract a data pointer that was packed by gpio_port_pack_addr.
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:503
uintptr_t gpio_port_t
GPIO port type.
Definition gpio_ll.h:95
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:258
@ GPIO_PULL_KEEP
Keep the signal at current logic level with pull up/down resistors.
Definition gpio_ll.h:261
@ GPIO_PULL_DOWN
Pull down resistor enabled.
Definition gpio_ll.h:260
@ GPIO_PULL_UP
Pull up resistor enabled.
Definition gpio_ll.h:259
@ GPIO_PULL_WEAKEST
Use the weakest (highest Ohm value) resistor.
Definition gpio_ll.h:276
@ GPIO_PULL_WEAK
Use a weak pull resistor.
Definition gpio_ll.h:277
@ GPIO_PULL_STRONG
Use a strong pull resistor.
Definition gpio_ll.h:278
@ GPIO_PULL_STRONGEST
Use the strongest pull resistor.
Definition gpio_ll.h:279
@ GPIO_OUTPUT_OPEN_SOURCE
Use pin as output in open emitter configuration.
Definition gpio_ll.h:202
@ GPIO_USED_BY_PERIPHERAL
The GPIO pin is used by a peripheral.
Definition gpio_ll.h:221
@ GPIO_OUTPUT_OPEN_DRAIN
Use pin as output in open collector configuration.
Definition gpio_ll.h:189
@ GPIO_OUTPUT_PUSH_PULL
Use pin as output in push-pull configuration.
Definition gpio_ll.h:176
@ GPIO_DISCONNECT
Disconnect pin from all peripherals.
Definition gpio_ll.h:249
@ GPIO_INPUT
Use pin as input.
Definition gpio_ll.h:208
@ GPIO_SLEW_SLOWEST
let the output voltage level rise/fall as slow as possible
Definition gpio_ll.h:340
@ GPIO_SLEW_FAST
let the output voltage level rise/fall fast
Definition gpio_ll.h:343
@ GPIO_SLEW_SLOW
let the output voltage level rise/fall slowly
Definition gpio_ll.h:342
@ GPIO_SLEW_FASTEST
let the output voltage level rise/fall as fast as possible
Definition gpio_ll.h:344
@ GPIO_DRIVE_STRONG
Use a strong drive strength.
Definition gpio_ll.h:309
@ GPIO_DRIVE_WEAK
Use a weak drive strength.
Definition gpio_ll.h:308
@ GPIO_DRIVE_STRONGEST
Use the strongest drive strength.
Definition gpio_ll.h:310
@ GPIO_DRIVE_WEAKEST
Use the weakest drive strength.
Definition gpio_ll.h:307
uint< NUM > _t uword_t
Word sized unsigned integer.
Public members of gpio_conf_t
Definition gpio_ll.h:378
uint8_t bits
The raw bits of the configuration.
Definition gpio_ll.h:379
gpio_pull_t pull
Pull resistor configuration.
Definition gpio_ll.h:388
bool initial_value
Initial value of the output.
Definition gpio_ll.h:402
gpio_state_t state
State of the pin.
Definition gpio_ll.h:384