Skip to content

Commit 6dc0f4f

Browse files
committed
add an option to turn off QSPI when sleep
1 parent c394af4 commit 6dc0f4f

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 12)
4141
#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 11)
4242
#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 13)
43+
#define MICROPY_QSPI_OFF_WHEN_SLEEP
4344

4445
#define BOARD_HAS_CRYSTAL 1
4546

ports/nrf/supervisor/port.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,19 @@ void port_interrupt_after_ticks(uint32_t ticks) {
295295
}
296296

297297
void port_sleep_until_interrupt(void) {
298+
#if defined(MICROPY_QSPI_CS) && defined(MICROPY_QSPI_OFF_WHEN_SLEEP)
299+
// Turn off QSPI when USB is disconnected
300+
if (NRF_QSPI->ENABLE && !(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk)) {
301+
// Keep CS high when QSPI is diabled
302+
nrf_gpio_cfg_output(MICROPY_QSPI_CS);
303+
nrf_gpio_pin_write(MICROPY_QSPI_CS, 1);
304+
305+
*(volatile uint32_t *)0x40029010 = 1;
306+
*(volatile uint32_t *)0x40029054 = 1;
307+
NRF_QSPI->ENABLE = 0;
308+
}
309+
#endif
310+
298311
// Clear the FPU interrupt because it can prevent us from sleeping.
299312
if (NVIC_GetPendingIRQ(FPU_IRQn)) {
300313
__set_FPSCR(__get_FPSCR() & ~(0x9f));

ports/nrf/supervisor/qspi_flash.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,35 @@
3838
#include "supervisor/shared/external_flash/common_commands.h"
3939
#include "supervisor/shared/external_flash/qspi_flash.h"
4040

41+
#if defined(MICROPY_QSPI_OFF_WHEN_SLEEP)
42+
#define QSPI_ENABLE qspi_enable
43+
44+
static void qspi_enable(void)
45+
{
46+
if (NRF_QSPI->ENABLE) {
47+
return;
48+
}
49+
50+
nrf_qspi_enable(NRF_QSPI);
51+
52+
nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
53+
nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE);
54+
55+
uint32_t remaining_attempts = 100;
56+
do {
57+
if (nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)) {
58+
break;
59+
}
60+
NRFX_DELAY_US(10);
61+
} while (--remaining_attempts);
62+
}
63+
64+
#else
65+
#define QSPI_ENABLE()
66+
#endif
67+
4168
bool spi_flash_command(uint8_t command) {
69+
QSPI_ENABLE();
4270
nrf_qspi_cinstr_conf_t cinstr_cfg = {
4371
.opcode = command,
4472
.length = 1,
@@ -51,6 +79,7 @@ bool spi_flash_command(uint8_t command) {
5179
}
5280

5381
bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) {
82+
QSPI_ENABLE();
5483
nrf_qspi_cinstr_conf_t cinstr_cfg = {
5584
.opcode = command,
5685
.length = length + 1,
@@ -64,6 +93,7 @@ bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length)
6493
}
6594

6695
bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
96+
QSPI_ENABLE();
6797
nrf_qspi_cinstr_conf_t cinstr_cfg = {
6898
.opcode = command,
6999
.length = length + 1,
@@ -76,20 +106,23 @@ bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
76106
}
77107

78108
bool spi_flash_sector_command(uint8_t command, uint32_t address) {
109+
QSPI_ENABLE();
79110
if (command != CMD_SECTOR_ERASE) {
80111
return false;
81112
}
82113
return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address) == NRFX_SUCCESS;
83114
}
84115

85116
bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
117+
QSPI_ENABLE();
86118
// TODO: In theory, this also needs to handle unaligned data and
87119
// non-multiple-of-4 length. (in practice, I don't think the fat layer
88120
// generates such writes)
89121
return nrfx_qspi_write(data, length, address) == NRFX_SUCCESS;
90122
}
91123

92124
bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
125+
QSPI_ENABLE();
93126
int misaligned = ((intptr_t)data) & 3;
94127
// If the data is misaligned, we need to read 4 bytes
95128
// into an aligned buffer, and then copy 1, 2, or 3 bytes from the aligned

0 commit comments

Comments
 (0)