diff options
| author | Yihui Xiong <yihui.xiong@hotmail.com> | 2020-08-05 01:10:58 +0800 |
|---|---|---|
| committer | Yihui Xiong <yihui.xiong@hotmail.com> | 2020-08-05 01:10:58 +0800 |
| commit | 6dc0f4f1b68f4ac24bf85cc51252106ccfe43776 (patch) | |
| tree | 10d9764d21030d227a48cbef941620a542c9a4d5 /ports/nrf | |
| parent | c394af412837f96164ebcc88d5301bece19e4a6f (diff) | |
add an option to turn off QSPI when sleep
Diffstat (limited to 'ports/nrf')
| -rw-r--r-- | ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h | 1 | ||||
| -rw-r--r-- | ports/nrf/supervisor/port.c | 13 | ||||
| -rw-r--r-- | ports/nrf/supervisor/qspi_flash.c | 33 |
3 files changed, 47 insertions, 0 deletions
diff --git a/ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h b/ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h index 086718089..04a49e5e2 100644 --- a/ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h +++ b/ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h @@ -40,6 +40,7 @@ #define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 12) #define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 11) #define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 13) +#define MICROPY_QSPI_OFF_WHEN_SLEEP #define BOARD_HAS_CRYSTAL 1 diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index e681e6825..68d6f5f71 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -295,6 +295,19 @@ void port_interrupt_after_ticks(uint32_t ticks) { } void port_sleep_until_interrupt(void) { +#if defined(MICROPY_QSPI_CS) && defined(MICROPY_QSPI_OFF_WHEN_SLEEP) + // Turn off QSPI when USB is disconnected + if (NRF_QSPI->ENABLE && !(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk)) { + // Keep CS high when QSPI is diabled + nrf_gpio_cfg_output(MICROPY_QSPI_CS); + nrf_gpio_pin_write(MICROPY_QSPI_CS, 1); + + *(volatile uint32_t *)0x40029010 = 1; + *(volatile uint32_t *)0x40029054 = 1; + NRF_QSPI->ENABLE = 0; + } +#endif + // Clear the FPU interrupt because it can prevent us from sleeping. if (NVIC_GetPendingIRQ(FPU_IRQn)) { __set_FPSCR(__get_FPSCR() & ~(0x9f)); diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index 90260b091..83261f080 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -38,7 +38,35 @@ #include "supervisor/shared/external_flash/common_commands.h" #include "supervisor/shared/external_flash/qspi_flash.h" +#if defined(MICROPY_QSPI_OFF_WHEN_SLEEP) +#define QSPI_ENABLE qspi_enable + +static void qspi_enable(void) +{ + if (NRF_QSPI->ENABLE) { + return; + } + + nrf_qspi_enable(NRF_QSPI); + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE); + + uint32_t remaining_attempts = 100; + do { + if (nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)) { + break; + } + NRFX_DELAY_US(10); + } while (--remaining_attempts); +} + +#else +#define QSPI_ENABLE() +#endif + bool spi_flash_command(uint8_t command) { + QSPI_ENABLE(); nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = command, .length = 1, @@ -51,6 +79,7 @@ bool spi_flash_command(uint8_t command) { } bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) { + QSPI_ENABLE(); nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = command, .length = length + 1, @@ -64,6 +93,7 @@ bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) } bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { + QSPI_ENABLE(); nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = command, .length = length + 1, @@ -76,6 +106,7 @@ bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) { } bool spi_flash_sector_command(uint8_t command, uint32_t address) { + QSPI_ENABLE(); if (command != CMD_SECTOR_ERASE) { return false; } @@ -83,6 +114,7 @@ bool spi_flash_sector_command(uint8_t command, uint32_t address) { } bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { + QSPI_ENABLE(); // TODO: In theory, this also needs to handle unaligned data and // non-multiple-of-4 length. (in practice, I don't think the fat layer // generates such writes) @@ -90,6 +122,7 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) { } bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) { + QSPI_ENABLE(); int misaligned = ((intptr_t)data) & 3; // If the data is misaligned, we need to read 4 bytes // into an aligned buffer, and then copy 1, 2, or 3 bytes from the aligned |
