Skip to content

Commit

Permalink
hw/mcu/stm32h7: Use linear sector flash driver
Browse files Browse the repository at this point in the history
STM32H7 actually has liner flash with sectors of 128kB.
There is no need for stm32_flash_sectors table in BSP.

Additionally non-linear version that was used so far
would not compile for some H7 chips that have different
FLASH CR register and where FLASH_VOLATEG_RANGE_3 is not defined.

Liner sector variant was chosen when FLASH_PAGE_SIZE was defined.
While H7 and H5 don't have this definition they do have
FLASH_SECTOR_SIZE and when this definition is present
FLASH_IS_LINEAR is also set to 1

For U5 where minimal write size is 16 bytes function
stm32_flash_write_linear() was using to small buffer
possibly clobbering some stack values.
Now val variable is an array to accommodate 16 and 32
accesses needed for U5 and H7

Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>
  • Loading branch information
kasjer committed Apr 24, 2024
1 parent edfe1c1 commit 3e28786
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 23 deletions.
16 changes: 0 additions & 16 deletions hw/bsp/nucleo-h723zg/src/hal_bsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,6 @@ struct stm32_pwm_conf os_bsp_pwm2_cfg = {
};
#endif

const uint32_t stm32_flash_sectors[] = {
0x08000000, /* 128kB */
0x08020000, /* 128kB */
0x08040000, /* 128kB */
0x08060000, /* 128kB */
0x08080000, /* 128kB */
0x080a0000, /* 128kB */
0x080c0000, /* 128kB */
0x080e0000, /* 128kB */
0x08100000, /* End of flash */
};

#define SZ (sizeof(stm32_flash_sectors) / sizeof(stm32_flash_sectors[0]))
static_assert(MYNEWT_VAL(STM32_FLASH_NUM_AREAS) + 1 == SZ,
"STM32_FLASH_NUM_AREAS does not match flash sectors");

#if MYNEWT_VAL(UART_0)
const struct stm32_uart_cfg os_bsp_uart0_cfg = {
.suc_uart = USART3,
Expand Down
17 changes: 10 additions & 7 deletions hw/mcu/stm/stm32_common/src/hal_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#else
#define FLASH_SECTOR_SIZE FLASH_PAGE_SIZE
#endif
#elif defined(FLASH_SECTOR_SIZE)
#undef FLASH_IS_LINEAR
#define FLASH_IS_LINEAR 1
#endif

static int stm32_flash_read(const struct hal_flash *dev, uint32_t address,
Expand Down Expand Up @@ -80,11 +83,13 @@ stm32_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
}

#if FLASH_IS_LINEAR
#define VAL_SIZE (((MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) - 1) / 8) + 1)

static int
stm32_flash_write_linear(const struct hal_flash *dev, uint32_t address,
const void *src, uint32_t num_bytes)
{
uint64_t val;
uint64_t val[VAL_SIZE];
uint32_t i;
int rc;
uint8_t align;
Expand All @@ -102,6 +107,8 @@ stm32_flash_write_linear(const struct hal_flash *dev, uint32_t address,
num_words = ((num_bytes - 1) >> 3) + 1;
#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 16
num_words = ((num_bytes - 1) >> 4) + 1;
#elif MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) == 32
num_words = ((num_bytes - 1) >> 5) + 1;
#else
#error "Unsupported MCU_FLASH_MIN_WRITE_SIZE"
#endif
Expand All @@ -121,10 +128,10 @@ stm32_flash_write_linear(const struct hal_flash *dev, uint32_t address,
/* FIXME: L1 was previously unlocking flash before erasing/programming,
* and locking again afterwards. Maybe all MCUs should do the same?
*/
#if MYNEWT_VAL(MCU_STM32U5)
#if MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) > 8
rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, (uint32_t)&val);
#else
rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, val);
rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, val[0]);
#endif
if (rc != HAL_OK) {
return rc;
Expand Down Expand Up @@ -165,11 +172,7 @@ stm32_flash_write_non_linear(const struct hal_flash *dev, uint32_t address,
STM32_HAL_FLASH_CLEAR_ERRORS();

for (i = 0; i < num_bytes; i += inc) {
#if MYNEWT_VAL(MCU_STM32H7)
rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, (uint32_t)(sptr + i));
#else
rc = HAL_FLASH_Program(FLASH_PROGRAM_TYPE, address, sptr[i]);
#endif
if (rc != 0) {
return rc;
}
Expand Down
58 changes: 58 additions & 0 deletions hw/mcu/stm/stm32h7xx/src/hal_flash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#include <syscfg/syscfg.h>
#include <mcu/stm32_hal.h>
#include "hal/hal_flash_int.h"

#define STM32_FLASH_SIZE (MYNEWT_VAL(STM32_FLASH_SIZE_KB) * 1024)

int
stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
{
FLASH_EraseInitTypeDef eraseinit;
uint32_t PageError;
HAL_StatusTypeDef rc;

(void)PageError;

if (!(sector_address & (FLASH_SECTOR_SIZE - 1))) {
eraseinit.TypeErase = FLASH_TYPEERASE_SECTORS;
#ifdef FLASH_BANK_2
if ((sector_address - dev->hf_base_addr) < (STM32_FLASH_SIZE / 2)) {
eraseinit.Banks = FLASH_BANK_1;
} else {
eraseinit.Banks = FLASH_BANK_2;
}
#else
eraseinit.Banks = FLASH_BANK_1;
#endif
eraseinit.Sector = (sector_address - dev->hf_base_addr) / FLASH_SECTOR_SIZE;
eraseinit.NbSectors = 1;
#if defined(FLASH_CR_PSIZE)
eraseinit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
#endif
rc = HAL_FLASHEx_Erase(&eraseinit, &PageError);
if (rc == HAL_OK) {
return 0;
}
}

return -1;
}

0 comments on commit 3e28786

Please sign in to comment.