Skip to content

Commit 807f049

Browse files
authored
Merge pull request #3244 from xiongyihui/main
add an option to turn off QSPI when sleep
2 parents 78f90db + af1291e commit 807f049

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

ports/nrf/boards/makerdiary_m60_keyboard/mpconfigboard.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@
3030
#define MICROPY_HW_BOARD_NAME "Makerdiary M60 Keyboard"
3131
#define MICROPY_HW_MCU_NAME "nRF52840"
3232

33-
#define CP_RGB_STATUS_R (&pin_P0_30)
34-
#define CP_RGB_STATUS_G (&pin_P0_29)
35-
#define CP_RGB_STATUS_B (&pin_P0_31)
33+
// RGB LEDs use PWM peripheral, avoid using them to save energy
34+
// #define CP_RGB_STATUS_R (&pin_P0_30)
35+
// #define CP_RGB_STATUS_G (&pin_P0_29)
36+
// #define CP_RGB_STATUS_B (&pin_P0_31)
3637

3738
#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 10)
3839
#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 14)

ports/nrf/supervisor/port.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
#include "common-hal/audiopwmio/PWMAudioOut.h"
6666
#endif
6767

68+
#if defined(MICROPY_QSPI_CS)
69+
extern void qspi_disable(void);
70+
#endif
71+
6872
static void power_warning_handler(void) {
6973
reset_into_safe_mode(BROWNOUT);
7074
}
@@ -295,6 +299,10 @@ void port_interrupt_after_ticks(uint32_t ticks) {
295299
}
296300

297301
void port_sleep_until_interrupt(void) {
302+
#if defined(MICROPY_QSPI_CS)
303+
qspi_disable();
304+
#endif
305+
298306
// Clear the FPU interrupt because it can prevent us from sleeping.
299307
if (NVIC_GetPendingIRQ(FPU_IRQn)) {
300308
__set_FPSCR(__get_FPSCR() & ~(0x9f));

ports/nrf/supervisor/qspi_flash.c

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

41+
// When USB is disconnected, disable QSPI in sleep mode to save energy
42+
void qspi_disable(void)
43+
{
44+
// If VBUS is detected, no need to disable QSPI
45+
if (NRF_QSPI->ENABLE && !(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk)) {
46+
// Keep CS high when QSPI is diabled
47+
nrf_gpio_cfg_output(MICROPY_QSPI_CS);
48+
nrf_gpio_pin_write(MICROPY_QSPI_CS, 1);
49+
50+
// Workaround to disable QSPI according to nRF52840 Revision 1 Errata V1.4 - 3.8
51+
NRF_QSPI->TASKS_DEACTIVATE = 1;
52+
*(volatile uint32_t *)0x40029054 = 1;
53+
NRF_QSPI->ENABLE = 0;
54+
}
55+
}
56+
57+
void qspi_enable(void)
58+
{
59+
if (NRF_QSPI->ENABLE) {
60+
return;
61+
}
62+
63+
nrf_qspi_enable(NRF_QSPI);
64+
65+
nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
66+
nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE);
67+
68+
uint32_t remaining_attempts = 100;
69+
do {
70+
if (nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)) {
71+
break;
72+
}
73+
NRFX_DELAY_US(10);
74+
} while (--remaining_attempts);
75+
}
76+
4177
bool spi_flash_command(uint8_t command) {
78+
qspi_enable();
4279
nrf_qspi_cinstr_conf_t cinstr_cfg = {
4380
.opcode = command,
4481
.length = 1,
@@ -51,6 +88,7 @@ bool spi_flash_command(uint8_t command) {
5188
}
5289

5390
bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) {
91+
qspi_enable();
5492
nrf_qspi_cinstr_conf_t cinstr_cfg = {
5593
.opcode = command,
5694
.length = length + 1,
@@ -64,6 +102,7 @@ bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length)
64102
}
65103

66104
bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
105+
qspi_enable();
67106
nrf_qspi_cinstr_conf_t cinstr_cfg = {
68107
.opcode = command,
69108
.length = length + 1,
@@ -76,20 +115,23 @@ bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
76115
}
77116

78117
bool spi_flash_sector_command(uint8_t command, uint32_t address) {
118+
qspi_enable();
79119
if (command != CMD_SECTOR_ERASE) {
80120
return false;
81121
}
82122
return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address) == NRFX_SUCCESS;
83123
}
84124

85125
bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
126+
qspi_enable();
86127
// TODO: In theory, this also needs to handle unaligned data and
87128
// non-multiple-of-4 length. (in practice, I don't think the fat layer
88129
// generates such writes)
89130
return nrfx_qspi_write(data, length, address) == NRFX_SUCCESS;
90131
}
91132

92133
bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
134+
qspi_enable();
93135
int misaligned = ((intptr_t)data) & 3;
94136
// If the data is misaligned, we need to read 4 bytes
95137
// into an aligned buffer, and then copy 1, 2, or 3 bytes from the aligned

0 commit comments

Comments
 (0)