diff --git a/stm-firmware/include/stm-periph/backup-ram.h b/stm-firmware/include/stm-periph/backup-ram.h index ff23813..a2d2292 100644 --- a/stm-firmware/include/stm-periph/backup-ram.h +++ b/stm-firmware/include/stm-periph/backup-ram.h @@ -23,29 +23,31 @@ /** * @brief Init the backup ram and make it accesible */ -void backup_ram_init(); +void backup_ram_init(void); /** * @brief Disable access to the backup RAM. This saves power */ -void backup_ram_disable(); +void backup_ram_disable(void); /** - * @brief Whis function overwrites the backup RAM with 0x00 + * @brief Whis function overwrites the backup RAM with 0x00000000 */ -void backup_ram_wipe(); +void backup_ram_wipe(void); /** * @brief Read data from the backup RAM * @param addr Address offset inside memory - * @param data read 32bit data + * @param data Read data + * @param count amount of 32 bit words to read + * @return 0 if successful */ -int backup_ram_get_data(uint32_t addr, uint32_t *data); +int backup_ram_get_data(uint32_t addr, uint32_t *data, uint32_t count); /** * @brief Write data structure to backup RAM - * @param data - * @return + * @param[in] data Data to write. + * @param count Count of 32 bit words to write + * @return 0 if successful */ -int backup_ram_write_data(uint32_t addr, uint32_t data); - +int backup_ram_write_data(uint32_t addr, const uint32_t *data, uint32_t count); diff --git a/stm-firmware/stm-periph/backup-ram.c b/stm-firmware/stm-periph/backup-ram.c index b2b75a5..d2bca10 100644 --- a/stm-firmware/stm-periph/backup-ram.c +++ b/stm-firmware/stm-periph/backup-ram.c @@ -21,34 +21,82 @@ #include #include #include +#include -void backup_ram_init() +#define BACKUP_RAM_BASE BKPSRAM_BASE +#define BACKUP_RAM_SIZE 4096U +#define BACKUP_RAM_SIZE_WORDS (BACKUP_RAM_SIZE / 4U) +#define BACKUP_RAM_END_ADDR (BACKUP_RAM_BASE + BACKUP_RAM_SIZE - 1U) + +#define backup_ram ((volatile uint32_t *)BACKUP_RAM_BASE) + +#if !is_power_of_two(BACKUP_RAM_SIZE) +#error "Backup RAM size ahs to be a power of two!" +#endif + +void backup_ram_init(void) { rcc_manager_enable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_PWREN)); /* Enable access to backup RAM register set */ PWR->CR |= PWR_CR_DBP; + /* Enable the backup regulator */ + PWR->CSR |= PWR_CSR_BRE; + + /* Wait until regulator is ready */ + while (!(PWR->CSR & PWR_CSR_BRR)); + /* Enable clock for backup ram interface */ rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_BKPSRAMEN)); } -void backup_ram_disable() +void backup_ram_disable(void) { + /* Disable access to backup RAM register set */ + PWR->CR &= ~PWR_CR_DBP; rcc_manager_disable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_PWREN)); + rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_BKPSRAMEN)); } -void backup_ram_wipe() +void backup_ram_wipe(void) { + uint32_t i; + for (i = 0; i < BACKUP_RAM_SIZE_WORDS; i++) + backup_ram[i] = 0UL; } -int backup_ram_get_data(uint32_t addr, uint32_t *data) +int backup_ram_get_data(uint32_t addr, uint32_t *data, uint32_t count) { + volatile uint32_t *ptr; + if (!data) + return -1002; + if (addr >= BACKUP_RAM_SIZE_WORDS) + return -1001; + + ptr = &backup_ram[addr]; + + for (; count > 0; count--) + *(data++) = *(ptr++); + + return 0; } -int backup_ram_write_data(uint32_t addr, uint32_t data) +int backup_ram_write_data(uint32_t addr, const uint32_t *data, uint32_t count) { + volatile uint32_t *ptr; + if (!data) + return -1002; + if (addr >= BACKUP_RAM_SIZE_WORDS) + return -1001; + + ptr = &backup_ram[addr]; + + for (; count > 0; count--) + *(ptr++) = *(data++); + + return 0; }