From e4207457835020cc14440f236f91cbae9ad231e5 Mon Sep 17 00:00:00 2001 From: Valerio Flamminii <valerio.flamminii@skywarder.eu> Date: Sun, 3 Mar 2024 22:15:16 +0100 Subject: [PATCH] aggiunte erase_block64 e software_reset() --- .../drivers/QuadSpi-Flash/qspi-flash.cpp | 94 ++++++++++++++++++- src/tests/drivers/QuadSpi-Flash/qspi-flash.h | 13 ++- .../drivers/QuadSpi-Flash/test-Qflash.cpp | 23 ++++- 3 files changed, 124 insertions(+), 6 deletions(-) diff --git a/src/tests/drivers/QuadSpi-Flash/qspi-flash.cpp b/src/tests/drivers/QuadSpi-Flash/qspi-flash.cpp index 125413587..fd4b42bfa 100644 --- a/src/tests/drivers/QuadSpi-Flash/qspi-flash.cpp +++ b/src/tests/drivers/QuadSpi-Flash/qspi-flash.cpp @@ -428,7 +428,7 @@ bool qspi_flash::sector_erase(uint32_t address) { // erase block (32K) which contains the address (24 bit) specified bool qspi_flash::block32_erase(uint32_t address) { - // erase a 32K block of data, any ddress of the block is valid + // erase a 32K block of data, any address of the block is valid // 1 wait until the memory has finished any operation in progress // 2 write_enable command // 3 erase block_32 command @@ -468,6 +468,49 @@ bool qspi_flash::block32_erase(uint32_t address) { } +// erase a block (32K) which contains the address (24 bit) specified +bool qspi_flash::block64_erase(uint32_t address) { + + // erase a 64K block of data, any address of the block is valid + // 1 wait until the memory has finished any operation in progress + // 2 write_enable command + // 3 erase block_64 command + // 4 wait till flash has completed the operation + // 5 write_disable command, just to be sure + // 6 check the result (flasg E_FAIL) + + waitProgress(); + + write_enable(); + + QSPI::abort_reset(); + + // set quadspi CCR register + // indirect write mode, 3-byte address, no data. all on one wire. + QUADSPI->CCR |= QUADSPI_CCR_IMODE_0 | // istruction on one wire + QUADSPI_CCR_ADSIZE_1 | // 3-byte address + QUADSPI_CCR_ADMODE_0; // address on a single line + + QSPI::enable(); + + // add instruction + QUADSPI->CCR |= Commands::BLOCK_64_ERASE; + + // start communication by writing the address in QUADSPI->AR + QUADSPI->AR = address; + + QSPI::waitBusy(); + + QSPI::disable(); + + waitProgress(); + + write_disable(); + + return check_erase(); +} + + bool qspi_flash::byte_program(uint8_t data, uint32_t address) { // write a byte at the specified address (any address is ok) @@ -544,6 +587,55 @@ uint8_t qspi_flash::read_security_reg() { } +void qspi_flash::software_reset() { + + // if software reset is performed at the same time of another programe/erase operation, + // that current operation will not be executed correctly, and data could be lost. + + // this functionality combines two commands, RSTEN and RST, + // they need to be sent according to this order: + // 1 - RSTEN instruction (reset enable) + // 2 - RST instruction (software reset) + // if any operation is executed before the RST instruction, the reset enable (RSTEN) is + // invalid. + + // commands sequence: RSTEN>>wait 1ms>>RST>>wait 1ms + // -------------------- send RSTEN command ------------------------- + waitProgress(); + + QSPI::abort_reset(); + + // indirect write mode, no data, no address, instruction on a single line + QUADSPI->CCR |= QUADSPI_CCR_IMODE_0; + + QSPI::enable(); + + // start the communication by writing the reset enable instruction + QUADSPI->CCR |= Commands::RESET_ENABLE; + + QSPI::waitBusy(); + + QSPI::disable(); + + Thread::sleep(1); // wait 1 ms + + // ------------------- send RST command -------------------------- + QSPI::abort_reset(); + + QUADSPI->CCR |= QUADSPI_CCR_IMODE_0; + + QSPI::enable(); + + QUADSPI->CCR |= Commands::RESET_MEMORY; + + QSPI::waitBusy(); + + QSPI::disable(); + + Thread::sleep(1); +} + + bool qspi_flash::check_erase() { diff --git a/src/tests/drivers/QuadSpi-Flash/qspi-flash.h b/src/tests/drivers/QuadSpi-Flash/qspi-flash.h index 17b5c0985..96f701a38 100644 --- a/src/tests/drivers/QuadSpi-Flash/qspi-flash.h +++ b/src/tests/drivers/QuadSpi-Flash/qspi-flash.h @@ -86,15 +86,21 @@ public: // erase the sector which contains the address (24 bit) specified bool sector_erase(uint32_t address); - // erase block (32K) which contains the address (24 bit) specified + // erase a block (32K) which contains the address (24 bit) specified bool block32_erase(uint32_t address); + // erase a block (32K) which contains the address (24 bit) specified + bool block64_erase(uint32_t address); + // read a byte at a specific address (24 bit) in memory uint8_t read_byte(uint32_t address); // write a byte at a specific address (24 bit) in memory bool byte_program(uint8_t data, uint32_t address); + // ATTENTION it may take a while! - makes the flash return to power-on default status. + void software_reset(); + // check if flash is executing some operation (program/erase or write registers) bool isInProgress(); @@ -148,9 +154,12 @@ private: // erase a specific sector of the memory SECTOR_ERASE = 0x20, - // erase a specific block of 32K of the memory + // erase a specific block of 32KB of the memory BLOCK_32_ERASE = 0x52, + // erase a specific block of 64KB of the memory + BLOCK_64_ERASE = 0xD8, + // erase all data on the chip - THIS COULD TAKE A LONG TIME ! ERASE_CHIP = 0xC7, diff --git a/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp b/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp index 57752d79a..ac63ed3ea 100644 --- a/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp +++ b/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp @@ -70,14 +70,31 @@ int main() { // test funzione read_byte(): OCCHIO IMPOSTA SEMPRE LA DIMENSIONE DELLA FLASH printf("\ntest funzione read_byte()\n"); - // test block32_erase: FUNZIONA - printf("valore block32_erase(): %d\n", mymemory.block32_erase(0x3FFFFF)); + // test block32_erase(): FUNZIONA + printf("valore block32_erase(): %d\n", mymemory.block32_erase(0x3FFFFF)); + + // test block64_erase(): FUNZIONA + printf("valore block64_erase(): %d\n", mymemory.block64_erase(0x3fffff)); printf("valore read_byte: %d\n", mymemory.read_byte(0)); printf("----- end read_byte() test\n"); - // test erase chip function() SEMBRA FUNZIONARE TUTTO FINO AD ORA !!!!!! + // test funzione reset(): FUNZIONA + /* + printf("\n------- start test funzione reset() ----------\n"); + + Thread::sleep(100); + mymemory.write_enable(); + printf("status reg prima : %d\n", mymemory.read_status_reg()); + //mymemory.software_reset(); + printf("status reg dopo: %d\n", mymemory.read_status_reg()); + + printf("------- end test funzione reset() ----------\n"); + */ + + + // test erase chip function(): FUNZIONA /* printf("\nstart TEST erase chip function\n"); -- GitLab