add an option to turn off QSPI when sleep
This commit is contained in:
parent
c394af4128
commit
6dc0f4f1b6
|
@ -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
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue