Skip to content

Commit c036bb8

Browse files
authored
Add 64KB block erase functionality to QSPI
1 parent 9498417 commit c036bb8

1 file changed

Lines changed: 61 additions & 6 deletions

File tree

src/per/qspi.cpp

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

453508
QSPIHandle::Result QSPIHandle::Impl::EraseSector(uint32_t address)
454509
{

0 commit comments

Comments
 (0)