Loading...
Searching...
No Matches
gpio_ll_arch.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Freie Universität Berlin
3 * 2017 OTA keys S.A.
4 * 2023 Otto-von-Guericke-Universität Magdeburg
5 *
6 * This file is subject to the terms and conditions of the GNU Lesser
7 * General Public License v2.1. See the file LICENSE in the top level
8 * directory for more details.
9 */
10
22#ifndef GPIO_LL_ARCH_H
23#define GPIO_LL_ARCH_H
24
25#include "architecture.h"
26#include "periph/gpio_ll.h"
27#include "periph_cpu.h"
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#ifndef DOXYGEN /* hide implementation specific details from Doxygen */
34
35/* Provide base address of the GPIO peripheral via APB */
36#if defined(PORT_SEC)
37# define GPIO_APB_BASE PORT_SEC
38#else
39# define GPIO_APB_BASE PORT
40#endif
41
42/* Provide base address of the GPIO peripheral via IOBUS */
43#if defined(PORT_IOBUS_SEC)
44# define GPIO_IOBUS_BASE PORT_IOBUS_SEC
45#elif defined(PORT_IOBUS)
46# define GPIO_IOBUS_BASE PORT_IOBUS
47#else
48# define GPIO_IOBUS_BASE GPIO_APB_BASE /* no IOBUS present, fall back to APB */
49#endif
50
54#define GPIO_PORT(num) ((uintptr_t)&GPIO_IOBUS_BASE->Group[(num)])
55
59#define GPIO_PORT_NUM(port) \
60 (((port) - (uintptr_t)&GPIO_IOBUS_BASE->Group[0]) / sizeof(GPIO_IOBUS_BASE->Group[0]))
61
62static inline PortGroup *sam0_gpio_iobus2ap(PortGroup *iobus)
63{
64 const uintptr_t iobus_base = (uintptr_t)GPIO_IOBUS_BASE;
65 const uintptr_t apb_base = (uintptr_t)GPIO_APB_BASE;
66
67 return (PortGroup *)((uintptr_t)iobus - (iobus_base - apb_base));
68}
69
70static inline uword_t gpio_ll_read(gpio_port_t port)
71{
72 PortGroup *p = (PortGroup *)port;
73 if (!IS_USED(MODULE_PERIPH_GPIO_FAST_READ)) {
74 p = sam0_gpio_iobus2ap(p);
75 }
76 return p->IN.reg;
77}
78
79static inline uword_t gpio_ll_read_output(gpio_port_t port)
80{
81 PortGroup *p = (PortGroup *)port;
82 return p->OUT.reg;
83}
84
85static inline void gpio_ll_set(gpio_port_t port, uword_t mask)
86{
87 PortGroup *p = (PortGroup *)port;
88 p->OUTSET.reg = mask;
89}
90
91static inline void gpio_ll_clear(gpio_port_t port, uword_t mask)
92{
93 PortGroup *p = (PortGroup *)port;
94 p->OUTCLR.reg = mask;
95}
96
97static inline void gpio_ll_toggle(gpio_port_t port, uword_t mask)
98{
99 PortGroup *p = (PortGroup *)port;
100 p->OUTTGL.reg = mask;
101}
102
103static inline void gpio_ll_write(gpio_port_t port, uword_t mask)
104{
105 PortGroup *p = (PortGroup *)port;
106 p->OUT.reg = mask;
107}
108
109static inline void gpio_ll_switch_dir_output(gpio_port_t port, uword_t outputs)
110{
111 PortGroup *p = (PortGroup *)port;
112 p->DIRSET.reg = outputs;
113}
114
115static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t inputs)
116{
117 PortGroup *p = (PortGroup *)port;
118 p->DIRCLR.reg = inputs;
119}
120
121static inline gpio_port_t gpio_get_port(gpio_t pin)
122{
123 return (gpio_port_t)(pin & ~(0x1f));
124}
125
126static inline uint8_t gpio_get_pin_num(gpio_t pin)
127{
128 return pin & 0x1f;
129}
130
131static inline gpio_port_t gpio_port_pack_addr(void *addr)
132{
133 return (gpio_port_t)addr;
134}
135
136static inline void * gpio_port_unpack_addr(gpio_port_t port)
137{
138 if (port < GPIO_PORT(0)) {
139 return (void *)port;
140 }
141 if (port > GPIO_PORT(ARRAY_SIZE(GPIO_IOBUS_BASE->Group))) {
142 return (void *)port;
143 }
144
145 return NULL;
146}
147
148static inline bool is_gpio_port_num_valid(uint_fast8_t num)
149{
150 return (num < ARRAY_SIZE(GPIO_IOBUS_BASE->Group));
151}
152
153#endif /* DOXYGEN */
154#ifdef __cplusplus
155}
156#endif
157
158#endif /* GPIO_LL_ARCH_H */
Platform-independent access to architecture details.
#define ARRAY_SIZE(a)
Calculate the number of elements in a static array.
Definition container.h:83
Peripheral GPIO Low-Level API.
static uint8_t gpio_get_pin_num(gpio_t pin)
Extract the pin number from a gpio_t
static void gpio_ll_switch_dir_output(gpio_port_t port, uword_t outputs)
Turn GPIO pins specified by the bitmask outputs to outputs.
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.
static void gpio_ll_switch_dir_input(gpio_port_t port, uword_t inputs)
Turn GPIO pins specified by the bitmask inputs to inputs.
static gpio_port_t gpio_port_pack_addr(void *addr)
Pack a pointer into a gpio_port_t.
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 void * gpio_port_unpack_addr(gpio_port_t port)
Extract a data pointer that was packed by gpio_port_pack_addr.
#define GPIO_PORT(num)
Get the gpio_port_t value of the port identified by num.
Definition gpio_ll.h:106
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.
uintptr_t gpio_port_t
GPIO port type.
Definition gpio_ll.h:87
uint< NUM > _t uword_t
Word sized unsigned integer.
#define IS_USED(module)
Checks whether a module is being used or not.
Definition modules.h:71