Skip to content

Commit

Permalink
feat: add internal flash for mcu stm32wba (#348)
Browse files Browse the repository at this point in the history
Add support for internal flash for stm32wba family
  • Loading branch information
cassio-lazaro authored Jun 28, 2024
1 parent a1c28bb commit 8629391
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
31 changes: 26 additions & 5 deletions hal_st/stm32fxxx/FlashInternalStm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ namespace hal
{
HAL_FLASH_Unlock();

#if defined(STM32WB) || defined(STM32G4) || defined(STM32G0)
#if defined(STM32WBA)
AlignedWriteBuffer(buffer, address);
#elif defined(STM32WB) || defined(STM32G4) || defined(STM32G0)
AlignedWriteBuffer<uint64_t, FLASH_TYPEPROGRAM_DOUBLEWORD>(buffer, address);
#elif defined(STM32WBA)
AlignedWriteBuffer<uint64_t, FLASH_TYPEPROGRAM_QUADWORD>(buffer, address);
#else
uint32_t word;
while (buffer.size() >= sizeof(word) && ((address & (sizeof(word) - 1)) == 0))
Expand All @@ -30,8 +30,6 @@ namespace hal

#if defined(STM32F0) || defined(STM32F3)
AlignedWriteBuffer<uint16_t, FLASH_TYPEPROGRAM_HALFWORD>(buffer, address);
#elif defined(STM32WBA)
AlignedWriteBuffer<uint16_t, FLASH_TYPEPROGRAM_QUADWORD>(buffer, address);
#elif !defined(STM32WB) && !defined(STM32G4) && !defined(STM32G0) && !defined(STM32WBA)
for (uint8_t byte : buffer)
{
Expand Down Expand Up @@ -107,6 +105,29 @@ namespace hal
}
}

#ifdef STM32WBA
const uint8_t alignment = sizeof(uint64_t) * 2;
void FlashInternalStmBase::AlignedWriteBuffer(infra::ConstByteRange buffer, uint32_t address)
{
services::FlashAlign::WithAlignment<alignment> flashAlign;
flashAlign.Align(address, buffer);

services::FlashAlign::Chunk* chunk = flashAlign.First();
auto dataSize = chunk->data.size();
while (chunk != nullptr)
{
really_assert(chunk->data.size() % sizeof(alignment) == 0);
auto fullAddress = reinterpret_cast<uint32_t>(flashMemory.begin() + chunk->alignedAddress);

uint32_t addr = reinterpret_cast<uint32_t>(chunk->data.begin());
auto result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, fullAddress, addr);
really_assert(result == HAL_OK);
fullAddress += alignment;
chunk = flashAlign.Next();
}
}
#endif

FlashInternalStm::FlashInternalStm(infra::MemoryRange<uint32_t> sectorSizes, infra::ConstByteRange flashMemory)
: FlashInternalStmBase(flashMemory)
, sectorSizes(sectorSizes)
Expand Down
3 changes: 3 additions & 0 deletions hal_st/stm32fxxx/FlashInternalStm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ namespace hal
private:
template<typename alignment, uint32_t flashType>
void AlignedWriteBuffer(infra::ConstByteRange buffer, uint32_t address);
#ifdef STM32WBA
void AlignedWriteBuffer(infra::ConstByteRange buffer, uint32_t address);
#endif

private:
infra::ConstByteRange flashMemory;
Expand Down
31 changes: 27 additions & 4 deletions hal_st/synchronous_stm32fxxx/SynchronousFlashInternalStm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ namespace hal
{
HAL_FLASH_Unlock();

#if defined(STM32WB) || defined(STM32G4) || defined(STM32G0)
#if defined(STM32WBA)
AlignedWriteBuffer(buffer, address);
#elif defined(STM32WB) || defined(STM32G4) || defined(STM32G0)
AlignedWriteBuffer<uint64_t, FLASH_TYPEPROGRAM_DOUBLEWORD>(buffer, address);
#elif defined(STM32WBA)
AlignedWriteBuffer<uint64_t, FLASH_TYPEPROGRAM_QUADWORD>(buffer, address);
Expand All @@ -29,9 +31,7 @@ namespace hal

#if defined(STM32F0) || defined(STM32F3)
AlignedWriteBuffer<uint16_t, FLASH_TYPEPROGRAM_HALFWORD>(buffer, address);
#elif defined(STM32WBA)
AlignedWriteBuffer<uint16_t, FLASH_TYPEPROGRAM_QUADWORD>(buffer, address);
#elif !defined(STM32WB) && !defined(STM32G4) && !defined(STM32G0)
#elif !defined(STM32WB) && !defined(STM32G4) && !defined(STM32G0) && !defined(STM32WBA)
for (uint8_t byte : buffer)
{
auto result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, reinterpret_cast<uint32_t>(flashMemory.begin() + address), byte);
Expand Down Expand Up @@ -101,6 +101,29 @@ namespace hal
}
}

#ifdef STM32WBA
const uint8_t alignment = sizeof(uint64_t) * 2;
void SynchronousFlashInternalStmBase::AlignedWriteBuffer(infra::ConstByteRange buffer, uint32_t address)
{
services::FlashAlign::WithAlignment<alignment> flashAlign;
flashAlign.Align(address, buffer);

services::FlashAlign::Chunk* chunk = flashAlign.First();
auto dataSize = chunk->data.size();
while (chunk != nullptr)
{
really_assert(chunk->data.size() % sizeof(alignment) == 0);
auto fullAddress = reinterpret_cast<uint32_t>(flashMemory.begin() + chunk->alignedAddress);

uint32_t addr = reinterpret_cast<uint32_t>(chunk->data.begin());
auto result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, fullAddress, addr);
really_assert(result == HAL_OK);
fullAddress += alignment;
chunk = flashAlign.Next();
}
}
#endif

SynchronousFlashInternalStm::SynchronousFlashInternalStm(infra::MemoryRange<uint32_t> sectorSizes, infra::ConstByteRange flashMemory)
: SynchronousFlashInternalStmBase(flashMemory)
, sectorSizes(sectorSizes)
Expand Down
3 changes: 3 additions & 0 deletions hal_st/synchronous_stm32fxxx/SynchronousFlashInternalStm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ namespace hal
private:
template<typename alignment, uint32_t flashType>
void AlignedWriteBuffer(infra::ConstByteRange buffer, uint32_t address);
#ifdef STM32WBA
void AlignedWriteBuffer(infra::ConstByteRange buffer, uint32_t address);
#endif

private:
infra::ConstByteRange flashMemory;
Expand Down

0 comments on commit 8629391

Please sign in to comment.