diff options
| author | Scott Shawcroft <scott.shawcroft@gmail.com> | 2017-05-12 12:55:31 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott.shawcroft@gmail.com> | 2017-05-12 13:14:01 -0700 |
| commit | 7ea76e0889d3f11960056cfca3bde77a3b70c33e (patch) | |
| tree | d01549ae0293395e6560c39721969eecb3464962 | |
| parent | 6984425f5da415ff232bd93c1b3c3cf10f81c1c2 (diff) | |
atmel-samd: Pin reset improvements.
* Reset SWD lines to SWD rather than GPIO. This makes OpenOCD happier.
* Default speaker enable lines to False for CircuitPlayground to prevent
the speaker from buzzing when no sound is playing. Fixes #126
| -rw-r--r-- | atmel-samd/boards/circuitplayground_express/mpconfigboard.h | 2 | ||||
| -rw-r--r-- | atmel-samd/common-hal/microcontroller/Pin.c | 84 | ||||
| -rw-r--r-- | atmel-samd/common-hal/microcontroller/Pin.h | 1 | ||||
| -rw-r--r-- | atmel-samd/main.c | 10 |
4 files changed, 84 insertions, 13 deletions
diff --git a/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 243e50358..c31e7f8eb 100644 --- a/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -30,6 +30,8 @@ #define MICROPY_PORT_A (PORT_PA16 | PORT_PA20 | PORT_PA21 | PORT_PA24 | PORT_PA25) #define MICROPY_PORT_B (PORT_PB22) +#define SPEAKER_ENABLE_PIN (&pin_PA30) + #define AUTORESET_DELAY_MS 500 #include "spi_flash.h" diff --git a/atmel-samd/common-hal/microcontroller/Pin.c b/atmel-samd/common-hal/microcontroller/Pin.c index 3ac3430b2..56d8f8839 100644 --- a/atmel-samd/common-hal/microcontroller/Pin.c +++ b/atmel-samd/common-hal/microcontroller/Pin.c @@ -26,6 +26,8 @@ #include "shared-bindings/microcontroller/Pin.h" +#include "asf/sam0/drivers/port/port.h" + #include "rgb_led_status.h" #include "samd21_pins.h" @@ -36,6 +38,47 @@ bool neopixel_in_use; bool apa102_sck_in_use; bool apa102_mosi_in_use; #endif +#ifdef SPEAKER_ENABLE_PIN +bool speaker_enable_in_use; +#endif + +void reset_all_pins(void) { + struct system_pinmux_config config; + system_pinmux_get_config_defaults(&config); + config.powersave = true; + + uint32_t pin_mask[2] = PORT_OUT_IMPLEMENTED; + + // Do not full reset USB or SWD lines. + pin_mask[0] &= ~(PIN_PA24 | PIN_PA25 | PIN_PA30 | PIN_PA31); + + system_pinmux_group_set_config(&(PORT->Group[0]), pin_mask[0] & ~MICROPY_PORT_A, &config); + system_pinmux_group_set_config(&(PORT->Group[1]), pin_mask[1] & ~MICROPY_PORT_B, &config); + + // Configure SWD + system_pinmux_get_config_defaults(&config); + config.mux_position = 0x6; + system_pinmux_group_set_config(&(PORT->Group[0]), PIN_PA30 | PIN_PA31, &config); + + #ifdef MICROPY_HW_NEOPIXEL + neopixel_in_use = false; + #endif + #ifdef MICROPY_HW_APA102_MOSI + apa102_sck_in_use = false; + apa102_mosi_in_use = false; + #endif + + // After configuring SWD because it may be shared. + #ifdef SPEAKER_ENABLE_PIN + speaker_enable_in_use = false; + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_OUTPUT; + port_pin_set_config(SPEAKER_ENABLE_PIN->pin, &pin_conf); + port_pin_set_output_level(SPEAKER_ENABLE_PIN->pin, false); + #endif +} void reset_pin(uint8_t pin) { if (pin >= PORT_BITS) { @@ -63,8 +106,24 @@ void reset_pin(uint8_t pin) { struct system_pinmux_config config; system_pinmux_get_config_defaults(&config); - config.powersave = true; + if (pin == PIN_PA30 || pin == PIN_PA31) { + config.mux_position = 0x6; + } else { + config.powersave = true; + } system_pinmux_pin_set_config(pin, &config); + + #ifdef SPEAKER_ENABLE_PIN + if (pin == SPEAKER_ENABLE_PIN->pin) { + speaker_enable_in_use = false; + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_OUTPUT; + port_pin_set_config(SPEAKER_ENABLE_PIN->pin, &pin_conf); + port_pin_set_output_level(SPEAKER_ENABLE_PIN->pin, false); + } + #endif } void claim_pin(const mcu_pin_obj_t* pin) { @@ -81,6 +140,12 @@ void claim_pin(const mcu_pin_obj_t* pin) { apa102_sck_in_use = true; } #endif + + #ifdef SPEAKER_ENABLE_PIN + if (pin == SPEAKER_ENABLE_PIN) { + speaker_enable_in_use = true; + } + #endif } bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { @@ -98,10 +163,21 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { } #endif + #ifdef SPEAKER_ENABLE_PIN + if (pin == SPEAKER_ENABLE_PIN) { + return !speaker_enable_in_use; + } + #endif + PortGroup *const port = system_pinmux_get_group_from_gpio_pin(pin->pin); uint32_t pin_index = (pin->pin); - PORT_PINCFG_Type state = port->PINCFG[pin_index]; + volatile PORT_PINCFG_Type *state = &port->PINCFG[pin_index]; + volatile PORT_PMUX_Type *pmux = &port->PMUX[pin_index / 2]; + + if (pin->pin == PIN_PA30 || pin->pin == PIN_PA31) { + return state->bit.PMUXEN == 1 && ((pmux->reg >> (4 * pin_index % 2)) & 0xf) == 0x6; + } - return state.bit.PMUXEN == 0 && state.bit.INEN == 0 && - state.bit.PULLEN == 0 && (port->DIR.reg & (1 << pin_index)) == 0; + return state->bit.PMUXEN == 0 && state->bit.INEN == 0 && + state->bit.PULLEN == 0 && (port->DIR.reg & (1 << pin_index)) == 0; } diff --git a/atmel-samd/common-hal/microcontroller/Pin.h b/atmel-samd/common-hal/microcontroller/Pin.h index 27c998e5c..fdf05885d 100644 --- a/atmel-samd/common-hal/microcontroller/Pin.h +++ b/atmel-samd/common-hal/microcontroller/Pin.h @@ -78,6 +78,7 @@ extern bool apa102_sck_in_use; extern bool apa102_mosi_in_use; #endif +void reset_all_pins(void); // reset_pin takes the pin number instead of the pointer so that objects don't // need to store a full pointer. void reset_pin(uint8_t pin); diff --git a/atmel-samd/main.c b/atmel-samd/main.c index 6184d64eb..da9c08019 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -172,15 +172,7 @@ void reset_samd21(void) { while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) {} DAC->CTRLA.reg |= DAC_CTRLA_SWRST; - // Reset pins - struct system_pinmux_config config; - system_pinmux_get_config_defaults(&config); - config.powersave = true; - - uint32_t pin_mask[2] = PORT_OUT_IMPLEMENTED; - - system_pinmux_group_set_config(&(PORT->Group[0]), pin_mask[0] & ~MICROPY_PORT_A, &config); - system_pinmux_group_set_config(&(PORT->Group[1]), pin_mask[1] & ~MICROPY_PORT_B, &config); + reset_all_pins(); audioout_reset(); pwmout_reset(); |
