diff options
| author | Scott Shawcroft <scott@tannewt.org> | 2019-04-05 19:06:37 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott@tannewt.org> | 2019-04-05 19:06:37 -0700 |
| commit | 7686f93ef456aa46f538da3159d0e12cae9fa737 (patch) | |
| tree | bdd9d98d82e09d9ea725284e9bb2eee2d71c2f41 /supervisor/shared | |
| parent | 8b9e93329d5b9c732954f0d8f1ba2c97819ad774 (diff) | |
Fix crash when getting board.SPI outside the VM
If one of the default pins was already in use it would crash.
The internal API has been refined to allow us to get the value
without causing an init of the singleton.
Fixes #1753
Diffstat (limited to 'supervisor/shared')
| -rw-r--r-- | supervisor/shared/board_busses.c | 45 | ||||
| -rw-r--r-- | supervisor/shared/board_busses.h | 3 | ||||
| -rw-r--r-- | supervisor/shared/external_flash/spi_flash.c | 4 | ||||
| -rw-r--r-- | supervisor/shared/safe_mode.c | 3 |
4 files changed, 40 insertions, 15 deletions
diff --git a/supervisor/shared/board_busses.c b/supervisor/shared/board_busses.c index d77c4f331..b2d04207d 100644 --- a/supervisor/shared/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -71,23 +71,42 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); STATIC busio_spi_obj_t spi_obj; STATIC mp_obj_t spi_singleton = NULL; -mp_obj_t board_spi(void) { - if (spi_singleton == NULL) { - busio_spi_obj_t *self = &spi_obj; - self->base.type = &busio_spi_type; - assert_pin_free(DEFAULT_SPI_BUS_SCK); - assert_pin_free(DEFAULT_SPI_BUS_MOSI); - assert_pin_free(DEFAULT_SPI_BUS_MISO); - const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK); - const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); - const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); - common_hal_busio_spi_construct(self, clock, mosi, miso); - spi_singleton = (mp_obj_t)self; +// TODO(tannewt): Move this to shared-bindings/board/__init__.c and corresponding shared-module. +mp_obj_t common_hal_board_get_spi(void) { + return spi_singleton; +} + +mp_obj_t common_hal_board_create_spi(void) { + if (spi_singleton != NULL) { + return spi_singleton; + } + busio_spi_obj_t *self = &spi_obj; + self->base.type = &busio_spi_type; + if (!common_hal_mcu_pin_is_free(DEFAULT_SPI_BUS_SCK) || + !common_hal_mcu_pin_is_free(DEFAULT_SPI_BUS_MOSI) || + !common_hal_mcu_pin_is_free(DEFAULT_SPI_BUS_MISO)) { + return NULL; } + const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK); + const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); + const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); + common_hal_busio_spi_construct(self, clock, mosi, miso); + spi_singleton = (mp_obj_t)self; return spi_singleton; } -#else + mp_obj_t board_spi(void) { + mp_obj_t singleton = common_hal_board_get_spi(); + if (singleton != NULL) { + return singleton; + } + assert_pin_free(DEFAULT_SPI_BUS_SCK); + assert_pin_free(DEFAULT_SPI_BUS_MOSI); + assert_pin_free(DEFAULT_SPI_BUS_MISO); + return common_hal_board_create_spi(); +} +#else +mp_obj_t common_hal_board_spi(void) { mp_raise_NotImplementedError(translate("No default SPI bus")); return NULL; } diff --git a/supervisor/shared/board_busses.h b/supervisor/shared/board_busses.h index 0ccb3ba6a..bdb3884f6 100644 --- a/supervisor/shared/board_busses.h +++ b/supervisor/shared/board_busses.h @@ -29,7 +29,8 @@ #include "py/obj.h" -mp_obj_t board_i2c(void); +mp_obj_t common_hal_board_get_spi(void); +mp_obj_t common_hal_board_create_spi(void); MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj); mp_obj_t board_spi(void); diff --git a/supervisor/shared/external_flash/spi_flash.c b/supervisor/shared/external_flash/spi_flash.c index ec7101bc9..12888f2d3 100644 --- a/supervisor/shared/external_flash/spi_flash.c +++ b/supervisor/shared/external_flash/spi_flash.c @@ -132,11 +132,15 @@ bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length) } void spi_flash_init(void) { + cs_pin.base.type = &digitalio_digitalinout_type; common_hal_digitalio_digitalinout_construct(&cs_pin, SPI_FLASH_CS_PIN); + // Set CS high (disabled). common_hal_digitalio_digitalinout_switch_to_output(&cs_pin, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&cs_pin); + spi.base.type = &busio_spi_type; common_hal_busio_spi_construct(&spi, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN); common_hal_busio_spi_never_reset(&spi); } diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 3bb75b897..7182bbcca 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -77,7 +77,8 @@ safe_mode_t wait_for_safe_mode_reset(void) { return NO_SAFE_MODE; } -void reset_into_safe_mode(safe_mode_t reason) { +// Inline this so it's easy to break on it from GDB. +void __attribute__((noinline,)) reset_into_safe_mode(safe_mode_t reason) { if (current_safe_mode > BROWNOUT && reason > BROWNOUT) { while (true) { // This very bad because it means running in safe mode didn't save us. Only ignore brownout |
