gpio_ll_arch.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2021 Gunar Schorcht
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
9 #pragma once
10 
23 #include "gpio_arch.h"
24 #include "irq.h"
25 #include "soc/gpio_reg.h"
26 #include "soc/soc.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #ifndef DOXYGEN /* hide implementation specific details from Doxygen */
33 
34 static inline gpio_port_t gpio_port(uword_t num)
35 {
36  return num;
37 }
38 
39 static inline uword_t gpio_port_num(gpio_port_t port)
40 {
41  if (GPIO_PORT_NUMOF == 1) {
42  return 0;
43  }
44 
45  return port;
46 }
47 
48 static inline uword_t gpio_ll_read(gpio_port_t port)
49 {
50  static_assert(GPIO_PORT_NUMOF < 3);
51  volatile uword_t *in = (uint32_t *)GPIO_IN_REG;
52  /* return 0 for unconfigured pins, the current level at the pin otherwise */
53 #if GPIO_PORT_NUM > 1
54  if (gpio_port_num(port) != 0) {
55  in = (uint32_t *)GPIO_IN1_REG;
56  }
57 #endif
58 
59  return *in;
60 }
61 
62 static inline uword_t gpio_ll_read_output(gpio_port_t port)
63 {
64  static_assert(GPIO_PORT_NUMOF < 3);
65  volatile uword_t *out = (uint32_t *)GPIO_OUT_REG;
66 #if GPIO_PORT_NUM > 1
67  if (gpio_port_num(port) != 0) {
68  out = (uint32_t *)GPIO_OUT1_REG;
69  }
70 #endif
71 
72  return *out;
73 }
74 
75 static inline void gpio_ll_set(gpio_port_t port, uword_t mask)
76 {
77  static_assert(GPIO_PORT_NUMOF < 3);
78  volatile uword_t *out_w1ts = (uint32_t *)GPIO_OUT_W1TS_REG;
79  if (gpio_port_num(port) != 0) {
80 #if GPIO_PORT_NUM > 1
81  out_w1ts = (uint32_t)GPIO_OUT1_W1TS;
82 #endif
83  }
84 
85  *out_w1ts = mask;
86 }
87 
88 static inline void gpio_ll_clear(gpio_port_t port, uword_t mask)
89 {
90  static_assert(GPIO_PORT_NUMOF < 3);
91  volatile uword_t *out_w1tc = (uint32_t *)GPIO_OUT_W1TC_REG;
92  if (gpio_port_num(port) != 0) {
93 #if GPIO_PORT_NUM > 1
94  out_w1tc = (uint32_t)GPIO_OUT1_W1TC;
95 #endif
96  }
97 
98  *out_w1tc = mask;
99 }
100 
101 static inline void gpio_ll_toggle(gpio_port_t port, uword_t mask)
102 {
103  static_assert(GPIO_PORT_NUMOF < 3);
104  volatile uword_t *out = (uint32_t *)GPIO_OUT_REG;
105 #if GPIO_PORT_NUM > 1
106  if (gpio_port_num(port) != 0) {
107  out = (uint32_t *)GPIO_OUT1_REG;
108  }
109 #endif
110  unsigned irq_state = irq_disable();
111  *out ^= mask;
112  irq_restore(irq_state);
113 }
114 
115 static inline void gpio_ll_write(gpio_port_t port, uword_t value)
116 {
117  static_assert(GPIO_PORT_NUMOF < 3);
118  volatile uword_t *out = (uint32_t *)GPIO_OUT_REG;
119 #if GPIO_PORT_NUM > 1
120  if (gpio_port_num(port) != 0) {
121  out = (uint32_t *)GPIO_OUT1_REG;
122  }
123 #endif
124  *out = value;
125 }
126 
127 static inline gpio_port_t gpio_get_port(gpio_t pin)
128 {
129  return gpio_port(pin >> 5);
130 }
131 
132 static inline uint8_t gpio_get_pin_num(gpio_t pin)
133 {
134  return pin & 0x1f;
135 }
136 
137 static inline gpio_port_t gpio_port_pack_addr(void *addr)
138 {
139  return (gpio_port_t)addr;
140 }
141 
142 static inline void * gpio_port_unpack_addr(gpio_port_t port)
143 {
144  if (port <= 1) {
145  return NULL;
146  }
147 
148  return (void *)port;
149 }
150 
151 static inline bool is_gpio_port_num_valid(uint_fast8_t num)
152 {
153  return (num < GPIO_PORT_NUMOF);
154 }
155 
156 #endif /* DOXYGEN */
157 
158 #ifdef __cplusplus
159 }
160 #endif
#define static_assert(cond,...)
static_assert for c-version < c11
Definition: assert.h:153
Architecture specific GPIO functions for ESP8266.
MAYBE_INLINE void irq_restore(unsigned state)
This function restores the IRQ disable bit in the status register to the value contained within passe...
MAYBE_INLINE unsigned irq_disable(void)
This function sets the IRQ disable bit in the status register.
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_port_t gpio_port(uword_t num)
Get the gpio_port_t value of the port number num.
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
uword_t gpio_port_num(gpio_port_t port)
Get the number of the GPIO port port refers to.
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:95
uint< NUM > _t uword_t
Word sized unsigned integer.
Definition: architecture.h:69
IRQ driver interface.