diff --git a/arch/arm/src/stm32/chip/stm32_flash.h b/arch/arm/src/stm32/chip/stm32_flash.h index 6bc1085bd1..13c966c05c 100644 --- a/arch/arm/src/stm32/chip/stm32_flash.h +++ b/arch/arm/src/stm32/chip/stm32_flash.h @@ -59,16 +59,33 @@ #if defined(CONFIG_STM32_FLASH_CONFIG_DEFAULT) # if defined(CONFIG_STM32_STM32L15XX) +# if defined(CONFIG_STM32_HIGHDENSITY) -/* The STM32 L15xx/L16xx can support up to 384KB of FLASH. (In reality, supported - * L15xx parts have no more than 128KB). The program memory block is divided into - * 96 sectors of 4 Kbytes each, and each sector is further split up into 16 pages of - * 256 bytes each. The sector is the write protection granularity. In total, the +/* Different STM32L1xxx MCU version are now called by different 'categories' instead + * of 'densities'. Cat.5 MCU can have up to 512KB of FLASH. STM32L1xxx also have + * data EEPROM, up to 16KB. + */ + +# define STM32_FLASH_NPAGES 2048 +# define STM32_FLASH_PAGESIZE 256 +# else + +/* The STM32 (< Cat.5) L15xx/L16xx can support up to 384KB of FLASH. (In reality, most + * supported L15xx parts have no more than 128KB). The program memory block is divided + * into 96 sectors of 4 Kbytes each, and each sector is further split up into 16 pages + * of 256 bytes each. The sector is the write protection granularity. In total, the * program memory block contains 1536 pages. */ -# define STM32_FLASH_NPAGES 1536 -# define STM32_FLASH_PAGESIZE 256 +# define STM32_FLASH_NPAGES 1536 +# define STM32_FLASH_PAGESIZE 256 +# endif + + /* Maximum EEPROM size on Cat.5 MCU. TODO: this should be in chip config. */ + +# ifndef STM32_EEPROM_SIZE +# define STM32_EEPROM_SIZE (16 * 1024) +# endif # elif defined(CONFIG_STM32_LOWDENSITY) # define STM32_FLASH_NPAGES 32 @@ -201,27 +218,40 @@ # elif defined(CONFIG_STM32_FLASH_CONFIG_I) # endif # endif -#endif +#endif /* !defined(CONFIG_STM32_FLASH_CONFIG_DEFAULT) */ #ifdef STM32_FLASH_PAGESIZE # define STM32_FLASH_SIZE (STM32_FLASH_NPAGES * STM32_FLASH_PAGESIZE) -#endif /* def STM32_FLASH_PAGESIZE */ +#endif /* Register Offsets *****************************************************************/ -#define STM32_FLASH_ACR_OFFSET 0x0000 -#define STM32_FLASH_KEYR_OFFSET 0x0004 -#define STM32_FLASH_OPTKEYR_OFFSET 0x0008 -#define STM32_FLASH_SR_OFFSET 0x000c -#define STM32_FLASH_CR_OFFSET 0x0010 - -#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F33XX) || defined(CONFIG_STM32_STM32F37XX) -# define STM32_FLASH_AR_OFFSET 0x0014 -# define STM32_FLASH_OBR_OFFSET 0x001c -# define STM32_FLASH_WRPR_OFFSET 0x0020 -#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) -# define STM32_FLASH_OPTCR_OFFSET 0x0014 +#define STM32_FLASH_ACR_OFFSET 0x0000 +#if defined(CONFIG_STM32_STM32L15XX) +# define STM32_FLASH_PECR_OFFSET 0x0004 +# define STM32_FLASH_PDKEYR_OFFSET 0x0008 +# define STM32_FLASH_PEKEYR_OFFSET 0x000c +# define STM32_FLASH_PRGKEYR_OFFSET 0x0010 +# define STM32_FLASH_OPTKEYR_OFFSET 0x0014 +# define STM32_FLASH_SR_OFFSET 0x0018 +# define STM32_FLASH_OBR_OFFSET 0x001c +# define STM32_FLASH_WRPR1_OFFSET 0x0020 +# define STM32_FLASH_WRPR2_OFFSET 0x0080 +# define STM32_FLASH_WRPR3_OFFSET 0x0084 +# define STM32_FLASH_WRPR4_OFFSET 0x0088 +#else +# define STM32_FLASH_KEYR_OFFSET 0x0004 +# define STM32_FLASH_OPTKEYR_OFFSET 0x0008 +# define STM32_FLASH_SR_OFFSET 0x000c +# define STM32_FLASH_CR_OFFSET 0x0010 +# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F33XX) || defined(CONFIG_STM32_STM32F37XX) +# define STM32_FLASH_AR_OFFSET 0x0014 +# define STM32_FLASH_OBR_OFFSET 0x001c +# define STM32_FLASH_WRPR_OFFSET 0x0020 +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_FLASH_OPTCR_OFFSET 0x0014 +# endif #endif #if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) @@ -230,22 +260,36 @@ /* Register Addresses ***************************************************************/ -#define STM32_FLASH_ACR (STM32_FLASHIF_BASE+STM32_FLASH_ACR_OFFSET) -#define STM32_FLASH_KEYR (STM32_FLASHIF_BASE+STM32_FLASH_KEYR_OFFSET) -#define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE+STM32_FLASH_OPTKEYR_OFFSET) -#define STM32_FLASH_SR (STM32_FLASHIF_BASE+STM32_FLASH_SR_OFFSET) -#define STM32_FLASH_CR (STM32_FLASHIF_BASE+STM32_FLASH_CR_OFFSET) +#define STM32_FLASH_ACR (STM32_FLASHIF_BASE+STM32_FLASH_ACR_OFFSET) +#if defined(CONFIG_STM32_STM32L15XX) +# define STM32_FLASH_PECR (STM32_FLASHIF_BASE+STM32_FLASH_PECR_OFFSET) +# define STM32_FLASH_PDKEYR (STM32_FLASHIF_BASE+STM32_FLASH_PDKEYR_OFFSET) +# define STM32_FLASH_PEKEYR (STM32_FLASHIF_BASE+STM32_FLASH_PEKEYR_OFFSET) +# define STM32_FLASH_PRGKEYR (STM32_FLASHIF_BASE+STM32_FLASH_PRGKEYR_OFFSET) +# define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE+STM32_FLASH_OPTKEYR_OFFSET) +# define STM32_FLASH_SR (STM32_FLASHIF_BASE+STM32_FLASH_SR_OFFSET) +# define STM32_FLASH_OBR (STM32_FLASHIF_BASE+STM32_FLASH_OBR_OFFSET) +# define STM32_FLASH_WRPR1 (STM32_FLASHIF_BASE+STM32_FLASH_WRPR1_OFFSET) +# define STM32_FLASH_WRPR2 (STM32_FLASHIF_BASE+STM32_FLASH_WRPR2_OFFSET) +# define STM32_FLASH_WRPR3 (STM32_FLASHIF_BASE+STM32_FLASH_WRPR3_OFFSET) +# define STM32_FLASH_WRPR4 (STM32_FLASHIF_BASE+STM32_FLASH_WRPR4_OFFSET) +#else +# define STM32_FLASH_KEYR (STM32_FLASHIF_BASE+STM32_FLASH_KEYR_OFFSET) +# define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE+STM32_FLASH_OPTKEYR_OFFSET) +# define STM32_FLASH_SR (STM32_FLASHIF_BASE+STM32_FLASH_SR_OFFSET) +# define STM32_FLASH_CR (STM32_FLASHIF_BASE+STM32_FLASH_CR_OFFSET) -#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F33XX) || defined(CONFIG_STM32_STM32F37XX) -# define STM32_FLASH_AR (STM32_FLASHIF_BASE+STM32_FLASH_AR_OFFSET) -# define STM32_FLASH_OBR (STM32_FLASHIF_BASE+STM32_FLASH_OBR_OFFSET) -# define STM32_FLASH_WRPR (STM32_FLASHIF_BASE+STM32_FLASH_WRPR_OFFSET) -#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) -# define STM32_FLASH_OPTCR (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR_OFFSET) -#endif -#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) -# define STM32_FLASH_OPTCR1 (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR1_OFFSET) +# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F33XX) || defined(CONFIG_STM32_STM32F37XX) +# define STM32_FLASH_AR (STM32_FLASHIF_BASE+STM32_FLASH_AR_OFFSET) +# define STM32_FLASH_OBR (STM32_FLASHIF_BASE+STM32_FLASH_OBR_OFFSET) +# define STM32_FLASH_WRPR (STM32_FLASHIF_BASE+STM32_FLASH_WRPR_OFFSET) +# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +# define STM32_FLASH_OPTCR (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR_OFFSET) +# endif +# if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) +# define STM32_FLASH_OPTCR1 (STM32_FLASHIF_BASE+STM32_FLASH_OPTCR1_OFFSET) +# endif #endif /* Register Bitfield Definitions ****************************************************/ @@ -303,6 +347,34 @@ # define FLASH_SR_PGPERR (1 << 6) /* Bit 6: Programming parallelism error */ # define FLASH_SR_PGSERR (1 << 7) /* Bit 7: Programming sequence error */ # define FLASH_SR_BSY (1 << 16) /* Bit 16: Busy */ +#elif defined(CONFIG_STM32_STM32L15XX) +# define FLASH_SR_BSY (1 << 0) /* Bit 0: Busy */ +# define FLASH_SR_EOP (1 << 1) /* Bit 1: End of operation */ +# define FLASH_SR_ENDHV (1 << 2) /* Bit 2: End of high voltage */ +# define FLASH_SR_READY (1 << 3) /* Bit 3: Flash memory module ready after low power mode */ +# define FLASH_SR_WRPERR (1 << 8) /* Bit 8: Write protection error */ +# define FLASH_SR_PGAERR (1 << 9) /* Bit 9: Programming alignment error */ +# define FLASH_SR_SIZERR (1 << 10) /* Bit 10: Size error */ +# define FLASH_SR_OPTVERR (1 << 11) /* Bit 11: Option validity error */ +# define FLASH_SR_OPTVERRUSR (1 << 12) /* Bit 12: Option UserValidity Error */ +# define FLASH_SR_RDERR (1 << 13) /* Bit 13: Read protected error */ +#endif + +/* Program/Erase Control Register (PECR) */ + +#if defined(CONFIG_STM32_STM32L15XX) +# define FLASH_PECR_PELOCK (1 << 0) /* Bit 0: PECR and data EEPROM lock */ +# define FLASH_PECR_PRGLOCK (1 << 1) /* Bit 1: Program memory lock */ +# define FLASH_PECR_OPTLOCK (1 << 2) /* Bit 2: Option bytes block lock */ +# define FLASH_PECR_PROG (1 << 3) /* Bit 3: Program memory selection */ +# define FLASH_PECR_DATA (1 << 4) /* Bit 4: Data EEPROM selection */ +# define FLASH_PECR_FTDW (1 << 8) /* Bit 8: Fixed time data write for Byte, Half Word and Word programming */ +# define FLASH_PECR_ERASE (1 << 9) /* Bit 9: Page or Double Word erase mode */ +# define FLASH_PECR_FPRG (1 << 10) /* Bit 10: Half Page/Double Word programming mode */ +# define FLASH_PECR_PARALLBANK (1 << 15) /* Bit 15: Parallel bank mode */ +# define FLASH_PECR_EOPIE (1 << 16) /* Bit 16: End of programming interrupt enable */ +# define FLASH_PECR_ERRIE (1 << 17) /* Bit 17: Error interrupt enable */ +# define FLASH_PECR_OBL_LAUNCH (1 << 18) /* Bit 18: Launch the option byte loading */ #endif /* Flash Control Register (CR) */ @@ -380,7 +452,6 @@ # define FLASH_OPTCR1_BFB2_SHIFT (4) /* Bits 4: Dual-bank Boot option byte */ # define FLASH_OPTCR1_BFB2_MASK (1 << FLASH_OPTCR_NWRP_SHIFT) - #endif #if defined(CONFIG_STM32_STM32F446) diff --git a/arch/arm/src/stm32/stm32_flash.c b/arch/arm/src/stm32/stm32_flash.c index fb1e1cac22..1dae18724c 100644 --- a/arch/arm/src/stm32/stm32_flash.c +++ b/arch/arm/src/stm32/stm32_flash.c @@ -59,10 +59,10 @@ #include "up_arch.h" -/* Only for the STM32F[1|3|4]0xx family for now */ +/* Only for the STM32F[1|3|4]0xx family and STM32L15xx (EEPROM only) for now */ #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined (CONFIG_STM32_STM32F40XX) + defined (CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) #if defined(CONFIG_STM32_FLASH_CONFIG_DEFAULT) && \ (defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)) @@ -73,15 +73,25 @@ * Pre-processor Definitions ************************************************************************************/ -#define FLASH_KEY1 0x45670123 -#define FLASH_KEY2 0xCDEF89AB +#if defined(CONFIG_STM32_STM32L15XX) +# define FLASH_KEY1 0x8C9DAEBF +# define FLASH_KEY2 0x13141516 +#else +# define FLASH_KEY1 0x45670123 +# define FLASH_KEY2 0xCDEF89AB +#endif #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) -#define FLASH_CR_PAGE_ERASE FLASH_CR_PER -#define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPRT_ERR +# define FLASH_CR_PAGE_ERASE FLASH_CR_PER +# define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPRT_ERR #elif defined(CONFIG_STM32_STM32F40XX) -#define FLASH_CR_PAGE_ERASE FLASH_CR_SER -#define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPERR +# define FLASH_CR_PAGE_ERASE FLASH_CR_SER +# define FLASH_SR_WRITE_PROTECTION_ERROR FLASH_SR_WRPERR +#endif + +#if defined(CONFIG_STM32_STM32L15XX) +# define EEPROM_KEY1 0x89ABCDEF +# define EEPROM_KEY2 0x02030405 #endif /************************************************************************************ @@ -107,6 +117,8 @@ static inline void sem_unlock(void) sem_post(&g_sem); } +#if !defined(CONFIG_STM32_STM32L15XX) + static void flash_unlock(void) { while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) @@ -128,6 +140,8 @@ static void flash_lock(void) modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_LOCK); } +#endif /* !defined(CONFIG_STM32_STM32L15XX) */ + #if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) static void data_cache_disable(void) { @@ -146,6 +160,183 @@ static void data_cache_enable(void) } #endif /* defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) */ +#if defined(CONFIG_STM32_STM32L15XX) + +static void stm32_eeprom_unlock(void) +{ + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) + { + up_waste(); + } + + if (getreg32(STM32_FLASH_PECR) & FLASH_PECR_PELOCK) + { + /* Unlock sequence */ + + putreg32(EEPROM_KEY1, STM32_FLASH_PEKEYR); + putreg32(EEPROM_KEY2, STM32_FLASH_PEKEYR); + } +} + +static void stm32_eeprom_lock(void) +{ + modifyreg32(STM32_FLASH_PECR, 0, FLASH_PECR_PELOCK); +} + +static void flash_unlock(void) +{ + if (getreg32(STM32_FLASH_PECR) & FLASH_PECR_PRGLOCK) + { + stm32_eeprom_unlock(); + + /* Unlock sequence */ + + putreg32(FLASH_KEY1, STM32_FLASH_PRGKEYR); + putreg32(FLASH_KEY2, STM32_FLASH_PRGKEYR); + } +} + +static void flash_lock(void) +{ + modifyreg32(STM32_FLASH_PECR, 0, FLASH_PECR_PRGLOCK); + stm32_eeprom_lock(); +} + +static ssize_t stm32_eeprom_erase_write(size_t addr, const void *buf, + size_t buflen) +{ + const char *cbuf = buf; + size_t i; + + if (buflen == 0) + { + return 0; + } + + /* Check for valid address range */ + + if (addr >= STM32_EEPROM_BASE) + { + addr -= STM32_EEPROM_BASE; + } + + if (addr >= STM32_EEPROM_SIZE) + { + return -EINVAL; + } + + /* TODO: Voltage range must be range 1 or 2. Erase/program not allowed in + * range 3. + */ + + stm32_eeprom_unlock(); + + /* Clear pending status flags. */ + + putreg32(FLASH_SR_WRPERR | FLASH_SR_PGAERR | + FLASH_SR_SIZERR | FLASH_SR_OPTVERR | + FLASH_SR_OPTVERRUSR | FLASH_SR_RDERR, STM32_FLASH_SR); + + /* Enable automatic erasing (by disabling 'fixed time' programming). */ + + modifyreg32(STM32_FLASH_PECR, FLASH_PECR_FTDW, 0); + + /* Write buffer to EEPROM data memory. */ + + addr += STM32_EEPROM_BASE; + i = 0; + while (i < buflen) + { + uint32_t writeval; + size_t left = buflen - i; + + if ((addr & 0x03) == 0x00 && left >= 4) + { + /* Read/erase/write word */ + + writeval = cbuf ? *(uint32_t *)cbuf : 0; + putreg32(writeval, addr); + } + else if ((addr & 0x01) == 0x00 && left >= 2) + { + /* Read/erase/write half-word */ + + writeval = cbuf ? *(uint16_t *)cbuf : 0; + putreg16(writeval, addr); + } + else + { + /* Read/erase/write byte */ + + writeval = cbuf ? *(uint8_t *)cbuf : 0; + putreg8(writeval, addr); + } + + /* ... and wait to complete. */ + + while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) + { + up_waste(); + } + + /* Verify */ + + /* We do not check Options Byte invalid flags FLASH_SR_OPTVERR + * and FLASH_SR_OPTVERRUSR for EEPROM erase/write. They are unrelated + * and STM32L standard library does not check for these either. + */ + + if (getreg32(STM32_FLASH_SR) & (FLASH_SR_WRPERR | FLASH_SR_PGAERR | + FLASH_SR_SIZERR | FLASH_SR_RDERR)) + { + stm32_eeprom_lock(); + return -EROFS; + } + + if ((addr & 0x03) == 0x00 && left >= 4) + { + if (getreg32(addr) != writeval) + { + stm32_eeprom_lock(); + return -EIO; + } + + addr += 4; + i += 4; + cbuf += !!(cbuf) * 4; + } + else if ((addr & 0x01) == 0x00 && left >= 2) + { + if (getreg16(addr) != writeval) + { + stm32_eeprom_lock(); + return -EIO; + } + + addr += 2; + i += 2; + cbuf += !!(cbuf) * 2; + } + else + { + if (getreg8(addr) != writeval) + { + stm32_eeprom_lock(); + return -EIO; + } + + addr += 1; + i += 1; + cbuf += !!(cbuf) * 1; + } + } + + stm32_eeprom_lock(); + return buflen; +} + +#endif /* defined(CONFIG_STM32_STM32L15XX) */ + /************************************************************************************ * Public Functions ************************************************************************************/ @@ -164,6 +355,35 @@ void stm32_flash_lock(void) sem_unlock(); } +#if defined(CONFIG_STM32_STM32L15XX) + +size_t stm32_eeprom_size(void) +{ + return STM32_EEPROM_SIZE; +} + +size_t stm32_eeprom_getaddress(void) +{ + return STM32_EEPROM_BASE; +} + +ssize_t stm32_eeprom_write(size_t addr, const void *buf, size_t buflen) +{ + if (!buf) + { + return -EINVAL; + } + + return stm32_eeprom_erase_write(addr, buf, buflen); +} + +ssize_t stm32_eeprom_erase(size_t addr, size_t eraselen) +{ + return stm32_eeprom_erase_write(addr, NULL, eraselen); +} + +#endif /* defined(CONFIG_STM32_STM32L15XX) */ + #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) size_t up_progmem_pagesize(size_t page) { @@ -260,6 +480,8 @@ size_t up_progmem_getaddress(size_t page) #endif /* def CONFIG_STM32_STM32F40XX */ +#if !defined(CONFIG_STM32_STM32L15XX) + size_t up_progmem_npages(void) { return STM32_FLASH_NPAGES; @@ -271,14 +493,14 @@ bool up_progmem_isuniform(void) return true; #else return false; -#endif /* def STM32_FLASH_PAGESIZE */ +#endif } ssize_t up_progmem_erasepage(size_t page) { #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) size_t page_address; -#endif /* defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) */ +#endif if (page >= STM32_FLASH_NPAGES) { @@ -438,5 +660,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) return written; } +#endif /* !defined(CONFIG_STM32_STM32L15XX) */ + #endif /* defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined (CONFIG_STM32_STM32F40XX) */ + defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) */ diff --git a/arch/arm/src/stm32/stm32_flash.h b/arch/arm/src/stm32/stm32_flash.h index 10c5cc189e..6da1b0b703 100644 --- a/arch/arm/src/stm32/stm32_flash.h +++ b/arch/arm/src/stm32/stm32_flash.h @@ -46,4 +46,60 @@ #include "chip.h" #include "chip/stm32_flash.h" +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_eeprom_size + * + * Description: + * Get EEPROM data memory size + * + * Returns: + * Length of EEPROM memory region + * + ************************************************************************************/ + +size_t stm32_eeprom_size(void); + +/************************************************************************************ + * Name: stm32_eeprom_getaddress + * + * Description: + * Get EEPROM data memory address + * + * Returns: + * Address of EEPROM memory region + * + ************************************************************************************/ + +size_t stm32_eeprom_getaddress(void); + +/************************************************************************************ + * Name: stm32_eeprom_write + * + * Description: + * Write buffer to EEPROM data memory address + * + * Returns: + * Number of written bytes or error code. + * + ************************************************************************************/ + +ssize_t stm32_eeprom_write(size_t addr, const void *buf, size_t buflen); + +/************************************************************************************ + * Name: stm32_eeprom_erase + * + * Description: + * Erase memory on EEPROM data memory address + * + * Returns: + * Number of erased bytes or error code. + * + ************************************************************************************/ + +ssize_t stm32_eeprom_erase(size_t addr, size_t eraselen); + #endif /* __ARCH_ARM_SRC_STM32_STM32_FLASH_H */