70 lines
2.0 KiB
C
70 lines
2.0 KiB
C
/** library to program EEPROM using block programming
|
|
* @file
|
|
* @author King Kévin <kingkevin@cuvoodoo.info>
|
|
* @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 <stdint.h> // standard integer types
|
|
#include <stdbool.h> // 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;
|
|
}
|