summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/nrf/supervisor/port.c16
-rw-r--r--ports/nrf/supervisor/qspi_flash.c39
2 files changed, 34 insertions, 21 deletions
diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c
index 05970a3ed..36c9f836e 100644
--- a/ports/nrf/supervisor/port.c
+++ b/ports/nrf/supervisor/port.c
@@ -65,6 +65,10 @@
#include "common-hal/audiopwmio/PWMAudioOut.h"
#endif
+#if defined(MICROPY_QSPI_CS) && defined(MICROPY_QSPI_OFF_WHEN_SLEEP)
+extern void qspi_disable(void);
+#endif
+
static void power_warning_handler(void) {
reset_into_safe_mode(BROWNOUT);
}
@@ -296,17 +300,7 @@ 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);
-
- // Workaround to disable QSPI according to nRF52840 Revision 1 Errata V1.4 - 3.8
- NRF_QSPI->TASKS_DEACTIVATE = 1;
- *(volatile uint32_t *)0x40029054 = 1;
- NRF_QSPI->ENABLE = 0;
- }
+ qspi_disable();
#endif
// Clear the FPU interrupt because it can prevent us from sleeping.
diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c
index d5c60ac9e..852f0c44a 100644
--- a/ports/nrf/supervisor/qspi_flash.c
+++ b/ports/nrf/supervisor/qspi_flash.c
@@ -38,10 +38,9 @@
#include "supervisor/shared/external_flash/common_commands.h"
#include "supervisor/shared/external_flash/qspi_flash.h"
+// When USB is disconnected, disable QSPI in sleep mode to save energy
#if defined(MICROPY_QSPI_OFF_WHEN_SLEEP)
-#define QSPI_ENABLE() qspi_enable()
-
-static void qspi_enable(void)
+void qspi_enable(void)
{
if (NRF_QSPI->ENABLE) {
return;
@@ -61,12 +60,32 @@ static void qspi_enable(void)
} while (--remaining_attempts);
}
+void qspi_disable(void)
+{
+ // 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);
+
+ // Workaround to disable QSPI according to nRF52840 Revision 1 Errata V1.4 - 3.8
+ NRF_QSPI->TASKS_DEACTIVATE = 1;
+ *(volatile uint32_t *)0x40029054 = 1;
+ NRF_QSPI->ENABLE = 0;
+ }
+}
#else
-#define QSPI_ENABLE() ((void)0)
+void qspi_enable(void)
+{
+}
+
+void qspi_disable(void)
+{
+}
#endif
bool spi_flash_command(uint8_t command) {
- QSPI_ENABLE();
+ qspi_enable();
nrf_qspi_cinstr_conf_t cinstr_cfg = {
.opcode = command,
.length = 1,
@@ -79,7 +98,7 @@ bool spi_flash_command(uint8_t command) {
}
bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) {
- QSPI_ENABLE();
+ qspi_enable();
nrf_qspi_cinstr_conf_t cinstr_cfg = {
.opcode = command,
.length = length + 1,
@@ -93,7 +112,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();
+ qspi_enable();
nrf_qspi_cinstr_conf_t cinstr_cfg = {
.opcode = command,
.length = length + 1,
@@ -106,7 +125,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();
+ qspi_enable();
if (command != CMD_SECTOR_ERASE) {
return false;
}
@@ -114,7 +133,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();
+ 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)
@@ -122,7 +141,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();
+ 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