Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: sync uart and flash for wba #453

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 54 additions & 59 deletions hal_st/synchronous_stm32fxxx/SynchronousFlashInternalStm.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
#include "hal_st/synchronous_stm32fxxx/SynchronousFlashInternalStm.hpp"
#include "services/util/FlashAlign.hpp"
#include "hal_st/stm32fxxx/FlashInternalStmDetail.hpp"

namespace
{
struct uint128_t
{
#ifdef __ARM_BIG_ENDIAN
uint64_t high;
uint64_t low;
#else
uint64_t low;
uint64_t high;
#endif
};

#if defined(FLASH_DBANK_SUPPORT)
uint32_t GetBank(uint32_t sectorIndex)
{
return sectorIndex < FLASH_PAGE_NB ? FLASH_BANK_1 : FLASH_BANK_2;
}
#endif
}

namespace hal
{
Expand All @@ -10,13 +31,12 @@ namespace hal
void SynchronousFlashInternalStmBase::WriteBuffer(infra::ConstByteRange buffer, uint32_t address)
{
HAL_FLASH_Unlock();
const auto flashBegin = reinterpret_cast<uint32_t>(flashMemory.begin());

#if defined(STM32WBA)
AlignedWriteBuffer(buffer, address);
#if defined(STM32WBA) || defined(STM32H5)
detail::AlignedWriteBuffer<uint128_t, FLASH_TYPEPROGRAM_QUADWORD, true>(buffer, address, flashBegin);
#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);
detail::AlignedWriteBuffer<uint64_t, FLASH_TYPEPROGRAM_DOUBLEWORD, false>(buffer, address, flashBegin);
#else
uint32_t word;
while (buffer.size() >= sizeof(word) && ((address & (sizeof(word) - 1)) == 0))
Expand All @@ -30,7 +50,7 @@ namespace hal
#endif

#if defined(STM32F0) || defined(STM32F3)
AlignedWriteBuffer<uint16_t, FLASH_TYPEPROGRAM_HALFWORD>(buffer, address);
detail::AlignedWriteBuffer<uint16_t, FLASH_TYPEPROGRAM_HALFWORD, false>(buffer, address);
#elif !defined(STM32WB) && !defined(STM32G4) && !defined(STM32G0) && !defined(STM32WBA)
for (uint8_t byte : buffer)
{
Expand All @@ -53,15 +73,35 @@ namespace hal
HAL_FLASH_Unlock();

#if defined(STM32WB) || defined(STM32G4) || defined(STM32G0) || defined(STM32WBA)
uint32_t pageError = 0;

FLASH_EraseInitTypeDef eraseInitStruct;
eraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
eraseInitStruct.Page = beginIndex;
eraseInitStruct.NbPages = endIndex - beginIndex;
auto erase = [](uint32_t beginIndex, uint32_t nbPages, uint32_t bank)
{
uint32_t sectorError = 0;

FLASH_EraseInitTypeDef eraseInitStruct{};
#if defined(FLASH_DBANK_SUPPORT)
eraseInitStruct.Banks = bank;
#endif
eraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
eraseInitStruct.Page = beginIndex;
eraseInitStruct.NbPages = nbPages;

auto result = HAL_FLASHEx_Erase(&eraseInitStruct, &sectorError);
really_assert(result == HAL_OK);
};

#if defined(FLASH_DBANK_SUPPORT)
if (GetBank(beginIndex) == GetBank(endIndex - 1))
erase(beginIndex % FLASH_PAGE_NB, endIndex - beginIndex, GetBank(beginIndex));
else
{
erase(beginIndex, FLASH_PAGE_NB - beginIndex, FLASH_BANK_1);
erase(0, endIndex - FLASH_PAGE_NB + 1, FLASH_BANK_2);
}
#else
erase(beginIndex, endIndex - beginIndex, 0);
#endif

auto result = HAL_FLASHEx_Erase(&eraseInitStruct, &pageError);
really_assert(result == HAL_OK);
#else
for (uint32_t index = beginIndex; index != endIndex; ++index)
{
Expand All @@ -79,51 +119,6 @@ namespace hal
HAL_FLASH_Lock();
}

template<typename alignment, uint32_t flashType>
void SynchronousFlashInternalStmBase::AlignedWriteBuffer(infra::ConstByteRange buffer, uint32_t address)
{
services::FlashAlign::WithAlignment<sizeof(alignment)> flashAlign;
flashAlign.Align(address, buffer);

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

for (alignment data : infra::ReinterpretCastMemoryRange<const alignment>(chunk->data))
{
auto result = HAL_FLASH_Program(flashType, fullAddress, data);
really_assert(result == HAL_OK);
fullAddress += sizeof(alignment);
}
chunk = flashAlign.Next();
}
}

#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
14 changes: 4 additions & 10 deletions hal_st/synchronous_stm32fxxx/SynchronousUartStm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,15 @@ namespace hal
uartHandle.Init.Parity = USART_PARITY_NONE;
uartHandle.Init.Mode = USART_MODE_TX_RX;
uartHandle.Init.HwFlowCtl = flowControl;
#if defined(STM32F0) || defined(STM32F3) || defined(STM32F7) || defined(STM32WB)
uartHandle.Init.OverSampling = USART_OVERSAMPLING_8;
#if defined(UART_ONE_BIT_SAMPLE_ENABLE)
uartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_ENABLE;
#else
uartHandle.Init.OverSampling = UART_OVERSAMPLING_8;
#endif
uartHandle.Init.OverSampling = UART_OVERSAMPLING_8;

HAL_UART_Init(&uartHandle);

peripheralUart[uartIndex]->CR2 &= ~USART_CLOCK_ENABLED;

#if defined(STM32F0) || defined(STM32F1) || defined(STM32F3) || defined(STM32F7) || defined(STM32WB) || defined(STM32G4) || defined(STM32G0)
peripheralUart[uartIndex]->CR1 |= 1 << (USART_IT_RXNE & USART_IT_MASK);
#else
peripheralUart[uartIndex]->CR1 |= USART_IT_RXNE & USART_IT_MASK;
#endif
peripheralUart[uartIndex]->CR1 |= USART_CR1_RXNEIE;
}

SynchronousUartStm::~SynchronousUartStm()
Expand Down
Loading