Merge pull request #15412 from bergzand/pr/flashpage/merge_raw
periph_flashpage: Make pagewise API optional
This commit is contained in:
commit
d9598a0f54
@ -11,7 +11,7 @@ config CPU_FAM_CC2538
|
|||||||
select HAS_CPU_CC2538
|
select HAS_CPU_CC2538
|
||||||
select HAS_PERIPH_CPUID
|
select HAS_PERIPH_CPUID
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_GPIO
|
select HAS_PERIPH_GPIO
|
||||||
select HAS_PERIPH_GPIO_IRQ
|
select HAS_PERIPH_GPIO_IRQ
|
||||||
select HAS_PERIPH_HWRNG
|
select HAS_PERIPH_HWRNG
|
||||||
|
|||||||
@ -3,7 +3,7 @@ CPU_FAM = cc2538
|
|||||||
|
|
||||||
FEATURES_PROVIDED += periph_cpuid
|
FEATURES_PROVIDED += periph_cpuid
|
||||||
FEATURES_PROVIDED += periph_flashpage
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
FEATURES_PROVIDED += periph_flashpage_raw
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
||||||
FEATURES_PROVIDED += periph_hwrng
|
FEATURES_PROVIDED += periph_hwrng
|
||||||
FEATURES_PROVIDED += periph_uart_modecfg
|
FEATURES_PROVIDED += periph_uart_modecfg
|
||||||
|
|||||||
@ -65,9 +65,9 @@ extern "C" {
|
|||||||
/* The minimum block size which can be written is 4B. However, the erase
|
/* The minimum block size which can be written is 4B. However, the erase
|
||||||
* block is always FLASHPAGE_SIZE.
|
* block is always FLASHPAGE_SIZE.
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
|
||||||
/* Writing should be always 4 bytes aligned */
|
/* Writing should be always 4 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (4U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -61,16 +61,25 @@ static inline void _erase(uint32_t *page_addr)
|
|||||||
irq_restore(state);
|
irq_restore(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((section (".ramfunc")))
|
void flashpage_erase(unsigned page)
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|
||||||
{
|
{
|
||||||
/* assert multiples of FLASHPAGE_RAW_BLOCKSIZE are written and no less of
|
assert((unsigned) page < FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
|
uint32_t *page_addr = (uint32_t *)flashpage_addr(page);
|
||||||
|
|
||||||
|
_erase(page_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section (".ramfunc")))
|
||||||
|
void flashpage_write(void *target_addr, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
/* assert multiples of FLASHPAGE_WRITE_BLOCK_SIZE are written and no less of
|
||||||
that length. */
|
that length. */
|
||||||
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
|
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
|
||||||
|
|
||||||
/* ensure writes are aligned */
|
/* ensure writes are aligned */
|
||||||
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
|
assert(!(((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) ||
|
||||||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
|
((unsigned)data % FLASHPAGE_WRITE_BLOCK_ALIGNMENT)));
|
||||||
|
|
||||||
/* ensure the length doesn't exceed the actual flash size */
|
/* ensure the length doesn't exceed the actual flash size */
|
||||||
assert(((unsigned)target_addr + len) <=
|
assert(((unsigned)target_addr + len) <=
|
||||||
@ -90,7 +99,7 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
/* starts the write-sequence state machine */
|
/* starts the write-sequence state machine */
|
||||||
DEBUG("[flashpage_raw] write: now writing the data\n");
|
DEBUG("[flashpage_raw] write: now writing the data\n");
|
||||||
FLASH_CTRL_FCTL |= FLASH_CTRL_FCTL_WRITE;
|
FLASH_CTRL_FCTL |= FLASH_CTRL_FCTL_WRITE;
|
||||||
for (unsigned i = 0; i < (len / FLASHPAGE_RAW_BLOCKSIZE); i++) {
|
for (unsigned i = 0; i < (len / FLASHPAGE_WRITE_BLOCK_SIZE); i++) {
|
||||||
FLASH_CTRL_FWDATA = (uint32_t) *(data_addr++);
|
FLASH_CTRL_FWDATA = (uint32_t) *(data_addr++);
|
||||||
/* wait for flash operation to complete */
|
/* wait for flash operation to complete */
|
||||||
while (FLASH_CTRL_FCTL & FLASH_CTRL_FCTL_FULL) {}
|
while (FLASH_CTRL_FCTL & FLASH_CTRL_FCTL_FULL) {}
|
||||||
@ -98,18 +107,3 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
/* re-enable interrupts */
|
/* re-enable interrupts */
|
||||||
irq_restore(state);
|
irq_restore(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write(int page, const void *data)
|
|
||||||
{
|
|
||||||
assert((unsigned) page < FLASHPAGE_NUMOF);
|
|
||||||
|
|
||||||
uint32_t *page_addr = (uint32_t *)flashpage_addr(page);
|
|
||||||
|
|
||||||
/* erase page */
|
|
||||||
_erase(page_addr);
|
|
||||||
|
|
||||||
/* write page */
|
|
||||||
if (data != NULL) {
|
|
||||||
flashpage_write_raw(page_addr, data, FLASHPAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ config CPU_COMMON_EFM32
|
|||||||
select HAS_CPU_EFM32
|
select HAS_CPU_EFM32
|
||||||
select HAS_PERIPH_CPUID
|
select HAS_PERIPH_CPUID
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_GPIO
|
select HAS_PERIPH_GPIO
|
||||||
select HAS_PERIPH_GPIO_IRQ
|
select HAS_PERIPH_GPIO_IRQ
|
||||||
select HAS_PERIPH_WDT
|
select HAS_PERIPH_WDT
|
||||||
|
|||||||
@ -11,7 +11,7 @@ endif
|
|||||||
FEATURES_PROVIDED += arch_efm32
|
FEATURES_PROVIDED += arch_efm32
|
||||||
FEATURES_PROVIDED += periph_cpuid
|
FEATURES_PROVIDED += periph_cpuid
|
||||||
FEATURES_PROVIDED += periph_flashpage
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
FEATURES_PROVIDED += periph_flashpage_raw
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
||||||
FEATURES_PROVIDED += periph_wdt
|
FEATURES_PROVIDED += periph_wdt
|
||||||
|
|
||||||
|
|||||||
@ -46,9 +46,9 @@ extern "C" {
|
|||||||
/* The minimum block size which can be written is 4B. However, the erase
|
/* The minimum block size which can be written is 4B. However, the erase
|
||||||
* block is always FLASHPAGE_SIZE.
|
* block is always FLASHPAGE_SIZE.
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
|
||||||
/* Writing should be always 4 bytes aligned */
|
/* Writing should be always 4 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (4U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -26,15 +26,27 @@
|
|||||||
|
|
||||||
#include "em_msc.h"
|
#include "em_msc.h"
|
||||||
|
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
void flashpage_erase(unsigned page)
|
||||||
{
|
{
|
||||||
/* assert multiples of FLASHPAGE_RAW_BLOCKSIZE are written and no less of
|
assert(page < (int)FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
|
uint32_t *page_addr = (uint32_t *)flashpage_addr(page);
|
||||||
|
|
||||||
|
/* erase given page */
|
||||||
|
MSC_Init();
|
||||||
|
MSC_ErasePage(page_addr);
|
||||||
|
MSC_Deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void flashpage_write(void *target_addr, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
/* assert multiples of FLASHPAGE_WRITE_BLOCK_SIZE are written and no less of
|
||||||
that length. */
|
that length. */
|
||||||
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
|
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
|
||||||
|
|
||||||
/* ensure writes are aligned */
|
/* ensure writes are aligned */
|
||||||
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
|
assert(!(((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) ||
|
||||||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
|
((unsigned)data % FLASHPAGE_WRITE_BLOCK_ALIGNMENT)));
|
||||||
|
|
||||||
/* ensure the length doesn't exceed the actual flash size */
|
/* ensure the length doesn't exceed the actual flash size */
|
||||||
assert(((unsigned)target_addr + len) <
|
assert(((unsigned)target_addr + len) <
|
||||||
@ -47,20 +59,3 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
MSC_WriteWord(page_addr, data_addr, len);
|
MSC_WriteWord(page_addr, data_addr, len);
|
||||||
MSC_Deinit();
|
MSC_Deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write(int page, const void *data)
|
|
||||||
{
|
|
||||||
assert(page < (int)FLASHPAGE_NUMOF);
|
|
||||||
|
|
||||||
uint32_t *page_addr = (uint32_t *)flashpage_addr(page);
|
|
||||||
|
|
||||||
/* erase given page */
|
|
||||||
MSC_Init();
|
|
||||||
MSC_ErasePage(page_addr);
|
|
||||||
MSC_Deinit();
|
|
||||||
|
|
||||||
/* write data to page */
|
|
||||||
if (data != NULL) {
|
|
||||||
flashpage_write_raw(page_addr, data, FLASHPAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ config CPU_FAM_K
|
|||||||
bool
|
bool
|
||||||
select CPU_COMMON_KINETIS
|
select CPU_COMMON_KINETIS
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_MCG
|
select HAS_PERIPH_MCG
|
||||||
|
|
||||||
config CPU_FAM_L
|
config CPU_FAM_L
|
||||||
@ -33,7 +33,7 @@ config CPU_FAM_W
|
|||||||
bool
|
bool
|
||||||
select CPU_COMMON_KINETIS
|
select CPU_COMMON_KINETIS
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_MCG
|
select HAS_PERIPH_MCG
|
||||||
|
|
||||||
## CPU Models
|
## CPU Models
|
||||||
|
|||||||
@ -21,7 +21,7 @@ include $(LAST_MAKEFILEDIR)/kinetis-info.mk
|
|||||||
|
|
||||||
ifneq (,$(filter k w,$(CPU_FAM)))
|
ifneq (,$(filter k w,$(CPU_FAM)))
|
||||||
FEATURES_PROVIDED += periph_flashpage
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
FEATURES_PROVIDED += periph_flashpage_raw
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (ea,$(CPU_FAM))
|
ifeq (ea,$(CPU_FAM))
|
||||||
|
|||||||
@ -146,12 +146,12 @@
|
|||||||
/* The minimum block size which can be written is 8B (Phrase). However, the
|
/* The minimum block size which can be written is 8B (Phrase). However, the
|
||||||
* erase block is always FLASHPAGE_SIZE.
|
* erase block is always FLASHPAGE_SIZE.
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_PHRASE (8U)
|
#define FLASHPAGE_BLOCK_PHRASE (8U)
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE FLASHPAGE_RAW_PHRASE
|
#define FLASHPAGE_WRITE_BLOCK_SIZE FLASHPAGE_BLOCK_PHRASE
|
||||||
/* Writing should be always 8 bytes aligned */
|
/* Writing should be always 8 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT FLASHPAGE_RAW_PHRASE
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT FLASHPAGE_BLOCK_PHRASE
|
||||||
/* Section erase and programming must be 16 bytes aligned */
|
/* Section erase and programming must be 16 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_SECTION_ALIGNMENT (16U)
|
#define FLASHPAGE_BLOCK_SECTION_ALIGNMENT (16U)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -87,11 +87,11 @@
|
|||||||
/* The minimum block size which can be written is 4B. However, the erase
|
/* The minimum block size which can be written is 4B. However, the erase
|
||||||
* block is always FLASHPAGE_SIZE.
|
* block is always FLASHPAGE_SIZE.
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
|
||||||
/* Writing should be always 4 bytes aligned */
|
/* Writing should be always 4 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (4U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
|
||||||
/* Section erase and programming must be 8 bytes aligned */
|
/* Section erase and programming must be 8 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_SECTION_ALIGNMENT (8U)
|
#define FLASHPAGE_BLOCK_SECTION_ALIGNMENT (8U)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -132,12 +132,12 @@ static int _check_errors(void)
|
|||||||
static int _verify_erased(uint32_t address, size_t len)
|
static int _verify_erased(uint32_t address, size_t len)
|
||||||
{
|
{
|
||||||
/* Ensures verifies are aligned */
|
/* Ensures verifies are aligned */
|
||||||
assert(!(address % FLASHPAGE_RAW_SECTION_ALIGNMENT));
|
assert(!(address % FLASHPAGE_BLOCK_SECTION_ALIGNMENT));
|
||||||
|
|
||||||
/* We verify FLASHPAGE_RAW_SECTION_ALIGNMENT Bytes at a time, we
|
/* We verify FLASHPAGE_BLOCK_SECTION_ALIGNMENT Bytes at a time, we
|
||||||
round up before adjusting to FLASHPAGE_RAW_SECTION_ALIGNMENT */
|
round up before adjusting to FLASHPAGE_BLOCK_SECTION_ALIGNMENT */
|
||||||
uint32_t num = (len + (FLASHPAGE_RAW_SECTION_ALIGNMENT - 1)) /
|
uint32_t num = (len + (FLASHPAGE_BLOCK_SECTION_ALIGNMENT - 1)) /
|
||||||
FLASHPAGE_RAW_SECTION_ALIGNMENT;
|
FLASHPAGE_BLOCK_SECTION_ALIGNMENT;
|
||||||
|
|
||||||
/* Setup command and run */
|
/* Setup command and run */
|
||||||
FCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_VERIFY_SECTION, address);
|
FCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_VERIFY_SECTION, address);
|
||||||
@ -150,7 +150,7 @@ static int _verify_erased(uint32_t address, size_t len)
|
|||||||
static int _sector_erase(uint32_t address)
|
static int _sector_erase(uint32_t address)
|
||||||
{
|
{
|
||||||
/* Ensures erases are aligned */
|
/* Ensures erases are aligned */
|
||||||
assert(!(address % FLASHPAGE_RAW_SECTION_ALIGNMENT));
|
assert(!(address % FLASHPAGE_BLOCK_SECTION_ALIGNMENT));
|
||||||
|
|
||||||
/* Setup command and run */
|
/* Setup command and run */
|
||||||
FCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_SECTOR, address);
|
FCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_SECTOR, address);
|
||||||
@ -163,7 +163,7 @@ static int _flash_write(uint32_t address, uint32_t *data)
|
|||||||
{
|
{
|
||||||
/* Setup command and run */
|
/* Setup command and run */
|
||||||
FCCOBx[1] = *data++;
|
FCCOBx[1] = *data++;
|
||||||
if (FLASHPAGE_RAW_BLOCKSIZE == 8U) {
|
if (FLASHPAGE_WRITE_BLOCK_SIZE == 8U) {
|
||||||
FCCOBx[2] = *data;
|
FCCOBx[2] = *data;
|
||||||
FCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_PHRASE, address);
|
FCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_PHRASE, address);
|
||||||
}
|
}
|
||||||
@ -175,21 +175,29 @@ static int _flash_write(uint32_t address, uint32_t *data)
|
|||||||
return _check_errors();
|
return _check_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
void flashpage_erase(unsigned page)
|
||||||
{
|
{
|
||||||
/* Assert multiples of FLASHPAGE_RAW_BLOCKSIZE are written and no less of
|
assert(page < (int)FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
|
/* ERASE sector */
|
||||||
|
_sector_erase((uint32_t)flashpage_addr(page));
|
||||||
|
}
|
||||||
|
|
||||||
|
void flashpage_write(void *target_addr, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
/* Assert multiples of FLASHPAGE_WRITE_BLOCK_SIZE are written and no less of
|
||||||
that length. */
|
that length. */
|
||||||
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
|
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
|
||||||
|
|
||||||
/* Ensure writes are aligned */
|
/* Ensure writes are aligned */
|
||||||
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
|
assert(!(((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) ||
|
||||||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
|
((unsigned)data % FLASHPAGE_WRITE_BLOCK_ALIGNMENT)));
|
||||||
|
|
||||||
/* Ensure the length doesn't exceed the actual flash size */
|
/* Ensure the length doesn't exceed the actual flash size */
|
||||||
assert(((unsigned)target_addr + len) <
|
assert(((unsigned)target_addr + len) <
|
||||||
(CPU_FLASH_BASE + (FLASHPAGE_SIZE * FLASHPAGE_NUMOF)) + 1);
|
(CPU_FLASH_BASE + (FLASHPAGE_SIZE * FLASHPAGE_NUMOF)) + 1);
|
||||||
|
|
||||||
#ifdef FLASHPAGE_RAW_PHRASE
|
#ifdef FLASHPAGE_BLOCK_PHRASE
|
||||||
const uint64_t *data_addr = data;
|
const uint64_t *data_addr = data;
|
||||||
uint64_t *dst = target_addr;
|
uint64_t *dst = target_addr;
|
||||||
#else
|
#else
|
||||||
@ -203,24 +211,9 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write to flash FLASHPAGE_RAW_BLOCKSIZE bytes at a time */
|
/* Write to flash FLASHPAGE_WRITE_BLOCK_SIZE bytes at a time */
|
||||||
for (size_t i = 0; i < (len / FLASHPAGE_RAW_BLOCKSIZE); i++) {
|
for (size_t i = 0; i < (len / FLASHPAGE_WRITE_BLOCK_SIZE); i++) {
|
||||||
_flash_write((uint32_t) dst++, (uint32_t *) data_addr++);
|
_flash_write((uint32_t) dst++, (uint32_t *) data_addr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write(int page, const void *data)
|
|
||||||
{
|
|
||||||
assert(page < (int)FLASHPAGE_NUMOF);
|
|
||||||
|
|
||||||
uint32_t *page_addr = flashpage_addr(page);
|
|
||||||
|
|
||||||
/* ERASE sector */
|
|
||||||
_sector_erase((uint32_t)page_addr);
|
|
||||||
|
|
||||||
/* WRITE sector */
|
|
||||||
if (data != NULL) {
|
|
||||||
flashpage_write_raw(page_addr, data, FLASHPAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ config CPU_ARCH_MSP430
|
|||||||
select HAS_ARCH_16BIT
|
select HAS_ARCH_16BIT
|
||||||
select HAS_ARCH_MSP430
|
select HAS_ARCH_MSP430
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_PM
|
select HAS_PERIPH_PM
|
||||||
|
|
||||||
config CPU_CORE_MSP430
|
config CPU_CORE_MSP430
|
||||||
|
|||||||
@ -4,5 +4,5 @@ CPU_CORE = msp430
|
|||||||
FEATURES_PROVIDED += arch_16bit
|
FEATURES_PROVIDED += arch_16bit
|
||||||
FEATURES_PROVIDED += arch_msp430
|
FEATURES_PROVIDED += arch_msp430
|
||||||
FEATURES_PROVIDED += periph_flashpage
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
FEATURES_PROVIDED += periph_flashpage_raw
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
FEATURES_PROVIDED += periph_pm
|
FEATURES_PROVIDED += periph_pm
|
||||||
|
|||||||
@ -50,9 +50,9 @@ extern "C" {
|
|||||||
/* The minimum block size which can be written is 1B. However, the erase
|
/* The minimum block size which can be written is 1B. However, the erase
|
||||||
* block is always FLASHPAGE_SIZE.
|
* block is always FLASHPAGE_SIZE.
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (1U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (1U)
|
||||||
/* Writing should be always 2 byte aligned */
|
/* Writing should be always 2 byte aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (2U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (2U)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -55,15 +55,25 @@ static inline void _erase(uint16_t *page_addr)
|
|||||||
_lock(state);
|
_lock(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
void flashpage_erase(unsigned page)
|
||||||
{
|
{
|
||||||
/* assert multiples of FLASHPAGE_RAW_BLOCKSIZE are written and no less of
|
assert((unsigned) page < FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
|
uint16_t *page_addr = (uint16_t *)flashpage_addr(page);
|
||||||
|
|
||||||
|
/* erase page */
|
||||||
|
_erase(page_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flashpage_write(void *target_addr, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
/* assert multiples of FLASHPAGE_WRITE_BLOCK_SIZE are written and no less of
|
||||||
that length. */
|
that length. */
|
||||||
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
|
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
|
||||||
|
|
||||||
/* ensure writes are aligned */
|
/* ensure writes are aligned */
|
||||||
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
|
assert(!(((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) ||
|
||||||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
|
((unsigned)data % FLASHPAGE_WRITE_BLOCK_ALIGNMENT)));
|
||||||
|
|
||||||
/* ensure the length doesn't exceed the actual flash size */
|
/* ensure the length doesn't exceed the actual flash size */
|
||||||
assert(((unsigned)target_addr + len) <
|
assert(((unsigned)target_addr + len) <
|
||||||
@ -87,18 +97,3 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
/* lock flash and re-enable interrupts */
|
/* lock flash and re-enable interrupts */
|
||||||
_lock(state);
|
_lock(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write(int page, const void *data)
|
|
||||||
{
|
|
||||||
assert((unsigned) page < FLASHPAGE_NUMOF);
|
|
||||||
|
|
||||||
uint16_t *page_addr = (uint16_t *)flashpage_addr(page);
|
|
||||||
|
|
||||||
/* erase page */
|
|
||||||
_erase(page_addr);
|
|
||||||
|
|
||||||
/* write page */
|
|
||||||
if (data != NULL) {
|
|
||||||
flashpage_write_raw(page_addr, data, FLASHPAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -52,9 +52,9 @@ extern "C" {
|
|||||||
/* The minimum block size which can be written is 4B. However, the erase
|
/* The minimum block size which can be written is 4B. However, the erase
|
||||||
* block is always FLASHPAGE_SIZE.
|
* block is always FLASHPAGE_SIZE.
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
|
||||||
/* Writing should be always 4 bytes aligned */
|
/* Writing should be always 4 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (4U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -107,9 +107,9 @@ extern "C" {
|
|||||||
/* The minimum block size which can be written is 4B. However, the erase
|
/* The minimum block size which can be written is 4B. However, the erase
|
||||||
* block is always FLASHPAGE_SIZE.
|
* block is always FLASHPAGE_SIZE.
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
|
||||||
/* Writing should be always 4 bytes aligned */
|
/* Writing should be always 4 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (4U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef CPU_MODEL_NRF52840XXAA
|
#ifdef CPU_MODEL_NRF52840XXAA
|
||||||
|
|||||||
@ -8,7 +8,7 @@ config CPU_COMMON_NRF5X
|
|||||||
bool
|
bool
|
||||||
select HAS_PERIPH_CPUID
|
select HAS_PERIPH_CPUID
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_GPIO
|
select HAS_PERIPH_GPIO
|
||||||
select HAS_PERIPH_GPIO_IRQ
|
select HAS_PERIPH_GPIO_IRQ
|
||||||
select HAS_PERIPH_HWRNG
|
select HAS_PERIPH_HWRNG
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
# Put defined MCU peripherals here (in alphabetical order)
|
# Put defined MCU peripherals here (in alphabetical order)
|
||||||
FEATURES_PROVIDED += periph_cpuid
|
FEATURES_PROVIDED += periph_cpuid
|
||||||
FEATURES_PROVIDED += periph_flashpage
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
FEATURES_PROVIDED += periph_flashpage_raw
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
||||||
FEATURES_PROVIDED += periph_hwrng
|
FEATURES_PROVIDED += periph_hwrng
|
||||||
FEATURES_PROVIDED += periph_temperature
|
FEATURES_PROVIDED += periph_temperature
|
||||||
|
|||||||
@ -23,33 +23,7 @@
|
|||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "periph/flashpage.h"
|
#include "periph/flashpage.h"
|
||||||
|
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
void flashpage_erase(unsigned page)
|
||||||
{
|
|
||||||
/* assert multiples of FLASHPAGE_RAW_BLOCKSIZE are written and no less of
|
|
||||||
that length. */
|
|
||||||
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
|
|
||||||
|
|
||||||
/* ensure writes are aligned */
|
|
||||||
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
|
|
||||||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
|
|
||||||
|
|
||||||
/* ensure the length doesn't exceed the actual flash size */
|
|
||||||
assert(((unsigned)target_addr + len) <
|
|
||||||
(CPU_FLASH_BASE + (FLASHPAGE_SIZE * FLASHPAGE_NUMOF)) + 1);
|
|
||||||
|
|
||||||
uint32_t *page_addr = target_addr;
|
|
||||||
const uint32_t *data_addr = data;
|
|
||||||
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
|
|
||||||
for (unsigned i = 0; i < (len / FLASHPAGE_RAW_BLOCKSIZE); i++) {
|
|
||||||
*page_addr++ = data_addr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finish up */
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flashpage_write(int page, const void *data)
|
|
||||||
{
|
{
|
||||||
assert(page < (int)FLASHPAGE_NUMOF);
|
assert(page < (int)FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
@ -59,9 +33,30 @@ void flashpage_write(int page, const void *data)
|
|||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
|
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
|
||||||
NRF_NVMC->ERASEPAGE = (uint32_t)page_addr;
|
NRF_NVMC->ERASEPAGE = (uint32_t)page_addr;
|
||||||
while (NRF_NVMC->READY == 0) {}
|
while (NRF_NVMC->READY == 0) {}
|
||||||
|
}
|
||||||
/* write data to page */
|
|
||||||
if (data != NULL) {
|
void flashpage_write(void *target_addr, const void *data, size_t len)
|
||||||
flashpage_write_raw(page_addr, data, FLASHPAGE_SIZE);
|
{
|
||||||
}
|
/* assert multiples of FLASHPAGE_WRITE_BLOCK_SIZE are written and no less of
|
||||||
|
that length. */
|
||||||
|
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
|
||||||
|
|
||||||
|
/* ensure writes are aligned */
|
||||||
|
assert(!(((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) ||
|
||||||
|
((unsigned)data % FLASHPAGE_WRITE_BLOCK_ALIGNMENT)));
|
||||||
|
|
||||||
|
/* ensure the length doesn't exceed the actual flash size */
|
||||||
|
assert(((unsigned)target_addr + len) <
|
||||||
|
(CPU_FLASH_BASE + (FLASHPAGE_SIZE * FLASHPAGE_NUMOF)) + 1);
|
||||||
|
|
||||||
|
uint32_t *page_addr = target_addr;
|
||||||
|
const uint32_t *data_addr = data;
|
||||||
|
|
||||||
|
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
|
||||||
|
for (unsigned i = 0; i < (len / FLASHPAGE_WRITE_BLOCK_SIZE); i++) {
|
||||||
|
*page_addr++ = data_addr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finish up */
|
||||||
|
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ config CPU_COMMON_SAM0
|
|||||||
select HAS_PERIPH_CPUID
|
select HAS_PERIPH_CPUID
|
||||||
select HAS_PERIPH_DMA
|
select HAS_PERIPH_DMA
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_FLASHPAGE_RWEE
|
select HAS_PERIPH_FLASHPAGE_RWEE
|
||||||
select HAS_PERIPH_GPIO
|
select HAS_PERIPH_GPIO
|
||||||
select HAS_PERIPH_GPIO_IRQ
|
select HAS_PERIPH_GPIO_IRQ
|
||||||
|
|||||||
@ -3,7 +3,7 @@ CPU_FAM := $(shell echo $(CPU_MODEL) | cut -c -6)
|
|||||||
FEATURES_PROVIDED += periph_cpuid
|
FEATURES_PROVIDED += periph_cpuid
|
||||||
FEATURES_PROVIDED += periph_dma
|
FEATURES_PROVIDED += periph_dma
|
||||||
FEATURES_PROVIDED += periph_flashpage
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
FEATURES_PROVIDED += periph_flashpage_raw
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
FEATURES_PROVIDED += periph_flashpage_rwee
|
FEATURES_PROVIDED += periph_flashpage_rwee
|
||||||
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
||||||
FEATURES_PROVIDED += periph_i2c_reconfigure
|
FEATURES_PROVIDED += periph_i2c_reconfigure
|
||||||
|
|||||||
@ -111,9 +111,9 @@ as shown in the NVM Row Organization figure. */
|
|||||||
/* The minimum block size which can be written is 16B. However, the erase
|
/* The minimum block size which can be written is 16B. However, the erase
|
||||||
* block is always FLASHPAGE_SIZE (SAM0 row).
|
* block is always FLASHPAGE_SIZE (SAM0 row).
|
||||||
*/
|
*/
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (16)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (16)
|
||||||
/* Writing should be always 4 byte aligned */
|
/* Writing should be always 4 byte aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (4)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4)
|
||||||
/* Add RWWEE memory if supported by revision of the chip
|
/* Add RWWEE memory if supported by revision of the chip
|
||||||
* On some chips it is called RWW EEPROM while on some DATAFLASH, try to
|
* On some chips it is called RWW EEPROM while on some DATAFLASH, try to
|
||||||
* catch all without relying on the CPU model but on the named defines
|
* catch all without relying on the CPU model but on the named defines
|
||||||
|
|||||||
@ -284,28 +284,13 @@ static void _write_row(uint8_t *dst, const void *_data, size_t len, size_t chunk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write(int page, const void *data)
|
void flashpage_erase(unsigned page)
|
||||||
{
|
{
|
||||||
assert((unsigned)page < FLASHPAGE_NUMOF);
|
assert((unsigned)page < FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
_erase_page(flashpage_addr(page), _cmd_erase_row);
|
_erase_page(flashpage_addr(page), _cmd_erase_row);
|
||||||
|
|
||||||
if (data == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* One RIOT page is FLASHPAGE_PAGES_PER_ROW SAM0 flash pages (a row) as
|
|
||||||
* defined in the file cpu/sam0_common/include/cpu_conf.h, therefore we
|
|
||||||
* have to split the write into FLASHPAGE_PAGES_PER_ROW raw calls
|
|
||||||
* underneath, each writing a physical page in chunks of 4 bytes (see
|
|
||||||
* flashpage_write_raw)
|
|
||||||
* The erasing is done once as a full row is always erased.
|
|
||||||
*/
|
|
||||||
_write_row(flashpage_addr(page), data, FLASHPAGE_SIZE, NVMCTRL_PAGE_SIZE,
|
|
||||||
_cmd_write_page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
void flashpage_write(void *target_addr, const void *data, size_t len)
|
||||||
{
|
{
|
||||||
/* ensure the length doesn't exceed the actual flash size */
|
/* ensure the length doesn't exceed the actual flash size */
|
||||||
assert(((unsigned)target_addr + len) <=
|
assert(((unsigned)target_addr + len) <=
|
||||||
@ -368,7 +353,7 @@ static void _cmd_write_page_rwwee(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_rwwee_write_raw(void *target_addr, const void *data, size_t len)
|
void flashpage_rwwee_write(void *target_addr, const void *data, size_t len)
|
||||||
{
|
{
|
||||||
assert(((unsigned)target_addr + len) <=
|
assert(((unsigned)target_addr + len) <=
|
||||||
(CPU_FLASH_RWWEE_BASE + (FLASHPAGE_SIZE * FLASHPAGE_RWWEE_NUMOF)));
|
(CPU_FLASH_RWWEE_BASE + (FLASHPAGE_SIZE * FLASHPAGE_RWWEE_NUMOF)));
|
||||||
@ -376,7 +361,7 @@ void flashpage_rwwee_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
_write_row(target_addr, data, len, NVMCTRL_PAGE_SIZE, _cmd_write_page_rwwee);
|
_write_row(target_addr, data, len, NVMCTRL_PAGE_SIZE, _cmd_write_page_rwwee);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_rwwee_write(int page, const void *data)
|
void flashpage_rwwee_write_page(unsigned page, const void *data)
|
||||||
{
|
{
|
||||||
assert((unsigned)page < FLASHPAGE_RWWEE_NUMOF);
|
assert((unsigned)page < FLASHPAGE_RWWEE_NUMOF);
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ FEATURES_PROVIDED += periph_wdt
|
|||||||
|
|
||||||
ifneq (,$(filter $(CPU_FAM),f0 f1 f3 g0 g4 l0 l1 l4 l5 wb))
|
ifneq (,$(filter $(CPU_FAM),f0 f1 f3 g0 g4 l0 l1 l4 l5 wb))
|
||||||
FEATURES_PROVIDED += periph_flashpage
|
FEATURES_PROVIDED += periph_flashpage
|
||||||
FEATURES_PROVIDED += periph_flashpage_raw
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter $(CPU_FAM),l0 l1))
|
ifneq (,$(filter $(CPU_FAM),l0 l1))
|
||||||
|
|||||||
@ -116,20 +116,20 @@ extern "C" {
|
|||||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
|
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
|
||||||
defined(CPU_FAM_STM32L5)
|
defined(CPU_FAM_STM32L5)
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (8U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (8U)
|
||||||
#elif defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
#elif defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
|
||||||
#else
|
#else
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE (2U)
|
#define FLASHPAGE_WRITE_BLOCK_SIZE (2U)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
|
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
|
||||||
defined(CPU_FAM_STM32L5)
|
defined(CPU_FAM_STM32L5)
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (8U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (8U)
|
||||||
#else
|
#else
|
||||||
/* Writing should be always 4 bytes aligned */
|
/* Writing should be always 4 bytes aligned */
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT (4U)
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
|
||||||
#endif
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ config CPU_FAM_F0
|
|||||||
select CPU_CORE_CORTEX_M0
|
select CPU_CORE_CORTEX_M0
|
||||||
select HAS_CPU_STM32F0
|
select HAS_CPU_STM32F0
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
|
|
||||||
config HAS_CPU_STM32F0
|
config HAS_CPU_STM32F0
|
||||||
bool
|
bool
|
||||||
|
|||||||
@ -11,7 +11,7 @@ config CPU_FAM_F1
|
|||||||
select CPU_CORE_CORTEX_M3
|
select CPU_CORE_CORTEX_M3
|
||||||
select HAS_CPU_STM32F1
|
select HAS_CPU_STM32F1
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
default "f1" if CPU_FAM_F1
|
default "f1" if CPU_FAM_F1
|
||||||
|
|||||||
@ -11,7 +11,7 @@ config CPU_FAM_F3
|
|||||||
select CPU_CORE_CORTEX_M4F
|
select CPU_CORE_CORTEX_M4F
|
||||||
select HAS_CPU_STM32F3
|
select HAS_CPU_STM32F3
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
default "f3" if CPU_FAM_F3
|
default "f3" if CPU_FAM_F3
|
||||||
|
|||||||
@ -11,7 +11,7 @@ config CPU_FAM_G0
|
|||||||
select CPU_CORE_CORTEX_M0PLUS
|
select CPU_CORE_CORTEX_M0PLUS
|
||||||
select HAS_CPU_STM32G0
|
select HAS_CPU_STM32G0
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
default "g0" if CPU_FAM_G0
|
default "g0" if CPU_FAM_G0
|
||||||
|
|||||||
@ -12,7 +12,7 @@ config CPU_FAM_G4
|
|||||||
select HAS_CPU_STM32G4
|
select HAS_CPU_STM32G4
|
||||||
select HAS_CORTEXM_MPU
|
select HAS_CORTEXM_MPU
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_HWRNG
|
select HAS_PERIPH_HWRNG
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
|
|||||||
@ -11,7 +11,7 @@ config CPU_FAM_L0
|
|||||||
select CPU_CORE_CORTEX_M0PLUS
|
select CPU_CORE_CORTEX_M0PLUS
|
||||||
select HAS_CPU_STM32L0
|
select HAS_CPU_STM32L0
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_EEPROM
|
select HAS_PERIPH_EEPROM
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
|
|||||||
@ -12,7 +12,7 @@ config CPU_FAM_L1
|
|||||||
select HAS_CPU_STM32L1
|
select HAS_CPU_STM32L1
|
||||||
select HAS_CORTEXM_MPU
|
select HAS_CORTEXM_MPU
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_EEPROM
|
select HAS_PERIPH_EEPROM
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
|
|||||||
@ -12,7 +12,7 @@ config CPU_FAM_L4
|
|||||||
select HAS_CPU_STM32L4
|
select HAS_CPU_STM32L4
|
||||||
select HAS_CORTEXM_MPU
|
select HAS_CORTEXM_MPU
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_HWRNG
|
select HAS_PERIPH_HWRNG
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
|
|||||||
@ -11,7 +11,7 @@ config CPU_FAM_L5
|
|||||||
select CPU_CORE_CORTEX_M33
|
select CPU_CORE_CORTEX_M33
|
||||||
select HAS_CPU_STM32L5
|
select HAS_CPU_STM32L5
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_HWRNG
|
select HAS_PERIPH_HWRNG
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
|
|||||||
@ -11,7 +11,7 @@ config CPU_FAM_WB
|
|||||||
select CPU_CORE_CORTEX_M4
|
select CPU_CORE_CORTEX_M4
|
||||||
select HAS_CPU_STM32WB
|
select HAS_CPU_STM32WB
|
||||||
select HAS_PERIPH_FLASHPAGE
|
select HAS_PERIPH_FLASHPAGE
|
||||||
select HAS_PERIPH_FLASHPAGE_RAW
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_HWRNG
|
select HAS_PERIPH_HWRNG
|
||||||
|
|
||||||
config CPU_FAM
|
config CPU_FAM
|
||||||
|
|||||||
@ -163,15 +163,30 @@ static void _erase_page(void *page_addr)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
void flashpage_erase(unsigned page)
|
||||||
{
|
{
|
||||||
/* assert multiples of FLASHPAGE_RAW_BLOCKSIZE are written and no less of
|
assert(page < (int)FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
|
/* ensure there is no attempt to write to CPU2 protected area */
|
||||||
|
#if defined(CPU_FAM_STM32WB)
|
||||||
|
assert(page < (int)(FLASH->SFR & FLASH_SFR_SFSA));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *page_addr = flashpage_addr(page);
|
||||||
|
|
||||||
|
/* ERASE sequence */
|
||||||
|
_erase_page(page_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flashpage_write(void *target_addr, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
/* assert multiples of FLASHPAGE_WRITE_BLOCK_SIZE are written and no less of
|
||||||
that length. */
|
that length. */
|
||||||
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
|
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
|
||||||
|
|
||||||
/* ensure writes are aligned */
|
/* ensure writes are aligned */
|
||||||
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
|
assert(!(((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) ||
|
||||||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
|
((unsigned)data % FLASHPAGE_WRITE_BLOCK_ALIGNMENT)));
|
||||||
|
|
||||||
/* ensure the length doesn't exceed the actual flash size */
|
/* ensure the length doesn't exceed the actual flash size */
|
||||||
assert(((unsigned)target_addr + len) <
|
assert(((unsigned)target_addr + len) <
|
||||||
@ -238,23 +253,3 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashpage_write(int page, const void *data)
|
|
||||||
{
|
|
||||||
assert(page < (int)FLASHPAGE_NUMOF);
|
|
||||||
|
|
||||||
/* ensure there is no attempt to write to CPU2 protected area */
|
|
||||||
#if defined(CPU_FAM_STM32WB)
|
|
||||||
assert(page < (int)(FLASH->SFR & FLASH_SFR_SFSA));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *page_addr = flashpage_addr(page);
|
|
||||||
|
|
||||||
/* ERASE sequence */
|
|
||||||
_erase_page(page_addr);
|
|
||||||
|
|
||||||
/* WRITE sequence */
|
|
||||||
if (data != NULL) {
|
|
||||||
flashpage_write_raw(page_addr, data, FLASHPAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -64,17 +64,17 @@ extern "C" {
|
|||||||
#define CPU_FLASH_BASE (0)
|
#define CPU_FLASH_BASE (0)
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* @def FLASHPAGE_RAW_BLOCKSIZE
|
* @def FLASHPAGE_WRITE_BLOCK_SIZE
|
||||||
*
|
*
|
||||||
* @brief For raw writings to the flash, this constant must define the
|
* @brief For raw writings to the flash, this constant must define the
|
||||||
* minimum write length allowed by the MCU.
|
* minimum write length allowed by the MCU.
|
||||||
*/
|
*/
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
#define FLASHPAGE_RAW_BLOCKSIZE
|
#define FLASHPAGE_WRITE_BLOCK_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def FLASHPAGE_RAW_ALIGNMENT
|
* @def FLASHPAGE_WRITE_BLOCK_ALIGNMENT
|
||||||
*
|
*
|
||||||
* @brief The buffers to be written to the flash MUST be aligned, as well as
|
* @brief The buffers to be written to the flash MUST be aligned, as well as
|
||||||
* the address on which the buffer is written to the flash. This variable
|
* the address on which the buffer is written to the flash. This variable
|
||||||
@ -82,7 +82,7 @@ extern "C" {
|
|||||||
* requirements.
|
* requirements.
|
||||||
*/
|
*/
|
||||||
#ifdef DOXYGEN
|
#ifdef DOXYGEN
|
||||||
#define FLASHPAGE_RAW_ALIGNMENT
|
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* @def FLASHPAGE_SIZE
|
* @def FLASHPAGE_SIZE
|
||||||
@ -114,7 +114,7 @@ enum {
|
|||||||
*
|
*
|
||||||
* @return starting memory address of the given page
|
* @return starting memory address of the given page
|
||||||
*/
|
*/
|
||||||
static inline void *flashpage_addr(int page)
|
static inline void *flashpage_addr(unsigned page)
|
||||||
{
|
{
|
||||||
return (void *)(CPU_FLASH_BASE + (page * FLASHPAGE_SIZE));
|
return (void *)(CPU_FLASH_BASE + (page * FLASHPAGE_SIZE));
|
||||||
}
|
}
|
||||||
@ -130,11 +130,18 @@ static inline void *flashpage_addr(int page)
|
|||||||
*
|
*
|
||||||
* @return page containing the given address
|
* @return page containing the given address
|
||||||
*/
|
*/
|
||||||
static inline int flashpage_page(void *addr)
|
static inline unsigned flashpage_page(void *addr)
|
||||||
{
|
{
|
||||||
return (int)(((int)addr - CPU_FLASH_BASE) / FLASHPAGE_SIZE);
|
return (((intptr_t)addr - CPU_FLASH_BASE) / FLASHPAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase the given page
|
||||||
|
*
|
||||||
|
* @param[in] page Page to erase
|
||||||
|
*/
|
||||||
|
void flashpage_erase(unsigned page);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write the given page with the given data
|
* @brief Write the given page with the given data
|
||||||
*
|
*
|
||||||
@ -142,7 +149,7 @@ static inline int flashpage_page(void *addr)
|
|||||||
* @param[in] data data to write to the page, MUST be FLASHPAGE_SIZE
|
* @param[in] data data to write to the page, MUST be FLASHPAGE_SIZE
|
||||||
* byte. Set to NULL for page erase only.
|
* byte. Set to NULL for page erase only.
|
||||||
*/
|
*/
|
||||||
void flashpage_write(int page, const void *data);
|
void flashpage_write_page(unsigned page, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write any number of data bytes to a given location in the
|
* @brief Write any number of data bytes to a given location in the
|
||||||
@ -152,20 +159,20 @@ void flashpage_write(int page, const void *data);
|
|||||||
* this function
|
* this function
|
||||||
*
|
*
|
||||||
* Both target address and data address must be aligned to
|
* Both target address and data address must be aligned to
|
||||||
* FLASHPAGE_RAW_ALIGN. @p len must be a multiple of FLASHPAGE_RAW_BLOCKSIZE.
|
* FLASHPAGE_BLOCK_ALIGN. @p len must be a multiple of FLASHPAGE_WRITE_BLOCK_SIZE.
|
||||||
* This function doesn't erase any area in flash, thus be sure the targeted
|
* This function doesn't erase any area in flash, thus be sure the targeted
|
||||||
* memory area is erased before writing on it (using the flashpage_write function).
|
* memory area is erased before writing on it (using the flashpage_write function).
|
||||||
*
|
*
|
||||||
* @param[in] target_addr address in flash to write to. MUST be aligned
|
* @param[in] target_addr address in flash to write to. MUST be aligned
|
||||||
* to FLASHPAGE_RAW_ALIGNMENT.
|
* to FLASHPAGE_WRITE_BLOCK_ALIGNMENT.
|
||||||
* @param[in] data data to write to the address. MUST be aligned
|
* @param[in] data data to write to the address. MUST be aligned
|
||||||
* to FLASHPAGE_RAW_ALIGNMENT.
|
* to FLASHPAGE_WRITE_BLOCK_ALIGNMENT.
|
||||||
* @param[in] len length of the data to be written. It MUST be
|
* @param[in] len length of the data to be written. It MUST be
|
||||||
* multiple of FLASHPAGE_RAW_BLOCKSIZE. Also,
|
* multiple of FLASHPAGE_WRITE_BLOCK_SIZE. Also,
|
||||||
* ensure it doesn't exceed the actual flash
|
* ensure it doesn't exceed the actual flash
|
||||||
* memory size.
|
* memory size.
|
||||||
*/
|
*/
|
||||||
void flashpage_write_raw(void *target_addr, const void *data, size_t len);
|
void flashpage_write(void *target_addr, const void *data, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the given page into the given memory location
|
* @brief Read the given page into the given memory location
|
||||||
@ -174,7 +181,7 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len);
|
|||||||
* @param[out] data memory to write the page to, MUST be FLASHPAGE_SIZE
|
* @param[out] data memory to write the page to, MUST be FLASHPAGE_SIZE
|
||||||
* byte
|
* byte
|
||||||
*/
|
*/
|
||||||
void flashpage_read(int page, void *data);
|
void flashpage_read(unsigned page, void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Verify the given page against the given data
|
* @brief Verify the given page against the given data
|
||||||
@ -186,7 +193,7 @@ void flashpage_read(int page, void *data);
|
|||||||
* @return FLASHPAGE_OK if data in the page is identical to @p data
|
* @return FLASHPAGE_OK if data in the page is identical to @p data
|
||||||
* @return FLASHPAGE_NOMATCH if data and page content diverge
|
* @return FLASHPAGE_NOMATCH if data and page content diverge
|
||||||
*/
|
*/
|
||||||
int flashpage_verify(int page, const void *data);
|
int flashpage_verify(unsigned page, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write the given page and verify the results
|
* @brief Write the given page and verify the results
|
||||||
@ -200,7 +207,7 @@ int flashpage_verify(int page, const void *data);
|
|||||||
* @return FLASHPAGE_OK on success
|
* @return FLASHPAGE_OK on success
|
||||||
* @return FLASHPAGE_NOMATCH if data and page content diverge
|
* @return FLASHPAGE_NOMATCH if data and page content diverge
|
||||||
*/
|
*/
|
||||||
int flashpage_write_and_verify(int page, const void *data);
|
int flashpage_write_and_verify(unsigned page, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Functions to support additional RWWEE flash section
|
* @brief Functions to support additional RWWEE flash section
|
||||||
@ -227,7 +234,7 @@ int flashpage_write_and_verify(int page, const void *data);
|
|||||||
*
|
*
|
||||||
* @return starting memory address of the given RWWEE page
|
* @return starting memory address of the given RWWEE page
|
||||||
*/
|
*/
|
||||||
static inline void *flashpage_rwwee_addr(int page)
|
static inline void *flashpage_rwwee_addr(unsigned page)
|
||||||
{
|
{
|
||||||
return (void *)(CPU_FLASH_RWWEE_BASE + (page * FLASHPAGE_SIZE));
|
return (void *)(CPU_FLASH_RWWEE_BASE + (page * FLASHPAGE_SIZE));
|
||||||
}
|
}
|
||||||
@ -255,7 +262,7 @@ static inline int flashpage_rwwee_page(void *addr)
|
|||||||
* @param[in] data data to write to the RWWEE page, MUST be FLASHPAGE_SIZE
|
* @param[in] data data to write to the RWWEE page, MUST be FLASHPAGE_SIZE
|
||||||
* byte. Set to NULL for RWWEE page erase only.
|
* byte. Set to NULL for RWWEE page erase only.
|
||||||
*/
|
*/
|
||||||
void flashpage_rwwee_write(int page, const void *data);
|
void flashpage_rwwee_write_page(unsigned page, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write any number of data bytes to a given location in the
|
* @brief Write any number of data bytes to a given location in the
|
||||||
@ -265,20 +272,20 @@ void flashpage_rwwee_write(int page, const void *data);
|
|||||||
* this function
|
* this function
|
||||||
*
|
*
|
||||||
* Both target address and data address must be aligned to
|
* Both target address and data address must be aligned to
|
||||||
* FLASHPAGE_RAW_ALIGN. @p len must be a multiple of FLASHPAGE_RAW_BLOCKSIZE.
|
* FLASHPAGE_BLOCK_ALIGN. @p len must be a multiple of FLASHPAGE_WRITE_BLOCK_SIZE.
|
||||||
* This function doesn't erase any area in flash, thus be sure the targeted
|
* This function doesn't erase any area in flash, thus be sure the targeted
|
||||||
* memory area is erased before writing on it (using the flashpage_write function).
|
* memory area is erased before writing on it (using the flashpage_write function).
|
||||||
*
|
*
|
||||||
* @param[in] target_addr RWWEE address in flash to write to. MUST be aligned
|
* @param[in] target_addr RWWEE address in flash to write to. MUST be aligned
|
||||||
* to FLASHPAGE_RAW_ALIGNMENT.
|
* to FLASHPAGE_WRITE_BLOCK_ALIGNMENT.
|
||||||
* @param[in] data data to write to the address. MUST be aligned
|
* @param[in] data data to write to the address. MUST be aligned
|
||||||
* to FLASHPAGE_RAW_ALIGNMENT.
|
* to FLASHPAGE_WRITE_BLOCK_ALIGNMENT.
|
||||||
* @param[in] len length of the data to be written. It MUST be
|
* @param[in] len length of the data to be written. It MUST be
|
||||||
* multiple of FLASHPAGE_RAW_BLOCKSIZE. Also,
|
* multiple of FLASHPAGE_WRITE_BLOCK_SIZE. Also,
|
||||||
* ensure it doesn't exceed the actual RWWEE flash
|
* ensure it doesn't exceed the actual RWWEE flash
|
||||||
* memory size.
|
* memory size.
|
||||||
*/
|
*/
|
||||||
void flashpage_rwwee_write_raw(void *target_addr, const void *data, size_t len);
|
void flashpage_rwwee_write(void *target_addr, const void *data, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the given RWWEE page into the given memory location
|
* @brief Read the given RWWEE page into the given memory location
|
||||||
@ -287,7 +294,7 @@ void flashpage_rwwee_write_raw(void *target_addr, const void *data, size_t len);
|
|||||||
* @param[out] data memory to write the RWWEE page to, MUST be FLASHPAGE_SIZE
|
* @param[out] data memory to write the RWWEE page to, MUST be FLASHPAGE_SIZE
|
||||||
* byte
|
* byte
|
||||||
*/
|
*/
|
||||||
void flashpage_rwwee_read(int page, void *data);
|
void flashpage_rwwee_read(unsigned page, void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Verify the given RWWEE page against the given data
|
* @brief Verify the given RWWEE page against the given data
|
||||||
@ -299,7 +306,7 @@ void flashpage_rwwee_read(int page, void *data);
|
|||||||
* @return FLASHPAGE_OK if data in the RWWEE page is identical to @p data
|
* @return FLASHPAGE_OK if data in the RWWEE page is identical to @p data
|
||||||
* @return FLASHPAGE_NOMATCH if data and RWWEE page content diverge
|
* @return FLASHPAGE_NOMATCH if data and RWWEE page content diverge
|
||||||
*/
|
*/
|
||||||
int flashpage_rwwee_verify(int page, const void *data);
|
int flashpage_rwwee_verify(unsigned page, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write the given RWWEE page and verify the results
|
* @brief Write the given RWWEE page and verify the results
|
||||||
@ -314,7 +321,7 @@ int flashpage_rwwee_verify(int page, const void *data);
|
|||||||
* @return FLASHPAGE_OK on success
|
* @return FLASHPAGE_OK on success
|
||||||
* @return FLASHPAGE_NOMATCH if data and RWWEE page content diverge
|
* @return FLASHPAGE_NOMATCH if data and RWWEE page content diverge
|
||||||
*/
|
*/
|
||||||
int flashpage_rwwee_write_and_verify(int page, const void *data);
|
int flashpage_rwwee_write_and_verify(unsigned page, const void *data);
|
||||||
|
|
||||||
#endif /* FLASHPAGE_RWWEE_NUMOF */
|
#endif /* FLASHPAGE_RWWEE_NUMOF */
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
FEATURES_REQUIRED += periph_flashpage
|
FEATURES_REQUIRED += periph_flashpage
|
||||||
FEATURES_REQUIRED += periph_flashpage_raw
|
FEATURES_REQUIRED += periph_flashpage_pagewise
|
||||||
|
|||||||
@ -42,7 +42,7 @@ static int _read(mtd_dev_t *dev, void *buf, uint32_t addr, uint32_t size)
|
|||||||
|
|
||||||
(void)dev;
|
(void)dev;
|
||||||
|
|
||||||
if (addr % FLASHPAGE_RAW_ALIGNMENT) {
|
if (addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,13 +61,13 @@ static int _write(mtd_dev_t *dev, const void *buf, uint32_t addr, uint32_t size)
|
|||||||
{
|
{
|
||||||
(void)dev;
|
(void)dev;
|
||||||
|
|
||||||
if (addr % FLASHPAGE_RAW_ALIGNMENT) {
|
if (addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if ((uintptr_t)buf % FLASHPAGE_RAW_ALIGNMENT) {
|
if ((uintptr_t)buf % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (size % FLASHPAGE_RAW_BLOCKSIZE) {
|
if (size % FLASHPAGE_WRITE_BLOCK_SIZE) {
|
||||||
return -EOVERFLOW;
|
return -EOVERFLOW;
|
||||||
}
|
}
|
||||||
if (addr + size > MTD_FLASHPAGE_END_ADDR) {
|
if (addr + size > MTD_FLASHPAGE_END_ADDR) {
|
||||||
@ -80,7 +80,7 @@ static int _write(mtd_dev_t *dev, const void *buf, uint32_t addr, uint32_t size)
|
|||||||
uint32_t dst_addr = addr;
|
uint32_t dst_addr = addr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flashpage_write_raw((void *)dst_addr, buf, size);
|
flashpage_write((void *)dst_addr, buf, size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t size)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i += sector_size) {
|
for (size_t i = 0; i < size; i += sector_size) {
|
||||||
flashpage_write(flashpage_page((void *)(dst_addr + i)), NULL);
|
flashpage_erase(flashpage_page((void *)(dst_addr + i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -19,15 +19,15 @@ config MODULE_PERIPH_INIT_FLASHPAGE
|
|||||||
default y if MODULE_PERIPH_INIT
|
default y if MODULE_PERIPH_INIT
|
||||||
depends on MODULE_PERIPH_FLASHPAGE
|
depends on MODULE_PERIPH_FLASHPAGE
|
||||||
|
|
||||||
config MODULE_PERIPH_FLASHPAGE_RAW
|
config MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
bool "Raw writing support"
|
bool "Pagewise writing support"
|
||||||
depends on HAS_PERIPH_FLASHPAGE_RAW
|
depends on HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
depends on MODULE_PERIPH_FLASHPAGE
|
depends on MODULE_PERIPH_FLASHPAGE
|
||||||
|
|
||||||
config MODULE_PERIPH_INIT_FLASHPAGE_RAW
|
config MODULE_PERIPH_INIT_FLASHPAGE_PAGEWISE
|
||||||
bool "Auto initialize Flashpage raw"
|
bool "Auto initialize Flashpage pagewise"
|
||||||
default y if MODULE_PERIPH_INIT
|
default y if MODULE_PERIPH_INIT
|
||||||
depends on MODULE_PERIPH_FLASHPAGE_RAW
|
depends on MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
|
|
||||||
config MODULE_PERIPH_FLASHPAGE_RWEE
|
config MODULE_PERIPH_FLASHPAGE_RWEE
|
||||||
bool "Read while Write support"
|
bool "Read while Write support"
|
||||||
|
|||||||
@ -28,18 +28,19 @@
|
|||||||
|
|
||||||
#include "periph/flashpage.h"
|
#include "periph/flashpage.h"
|
||||||
|
|
||||||
void flashpage_read(int page, void *data)
|
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
|
void flashpage_read(unsigned page, void *data)
|
||||||
{
|
{
|
||||||
assert(page < (int)FLASHPAGE_NUMOF);
|
assert(page < FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
#if defined(CPU_FAM_STM32WB)
|
#if defined(CPU_FAM_STM32WB)
|
||||||
assert(page < (int)(FLASH->SFR & FLASH_SFR_SFSA));
|
assert(page < (FLASH->SFR & FLASH_SFR_SFSA));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memcpy(data, flashpage_addr(page), FLASHPAGE_SIZE);
|
memcpy(data, flashpage_addr(page), FLASHPAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flashpage_verify(int page, const void *data)
|
int flashpage_verify(unsigned page, const void *data)
|
||||||
{
|
{
|
||||||
assert(page < (int)FLASHPAGE_NUMOF);
|
assert(page < (int)FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
@ -55,23 +56,35 @@ int flashpage_verify(int page, const void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int flashpage_write_and_verify(int page, const void *data)
|
int flashpage_write_and_verify(unsigned page, const void *data)
|
||||||
{
|
{
|
||||||
flashpage_write(page, data);
|
flashpage_write_page(page, data);
|
||||||
return flashpage_verify(page, data);
|
return flashpage_verify(page, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flashpage_write_page(unsigned page, const void *data)
|
||||||
|
{
|
||||||
|
assert((unsigned) page < FLASHPAGE_NUMOF);
|
||||||
|
|
||||||
|
flashpage_erase(page);
|
||||||
|
|
||||||
|
/* write page */
|
||||||
|
if (data != NULL) {
|
||||||
|
flashpage_write(flashpage_addr(page), data, FLASHPAGE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MODULE_PERIPH_FLASHPAGE_PAGEWISE */
|
||||||
|
|
||||||
#if defined(FLASHPAGE_RWWEE_NUMOF)
|
#if defined(FLASHPAGE_RWWEE_NUMOF)
|
||||||
|
|
||||||
void flashpage_rwwee_read(int page, void *data)
|
void flashpage_rwwee_read(unsigned page, void *data)
|
||||||
{
|
{
|
||||||
assert(page < (int)FLASHPAGE_RWWEE_NUMOF);
|
assert(page < (int)FLASHPAGE_RWWEE_NUMOF);
|
||||||
|
|
||||||
memcpy(data, flashpage_rwwee_addr(page), FLASHPAGE_SIZE);
|
memcpy(data, flashpage_rwwee_addr(page), FLASHPAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flashpage_rwwee_verify(int page, const void *data)
|
int flashpage_rwwee_verify(unsigned page, const void *data)
|
||||||
{
|
{
|
||||||
assert(page < (int)FLASHPAGE_RWWEE_NUMOF);
|
assert(page < (int)FLASHPAGE_RWWEE_NUMOF);
|
||||||
|
|
||||||
@ -83,9 +96,9 @@ int flashpage_rwwee_verify(int page, const void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int flashpage_rwwee_write_and_verify(int page, const void *data)
|
int flashpage_rwwee_write_and_verify(unsigned page, const void *data)
|
||||||
{
|
{
|
||||||
flashpage_rwwee_write(page, data);
|
flashpage_rwwee_write_page(page, data);
|
||||||
return flashpage_rwwee_verify(page, data);
|
return flashpage_rwwee_verify(page, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -124,10 +124,10 @@ config HAS_PERIPH_FLASHPAGE
|
|||||||
help
|
help
|
||||||
Indicates that a Flashpage peripheral is present.
|
Indicates that a Flashpage peripheral is present.
|
||||||
|
|
||||||
config HAS_PERIPH_FLASHPAGE_RAW
|
config HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
Indicates that the Flashpage peripheral supports raw writing.
|
Indicates that the Flashpage peripheral supports pagewise writing.
|
||||||
|
|
||||||
config HAS_PERIPH_FLASHPAGE_RWEE
|
config HAS_PERIPH_FLASHPAGE_RWEE
|
||||||
bool
|
bool
|
||||||
|
|||||||
@ -910,7 +910,6 @@ endif
|
|||||||
ifneq (,$(filter riotboot_flashwrite, $(USEMODULE)))
|
ifneq (,$(filter riotboot_flashwrite, $(USEMODULE)))
|
||||||
USEMODULE += riotboot_slot
|
USEMODULE += riotboot_slot
|
||||||
FEATURES_REQUIRED += periph_flashpage
|
FEATURES_REQUIRED += periph_flashpage
|
||||||
FEATURES_OPTIONAL += periph_flashpage_raw
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter riotboot_slot, $(USEMODULE)))
|
ifneq (,$(filter riotboot_slot, $(USEMODULE)))
|
||||||
|
|||||||
@ -41,9 +41,9 @@
|
|||||||
* 2. write image starting at second block
|
* 2. write image starting at second block
|
||||||
* 3. write first block
|
* 3. write first block
|
||||||
*
|
*
|
||||||
* When using periph_flashpage_raw with this module, the need to buffer a full
|
* When using raw mode is used with this module, the need to buffer a full
|
||||||
* flashpage page is removed, instead it must buffer two times the
|
* flashpage page is removed, instead it must buffer two times the
|
||||||
* FLASHPAGE_RAW_BLOCKSIZE. One is used to buffer the current write block,
|
* FLASHPAGE_WRITE_BLOCK_SIZE. One is used to buffer the current write block,
|
||||||
* the other buffers the first chunk (offset zero, page zero). This first
|
* the other buffers the first chunk (offset zero, page zero). This first
|
||||||
* chunk is written when finalizing the flash operation. The minimal size for
|
* chunk is written when finalizing the flash operation. The minimal size for
|
||||||
* RIOTBOOT_FLASHPAGE_BUFFER_SIZE is 4, at least the riotboot magic number must
|
* RIOTBOOT_FLASHPAGE_BUFFER_SIZE is 4, at least the riotboot magic number must
|
||||||
@ -70,7 +70,7 @@ extern "C" {
|
|||||||
* @brief Enable/disable raw writes to flash
|
* @brief Enable/disable raw writes to flash
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_RIOTBOOT_FLASHWRITE_RAW
|
#ifndef CONFIG_RIOTBOOT_FLASHWRITE_RAW
|
||||||
#define CONFIG_RIOTBOOT_FLASHWRITE_RAW IS_ACTIVE(MODULE_PERIPH_FLASHPAGE_RAW)
|
#define CONFIG_RIOTBOOT_FLASHWRITE_RAW 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,10 +78,10 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#if CONFIG_RIOTBOOT_FLASHWRITE_RAW
|
#if CONFIG_RIOTBOOT_FLASHWRITE_RAW
|
||||||
|
|
||||||
#if (FLASHPAGE_RAW_BLOCKSIZE < 4)
|
#if (FLASHPAGE_WRITE_BLOCK_SIZE < 4)
|
||||||
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE 4
|
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE 4
|
||||||
#else
|
#else
|
||||||
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE FLASHPAGE_RAW_BLOCKSIZE
|
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE FLASHPAGE_WRITE_BLOCK_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else /* CONFIG_RIOTBOOT_FLASHWRITE_RAW */
|
#else /* CONFIG_RIOTBOOT_FLASHWRITE_RAW */
|
||||||
@ -94,13 +94,14 @@ extern "C" {
|
|||||||
* @brief Extra attributes required for the firmware intermediate buffer
|
* @brief Extra attributes required for the firmware intermediate buffer
|
||||||
*/
|
*/
|
||||||
#define RIOTBOOT_FLASHPAGE_BUFFER_ATTRS \
|
#define RIOTBOOT_FLASHPAGE_BUFFER_ATTRS \
|
||||||
__attribute__((aligned(FLASHPAGE_RAW_ALIGNMENT)))
|
__attribute__((aligned(FLASHPAGE_WRITE_BLOCK_ALIGNMENT)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief firmware update state structure
|
* @brief firmware update state structure
|
||||||
*
|
*
|
||||||
* @note @ref FLASHPAGE_SIZE can be very large on some platforms, don't place
|
* @note @ref FLASHPAGE_SIZE can be very large on some platforms, don't place
|
||||||
* this struct on the stack or increase the thread stack size accordingly.
|
* this struct on the stack or increase the thread stack size
|
||||||
|
* accordingly.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int target_slot; /**< update targets this slot */
|
int target_slot; /**< update targets this slot */
|
||||||
|
|||||||
@ -59,7 +59,7 @@ int riotboot_flashwrite_init_raw(riotboot_flashwrite_t *state, int target_slot,
|
|||||||
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW && offset) {
|
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW && offset) {
|
||||||
/* Erase the first page only if the offset (!=0) specifies that there is
|
/* Erase the first page only if the offset (!=0) specifies that there is
|
||||||
* a checksum or other mechanism at the start of the page. */
|
* a checksum or other mechanism at the start of the page. */
|
||||||
flashpage_write(state->flashpage, NULL);
|
flashpage_erase(state->flashpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -78,9 +78,9 @@ int riotboot_flashwrite_flush(riotboot_flashwrite_t *state)
|
|||||||
/* Get the offset of the remaining chunk */
|
/* Get the offset of the remaining chunk */
|
||||||
size_t flashpage_pos = state->offset - flashwrite_buffer_pos;
|
size_t flashpage_pos = state->offset - flashwrite_buffer_pos;
|
||||||
/* Write remaining chunk */
|
/* Write remaining chunk */
|
||||||
flashpage_write_raw(slot_start + flashpage_pos,
|
flashpage_write(slot_start + flashpage_pos,
|
||||||
state->flashpage_buf,
|
state->flashpage_buf,
|
||||||
RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (flashpage_write_and_verify(state->flashpage, state->flashpage_buf) != FLASHPAGE_OK) {
|
if (flashpage_write_and_verify(state->flashpage, state->flashpage_buf) != FLASHPAGE_OK) {
|
||||||
@ -106,7 +106,7 @@ int riotboot_flashwrite_putbytes(riotboot_flashwrite_t *state,
|
|||||||
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW && flashpage_pos == 0) {
|
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW && flashpage_pos == 0) {
|
||||||
/* Erase the next page */
|
/* Erase the next page */
|
||||||
state->flashpage++;
|
state->flashpage++;
|
||||||
flashpage_write(state->flashpage, NULL);
|
flashpage_erase(state->flashpage);
|
||||||
}
|
}
|
||||||
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW &&
|
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW &&
|
||||||
flashwrite_buffer_pos == 0) {
|
flashwrite_buffer_pos == 0) {
|
||||||
@ -131,7 +131,7 @@ int riotboot_flashwrite_putbytes(riotboot_flashwrite_t *state,
|
|||||||
state->flashpage_buf, RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
state->flashpage_buf, RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
flashpage_write_raw((uint8_t*)addr + flashpage_pos,
|
flashpage_write((uint8_t*)addr + flashpage_pos,
|
||||||
state->flashpage_buf,
|
state->flashpage_buf,
|
||||||
RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ int riotboot_flashwrite_finish_raw(riotboot_flashwrite_t *state,
|
|||||||
|
|
||||||
#if CONFIG_RIOTBOOT_FLASHWRITE_RAW
|
#if CONFIG_RIOTBOOT_FLASHWRITE_RAW
|
||||||
memcpy(state->firstblock_buf, bytes, len);
|
memcpy(state->firstblock_buf, bytes, len);
|
||||||
flashpage_write_raw(slot_start, state->firstblock_buf, RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
flashpage_write(slot_start, state->firstblock_buf, RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
|
||||||
#else
|
#else
|
||||||
uint8_t *firstpage;
|
uint8_t *firstpage;
|
||||||
|
|
||||||
|
|||||||
@ -122,7 +122,8 @@ static void test_mtd_write_erase(void)
|
|||||||
|
|
||||||
static void test_mtd_write_read(void)
|
static void test_mtd_write_read(void)
|
||||||
{
|
{
|
||||||
const char buf[] __attribute__ ((aligned (FLASHPAGE_RAW_ALIGNMENT))) = "ABCDEFGHIJKLMNO";
|
const char buf[] __attribute__ ((aligned (FLASHPAGE_WRITE_BLOCK_ALIGNMENT)))
|
||||||
|
= "ABCDEFGHIJKLMNO";
|
||||||
|
|
||||||
/* stm32l0x and stm32l1x erase its flash with 0's */
|
/* stm32l0x and stm32l1x erase its flash with 0's */
|
||||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
||||||
|
|||||||
@ -8,6 +8,6 @@
|
|||||||
config APPLICATION
|
config APPLICATION
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
imply MODULE_PERIPH_FLASHPAGE_RAW
|
imply MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
imply MODULE_PERIPH_FLASHPAGE_RWEE
|
imply MODULE_PERIPH_FLASHPAGE_RWEE
|
||||||
depends on TEST_KCONFIG
|
depends on TEST_KCONFIG
|
||||||
|
|||||||
@ -2,7 +2,7 @@ BOARD ?= iotlab-m3
|
|||||||
include ../Makefile.tests_common
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
FEATURES_REQUIRED += periph_flashpage
|
FEATURES_REQUIRED += periph_flashpage
|
||||||
FEATURES_OPTIONAL += periph_flashpage_raw
|
FEATURES_OPTIONAL += periph_flashpage_pagewise
|
||||||
FEATURES_OPTIONAL += periph_flashpage_rwee
|
FEATURES_OPTIONAL += periph_flashpage_rwee
|
||||||
|
|
||||||
USEMODULE += od
|
USEMODULE += od
|
||||||
|
|||||||
@ -38,21 +38,17 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* When writing raw bytes on flash, data must be correctly aligned. */
|
/* When writing raw bytes on flash, data must be correctly aligned. */
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
#define ALIGNMENT_ATTR __attribute__((aligned(FLASHPAGE_WRITE_BLOCK_ALIGNMENT)))
|
||||||
#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] ALIGNMENT_ATTR;
|
static char raw_buf[64] ALIGNMENT_ATTR;
|
||||||
#else
|
|
||||||
#define ALIGNMENT_ATTR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate space for 1 flash page in RAM
|
* @brief Allocate space for 1 flash page in RAM
|
||||||
*
|
*
|
||||||
* @note The flash page in RAM must be correctly aligned, even in RAM, when
|
* @note The flash page in RAM must be correctly aligned, even in RAM, when
|
||||||
* using flashpage_raw. This is because some architecture uses
|
* using flashpage. This is because some architecture uses
|
||||||
* 32 bit alignment implicitly and there are cases (stm32l4) that
|
* 32 bit alignment implicitly and there are cases (stm32l4) that
|
||||||
* requires 64 bit alignment.
|
* requires 64 bit alignment.
|
||||||
*/
|
*/
|
||||||
@ -176,6 +172,7 @@ static int cmd_read(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
static int cmd_write(int argc, char **argv)
|
static int cmd_write(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int page;
|
int page;
|
||||||
@ -199,8 +196,8 @@ static int cmd_write(int argc, char **argv)
|
|||||||
page, flashpage_addr(page));
|
page, flashpage_addr(page));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
|
||||||
static uint32_t getaddr(const char *str)
|
static uint32_t getaddr(const char *str)
|
||||||
{
|
{
|
||||||
uint32_t addr = strtol(str, NULL, 16);
|
uint32_t addr = strtol(str, NULL, 16);
|
||||||
@ -229,7 +226,7 @@ static int cmd_write_raw(int argc, char **argv)
|
|||||||
/* try to align */
|
/* try to align */
|
||||||
memcpy(raw_buf, argv[2], strlen(argv[2]));
|
memcpy(raw_buf, argv[2], strlen(argv[2]));
|
||||||
|
|
||||||
flashpage_write_raw((void*)addr, raw_buf, strlen(raw_buf));
|
flashpage_write((void*)addr, raw_buf, strlen(raw_buf));
|
||||||
#if (__SIZEOF_POINTER__ == 2)
|
#if (__SIZEOF_POINTER__ == 2)
|
||||||
printf("wrote local data to flash address %#" PRIx16 " of len %u\n",
|
printf("wrote local data to flash address %#" PRIx16 " of len %u\n",
|
||||||
addr, strlen(raw_buf));
|
addr, strlen(raw_buf));
|
||||||
@ -239,7 +236,6 @@ static int cmd_write_raw(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int cmd_erase(int argc, char **argv)
|
static int cmd_erase(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -254,7 +250,7 @@ static int cmd_erase(int argc, char **argv)
|
|||||||
if (page < 0) {
|
if (page < 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
flashpage_write(page, NULL);
|
flashpage_erase(page);
|
||||||
|
|
||||||
printf("successfully erased page %i (addr %p)\n",
|
printf("successfully erased page %i (addr %p)\n",
|
||||||
page, flashpage_addr(page));
|
page, flashpage_addr(page));
|
||||||
@ -287,6 +283,7 @@ static int cmd_edit(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
static int cmd_test(int argc, char **argv)
|
static int cmd_test(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int page;
|
int page;
|
||||||
@ -349,8 +346,8 @@ static int cmd_test_last(int argc, char **argv)
|
|||||||
puts("wrote local page buffer to last flash page");
|
puts("wrote local page buffer to last flash page");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
|
||||||
/**
|
/**
|
||||||
* @brief Does a short raw write on last page available
|
* @brief Does a short raw write on last page available
|
||||||
*
|
*
|
||||||
@ -370,9 +367,9 @@ static int cmd_test_last_raw(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* erase the page first */
|
/* erase the page first */
|
||||||
flashpage_write(TEST_LAST_AVAILABLE_PAGE, NULL);
|
flashpage_erase(TEST_LAST_AVAILABLE_PAGE);
|
||||||
|
|
||||||
flashpage_write_raw(flashpage_addr(TEST_LAST_AVAILABLE_PAGE), raw_buf, strlen(raw_buf));
|
flashpage_write(flashpage_addr(TEST_LAST_AVAILABLE_PAGE), raw_buf, strlen(raw_buf));
|
||||||
|
|
||||||
/* verify that previous write_raw effectively wrote the desired data */
|
/* verify that previous write_raw effectively wrote the desired data */
|
||||||
if (memcmp(flashpage_addr(TEST_LAST_AVAILABLE_PAGE), raw_buf, strlen(raw_buf)) != 0) {
|
if (memcmp(flashpage_addr(TEST_LAST_AVAILABLE_PAGE), raw_buf, strlen(raw_buf)) != 0) {
|
||||||
@ -383,7 +380,6 @@ static int cmd_test_last_raw(int argc, char **argv)
|
|||||||
puts("wrote raw short buffer to last flash page");
|
puts("wrote raw short buffer to last flash page");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef FLASHPAGE_RWWEE_NUMOF
|
#ifdef FLASHPAGE_RWWEE_NUMOF
|
||||||
@ -507,7 +503,6 @@ static int cmd_test_last_rwwee(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
|
||||||
/**
|
/**
|
||||||
* @brief Does a short raw write on last page available
|
* @brief Does a short raw write on last page available
|
||||||
*
|
*
|
||||||
@ -524,9 +519,9 @@ static int cmd_test_last_rwwee_raw(int argc, char **argv)
|
|||||||
memcpy(raw_buf, "test12344321tset", 16);
|
memcpy(raw_buf, "test12344321tset", 16);
|
||||||
|
|
||||||
/* erase the page first */
|
/* erase the page first */
|
||||||
flashpage_rwwee_write(((int)FLASHPAGE_RWWEE_NUMOF - 1), NULL);
|
flashpage_rwwee_write_page(((int)FLASHPAGE_RWWEE_NUMOF - 1), NULL);
|
||||||
|
|
||||||
flashpage_rwwee_write_raw(flashpage_rwwee_addr((int)FLASHPAGE_RWWEE_NUMOF - 1), raw_buf, strlen(raw_buf));
|
flashpage_rwwee_write(flashpage_rwwee_addr((int)FLASHPAGE_RWWEE_NUMOF - 1), raw_buf, strlen(raw_buf));
|
||||||
|
|
||||||
/* verify that previous write_raw effectively wrote the desired data */
|
/* verify that previous write_raw effectively wrote the desired data */
|
||||||
if (memcmp(flashpage_rwwee_addr((int)FLASHPAGE_RWWEE_NUMOF - 1), raw_buf, strlen(raw_buf)) != 0) {
|
if (memcmp(flashpage_rwwee_addr((int)FLASHPAGE_RWWEE_NUMOF - 1), raw_buf, strlen(raw_buf)) != 0) {
|
||||||
@ -537,7 +532,6 @@ static int cmd_test_last_rwwee_raw(int argc, char **argv)
|
|||||||
puts("wrote raw short buffer to last RWWEE flash page");
|
puts("wrote raw short buffer to last RWWEE flash page");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -607,26 +601,24 @@ static const shell_command_t shell_commands[] = {
|
|||||||
{ "dump", "Dump the selected page to STDOUT", cmd_dump },
|
{ "dump", "Dump the selected page to STDOUT", cmd_dump },
|
||||||
{ "dump_local", "Dump the local page buffer to STDOUT", cmd_dump_local },
|
{ "dump_local", "Dump the local page buffer to STDOUT", cmd_dump_local },
|
||||||
{ "read", "Copy the given page to the local page buffer and dump to STDOUT", cmd_read },
|
{ "read", "Copy the given page to the local page buffer and dump to STDOUT", cmd_read },
|
||||||
|
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
{ "write", "Write the local page buffer to the given page", cmd_write },
|
{ "write", "Write the local page buffer to the given page", cmd_write },
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
|
||||||
{ "write_raw", "Write (ASCII, max 64B) data to the given address", cmd_write_raw },
|
|
||||||
#endif
|
#endif
|
||||||
|
{ "write_raw", "Write (ASCII, max 64B) data to the given address", cmd_write_raw },
|
||||||
{ "erase", "Erase the given page buffer", cmd_erase },
|
{ "erase", "Erase the given page buffer", cmd_erase },
|
||||||
{ "edit", "Write bytes to the local page buffer", cmd_edit },
|
{ "edit", "Write bytes to the local page buffer", cmd_edit },
|
||||||
|
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
{ "test", "Write and verify test pattern", cmd_test },
|
{ "test", "Write and verify test pattern", cmd_test },
|
||||||
{ "test_last", "Write and verify test pattern on last page available", cmd_test_last },
|
{ "test_last_pagewise", "Write and verify test pattern on last page available", cmd_test_last },
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
|
||||||
{ "test_last_raw", "Write and verify raw short write on last page available", cmd_test_last_raw },
|
|
||||||
#endif
|
#endif
|
||||||
|
{ "test_last_raw", "Write and verify raw short write on last page available", cmd_test_last_raw },
|
||||||
#ifdef FLASHPAGE_RWWEE_NUMOF
|
#ifdef FLASHPAGE_RWWEE_NUMOF
|
||||||
{ "read_rwwee", "Copy the given page from RWWEE to the local page buffer and dump to STDOUT", cmd_read_rwwee },
|
{ "read_rwwee", "Copy the given page from RWWEE to the local page buffer and dump to STDOUT", cmd_read_rwwee },
|
||||||
{ "write_rwwee", "Write the local page buffer to the given RWWEE page", cmd_write_rwwee },
|
{ "write_rwwee", "Write the local page buffer to the given RWWEE page", cmd_write_rwwee },
|
||||||
{ "test_rwwee", "Write and verify test pattern to RWWEE", cmd_test_rwwee },
|
{ "test_rwwee", "Write and verify test pattern to RWWEE", cmd_test_rwwee },
|
||||||
{ "test_last_rwwee", "Write and verify test pattern on last RWWEE page available", cmd_test_last_rwwee },
|
{ "test_last_rwwee", "Write and verify test pattern on last RWWEE page available", cmd_test_last_rwwee },
|
||||||
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
|
|
||||||
{ "test_last_rwwee_raw", "Write and verify raw short write on last RWWEE page available", cmd_test_last_rwwee_raw },
|
{ "test_last_rwwee_raw", "Write and verify raw short write on last RWWEE page available", cmd_test_last_rwwee_raw },
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#ifdef NVMCTRL_USER
|
#ifdef NVMCTRL_USER
|
||||||
{ "dump_config_page", "Dump the content of the MCU configuration page", cmd_dump_config },
|
{ "dump_config_page", "Dump the content of the MCU configuration page", cmd_dump_config },
|
||||||
{ "test_config_page", "Test writing config page. (!DANGER ZONE!)", cmd_test_config },
|
{ "test_config_page", "Test writing config page. (!DANGER ZONE!)", cmd_test_config },
|
||||||
|
|||||||
@ -16,17 +16,17 @@ def testfunc(child):
|
|||||||
child.expect('>')
|
child.expect('>')
|
||||||
|
|
||||||
# writes and verifies the last page of the flash
|
# writes and verifies the last page of the flash
|
||||||
child.sendline("test_last")
|
child.sendline("test_last_raw")
|
||||||
child.expect_exact('wrote local page buffer to last flash page')
|
child.expect_exact('wrote raw short buffer to last flash page')
|
||||||
child.expect('>')
|
child.expect('>')
|
||||||
|
|
||||||
# check if board has raw write capability and if so test that as well
|
# check if board has pagewise write capability and if so test that as well
|
||||||
# capability is deduced from help contents
|
# capability is deduced from help contents
|
||||||
child.sendline("help")
|
child.sendline("help")
|
||||||
index = child.expect(['test_last_raw', '>'])
|
index = child.expect(['test_last_pagewise', '>'])
|
||||||
if index == 0:
|
if index == 0:
|
||||||
child.sendline("test_last_raw")
|
child.sendline("test_last_pagewise")
|
||||||
child.expect_exact('wrote raw short buffer to last flash page')
|
child.expect_exact('wrote local page buffer to last flash page')
|
||||||
child.expect('>')
|
child.expect('>')
|
||||||
|
|
||||||
# check if board has RWWEE capability and if so test that as well
|
# check if board has RWWEE capability and if so test that as well
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user