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);