diff --git a/os/ex/Micron/m25q.c b/os/ex/Micron/m25q.c
index 9ae5958d8..c43fb7fe1 100644
--- a/os/ex/Micron/m25q.c
+++ b/os/ex/Micron/m25q.c
@@ -699,7 +699,9 @@ static flash_error_t start_erase_sector(void *instance, flash_sector_t sector) {
static flash_error_t verify_erase(void *instance, flash_sector_t sector) {
M25QDriver *devp = (M25QDriver *)instance;
- unsigned i;
+ uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE];
+ flash_address_t addr;
+ size_t n;
osalDbgCheck(instance != NULL);
osalDbgCheck(sector < descriptor.sectors_count);
@@ -717,6 +719,35 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) {
devp->state = FLASH_READ;
/* Read command.*/
+ addr = (flash_address_t)(sector * SECTOR_SIZE);
+ n = SECTOR_SIZE;
+ while (n > 0U) {
+ uint8_t *p;
+
+#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI
+ flash_cmd_addr_dummy_receive(devp, M25Q_CMD_FAST_READ,
+ addr, M25Q_READ_DUMMY_CYCLES,
+ sizeof cmpbuf, cmpbuf);
+#else
+ /* Normal read command in SPI mode.*/
+#endif
+
+ /* Checking for erased state of current buffer.*/
+ for (p = cmpbuf; p < &cmpbuf[M25Q_COMPARE_BUFFER_SIZE]; p++) {
+ if (*p != 0xFFU) {
+ /* Ready state again.*/
+ devp->state = FLASH_READY;
+
+ /* Bus released.*/
+ flash_bus_release(devp);
+
+ return FLASH_ERROR_VERIFY;
+ }
+ }
+
+ addr += sizeof cmpbuf;
+ n -= sizeof cmpbuf;
+ }
/* Ready state again.*/
devp->state = FLASH_READY;
diff --git a/os/ex/Micron/m25q.h b/os/ex/Micron/m25q.h
index 865cc32ea..c5a98eadf 100644
--- a/os/ex/Micron/m25q.h
+++ b/os/ex/Micron/m25q.h
@@ -175,6 +175,16 @@
#define M25Q_SUPPORTED_MEMORY_TYPE_IDS {0xBA, 0xBB}
#endif
+/**
+ * @brief Size of the compare buffer.
+ * @details This buffer is allocated in the stack frame of the function
+ * @p flashVerifyErase() and its size must be a power of two.
+ * Larger buffers lead to better verify performance but increase
+ * stack usage for that function.
+ */
+#if !defined(M25Q_COMPARE_BUFFER_SIZE) || defined(__DOXYGEN__)
+#define M25Q_COMPARE_BUFFER_SIZE 32
+#endif
/** @} */
/*===========================================================================*/
@@ -206,6 +216,10 @@
#error "invalid M25Q_READ_DUMMY_CYCLES value (1..15)"
#endif
+#if (M25Q_COMPARE_BUFFER_SIZE & (M25Q_COMPARE_BUFFER_SIZE - 1)) != 0
+#error "invalid M25Q_COMPARE_BUFFER_SIZE value"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
diff --git a/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch b/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch
index 9187ae1d8..573a54f12 100644
--- a/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch
+++ b/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch
@@ -33,7 +33,7 @@
-
+
diff --git a/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c b/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c
index 2f85ec5d2..bd506f9e8 100644
--- a/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c
+++ b/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c
@@ -112,16 +112,32 @@ int main(void) {
if (err != FLASH_NO_ERROR)
chSysHalt("erase error");
+ /* Verifying the erase operation.*/
+ err = flashVerifyErase(&m25q, 0);
+ if (err != FLASH_NO_ERROR)
+ chSysHalt("verify erase error");
+
/* Programming a pattern.*/
err = flashProgram(&m25q, 0, pattern, 128);
if (err != FLASH_NO_ERROR)
chSysHalt("program error");
+ /* Verifying the erase operation.*/
+ err = flashVerifyErase(&m25q, 0);
+ if (err != FLASH_ERROR_VERIFY)
+ chSysHalt("verify non-erase error");
+
/* Reading it back.*/
err = flashRead(&m25q, 0, buffer, 128);
if (err != FLASH_NO_ERROR)
chSysHalt("read error");
+ /* Erasing again.*/
+ (void) flashStartEraseSector(&m25q, 0);
+ err = flashWaitErase((BaseFlash *)&m25q);
+ if (err != FLASH_NO_ERROR)
+ chSysHalt("erase error");
+
/*
* Normal main() thread activity, in this demo it does nothing.
*/