@@ -65,6 +65,8 @@ class QSPIHandle::Impl
6565
6666 QSPIHandle::Result EraseSector (uint32_t address);
6767
68+ QSPIHandle::Result EraseBlock64K (uint32_t address);
69+
6870 uint32_t GetPin (size_t pin);
6971
7072 GPIO_TypeDef* GetPort (size_t pin);
@@ -434,21 +436,74 @@ QSPIHandle::Result QSPIHandle::Impl::Erase(uint32_t start_addr,
434436 uint32_t end_addr)
435437{
436438 uint32_t block_addr;
437- uint32_t block_size = IS25LP080D_SECTOR_SIZE; // 4kB blocks for now.
438- // 64kB chunks for now.
439- start_addr = start_addr - (start_addr % block_size);
439+ constexpr uint32_t BLOCK_64K = 0x10000 ; // 64KB
440+ constexpr uint32_t SECTOR_4K = 0x1000 ; // 4KB
441+
442+ // Align start address down to 4KB boundary
443+ start_addr = start_addr - (start_addr % SECTOR_4K);
444+
440445 while (end_addr > start_addr)
441446 {
442447 block_addr = start_addr & 0x0FFFFFFF ;
443- if (EraseSector (block_addr) != QSPIHandle::Result::OK)
448+
449+ // Use 64KB block erase when aligned and enough space remaining
450+ if ((block_addr % BLOCK_64K) == 0 && (end_addr - start_addr) >= BLOCK_64K)
444451 {
445- ERR_RECOVERY (Status::E_HAL_ERROR);
452+ if (EraseBlock64K (block_addr) != QSPIHandle::Result::OK)
453+ {
454+ ERR_RECOVERY (Status::E_HAL_ERROR);
455+ }
456+ start_addr += BLOCK_64K;
457+ }
458+ else
459+ {
460+ // Fall back to 4KB sector erase
461+ if (EraseSector (block_addr) != QSPIHandle::Result::OK)
462+ {
463+ ERR_RECOVERY (Status::E_HAL_ERROR);
464+ }
465+ start_addr += SECTOR_4K;
446466 }
447- start_addr += block_size;
448467 }
449468 return QSPIHandle::Result::OK;
450469}
451470
471+ QSPIHandle::Result QSPIHandle::Impl::EraseBlock64K (uint32_t address)
472+ {
473+ QSPI_CommandTypeDef s_command;
474+ s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
475+ s_command.Instruction = BLOCK_ERASE_CMD; // 0xD8 = 64KB block erase
476+ s_command.AddressMode = QSPI_ADDRESS_1_LINE;
477+ s_command.AddressSize = QSPI_ADDRESS_24_BITS;
478+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
479+ s_command.DataMode = QSPI_DATA_NONE;
480+ s_command.DummyCycles = 0 ;
481+ s_command.NbData = 1 ;
482+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
483+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
484+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
485+ s_command.Address = address;
486+
487+ RETURN_IF_ERR (CheckProgramMemory ());
488+ RETURN_IF_ERR (SetMode (Config::Mode::INDIRECT_POLLING));
489+
490+ if (WriteEnable () != QSPIHandle::Result::OK)
491+ {
492+ ERR_RECOVERY (Status::E_HAL_ERROR);
493+ }
494+ if (HAL_QSPI_Command (&halqspi_, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)
495+ != HAL_OK)
496+ {
497+ ERR_RECOVERY (Status::E_HAL_ERROR);
498+ }
499+ if (AutopollingMemReady (HAL_QPSI_TIMEOUT_DEFAULT_VALUE)
500+ != QSPIHandle::Result::OK)
501+ {
502+ ERR_RECOVERY (Status::E_HAL_ERROR);
503+ }
504+
505+ return QSPIHandle::Result::OK;
506+ }
452507
453508QSPIHandle::Result QSPIHandle::Impl::EraseSector (uint32_t address)
454509{
0 commit comments