Hi all,
I want to store a string in XIAO BLE Sense nRF52840’s onboard 2MB flash. I know it is possible using mbed-boards but I also wanted to try with non-mbed…
While browsing the nRF52 folder on my laptop I found “C:\Users\user_name\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.8\libraries\Adafruit_SPIFlash\src\qspi\Adafruit_FlashTransport_QSPI_NRF.cpp”
And based on it, I wrote-
#include <stdio.h>
#include <string.h>
#include <Adafruit_FlashTransport.h>
#include <nrfx_qspi.h>
// Create an instance of the QSPI flash transport
Adafruit_FlashTransport_QSPI flashTransport(24,25,26,27,28,29); //pin numbers from variant.h
const uint32_t flashAddress = 0x00000000;
const char dataToWrite[] = "Hello";
char dataRead[sizeof(dataToWrite)] = {0};
void setup() {
// Initializing Serial
Serial.begin(115200);
while (!Serial) {
delay(10);
}
// Initializing QSPI flash
flashTransport.begin();
// Erasing the data in the flash memory before write
if (flashTransport.eraseCommand(SFLASH_CMD_ERASE_SECTOR, flashAddress)) {
Serial.println("4KB data erased successfully!");
} else {
Serial.println("Failed to erase data in flash.");
}
// Writing the data to the flash memory
if (flashTransport.writeMemory(flashAddress, (uint8_t*)dataToWrite, sizeof(dataToWrite))) {
Serial.println("Data written to flash successfully!");
} else {
Serial.println("Failed to write data to flash.");
}
// Reading the data back from the flash memory
if (flashTransport.readMemory(flashAddress, (uint8_t*)dataRead, sizeof(dataToWrite))) {
Serial.print("Data read from flash: ");
Serial.println(dataRead);
} else {
Serial.println("Failed to read data from flash.");
}
}
void loop() {
// Idle loop
}
However, this returned-
4KB data erased successfully!
Failed to write data to flash.
Data read from flash: ������
The heart of Flash write is this section of code to write blocks of 4 bytes (the minimum write size), and write must be multiple of 4, plus they must be aligned with a multiple of 4:
__disable_irq();
// Autorize to write on flash
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
__DSB();
__ISB();
nvmc_wait_ready();
// Writes each word
for (size_t i = 0; i < words; i++) {
((volatile uint32_t *)dst_addr)[i] = data[i];
__DSB();
__ISB();
nvmc_wait_ready();
}
// Move back to read only
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
__DSB();
__ISB();
nvmc_wait_ready();
__enable_irq();
//***************************************
static inline void nvmc_wait_ready(void) {
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
__NOP();
}
}
I still struggle to be sure about the space authorized for user hat looks surper small: 7 × 4096= 28672 bytes I use this information bellow, but I’m not sure it is fully correct. If experts have more accurate information,I’m happy to take it:
Flash total size : 1 OR 2 MBytes?
Flash Adressing : 0x0000_0000 → 0x000F_FFFF
write by word of 32bits ONLY
to write 1 word of 32b in a page you need first to erase it completely!
erase par page of 4k only
you read on the flash seemlessly, as if it was standard RAM, that’s the cool part
Page # | start of pages addresses (hex) free for USER PROGRAM: