From cc9bbbd59c0880518b20e4ced6df8a705f48a280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 5 Jun 2019 14:24:55 +0200 Subject: [PATCH] [ion/external_flash] Unlock the flash before any erase In some cases, but we do not not why, these registers had some bits written to one, which locked the modification of some blocks of the external flash. We thus reset the locking bits of the registers. --- .../device/shared/drivers/external_flash.cpp | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/ion/src/device/shared/drivers/external_flash.cpp b/ion/src/device/shared/drivers/external_flash.cpp index 31776ff9a..d482aac98 100644 --- a/ion/src/device/shared/drivers/external_flash.cpp +++ b/ion/src/device/shared/drivers/external_flash.cpp @@ -56,6 +56,8 @@ using namespace Regs; enum class Command : uint8_t { ReadStatusRegister1 = 0x05, + ReadStatusRegister2 = 0x35, + WriteStatusRegister = 0x01, WriteStatusRegister2 = 0x31, WriteEnable = 0x06, ReadData = 0x03, @@ -80,15 +82,15 @@ static constexpr uint8_t NumberOfAddressBitsIn64KbyteBlock = 16; class ExternalFlashStatusRegister { public: - class StatusRegister1 : Register8 { + class StatusRegister1 : public Register8 { public: using Register8::Register8; REGS_BOOL_FIELD_R(BUSY, 0); }; - class StatusRegister2 : Register8 { + class StatusRegister2 : public Register8 { public: using Register8::Register8; - REGS_BOOL_FIELD_W(QE, 1); + REGS_BOOL_FIELD(QE, 1); }; }; @@ -372,11 +374,27 @@ int SectorAtAddress(uint32_t address) { return i; } +void unlockFlash() { + // Warning: unset_memory_mapped_mode must be called before + send_command(Command::WriteEnable); + wait(); + ExternalFlashStatusRegister::StatusRegister1 statusRegister1(0); + ExternalFlashStatusRegister::StatusRegister2 statusRegister2(0); + ExternalFlashStatusRegister::StatusRegister2 currentStatusRegister2(0); + send_read_command(Command::ReadStatusRegister2, reinterpret_cast(FlashAddressSpaceSize), reinterpret_cast(¤tStatusRegister2), sizeof(currentStatusRegister2)); + statusRegister2.setQE(currentStatusRegister2.getQE()); + + uint8_t registers[] = {statusRegister1.get(), statusRegister2.get()}; + send_write_command(Command::WriteStatusRegister, reinterpret_cast(FlashAddressSpaceSize), reinterpret_cast(registers), sizeof(registers)); + wait(); +} + void MassErase() { if (Config::NumberOfSectors == 0) { return; } unset_memory_mapped_mode(); + unlockFlash(); send_command(Command::WriteEnable); wait(); send_command(Command::ChipErase); @@ -387,6 +405,7 @@ void MassErase() { void EraseSector(int i) { assert(i >= 0 && i < Config::NumberOfSectors); unset_memory_mapped_mode(); + unlockFlash(); send_command(Command::WriteEnable); wait(); send_write_command(Command::Erase64KbyteBlock, reinterpret_cast(i << NumberOfAddressBitsIn64KbyteBlock), nullptr, 0);