1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #15412 from bergzand/pr/flashpage/merge_raw

periph_flashpage: Make pagewise API optional
This commit is contained in:
benpicco 2020-11-12 22:32:21 +01:00 committed by GitHub
commit d9598a0f54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 283 additions and 318 deletions

View File

@ -11,7 +11,7 @@ config CPU_FAM_CC2538
select HAS_CPU_CC2538
select HAS_PERIPH_CPUID
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_HWRNG

View File

@ -3,7 +3,7 @@ CPU_FAM = cc2538
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_raw
FEATURES_PROVIDED += periph_flashpage_pagewise
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_hwrng
FEATURES_PROVIDED += periph_uart_modecfg

View File

@ -65,9 +65,9 @@ extern "C" {
/* The minimum block size which can be written is 4B. However, the erase
* block is always FLASHPAGE_SIZE.
*/
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
/* Writing should be always 4 bytes aligned */
#define FLASHPAGE_RAW_ALIGNMENT (4U)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
/** @} */
#ifdef __cplusplus

View File

@ -61,16 +61,25 @@ static inline void _erase(uint32_t *page_addr)
irq_restore(state);
}
__attribute__ ((section (".ramfunc")))
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);
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. */
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
/* ensure writes are aligned */
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
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) <=
@ -90,7 +99,7 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
/* starts the write-sequence state machine */
DEBUG("[flashpage_raw] write: now writing the data\n");
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++);
/* wait for flash operation to complete */
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 */
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);
}
}

View File

@ -10,7 +10,7 @@ config CPU_COMMON_EFM32
select HAS_CPU_EFM32
select HAS_PERIPH_CPUID
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_WDT

View File

@ -11,7 +11,7 @@ endif
FEATURES_PROVIDED += arch_efm32
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_raw
FEATURES_PROVIDED += periph_flashpage_pagewise
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_wdt

View File

@ -46,9 +46,9 @@ extern "C" {
/* The minimum block size which can be written is 4B. However, the erase
* block is always FLASHPAGE_SIZE.
*/
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
/* Writing should be always 4 bytes aligned */
#define FLASHPAGE_RAW_ALIGNMENT (4U)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
/** @} */
/**

View File

@ -26,15 +26,27 @@
#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. */
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
/* ensure writes are aligned */
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
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) <
@ -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_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);
}
}

View File

@ -21,7 +21,7 @@ config CPU_FAM_K
bool
select CPU_COMMON_KINETIS
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_MCG
config CPU_FAM_L
@ -33,7 +33,7 @@ config CPU_FAM_W
bool
select CPU_COMMON_KINETIS
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_MCG
## CPU Models

View File

@ -21,7 +21,7 @@ include $(LAST_MAKEFILEDIR)/kinetis-info.mk
ifneq (,$(filter k w,$(CPU_FAM)))
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_raw
FEATURES_PROVIDED += periph_flashpage_pagewise
endif
ifeq (ea,$(CPU_FAM))

View File

@ -146,12 +146,12 @@
/* The minimum block size which can be written is 8B (Phrase). However, the
* erase block is always FLASHPAGE_SIZE.
*/
#define FLASHPAGE_RAW_PHRASE (8U)
#define FLASHPAGE_RAW_BLOCKSIZE FLASHPAGE_RAW_PHRASE
#define FLASHPAGE_BLOCK_PHRASE (8U)
#define FLASHPAGE_WRITE_BLOCK_SIZE FLASHPAGE_BLOCK_PHRASE
/* 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 */
#define FLASHPAGE_RAW_SECTION_ALIGNMENT (16U)
#define FLASHPAGE_BLOCK_SECTION_ALIGNMENT (16U)
/** @} */
#ifdef __cplusplus

View File

@ -87,11 +87,11 @@
/* The minimum block size which can be written is 4B. However, the erase
* block is always FLASHPAGE_SIZE.
*/
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
/* 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 */
#define FLASHPAGE_RAW_SECTION_ALIGNMENT (8U)
#define FLASHPAGE_BLOCK_SECTION_ALIGNMENT (8U)
/** @} */
#ifdef __cplusplus

View File

