Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ff7e729

Browse files
committed
Fix custom pin in use logic for SWD
This should allow you to use SWD pins unless a debugger is attached. You may have trouble connecting to SWD when CircuitPython has already begun using them. Fixes adafruit#1633
1 parent 74083da commit ff7e729

File tree

1 file changed

+35
-11
lines changed
  • ports/atmel-samd/common-hal/microcontroller

1 file changed

+35
-11
lines changed

ports/atmel-samd/common-hal/microcontroller/Pin.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,25 @@ bool speaker_enable_in_use;
4545

4646
#define PORT_COUNT (PORT_BITS / 32 + 1)
4747

48+
#ifdef SAMD51
49+
#define SWD_MUX GPIO_PIN_FUNCTION_H
50+
#endif
51+
#ifdef SAMD21
52+
#define SWD_MUX GPIO_PIN_FUNCTION_G
53+
#endif
54+
4855
STATIC uint32_t never_reset_pins[PORT_COUNT];
4956

5057
void reset_all_pins(void) {
5158
uint32_t pin_mask[PORT_COUNT] = PORT_OUT_IMPLEMENTED;
5259

53-
// Do not full reset USB or SWD lines.
54-
pin_mask[0] &= ~(PORT_PA24 | PORT_PA25 | PORT_PA30 | PORT_PA31);
60+
// Do not full reset USB lines.
61+
pin_mask[0] &= ~(PORT_PA24 | PORT_PA25);
62+
63+
// Do not reset SWD when a debugger is present.
64+
if (DSU->STATUSB.bit.DBGPRES == 1) {
65+
pin_mask[0] &= ~(PORT_PA30 | PORT_PA31);
66+
}
5567

5668
for (uint32_t i = 0; i < PORT_COUNT; i++) {
5769
pin_mask[i] &= ~never_reset_pins[i];
@@ -66,16 +78,14 @@ void reset_all_pins(void) {
6678
gpio_set_port_direction(GPIO_PORTD, pin_mask[3] & ~MICROPY_PORT_D, GPIO_DIRECTION_OFF);
6779
#endif
6880

69-
// Configure SWD
81+
// Configure SWD. SWDIO will be automatically switched on PA31 when a signal is input on
82+
// SWCLK.
7083
#ifdef SAMD51
7184
gpio_set_pin_function(PIN_PA30, MUX_PA30H_CM4_SWCLK);
72-
// SWDIO will be automatically switched on PA31 when a signal is input on
73-
// SWCLK.
7485
#endif
7586
#ifdef SAMD21
76-
//gpio_set_pin_function(PIN_PA30, GPIO_PIN_FUNCTION_G);
77-
//gpio_set_pin_direction(PIN_PA31, GPIO_DIRECTION_OUT);
78-
//gpio_set_pin_function(PIN_PA31, GPIO_PIN_FUNCTION_G);
87+
gpio_set_pin_function(PIN_PA30, GPIO_PIN_FUNCTION_G);
88+
gpio_set_pin_function(PIN_PA31, GPIO_PIN_FUNCTION_G);
7989
#endif
8090

8191
#ifdef MICROPY_HW_NEOPIXEL
@@ -128,12 +138,11 @@ void reset_pin_number(uint8_t pin_number) {
128138
if (pin_number == PIN_PA30
129139
#ifdef SAMD51
130140
) {
131-
gpio_set_pin_function(pin_number, GPIO_PIN_FUNCTION_H);
132141
#endif
133142
#ifdef SAMD21
134143
|| pin_number == PIN_PA31) {
135-
gpio_set_pin_function(pin_number, GPIO_PIN_FUNCTION_G);
136144
#endif
145+
gpio_set_pin_function(pin_number, SWD_MUX);
137146
} else {
138147
gpio_set_pin_direction(pin_number, GPIO_DIRECTION_OFF);
139148
gpio_set_pin_function(pin_number, GPIO_PIN_FUNCTION_OFF);
@@ -178,7 +187,18 @@ bool pin_number_is_free(uint8_t pin_number) {
178187
volatile PORT_PMUX_Type *pmux = &port->PMUX[pin_index / 2];
179188

180189
if (pin_number == PIN_PA30 || pin_number == PIN_PA31) {
181-
return state->bit.PMUXEN == 1 && ((pmux->reg >> (4 * pin_index % 2)) & 0xf) == 0x6;
190+
if (DSU->STATUSB.bit.DBGPRES == 1) {
191+
return false;
192+
}
193+
if (pin_number == PIN_PA30
194+
#ifdef SAMD51
195+
) {
196+
#endif
197+
#ifdef SAMD21
198+
|| pin_number == PIN_PA31) {
199+
#endif) {
200+
return state->bit.PMUXEN == 1 && ((pmux->reg >> (4 * pin_index % 2)) & 0xf) == SWD_MUX;
201+
}
182202
}
183203

184204
return state->bit.PMUXEN == 0 && state->bit.INEN == 0 &&
@@ -188,6 +208,10 @@ bool pin_number_is_free(uint8_t pin_number) {
188208
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
189209
#ifdef MICROPY_HW_NEOPIXEL
190210
if (pin == MICROPY_HW_NEOPIXEL) {
211+
// Special case for Metro M0 where the NeoPixel is also SWCLK
212+
if (MICROPY_HW_NEOPIXEL == &pin_PA30 && DSU->STATUSB.bit.DBGPRES == 1) {
213+
return false;
214+
}
191215
return !neopixel_in_use;
192216
}
193217
#endif

0 commit comments

Comments
 (0)