From e11deaa8749e37dbe235264a20428e1976336d55 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 18 Dec 2018 11:45:41 +0100 Subject: [PATCH] [ion/device] External flash: Send instruction only once in memory-mapped mode --- ion/src/device/external_flash.cpp | 28 +++++++++++++++++++++++++--- ion/src/device/external_flash.h | 1 + 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ion/src/device/external_flash.cpp b/ion/src/device/external_flash.cpp index ece42b00c..5de68b64c 100644 --- a/ion/src/device/external_flash.cpp +++ b/ion/src/device/external_flash.cpp @@ -126,14 +126,28 @@ static void set_as_memory_mapped() { send_command_full( QUADSPI::CCR::FunctionalMode::MemoryMapped, DefaultOperatingMode, - Command::FastRead, + Command::FastReadQuadIO, reinterpret_cast(FlashAddressSpaceSize), - 0, 0, - FastReadDummyCycles, + 0xA0, 1, + 2, //FIXME nullptr, 0 ); } +static void unset_memory_mapped_mode() { + /* Reset Continuous Read Mode Bits before issuing normal instructions. */ + uint8_t dummyData; + send_command_full( + QUADSPI::CCR::FunctionalMode::IndirectRead, + DefaultOperatingMode, + Command::FastReadQuadIO, + 0, + ~(0xA0), 1, + 2, //FIXME + &dummyData, 1 + ); +} + void send_command_full(QUADSPI::CCR::FunctionalMode functionalMode, QUADSPI::CCR::OperatingMode operatingMode, Command c, uint8_t * address, uint32_t altBytes, size_t numberOfAltBytes, uint8_t dummyCycles, uint8_t * data, size_t dataLength) { class QUADSPI::CCR ccr(0); ccr.setFMODE(functionalMode); @@ -155,6 +169,11 @@ void send_command_full(QUADSPI::CCR::FunctionalMode functionalMode, QUADSPI::CCR } ccr.setIMODE(operatingMode); ccr.setINSTRUCTION(static_cast(c)); + if (functionalMode == QUADSPI::CCR::FunctionalMode::MemoryMapped) { + ccr.setSIOO(true); + /* If the SIOO bit is set, the instruction is sent only for the first command following a write to QUADSPI_CCR. + * Subsequent command sequences skip the instruction phase, until there is a write to QUADSPI_CCR. */ + } QUADSPI.CCR()->set(ccr); if (address != reinterpret_cast(FlashAddressSpaceSize)) { QUADSPI.AR()->set(reinterpret_cast(address)); @@ -246,6 +265,7 @@ int SectorAtAddress(uint32_t address) { } void MassErase() { + unset_memory_mapped_mode(); send_command(Command::WriteEnable); wait(); send_command(Command::ChipErase); @@ -255,6 +275,7 @@ void MassErase() { void EraseSector(int i) { assert(i >= 0 && i < NumberOfSectors); + unset_memory_mapped_mode(); send_command(Command::WriteEnable); wait(); send_write_command(Command::Erase64KbyteBlock, reinterpret_cast(i << NumberOfAddressBitsIn64KbyteBlock), nullptr, 0); @@ -263,6 +284,7 @@ void EraseSector(int i) { } void WriteMemory(uint8_t * source, uint8_t * destination, size_t length) { + unset_memory_mapped_mode(); /* Each 256-byte page of the external flash memory (contained in a previously erased area) * may be programmed in burst mode with a single Page Program instruction. * However, when the end of a page is reached, the addressing wraps to the beginning. diff --git a/ion/src/device/external_flash.h b/ion/src/device/external_flash.h index f05bcf476..bde2678f8 100644 --- a/ion/src/device/external_flash.h +++ b/ion/src/device/external_flash.h @@ -53,6 +53,7 @@ enum class Command : uint8_t { WriteEnable = 0x06, ReadData = 0x03, FastRead = 0x0B, + FastReadQuadIO = 0xEB, // Program previously erased memory areas as being "0" PageProgram = 0x02, QuadPageProgram = 0x33,