6
6
7
7
#include < Arduino.h>
8
8
9
+ #define GPIO_MODE_MASK (GPIO_INPUT | GPIO_OUTPUT | GPIO_ACTIVE_LOW | GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN | GPIO_PULL_UP)
10
+ #define LISTIFY_MAX 256
11
+
12
+ /*
13
+ * Calculate GPIO ports/pins number statically from devicetree configuration
14
+ */
15
+
16
+ #define dN_gpios (N ) _CONCAT(_CONCAT(d, N), _gpios)
17
+ #define GPIO_ELEM (n,_ ) COND_CODE_1( DT_NODE_HAS_PROP(DT_PATH(zephyr_user), dN_gpios(n)), \
18
+ (DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX( DT_PATH(zephyr_user), dN_gpios(n), 0 )),), ())
19
+
20
+ #define GPIO_NGPIOS (n,_ ) COND_CODE_1( DT_NODE_HAS_PROP(DT_PATH(zephyr_user), dN_gpios(n)), \
21
+ (DT_PROP(DT_GPIO_CTLR_BY_IDX( DT_PATH(zephyr_user), dN_gpios(n), 0 ), ngpios),), ())
22
+
23
+ namespace {
24
+
25
+ template <class First >
26
+ constexpr int count_ngpios (const int sum, const First&) { return sum; }
27
+
28
+ template <class First , class Second , class ... Rest>
29
+ constexpr int count_ngpios (const int max, const First& first, const Second& second, const Rest&... rest)
30
+ {
31
+ return count_ngpios (first == second ? first.ngpios : second, second, rest...);
32
+ }
33
+
34
+ template <class First >
35
+ constexpr int count_groups (const int sum, const First&) { return sum; }
36
+
37
+ template <class First , class Second , class ... Rest>
38
+ constexpr int count_groups (const int sum, const First& first, const Second& second, const Rest&... rest)
39
+ {
40
+ return count_groups (first == second ? sum : sum + 1 , second, rest...);
41
+ }
42
+
43
+ template <class First >
44
+ constexpr int max_in_list (const int max, const First&) { return max; }
45
+
46
+ template <class First , class Second , class ... Rest>
47
+ constexpr int max_in_list (const int max, const First& first, const Second& second, const Rest&... rest)
48
+ {
49
+ return max_in_list (first >= second ? first : second, second, rest...);
50
+ }
51
+
52
+ const int port_num = count_groups(0 , LISTIFY(LISTIFY_MAX, GPIO_ELEM, ()) nullptr );
53
+ const int max_ngpios = max_in_list(0 , LISTIFY(LISTIFY_MAX, GPIO_NGPIOS, ()) 0 );
54
+
55
+ /*
56
+ * GPIO callback implementation
57
+ */
58
+
59
+ struct gpio_port_callback {
60
+ struct gpio_callback callback;
61
+ voidFuncPtr handlers[max_ngpios];
62
+ gpio_port_pins_t pins;
63
+ const struct device * dev;
64
+ } w_callback[port_num] = {0 };
65
+
66
+ struct gpio_port_callback * find_gpio_port_callback (const struct device * dev)
67
+ {
68
+ for (size_t i=0 ; i<ARRAY_SIZE (w_callback); i++) {
69
+ if (w_callback[i].dev == dev) {
70
+ return &w_callback[i];
71
+ }
72
+ if (w_callback[i].dev == nullptr ) {
73
+ w_callback[i].dev = dev;
74
+ return &w_callback[i];
75
+ }
76
+ }
77
+
78
+ return nullptr ;
79
+ }
80
+
81
+ void setInterruptHandler (pin_size_t pinNumber, voidFuncPtr func)
82
+ {
83
+ struct gpio_port_callback * pcb = find_gpio_port_callback (arduino_pins[pinNumber]->port );
84
+
85
+ if (pcb) {
86
+ pcb->handlers [BIT (arduino_pins[pinNumber]->pin )] = func;
87
+ }
88
+ }
89
+
90
+ void gpioCallback (const struct device *port, struct gpio_callback *cb, uint32_t pins)
91
+ {
92
+ struct gpio_port_callback * pcb = (struct gpio_port_callback *)cb;
93
+
94
+ for (uint32_t i=0 ; i<max_ngpios; i++) {
95
+ if (pins & BIT (i)) {
96
+ pcb->handlers [BIT (i)]();
97
+ }
98
+ }
99
+ }
100
+
101
+ void pinModeImpl (pin_size_t pinNumber, gpio_flags_t pinmode, voidFuncPtr callback, gpio_flags_t intmode)
102
+ {
103
+ gpio_pin_configure_dt (arduino_pins[pinNumber], pinmode);
104
+
105
+ if (callback) {
106
+ struct gpio_port_callback * pcb = find_gpio_port_callback (arduino_pins[pinNumber]->port );
107
+ __ASSERT (pcb != nullptr , " " );
108
+
109
+ pcb->pins |= BIT (arduino_pins[pinNumber]->pin );
110
+ setInterruptHandler (pinNumber, callback);
111
+
112
+ gpio_pin_interrupt_configure_dt (arduino_pins[pinNumber], intmode);
113
+ gpio_init_callback (&pcb->callback , gpioCallback, pcb->pins );
114
+ gpio_add_callback (arduino_pins[pinNumber]->port , &pcb->callback );
115
+ }
116
+ }
117
+
118
+ gpio_flags_t pinMode2flags (PinMode pinMode) {
119
+ if (pinMode == INPUT) {
120
+ return (GPIO_INPUT | GPIO_ACTIVE_HIGH);
121
+ } else if (pinMode == INPUT_PULLUP) {
122
+ return (GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_HIGH);
123
+ } else if (pinMode == INPUT_PULLDOWN) {
124
+ return (GPIO_INPUT | GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH);
125
+ } else if (pinMode == OUTPUT) {
126
+ return (GPIO_OUTPUT_LOW | GPIO_ACTIVE_HIGH);
127
+ } else {
128
+ __ASSERT (false , " Not supported PinStatus" );
129
+ return 0 ;
130
+ }
131
+ }
132
+
133
+ gpio_flags_t pinStatus2flags (PinStatus status) {
134
+ if (status == LOW) {
135
+ return GPIO_INT_LEVEL_LOW;
136
+ }
137
+ else if (status == HIGH) {
138
+ return GPIO_INT_LEVEL_HIGH;
139
+ }
140
+ else if (status == CHANGE) {
141
+ return GPIO_INT_EDGE_BOTH;
142
+ }
143
+ else if (status == FALLING) {
144
+ return GPIO_INT_EDGE_FALLING;
145
+ }
146
+ else if (status == RISING) {
147
+ return GPIO_INT_EDGE_RISING;
148
+ } else {
149
+ __ASSERT (false , " Not supported OUTPUT_OPENDRAIN" );
150
+ return 0 ;
151
+ }
152
+ }
153
+
154
+ } // anonymous namespace
155
+
156
+
157
+ /*
158
+ * APIs
159
+ */
160
+
9
161
void yield (void ) {
10
162
k_yield ();
11
163
}
@@ -16,19 +168,14 @@ void yield(void) {
16
168
* A high physical level will be interpreted as value 1
17
169
*/
18
170
void pinMode (pin_size_t pinNumber, PinMode pinMode) {
19
- if (pinMode == INPUT) { // input mode
20
- gpio_pin_configure_dt (arduino_pins[pinNumber],
21
- GPIO_INPUT | GPIO_ACTIVE_HIGH);
22
- } else if (pinMode == INPUT_PULLUP) { // input with internal pull-up
23
- gpio_pin_configure_dt (arduino_pins[pinNumber],
24
- GPIO_INPUT | GPIO_PULL_UP | GPIO_ACTIVE_HIGH);
25
- } else if (pinMode == INPUT_PULLDOWN) { // input with internal pull-down
26
- gpio_pin_configure_dt (arduino_pins[pinNumber],
27
- GPIO_INPUT | GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH);
28
- } else if (pinMode == OUTPUT) { // output mode
29
- gpio_pin_configure_dt (arduino_pins[pinNumber],
30
- GPIO_OUTPUT_LOW | GPIO_ACTIVE_HIGH);
31
- }
171
+ gpio_flags_t pinstatus = 0 ;
172
+
173
+ #ifdef CONFIG_GPIO_GET_CONFIG
174
+ /* preserve GPIO interrupt configuration */
175
+ gpio_pin_get_config_dt (arduino_pins[pinNumber], &pinstatus);
176
+ #endif
177
+
178
+ pinModeImpl (pinNumber, pinMode2flags (pinMode), nullptr , (pinstatus & ~GPIO_MODE_MASK));
32
179
}
33
180
34
181
void digitalWrite (pin_size_t pinNumber, PinStatus status) {
@@ -39,6 +186,22 @@ PinStatus digitalRead(pin_size_t pinNumber) {
39
186
return (gpio_pin_get_dt (arduino_pins[pinNumber]) == 1 ) ? HIGH : LOW;
40
187
}
41
188
189
+ #ifdef CONFIG_GPIO_GET_CONFIG
190
+ void attachInterrupt (pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinStatus)
191
+ {
192
+ gpio_flags_t pinmode = 0 ;
193
+
194
+ /* preserve GPIO configuration that configured by pinMode()*/
195
+ gpio_pin_get_config_dt (arduino_pins[pinNumber], &pinmode);
196
+ pinModeImpl (pinNumber, (pinmode & ~GPIO_INT_MASK), callback, pinStatus2flags (pinStatus));
197
+ }
198
+
199
+ void detachInterrupt (pin_size_t pinNumber)
200
+ {
201
+ setInterruptHandler (pinNumber, nullptr );
202
+ }
203
+ #endif
204
+
42
205
void delay (unsigned long ms) { k_sleep (K_MSEC (ms)); }
43
206
44
207
void delayMicroseconds (unsigned int us) { k_sleep (K_USEC (us)); }
0 commit comments