@ -132,12 +132,12 @@ static int _check_errors(void)
static int _verify_erased(uint32_t address, size_t len)
{
/* 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
round up before adjusting to FLASHPAGE_RAW_SECTION_ALIGNMENT */
uint32_t num = (len + (FLASHPAGE_RAW_SECTION_ALIGNMENT - 1)) /
FLASHPAGE_RAW_SECTION_ALIGNMENT;
/* We verify FLASHPAGE_BLOCK_SECTION_ALIGNMENT Bytes at a time, we
round up before adjusting to FLASHPAGE_BLOCK_SECTION_ALIGNMENT */
uint32_t num = (len + (FLASHPAGE_BLOCK_SECTION_ALIGNMENT - 1)) /
FLASHPAGE_BLOCK_SECTION_ALIGNMENT;
/* Setup command and run */
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)
{
/* Ensures erases are aligned */
assert(!(address % FLASHPAGE_RAW_SECTION_ALIGNMENT));
assert(!(address % FLASHPAGE_BLOCK_SECTION_ALIGNMENT));
/* Setup command and run */
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 */
FCCOBx[1] = *data++;
if (FLASHPAGE_RAW_BLOCKSIZE == 8U) {
if (FLASHPAGE_WRITE_BLOCK_SIZE == 8U) {
FCCOBx[2] = *data;
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();
}
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. */
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
/* Ensure writes are aligned */
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
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);
#ifdef FLASHPAGE_RAW_PHRASE
#ifdef FLASHPAGE_BLOCK_PHRASE
const uint64_t *data_addr = data;
uint64_t *dst = target_addr;
#else
@ -203,24 +211,9 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
return;
}
/* Write to flash FLASHPAGE_RAW_BLOCKSIZE bytes at a time */
for (size_t i = 0; i < (len / FLASHPAGE_RAW_BLOCKSIZE); i++) {
/* Write to flash FLASHPAGE_WRITE_BLOCK_SIZE bytes at a time */
for (size_t i = 0; i < (len / FLASHPAGE_WRITE_BLOCK_SIZE); i++) {
_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);
}
}

View File

@ -11,7 +11,7 @@ config CPU_ARCH_MSP430
select HAS_ARCH_16BIT
select HAS_ARCH_MSP430
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_PM
config CPU_CORE_MSP430

View File

@ -4,5 +4,5 @@ CPU_CORE = msp430
FEATURES_PROVIDED += arch_16bit
FEATURES_PROVIDED += arch_msp430
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_raw
FEATURES_PROVIDED += periph_flashpage_pagewise
FEATURES_PROVIDED += periph_pm

View File

@ -50,9 +50,9 @@ extern "C" {
/* The minimum block size which can be written is 1B. However, the erase
* block is always FLASHPAGE_SIZE.
*/
#define FLASHPAGE_RAW_BLOCKSIZE (1U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (1U)
/* Writing should be always 2 byte aligned */
#define FLASHPAGE_RAW_ALIGNMENT (2U)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (2U)
/** @} */
/**

View File

@ -55,15 +55,25 @@ static inline void _erase(uint16_t *page_addr)
_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. */
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
/* ensure writes are aligned */
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
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) <
@ -87,18 +97,3 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
/* lock flash and re-enable interrupts */
_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);
}
}

View File

@ -52,9 +52,9 @@ extern "C" {
/* The minimum block size which can be written is 4B. However, the erase
* block is always FLASHPAGE_SIZE.
*/
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
/* Writing should be always 4 bytes aligned */
#define FLASHPAGE_RAW_ALIGNMENT (4U)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
/** @} */
/**

View File

@ -107,9 +107,9 @@ extern "C" {
/* The minimum block size which can be written is 4B. However, the erase
* block is always FLASHPAGE_SIZE.
*/
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
/* Writing should be always 4 bytes aligned */
#define FLASHPAGE_RAW_ALIGNMENT (4U)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
/** @} */
#ifdef CPU_MODEL_NRF52840XXAA

View File

@ -8,7 +8,7 @@ config CPU_COMMON_NRF5X
bool
select HAS_PERIPH_CPUID
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_HWRNG

View File

@ -1,7 +1,7 @@
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_raw
FEATURES_PROVIDED += periph_flashpage_pagewise
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_hwrng
FEATURES_PROVIDED += periph_temperature

View File

@ -23,33 +23,7 @@
#include "assert.h"
#include "periph/flashpage.h"
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
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)
void flashpage_erase(unsigned page)
{
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->ERASEPAGE = (uint32_t)page_addr;
while (NRF_NVMC->READY == 0) {}
/* write data to page */
if (data != NULL) {
flashpage_write_raw(page_addr, data, FLASHPAGE_SIZE);
}
}
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. */
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;
}

View File

@ -10,7 +10,7 @@ config CPU_COMMON_SAM0
select HAS_PERIPH_CPUID
select HAS_PERIPH_DMA
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_FLASHPAGE_RWEE
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ

View File

@ -3,7 +3,7 @@ CPU_FAM := $(shell echo $(CPU_MODEL) | cut -c -6)
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_dma
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_raw
FEATURES_PROVIDED += periph_flashpage_pagewise
FEATURES_PROVIDED += periph_flashpage_rwee
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_i2c_reconfigure

View File

@ -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
* 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 */
#define FLASHPAGE_RAW_ALIGNMENT (4)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4)
/* Add RWWEE memory if supported by revision of the chip
* 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

View File

@ -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);
_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 */
assert(((unsigned)target_addr + len) <=
@ -368,7 +353,7 @@ static void _cmd_write_page_rwwee(void)
#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) <=
(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);
}
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);

View File

@ -11,7 +11,7 @@ FEATURES_PROVIDED += periph_wdt
ifneq (,$(filter $(CPU_FAM),f0 f1 f3 g0 g4 l0 l1 l4 l5 wb))
FEATURES_PROVIDED += periph_flashpage
FEATURES_PROVIDED += periph_flashpage_raw
FEATURES_PROVIDED += periph_flashpage_pagewise
endif
ifneq (,$(filter $(CPU_FAM),l0 l1))

View File

@ -116,20 +116,20 @@ extern "C" {
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
defined(CPU_FAM_STM32L5)
#define FLASHPAGE_RAW_BLOCKSIZE (8U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (8U)
#elif defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
#define FLASHPAGE_RAW_BLOCKSIZE (4U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (4U)
#else
#define FLASHPAGE_RAW_BLOCKSIZE (2U)
#define FLASHPAGE_WRITE_BLOCK_SIZE (2U)
#endif
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
defined(CPU_FAM_STM32L5)
#define FLASHPAGE_RAW_ALIGNMENT (8U)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (8U)
#else
/* Writing should be always 4 bytes aligned */
#define FLASHPAGE_RAW_ALIGNMENT (4U)
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (4U)
#endif
/** @} */

View File

@ -14,7 +14,7 @@ config CPU_FAM_F0
select CPU_CORE_CORTEX_M0
select HAS_CPU_STM32F0
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
config HAS_CPU_STM32F0
bool

View File

@ -11,7 +11,7 @@ config CPU_FAM_F1
select CPU_CORE_CORTEX_M3
select HAS_CPU_STM32F1
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
config CPU_FAM
default "f1" if CPU_FAM_F1

View File

@ -11,7 +11,7 @@ config CPU_FAM_F3
select CPU_CORE_CORTEX_M4F
select HAS_CPU_STM32F3
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
config CPU_FAM
default "f3" if CPU_FAM_F3

View File

@ -11,7 +11,7 @@ config CPU_FAM_G0
select CPU_CORE_CORTEX_M0PLUS
select HAS_CPU_STM32G0
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
config CPU_FAM
default "g0" if CPU_FAM_G0

View File

@ -12,7 +12,7 @@ config CPU_FAM_G4
select HAS_CPU_STM32G4
select HAS_CORTEXM_MPU
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_HWRNG
config CPU_FAM

View File

@ -11,7 +11,7 @@ config CPU_FAM_L0
select CPU_CORE_CORTEX_M0PLUS
select HAS_CPU_STM32L0
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_EEPROM
config CPU_FAM

View File

@ -12,7 +12,7 @@ config CPU_FAM_L1
select HAS_CPU_STM32L1
select HAS_CORTEXM_MPU
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_EEPROM
config CPU_FAM

View File

@ -12,7 +12,7 @@ config CPU_FAM_L4
select HAS_CPU_STM32L4
select HAS_CORTEXM_MPU
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_HWRNG
config CPU_FAM

View File

@ -11,7 +11,7 @@ config CPU_FAM_L5
select CPU_CORE_CORTEX_M33
select HAS_CPU_STM32L5
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_HWRNG
config CPU_FAM

View File

@ -11,7 +11,7 @@ config CPU_FAM_WB
select CPU_CORE_CORTEX_M4
select HAS_CPU_STM32WB
select HAS_PERIPH_FLASHPAGE
select HAS_PERIPH_FLASHPAGE_RAW
select HAS_PERIPH_FLASHPAGE_PAGEWISE
select HAS_PERIPH_HWRNG
config CPU_FAM

View File

@ -163,15 +163,30 @@ static void _erase_page(void *page_addr)
#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. */
assert(!(len % FLASHPAGE_RAW_BLOCKSIZE));
assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE));
/* ensure writes are aligned */
assert(!(((unsigned)target_addr % FLASHPAGE_RAW_ALIGNMENT) ||
((unsigned)data % FLASHPAGE_RAW_ALIGNMENT)));
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) <
@ -238,23 +253,3 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len)
}
#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);
}
}

View File

@ -64,17 +64,17 @@ extern "C" {
#define CPU_FLASH_BASE (0)
#endif
/**
* @def FLASHPAGE_RAW_BLOCKSIZE
* @def FLASHPAGE_WRITE_BLOCK_SIZE
*
* @brief For raw writings to the flash, this constant must define the
* minimum write length allowed by the MCU.
*/
#ifdef DOXYGEN
#define FLASHPAGE_RAW_BLOCKSIZE
#define FLASHPAGE_WRITE_BLOCK_SIZE
#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
* the address on which the buffer is written to the flash. This variable
@ -82,7 +82,7 @@ extern "C" {
* requirements.
*/
#ifdef DOXYGEN
#define FLASHPAGE_RAW_ALIGNMENT
#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT
#endif
/**
* @def FLASHPAGE_SIZE
@ -114,7 +114,7 @@ enum {
*
* @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));
}
@ -130,11 +130,18 @@ static inline void *flashpage_addr(int page)
*
* @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
*
@ -142,7 +149,7 @@ static inline int flashpage_page(void *addr)
* @param[in] data data to write to the page, MUST be FLASHPAGE_SIZE
* 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
@ -152,20 +159,20 @@ void flashpage_write(int page, const void *data);
* this function
*
* 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
* 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
* to FLASHPAGE_RAW_ALIGNMENT.
* to FLASHPAGE_WRITE_BLOCK_ALIGNMENT.
* @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
* multiple of FLASHPAGE_RAW_BLOCKSIZE. Also,
* multiple of FLASHPAGE_WRITE_BLOCK_SIZE. Also,
* ensure it doesn't exceed the actual flash
* 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
@ -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
* byte
*/
void flashpage_read(int page, void *data);
void flashpage_read(unsigned page, void *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_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
@ -200,7 +207,7 @@ int flashpage_verify(int page, const void *data);
* @return FLASHPAGE_OK on success
* @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
@ -227,7 +234,7 @@ int flashpage_write_and_verify(int page, const void *data);
*
* @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));
}
@ -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
* 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
@ -265,20 +272,20 @@ void flashpage_rwwee_write(int page, const void *data);
* this function
*
* 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
* 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
* to FLASHPAGE_RAW_ALIGNMENT.
* to FLASHPAGE_WRITE_BLOCK_ALIGNMENT.
* @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
* multiple of FLASHPAGE_RAW_BLOCKSIZE. Also,
* multiple of FLASHPAGE_WRITE_BLOCK_SIZE. Also,
* ensure it doesn't exceed the actual RWWEE flash
* 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
@ -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
* 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
@ -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_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
@ -314,7 +321,7 @@ int flashpage_rwwee_verify(int page, const void *data);
* @return FLASHPAGE_OK on success
* @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 */

