/*
 * bkpsram.c
 *
 *  Created on: 13.10.2016
 *      Author: pavel
 */

#include "stm32f4xx_rcc.h"
#include <stdbool.h>


bool fBckpSramInit = false;

bool bckp_sram_init() {
   uint16_t timeout = 0xFFFF;

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
   PWR_BackupAccessCmd(ENABLE);
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
   PWR_BackupRegulatorCmd(ENABLE);

   // Wait until the Backup SRAM low power Regulator is ready
   while(PWR_GetFlagStatus(PWR_FLAG_BRR) == RESET) {
       if (timeout-- == 0) {
           return false;
       }
   }
   fBckpSramInit = true;
   return true;
}

int8_t write_to_backup_sram( uint8_t *data, uint16_t bytes, uint16_t offset ) {
  const uint16_t backup_size = 0x1000;
  uint8_t* base_addr = (uint8_t *) BKPSRAM_BASE;
  uint16_t i;

  if (!fBckpSramInit) {
      /* ERROR : Backup SRAM is not ready */
      return -2;
  }
  if( bytes + offset >= backup_size ) {
    /* ERROR : the last byte is outside the backup SRAM region */
    return -1;
  }
  PWR_BackupAccessCmd(ENABLE);
  for( i = 0; i < bytes; i++ ) {
    *(base_addr + offset + i) = *(data + i);
  }
  return 0;
}

int8_t read_from_backup_sram( uint8_t *data, uint16_t bytes, uint16_t offset ) {
  const uint16_t backup_size = 0x1000;
  uint8_t* base_addr = (uint8_t *) BKPSRAM_BASE;
  uint16_t i;

  if (!fBckpSramInit) {
      /* ERROR : Backup SRAM is not ready */
      return -2;
  }
  PWR_BackupAccessCmd(ENABLE);
  if( bytes + offset >= backup_size ) {
    /* ERROR : the last byte is outside the backup SRAM region */
    return -1;
  }
  for( i = 0; i < bytes; i++ ) {
    *(data + i) = *(base_addr + offset + i);
  }
  return 0;
}
