33
33
#include "components/driver/include/driver/gpio.h"
34
34
#include "components/hal/include/hal/gpio_hal.h"
35
35
36
- STATIC uint64_t never_reset_pins ;
37
- STATIC uint64_t in_use ;
36
+ STATIC uint64_t _never_reset_pin_mask ;
37
+ STATIC uint64_t _preserved_pin_mask ;
38
+ STATIC uint64_t _in_use_pin_mask ;
38
39
39
- // 64-bit pin mask for a single bit
40
- #define PIN_BIT (pin_number ) (((uint64_t)1) << pin_number)
41
-
42
- // Bit mask of all pins that should never ever be reset.
40
+ // Bit mask of all pins that should never EVER be reset.
43
41
// Typically these are SPI flash and PSRAM control pins, and communication pins.
42
+ // "Reset forbidden" is stronger than "never reset" below, which may only be temporary.
44
43
static const uint64_t pin_mask_reset_forbidden =
45
44
#if defined(CONFIG_IDF_TARGET_ESP32 )
46
45
// Never ever reset serial pins for bootloader and possibly USB-serial converter.
@@ -105,7 +104,7 @@ void never_reset_pin_number(gpio_num_t pin_number) {
105
104
if (pin_number == NO_PIN || pin_number == (uint8_t )NO_PIN ) {
106
105
return ;
107
106
}
108
- never_reset_pins |= PIN_BIT (pin_number );
107
+ _never_reset_pin_mask |= PIN_BIT (pin_number );
109
108
}
110
109
111
110
void common_hal_never_reset_pin (const mcu_pin_obj_t * pin ) {
@@ -119,12 +118,29 @@ MP_WEAK bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
119
118
return false;
120
119
}
121
120
121
+ STATIC bool _reset_forbidden (gpio_num_t pin_number ) {
122
+ return pin_mask_reset_forbidden & PIN_BIT (pin_number );
123
+ }
124
+
125
+ STATIC bool _never_reset (gpio_num_t pin_number ) {
126
+ return _never_reset_pin_mask & PIN_BIT (pin_number );
127
+ }
128
+
129
+ STATIC bool _preserved_pin (gpio_num_t pin_number ) {
130
+ return _preserved_pin_mask & PIN_BIT (pin_number );
131
+ }
132
+
122
133
STATIC void _reset_pin (gpio_num_t pin_number ) {
123
134
// Never ever reset pins used for flash, RAM, and basic communication.
124
- if (pin_mask_reset_forbidden & PIN_BIT (pin_number )) {
135
+ if (_reset_forbidden (pin_number )) {
125
136
return ;
126
137
}
127
138
139
+ // Disable any existing hold on this pin,
140
+ if (GPIO_IS_VALID_OUTPUT_GPIO (pin_number )) {
141
+ gpio_hold_dis (pin_number );
142
+ }
143
+
128
144
// Give the board a chance to reset the pin in a particular way.
129
145
if (espressif_board_reset_pin_number (pin_number )) {
130
146
return ;
@@ -152,15 +168,27 @@ STATIC void _reset_pin(gpio_num_t pin_number) {
152
168
}
153
169
}
154
170
171
+ void preserve_pin_number (gpio_num_t pin_number ) {
172
+ if (GPIO_IS_VALID_OUTPUT_GPIO (pin_number )) {
173
+ gpio_hold_en (pin_number );
174
+ _preserved_pin_mask |= PIN_BIT (pin_number );
175
+ }
176
+ }
177
+
178
+ void clear_pin_preservations (void ) {
179
+ _preserved_pin_mask = 0 ;
180
+ }
181
+
182
+
155
183
// Mark pin as free and return it to a quiescent state.
156
184
void reset_pin_number (gpio_num_t pin_number ) {
157
185
// Some CircuitPython APIs deal in uint8_t pin numbers, but NO_PIN is -1.
158
186
// Also allow pin 255 to be treated as NO_PIN to avoid crashes
159
187
if (pin_number == NO_PIN || pin_number == (uint8_t )NO_PIN ) {
160
188
return ;
161
189
}
162
- never_reset_pins &= ~PIN_BIT (pin_number );
163
- in_use &= ~PIN_BIT (pin_number );
190
+ _never_reset_pin_mask &= ~PIN_BIT (pin_number );
191
+ _in_use_pin_mask &= ~PIN_BIT (pin_number );
164
192
165
193
_reset_pin (pin_number );
166
194
}
@@ -177,15 +205,20 @@ void common_hal_reset_pin(const mcu_pin_obj_t *pin) {
177
205
}
178
206
179
207
void reset_all_pins (void ) {
208
+ // Undo deep sleep holds in case we woke up from deep sleep.
209
+ // We still need to unhold individual pins, which is done by _reset_pin.
210
+ gpio_deep_sleep_hold_dis ();
211
+
180
212
for (uint8_t i = 0 ; i < GPIO_PIN_COUNT ; i ++ ) {
181
213
uint32_t iomux_address = GPIO_PIN_MUX_REG [i ];
182
214
if (iomux_address == 0 ||
183
- (never_reset_pins & PIN_BIT (i ))) {
215
+ _never_reset (i ) ||
216
+ _preserved_pin (i )) {
184
217
continue ;
185
218
}
186
219
_reset_pin (i );
187
220
}
188
- in_use = never_reset_pins ;
221
+ _in_use_pin_mask = _never_reset_pin_mask ;
189
222
}
190
223
191
224
void claim_pin_number (gpio_num_t pin_number ) {
@@ -194,7 +227,7 @@ void claim_pin_number(gpio_num_t pin_number) {
194
227
if (pin_number == NO_PIN || pin_number == (uint8_t )NO_PIN ) {
195
228
return ;
196
229
}
197
- in_use |= PIN_BIT (pin_number );
230
+ _in_use_pin_mask |= PIN_BIT (pin_number );
198
231
}
199
232
200
233
void claim_pin (const mcu_pin_obj_t * pin ) {
@@ -206,7 +239,7 @@ void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) {
206
239
}
207
240
208
241
bool pin_number_is_free (gpio_num_t pin_number ) {
209
- return !(in_use & PIN_BIT (pin_number ));
242
+ return !(_in_use_pin_mask & PIN_BIT (pin_number ));
210
243
}
211
244
212
245
bool common_hal_mcu_pin_is_free (const mcu_pin_obj_t * pin ) {
0 commit comments