View File

@ -1,2 +1,2 @@
FEATURES_REQUIRED += periph_flashpage
FEATURES_REQUIRED += periph_flashpage_raw
FEATURES_REQUIRED += periph_flashpage_pagewise

View File

@ -42,7 +42,7 @@ static int _read(mtd_dev_t *dev, void *buf, uint32_t addr, uint32_t size)
(void)dev;
if (addr % FLASHPAGE_RAW_ALIGNMENT) {
if (addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) {
return -EINVAL;
}
@ -61,13 +61,13 @@ static int _write(mtd_dev_t *dev, const void *buf, uint32_t addr, uint32_t size)
{
(void)dev;
if (addr % FLASHPAGE_RAW_ALIGNMENT) {
if (addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) {
return -EINVAL;
}
if ((uintptr_t)buf % FLASHPAGE_RAW_ALIGNMENT) {
if ((uintptr_t)buf % FLASHPAGE_WRITE_BLOCK_ALIGNMENT) {
return -EINVAL;
}
if (size % FLASHPAGE_RAW_BLOCKSIZE) {
if (size % FLASHPAGE_WRITE_BLOCK_SIZE) {
return -EOVERFLOW;
}
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;
#endif
flashpage_write_raw((void *)dst_addr, buf, size);
flashpage_write((void *)dst_addr, buf, size);
return 0;
}
@ -106,7 +106,7 @@ int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t size)
#endif
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;

View File

@ -19,15 +19,15 @@ config MODULE_PERIPH_INIT_FLASHPAGE
default y if MODULE_PERIPH_INIT
depends on MODULE_PERIPH_FLASHPAGE
config MODULE_PERIPH_FLASHPAGE_RAW
bool "Raw writing support"
depends on HAS_PERIPH_FLASHPAGE_RAW
config MODULE_PERIPH_FLASHPAGE_PAGEWISE
bool "Pagewise writing support"
depends on HAS_PERIPH_FLASHPAGE_PAGEWISE
depends on MODULE_PERIPH_FLASHPAGE
config MODULE_PERIPH_INIT_FLASHPAGE_RAW
bool "Auto initialize Flashpage raw"
config MODULE_PERIPH_INIT_FLASHPAGE_PAGEWISE
bool "Auto initialize Flashpage pagewise"
default y if MODULE_PERIPH_INIT
depends on MODULE_PERIPH_FLASHPAGE_RAW
depends on MODULE_PERIPH_FLASHPAGE_PAGEWISE
config MODULE_PERIPH_FLASHPAGE_RWEE
bool "Read while Write support"

View File

@ -28,18 +28,19 @@
#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)
assert(page < (int)(FLASH->SFR & FLASH_SFR_SFSA));
assert(page < (FLASH->SFR & FLASH_SFR_SFSA));
#endif
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);
@ -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);
}
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)
void flashpage_rwwee_read(int page, void *data)
void flashpage_rwwee_read(unsigned page, void *data)
{
assert(page < (int)FLASHPAGE_RWWEE_NUMOF);
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);
@ -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);
}

View File

@ -124,10 +124,10 @@ config HAS_PERIPH_FLASHPAGE
help
Indicates that a Flashpage peripheral is present.
config HAS_PERIPH_FLASHPAGE_RAW
config HAS_PERIPH_FLASHPAGE_PAGEWISE
bool
help
Indicates that the Flashpage peripheral supports raw writing.
Indicates that the Flashpage peripheral supports pagewise writing.
config HAS_PERIPH_FLASHPAGE_RWEE
bool

View File

@ -910,7 +910,6 @@ endif
ifneq (,$(filter riotboot_flashwrite, $(USEMODULE)))
USEMODULE += riotboot_slot
FEATURES_REQUIRED += periph_flashpage
FEATURES_OPTIONAL += periph_flashpage_raw
endif
ifneq (,$(filter riotboot_slot, $(USEMODULE)))

View File

