From 7a8ed993f338476f56d11beacb1260738a9e42ab Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Thu, 31 Mar 2022 06:36:37 +0200 Subject: [PATCH] spiFlash: bulk_erase: check bp before erase --- src/spiFlash.cpp | 43 +++++++++++++++++++++++++++++++++++++++---- src/spiFlash.hpp | 6 ++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/spiFlash.cpp b/src/spiFlash.cpp index 07fadcb..a0489fe 100644 --- a/src/spiFlash.cpp +++ b/src/spiFlash.cpp @@ -78,10 +78,30 @@ SPIFlash::SPIFlash(SPIInterface *spi, bool unprotect, int8_t verbose): int SPIFlash::bulk_erase() { - if (write_enable() == -1) - return -1; - _spi->spi_put(FLASH_CE, NULL, NULL, 0); - return _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 100000, true); + int ret, ret2 = 0; + uint32_t timeout=100000; + uint8_t bp = get_bp(); + if (bp != 0) { + if (!_unprotect) { + printError("Error: Can't erase flash: block protection is set"); + printError(" can't unlock without --unprotect-flash"); + return -1; + } + + if ((ret = disable_protection()) != 0) + return ret; + } + + if ((ret = write_enable()) != 0) + return ret; + ret2 = _spi->spi_put(FLASH_CE, NULL, NULL, 0); + if (ret2 == 0) + ret2 = _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, timeout, true); + + if (bp != 0) + ret = enable_protection(bp); + + return ret | ret2; } /* sector -> subsector for micron */ @@ -748,6 +768,21 @@ int8_t SPIFlash::get_tb() return (status & _flash_model->tb_offset) ? 1 : 0; } +/* read status register and extract bp area */ +uint8_t SPIFlash::get_bp() +{ + uint8_t mask = 0; + uint8_t status = read_status_reg(); + if (!_flash_model) { + mask = 0x1C; + } else { + for (int i = 0; i < _flash_model->bp_len; i++) + mask |= _flash_model->bp_offset[i]; + } + + return (status & mask); +} + /* convert bp area (status register) to len in byte */ std::map SPIFlash::bp_to_len(uint8_t bp, uint8_t tb) { diff --git a/src/spiFlash.hpp b/src/spiFlash.hpp index 57453c1..6c7a840 100644 --- a/src/spiFlash.hpp +++ b/src/spiFlash.hpp @@ -108,6 +108,12 @@ class SPIFlash { */ int8_t get_tb(); + /*! + * \brief retrieve BP (Block protect) bit from status register + * \return BP + */ + uint8_t get_bp(); + public: /*! * \brief convert block protect to len in byte