diff --git a/cpu/stm32_common/Makefile.include b/cpu/stm32_common/Makefile.include index e172bfbacf5f900550d44cf51c9959147e221bb6..1bb08442965d40b627c00d8de83db9d7478a2dc6 100644 --- a/cpu/stm32_common/Makefile.include +++ b/cpu/stm32_common/Makefile.include @@ -8,6 +8,12 @@ USEMODULE += periph_common # include stm32 common functions and stm32 common periph drivers USEMODULE += stm32_common stm32_common_periph +# flashpage and eeprom periph implementations share flash lock/unlock functions +# in periph_flash_common +ifneq (,$(filter periph_flashpage periph_eeprom,$(FEATURES_REQUIRED))) + FEATURES_REQUIRED += periph_flash_common +endif + # For stm32 cpu's we use the stm32_common.ld linker script export LINKFLAGS += -L$(RIOTCPU)/stm32_common/ldscripts LINKER_SCRIPT ?= stm32_common.ld diff --git a/cpu/stm32_common/periph/eeprom.c b/cpu/stm32_common/periph/eeprom.c new file mode 100644 index 0000000000000000000000000000000000000000..470ae47276ca167a6d9725ccecdd205d594e9607 --- /dev/null +++ b/cpu/stm32_common/periph/eeprom.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_stm32_common + * @ingroup drivers_periph_eeprom + * @{ + * + * @file + * @brief Low-level eeprom driver implementation + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include <assert.h> + +#include "cpu.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#include "periph/eeprom.h" + +extern void _lock(void); +extern void _unlock(void); + +#ifndef EEPROM_START_ADDR +#error "periph/eeprom: EEPROM_START_ADDR is not defined" +#endif + +uint8_t eeprom_read_byte(uint32_t pos) +{ + assert(pos < EEPROM_SIZE); + + DEBUG("Reading data from EEPROM at pos %lu\n", pos); + return *(uint8_t *)(EEPROM_START_ADDR + pos); +} + +void eeprom_write_byte(uint32_t pos, uint8_t data) +{ + assert(pos < EEPROM_SIZE); + + DEBUG("Writing data '%c' to EEPROM at pos %lu\n", data, pos); + _unlock(); + *(uint8_t *)(EEPROM_START_ADDR + pos) = data; + _lock(); +} diff --git a/cpu/stm32_common/periph/flash_common.c b/cpu/stm32_common/periph/flash_common.c new file mode 100644 index 0000000000000000000000000000000000000000..34f92e75f06fcf084e8485c88eb02733d881d529 --- /dev/null +++ b/cpu/stm32_common/periph/flash_common.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_stm32_common + * @{ + * + * @file + * @brief Low-level flash lock/unlock implementation + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include "cpu.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) +/* Data EEPROM and control register unlock keys */ +#define FLASH_KEY1 ((uint32_t)0x89ABCDEF) +#define FLASH_KEY2 ((uint32_t)0x02030405) +#define CNTRL_REG (FLASH->PECR) +#define CNTRL_REG_LOCK (FLASH_PECR_PELOCK) +#define KEY_REG (FLASH->PEKEYR) +#else +#define CNTRL_REG (FLASH->CR) +#define CNTRL_REG_LOCK (FLASH_CR_LOCK) +#define KEY_REG (FLASH->KEYR) +#endif + +void _unlock(void) +{ + DEBUG("[flash-common] unlocking the flash module\n"); + if (CNTRL_REG & CNTRL_REG_LOCK) { + KEY_REG = FLASH_KEY1; + KEY_REG = FLASH_KEY2; + } +} + +void _lock(void) +{ + DEBUG("[flash-common] locking the flash module\n"); + CNTRL_REG |= CNTRL_REG_LOCK; +} diff --git a/cpu/stm32_common/periph/flashpage.c b/cpu/stm32_common/periph/flashpage.c index 1884579c11c0b6ab77ed68ef6327d8404acc8607..e4454b18183b3cbb6a8c5e0ce1589a8267d0a5bc 100644 --- a/cpu/stm32_common/periph/flashpage.c +++ b/cpu/stm32_common/periph/flashpage.c @@ -32,32 +32,26 @@ #include "periph/flashpage.h" #if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) -/* Data EEPROM and control register unlock keys */ -#define FLASH_KEY1 ((uint32_t)0x89ABCDEF) -#define FLASH_KEY2 ((uint32_t)0x02030405) /* Program memory unlock keys */ #define FLASH_PRGKEY1 ((uint32_t)0x8C9DAEBF) #define FLASH_PRGKEY2 ((uint32_t)0x13141516) #define CNTRL_REG (FLASH->PECR) #define CNTRL_REG_LOCK (FLASH_PECR_PELOCK) -#define KEY_REG (FLASH->PEKEYR) #define FLASH_CR_PER (FLASH_PECR_ERASE | FLASH_PECR_PROG) #define FLASH_CR_PG (FLASH_PECR_FPRG | FLASH_PECR_PROG) #define FLASHPAGE_DIV (4U) /* write 4 bytes in one go */ #else #define CNTRL_REG (FLASH->CR) #define CNTRL_REG_LOCK (FLASH_CR_LOCK) -#define KEY_REG (FLASH->KEYR) #define FLASHPAGE_DIV (2U) #endif -static void _unlock(void) +extern void _lock(void); +extern void _unlock(void); + +static void _unlock_flash(void) { - DEBUG("[flashpage] unlocking the flash module\n"); - if (CNTRL_REG & CNTRL_REG_LOCK) { - KEY_REG = FLASH_KEY1; - KEY_REG = FLASH_KEY2; - } + _unlock(); #if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) DEBUG("[flashpage] unlocking the flash program memory\n"); @@ -71,12 +65,6 @@ static void _unlock(void) #endif } -static void _lock(void) -{ - DEBUG("[flashpage] locking the flash module\n"); - CNTRL_REG |= CNTRL_REG_LOCK; -} - static void _erase_page(void *page_addr) { #if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) @@ -90,7 +78,7 @@ static void _erase_page(void *page_addr) #endif /* unlock the flash module */ - _unlock(); + _unlock_flash(); /* make sure no flash operation is ongoing */ DEBUG("[flashpage] erase: waiting for any operation to finish\n"); @@ -153,7 +141,7 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len) #endif DEBUG("[flashpage_raw] unlocking the flash module\n"); - _unlock(); + _unlock_flash(); DEBUG("[flashpage] write: now writing the data\n"); #if !(defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1))