@ -41,9 +41,9 @@
* 2. write image starting at second 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_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
* 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
@ -70,7 +70,7 @@ extern "C" {
* @brief Enable/disable raw writes to flash
*/
#ifndef CONFIG_RIOTBOOT_FLASHWRITE_RAW
#define CONFIG_RIOTBOOT_FLASHWRITE_RAW IS_ACTIVE(MODULE_PERIPH_FLASHPAGE_RAW)
#define CONFIG_RIOTBOOT_FLASHWRITE_RAW 1
#endif
/**
@ -78,10 +78,10 @@ extern "C" {
*/
#if CONFIG_RIOTBOOT_FLASHWRITE_RAW
#if (FLASHPAGE_RAW_BLOCKSIZE < 4)
#if (FLASHPAGE_WRITE_BLOCK_SIZE < 4)
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE 4
#else
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE FLASHPAGE_RAW_BLOCKSIZE
#define RIOTBOOT_FLASHPAGE_BUFFER_SIZE FLASHPAGE_WRITE_BLOCK_SIZE
#endif
#else /* CONFIG_RIOTBOOT_FLASHWRITE_RAW */
@ -94,13 +94,14 @@ extern "C" {
* @brief Extra attributes required for the firmware intermediate buffer
*/
#define RIOTBOOT_FLASHPAGE_BUFFER_ATTRS \
__attribute__((aligned(FLASHPAGE_RAW_ALIGNMENT)))
__attribute__((aligned(FLASHPAGE_WRITE_BLOCK_ALIGNMENT)))
/**
* @brief firmware update state structure
*
* @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 {
int target_slot; /**< update targets this slot */

View File

@ -59,7 +59,7 @@ int riotboot_flashwrite_init_raw(riotboot_flashwrite_t *state, int target_slot,
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW && offset) {
/* Erase the first page only if the offset (!=0) specifies that there is
* a checksum or other mechanism at the start of the page. */
flashpage_write(state->flashpage, NULL);
flashpage_erase(state->flashpage);
}
return 0;
@ -78,9 +78,9 @@ int riotboot_flashwrite_flush(riotboot_flashwrite_t *state)
/* Get the offset of the remaining chunk */
size_t flashpage_pos = state->offset - flashwrite_buffer_pos;
/* Write remaining chunk */
flashpage_write_raw(slot_start + flashpage_pos,
state->flashpage_buf,
RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
flashpage_write(slot_start + flashpage_pos,
state->flashpage_buf,
RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
}
else {
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) {
/* Erase the next page */
state->flashpage++;
flashpage_write(state->flashpage, NULL);
flashpage_erase(state->flashpage);
}
if (CONFIG_RIOTBOOT_FLASHWRITE_RAW &&
flashwrite_buffer_pos == 0) {
@ -131,7 +131,7 @@ int riotboot_flashwrite_putbytes(riotboot_flashwrite_t *state,
state->flashpage_buf, RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
}
else {
flashpage_write_raw((uint8_t*)addr + flashpage_pos,
flashpage_write((uint8_t*)addr + flashpage_pos,
state->flashpage_buf,
RIOTBOOT_FLASHPAGE_BUFFER_SIZE);
}
@ -161,7 +161,7 @@ int riotboot_flashwrite_finish_raw(riotboot_flashwrite_t *state,
#if CONFIG_RIOTBOOT_FLASHWRITE_RAW
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
uint8_t *firstpage;

View File

@ -122,7 +122,8 @@ static void test_mtd_write_erase(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 */
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)

View File

@ -8,6 +8,6 @@
config APPLICATION
bool
default y
imply MODULE_PERIPH_FLASHPAGE_RAW
imply MODULE_PERIPH_FLASHPAGE_PAGEWISE
imply MODULE_PERIPH_FLASHPAGE_RWEE
depends on TEST_KCONFIG

View File

@ -2,7 +2,7 @@ BOARD ?= iotlab-m3
include ../Makefile.tests_common
FEATURES_REQUIRED += periph_flashpage
FEATURES_OPTIONAL += periph_flashpage_raw
FEATURES_OPTIONAL += periph_flashpage_pagewise
FEATURES_OPTIONAL += periph_flashpage_rwee
USEMODULE += od

View File

@ -38,21 +38,17 @@
#endif
/* When writing raw bytes on flash, data must be correctly aligned. */
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
#define ALIGNMENT_ATTR __attribute__ ((aligned (FLASHPAGE_RAW_ALIGNMENT)))
#define ALIGNMENT_ATTR __attribute__((aligned(FLASHPAGE_WRITE_BLOCK_ALIGNMENT)))
/*
* @brief Allocate an aligned buffer for raw writings
*/
static char raw_buf[64] ALIGNMENT_ATTR;
#else
#define ALIGNMENT_ATTR
#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
* using flashpage. This is because some architecture uses
* 32 bit alignment implicitly and there are cases (stm32l4) that
* requires 64 bit alignment.
*/
@ -176,6 +172,7 @@ static int cmd_read(int argc, char **argv)
return 0;
}
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
static int cmd_write(int argc, char **argv)
{
int page;
@ -199,8 +196,8 @@ static int cmd_write(int argc, char **argv)
page, flashpage_addr(page));
return 0;
}
#endif
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
static uint32_t getaddr(const char *str)
{
uint32_t addr = strtol(str, NULL, 16);
@ -229,7 +226,7 @@ static int cmd_write_raw(int argc, char **argv)
/* try to align */
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)
printf("wrote local data to flash address %#" PRIx16 " of len %u\n",
addr, strlen(raw_buf));
@ -239,7 +236,6 @@ static int cmd_write_raw(int argc, char **argv)
#endif
return 0;
}
#endif
static int cmd_erase(int argc, char **argv)
{
@ -254,7 +250,7 @@ static int cmd_erase(int argc, char **argv)
if (page < 0) {
return 1;
}
flashpage_write(page, NULL);
flashpage_erase(page);
printf("successfully erased page %i (addr %p)\n",
page, flashpage_addr(page));
@ -287,6 +283,7 @@ static int cmd_edit(int argc, char **argv)
return 0;
}
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
static int cmd_test(int argc, char **argv)
{
int page;
@ -349,8 +346,8 @@ static int cmd_test_last(int argc, char **argv)
puts("wrote local page buffer to last flash page");
return 0;
}
#endif
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
/**
* @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
/* 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 */
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");
return 0;
}
#endif
#ifdef FLASHPAGE_RWWEE_NUMOF
@ -507,7 +503,6 @@ static int cmd_test_last_rwwee(int argc, char **argv)
return 0;
}
#ifdef MODULE_PERIPH_FLASHPAGE_RAW
/**
* @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);
/* 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 */
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");
return 0;
}
#endif
#endif
@ -607,26 +601,24 @@ static const shell_command_t shell_commands[] = {
{ "dump", "Dump the selected page to STDOUT", cmd_dump },
{ "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 },
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
{ "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
{ "write_raw", "Write (ASCII, max 64B) data to the given address", cmd_write_raw },
{ "erase", "Erase the given page buffer", cmd_erase },
{ "edit", "Write bytes to the local page buffer", cmd_edit },
#ifdef MODULE_PERIPH_FLASHPAGE_PAGEWISE
{ "test", "Write and verify test pattern", cmd_test },
{ "test_last", "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 },
{ "test_last_pagewise", "Write and verify test pattern on last page available", cmd_test_last },
#endif
{ "test_last_raw", "Write and verify raw short write on last page available", cmd_test_last_raw },
#ifdef FLASHPAGE_RWWEE_NUMOF
{ "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 },
{ "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 },
#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 },
#endif
#endif
#ifdef NVMCTRL_USER
{ "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 },

View File

@ -16,17 +16,17 @@ def testfunc(child):
child.expect('>')
# writes and verifies the last page of the flash
child.sendline("test_last")
child.expect_exact('wrote local page buffer to last flash page')
child.sendline("test_last_raw")
child.expect_exact('wrote raw short buffer to last flash page')
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
child.sendline("help")
index = child.expect(['test_last_raw', '>'])
index = child.expect(['test_last_pagewise', '>'])
if index == 0:
child.sendline("test_last_raw")
child.expect_exact('wrote raw short buffer to last flash page')
child.sendline("test_last_pagewise")
child.expect_exact('wrote local page buffer to last flash page')
child.expect('>')
# check if board has RWWEE capability and if so test that as well