summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYihui Xiong <yihui.xiong@hotmail.com>2020-08-05 01:10:58 +0800
committerYihui Xiong <yihui.xiong@hotmail.com>2020-08-05 01:10:58 +0800
commit6dc0f4f1b68f4ac24bf85cc51252106ccfe43776 (patch)
tree10d9764d21030d227a48cbef941620a542c9a4d5
parentc394af412837f96164ebcc88d5301bece19e4a6f (diff)
add an option to turn off QSPI when sleep
-rw-r--r--ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h1
-rw-r--r--ports/nrf/supervisor/port.c13
-rw-r--r--ports/nrf/supervisor/qspi_flash.c33
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