Merge pull request #8917 from aabadie/pr/cpu/flashpage_l4
cpu/stm32l4: add support for flashpage
This commit is contained in:
commit
3e7c5423e5
@ -31,6 +31,10 @@
|
|||||||
#define CNTRL_REG_LOCK (FLASH_PECR_PELOCK)
|
#define CNTRL_REG_LOCK (FLASH_PECR_PELOCK)
|
||||||
#define KEY_REG (FLASH->PEKEYR)
|
#define KEY_REG (FLASH->PEKEYR)
|
||||||
#else
|
#else
|
||||||
|
#if defined(CPU_FAM_STM32L4)
|
||||||
|
#define FLASH_KEY1 ((uint32_t)0x45670123)
|
||||||
|
#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
|
||||||
|
#endif
|
||||||
#define CNTRL_REG (FLASH->CR)
|
#define CNTRL_REG (FLASH->CR)
|
||||||
#define CNTRL_REG_LOCK (FLASH_CR_LOCK)
|
#define CNTRL_REG_LOCK (FLASH_CR_LOCK)
|
||||||
#define KEY_REG (FLASH->KEYR)
|
#define KEY_REG (FLASH->KEYR)
|
||||||
|
|||||||
@ -41,9 +41,13 @@
|
|||||||
#define FLASH_CR_PG (FLASH_PECR_FPRG | FLASH_PECR_PROG)
|
#define FLASH_CR_PG (FLASH_PECR_FPRG | FLASH_PECR_PROG)
|
||||||
#define FLASHPAGE_DIV (4U) /* write 4 bytes in one go */
|
#define FLASHPAGE_DIV (4U) /* write 4 bytes in one go */
|
||||||
#else
|
#else
|
||||||
|
#if defined(CPU_FAM_STM32L4)
|
||||||
|
#define FLASHPAGE_DIV (8U)
|
||||||
|
#else
|
||||||
|
#define FLASHPAGE_DIV (2U)
|
||||||
|
#endif
|
||||||
#define CNTRL_REG (FLASH->CR)
|
#define CNTRL_REG (FLASH->CR)
|
||||||
#define CNTRL_REG_LOCK (FLASH_CR_LOCK)
|
#define CNTRL_REG_LOCK (FLASH_CR_LOCK)
|
||||||
#define FLASHPAGE_DIV (2U)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void _lock(void);
|
extern void _lock(void);
|
||||||
@ -78,7 +82,8 @@ static void _wait_for_pending_operations(void)
|
|||||||
|
|
||||||
static void _erase_page(void *page_addr)
|
static void _erase_page(void *page_addr)
|
||||||
{
|
{
|
||||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) || \
|
||||||
|
defined(CPU_FAM_STM32L4)
|
||||||
uint32_t *dst = page_addr;
|
uint32_t *dst = page_addr;
|
||||||
#else
|
#else
|
||||||
uint16_t *dst = page_addr;
|
uint16_t *dst = page_addr;
|
||||||
@ -101,7 +106,25 @@ static void _erase_page(void *page_addr)
|
|||||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
||||||
DEBUG("[flashpage] erase: trigger the page erase\n");
|
DEBUG("[flashpage] erase: trigger the page erase\n");
|
||||||
*dst = (uint32_t)0;
|
*dst = (uint32_t)0;
|
||||||
|
#elif defined(CPU_FAM_STM32L4)
|
||||||
|
DEBUG("[flashpage] erase: setting the page address\n");
|
||||||
|
CNTRL_REG |= FLASH_CR_PER;
|
||||||
|
uint8_t pn;
|
||||||
|
#if FLASHPAGE_NUMOF <= 256
|
||||||
|
pn = (uint8_t)flashpage_page(dst);
|
||||||
#else
|
#else
|
||||||
|
uint16_t page = flashpage_page(dst);
|
||||||
|
if (page > 255) {
|
||||||
|
CNTRL_REG |= FLASH_CR_BKER;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CNTRL_REG &= ~FLASH_CR_BKER;
|
||||||
|
}
|
||||||
|
pn = (uint8_t)page;
|
||||||
|
#endif
|
||||||
|
CNTRL_REG |= (uint32_t)(pn << FLASH_CR_PNB_Pos);
|
||||||
|
CNTRL_REG |= FLASH_CR_STRT;
|
||||||
|
#else /* CPU_FAM_STM32F0 || CPU_FAM_STM32F1 */
|
||||||
DEBUG("[flashpage] erase: setting the page address\n");
|
DEBUG("[flashpage] erase: setting the page address\n");
|
||||||
FLASH->AR = (uint32_t)dst;
|
FLASH->AR = (uint32_t)dst;
|
||||||
/* trigger the page erase and wait for it to be finished */
|
/* trigger the page erase and wait for it to be finished */
|
||||||
@ -118,7 +141,8 @@ static void _erase_page(void *page_addr)
|
|||||||
/* lock the flash module again */
|
/* lock the flash module again */
|
||||||
_lock();
|
_lock();
|
||||||
|
|
||||||
#if !(defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1))
|
#if !(defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) || \
|
||||||
|
defined(CPU_FAM_STM32L4))
|
||||||
/* restore the HSI state */
|
/* restore the HSI state */
|
||||||
if (!hsi_state) {
|
if (!hsi_state) {
|
||||||
stmclk_disable_hsi();
|
stmclk_disable_hsi();
|
||||||
@ -143,6 +167,9 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
||||||
uint32_t *dst = target_addr;
|
uint32_t *dst = target_addr;
|
||||||
const uint32_t *data_addr = data;
|
const uint32_t *data_addr = data;
|
||||||
|
#elif defined(CPU_FAM_STM32L4)
|
||||||
|
uint64_t *dst = target_addr;
|
||||||
|
const uint64_t *data_addr = data;
|
||||||
#else
|
#else
|
||||||
uint16_t *dst = (uint16_t *)target_addr;
|
uint16_t *dst = (uint16_t *)target_addr;
|
||||||
const uint16_t *data_addr = data;
|
const uint16_t *data_addr = data;
|
||||||
@ -174,7 +201,8 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
/* lock the flash module again */
|
/* lock the flash module again */
|
||||||
_lock();
|
_lock();
|
||||||
|
|
||||||
#if !(defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1))
|
#if !(defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) || \
|
||||||
|
defined(CPU_FAM_STM32L4))
|
||||||
/* restore the HSI state */
|
/* restore the HSI state */
|
||||||
if (!hsi_state) {
|
if (!hsi_state) {
|
||||||
stmclk_disable_hsi();
|
stmclk_disable_hsi();
|
||||||
@ -189,6 +217,8 @@ void flashpage_write(int page, const void *data)
|
|||||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
||||||
/* STM32L0/L1 only supports word sizes */
|
/* STM32L0/L1 only supports word sizes */
|
||||||
uint32_t *page_addr = flashpage_addr(page);
|
uint32_t *page_addr = flashpage_addr(page);
|
||||||
|
#elif defined(CPU_FAM_STM32L4)
|
||||||
|
uint64_t *page_addr = flashpage_addr(page);
|
||||||
#else
|
#else
|
||||||
/* Default is to support half-word sizes */
|
/* Default is to support half-word sizes */
|
||||||
uint16_t *page_addr = flashpage_addr(page);
|
uint16_t *page_addr = flashpage_addr(page);
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
FEATURES_PROVIDED += periph_flash_common
|
||||||
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
|
FEATURES_PROVIDED += periph_flashpage_raw
|
||||||
FEATURES_PROVIDED += periph_hwrng
|
FEATURES_PROVIDED += periph_hwrng
|
||||||
|
|
||||||
-include $(RIOTCPU)/stm32_common/Makefile.features
|
-include $(RIOTCPU)/stm32_common/Makefile.features
|
||||||
|
|||||||
@ -57,6 +57,27 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Flash page configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define FLASHPAGE_SIZE (2048U)
|
||||||
|
|
||||||
|
#if defined(CPU_MODEL_STM32L432KC) || defined(CPU_MODEL_STM32L433RC)
|
||||||
|
#define FLASHPAGE_NUMOF (128U)
|
||||||
|
#elif defined(CPU_MODEL_STM32L452RE)
|
||||||
|
#define FLASHPAGE_NUMOF (256U)
|
||||||
|
#else
|
||||||
|
#define FLASHPAGE_NUMOF (512U)
|
||||||
|
#endif
|
||||||
|
/* The minimum block size which can be written is 8B. However, the erase
|
||||||
|
* block is always FLASHPAGE_SIZE.
|
||||||
|
*/
|
||||||
|
#define FLASHPAGE_RAW_BLOCKSIZE (8U)
|
||||||
|
/* Writing should be always 8 bytes aligned */
|
||||||
|
#define FLASHPAGE_RAW_ALIGNMENT (8U)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -28,25 +28,28 @@
|
|||||||
|
|
||||||
#define LINE_LEN (16)
|
#define LINE_LEN (16)
|
||||||
|
|
||||||
/**
|
/* When writing raw bytes on flash, data must be correctly aligned. */
|
||||||
* @brief Allocate space for 1 flash page in RAM
|
|
||||||
*/
|
|
||||||
static uint8_t page_mem[FLASHPAGE_SIZE];
|
|
||||||
|
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
||||||
|
#define ALIGNMENT_ATTR __attribute__ ((aligned (FLASHPAGE_RAW_ALIGNMENT)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Allocate an aligned buffer for raw writings
|
* @brief Allocate an aligned buffer for raw writings
|
||||||
*/
|
*/
|
||||||
static char raw_buf[64] __attribute__ ((aligned (FLASHPAGE_RAW_ALIGNMENT)));
|
static char raw_buf[64] ALIGNMENT_ATTR;
|
||||||
|
#else
|
||||||
static uint32_t getaddr(const char *str)
|
#define ALIGNMENT_ATTR
|
||||||
{
|
|
||||||
uint32_t addr = strtol(str, NULL, 16);
|
|
||||||
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate space for 1 flash page in RAM
|
||||||
|
*
|
||||||
|
* @note The flash page in RAM must be correctly aligned, even in RAM, when
|
||||||
|
* using flashpage_raw. This is because some architecture uses
|
||||||
|
* 32 bit alignment implicitly and there are cases (stm32l4) that
|
||||||
|
* requires 64 bit alignment.
|
||||||
|
*/
|
||||||
|
static uint8_t page_mem[FLASHPAGE_SIZE] ALIGNMENT_ATTR;
|
||||||
|
|
||||||
static int getpage(const char *str)
|
static int getpage(const char *str)
|
||||||
{
|
{
|
||||||
int page = atoi(str);
|
int page = atoi(str);
|
||||||
@ -180,6 +183,13 @@ static int cmd_write(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
||||||
|
static uint32_t getaddr(const char *str)
|
||||||
|
{
|
||||||
|
uint32_t addr = strtol(str, NULL, 16);
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_write_raw(int argc, char **argv)
|
static int cmd_write_raw(int argc, char **argv)
|
||||||
{
|
{
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user