From 81152cfee2121e16931a146771fefa0495f6ba82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Wed, 21 Jul 2021 23:33:22 +0200 Subject: [PATCH] eeprom_blockprog: add EEPROM block programing library --- eeprom_blockprog.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ eeprom_blockprog.h | 14 ++++++++++ 2 files changed, 83 insertions(+) create mode 100644 eeprom_blockprog.c create mode 100644 eeprom_blockprog.h diff --git a/eeprom_blockprog.c b/eeprom_blockprog.c new file mode 100644 index 0000000..f9fea72 --- /dev/null +++ b/eeprom_blockprog.c @@ -0,0 +1,69 @@ +/** library to program EEPROM using block programming + * @file + * @author King Kévin + * @copyright SPDX-License-Identifier: GPL-3.0-or-later + * @date 2021 + * @warning functions need to be put in and run from RAM (because block programming is used) + */ + +// RAM code-putting from https://lujji.github.io/blog/executing-code-from-ram-on-stm8/ + +/* standard libraries */ +#include // standard integer types +#include // boolean types + +#include "stm8s.h" // STM8S definitions +#include "eeprom_blockprog.h" // own definitions + +// start address of EEPROM +#define EEPROM_ADDR 0x4000 +// block size from low-density devices (including STM8S103) +#define DATA_BLOCK_SIZE 64U + +#pragma codeseg RAM_SEG +bool eeprom_blockprog(const uint8_t* data, uint16_t length) +{ + if (0 == length) { + return true; // nothing to do + } + if (!data) { + return false; // data missing + } + if (0 != (length % DATA_BLOCK_SIZE)) { + return false; // we can only program whole blocks + } + + // disable DATA (e.g. EEPROM) write protection + // don't check if it is locked this it does not save that much time and uses memory) + FLASH_DUKR = FLASH_DUKR_KEY1; + FLASH_DUKR = FLASH_DUKR_KEY2; +// don't verify if unlock succeeded to save memory +// if (!(FLASH_IAPSR & FLASH_IAPSR_DUL)) { // un-protecting failed +// return false; +// } + + + // program data + uint8_t* eeprom = (uint8_t*)(EEPROM_ADDR); + while (length) { + // enable standard block programming + FLASH_CR2 |= FLASH_CR2_PRG; + FLASH_NCR2 &= ~FLASH_NCR2_NPRG; + // program block + for (uint8_t i = 0; i < DATA_BLOCK_SIZE; i++) { + *(eeprom++) = *(data++); + } + length -= DATA_BLOCK_SIZE; + // wait until program completed + while (FLASH_CR2 & FLASH_CR2_PRG); + // check if programming failed + // we don't check for WR_PG_DIS (while checking EOP) because EEPROM isn't (and can't be) write protected + if (!(FLASH_IAPSR & FLASH_IAPSR_EOP)) { + FLASH_IAPSR &= ~FLASH_IAPSR_DUL; // re-enable write protection + return false; + } + } + + FLASH_IAPSR &= ~FLASH_IAPSR_DUL; // re-enable write protection + return true; +} diff --git a/eeprom_blockprog.h b/eeprom_blockprog.h new file mode 100644 index 0000000..8b0c3d4 --- /dev/null +++ b/eeprom_blockprog.h @@ -0,0 +1,14 @@ +/** library to program EEPROM using block programming + * @file + * @author King Kévin + * @copyright SPDX-License-Identifier: GPL-3.0-or-later + * @date 2021 + * @warning functions need to be put in and run from RAM (because block programming is used) + */ + +/** program EEPROM using block programming + * @param[in] data data to be programmed + * @param[in] length length of data to be programmed (must be a multiple of the block length) + * @return if program succeeded + */ +bool eeprom_blockprog(const uint8_t* data, uint16_t length);