/*
 * sys_hal.c
 *
 *  Created on: 12.03.2017
 *      Author: pavel
 */

#include <stdint.h>
#include "sys_hal.h"
#include "sys_api.h"
#include "common_config.h"
#include "main.h"
//#include "hal.h"
#ifdef PRINTF_STDLIB
#include <stdio.h>
#endif
#ifdef PRINTF_CUSTOM
#include "tinystdio.h"
#endif

/**
  * @brief
  */
void SYS_ReadFromFlash(uint8_t *data, uint32_t size, uint32_t baseAddress)
{
  for (uint32_t i = 0; i < size; i++)
    *data++ = (*(uint32_t*)baseAddress++);
}

/**
  * @brief
  */
void SYS_WriteToFlash(uint8_t *data, uint32_t size, uint32_t crc)
{
  uint32_t baseAddress = SYS_SECTOR;
  uint32_t checkCrc = 0;
  bool fAlarm = 0;
  FLASH_Status status;
  uint8_t *pdata = data;

  for (uint8_t i = 0; i < 3; i++)
  {
    fAlarm = 0;
    FLASH_Unlock();

    SYS_EraseFlashSector();

    for (uint32_t i = 0; i < size; i++)
        if ((status = FLASH_ProgramByte(baseAddress++, *pdata++)) != FLASH_COMPLETE) {
             DBG printf("FLASH_ProgramByte error: %d\r\n", status);
             break;
         }

    if ((status = FLASH_ProgramWord((uint32_t)SYS_CRC_ADDRESS, crc)) != FLASH_COMPLETE) {
         DBG printf("FLASH_ProgramWord error: %d\r\n", status);
     }

    FLASH_Lock();

//    /* Считываем что записали */
//    SYS_ReadFromFlash((uint8_t*)data, size, SYS_SECTOR);
//
//    checkCrc = SYS_GetCRC(data);

    checkCrc = SYS_GetCRC((SYS_t *)SYS_SECTOR);

    /* Проверяем  CRC того что было записано */
    if (checkCrc == crc) {
      DBG printf("SYS write OK\r\n");
      break;
    }
    else
      fAlarm = 1; // Авария
  }

  /* Произошел сбой при записи - заносим ошибку в лог и перезагружаемся */
  if (fAlarm) {
    DBG printf("Flash write error: 1%d", (uint8_t)status);;
    NVIC_SystemReset();
//    while (1)
//    {};
  }
}

/**
  * @brief  Очистка сектора настроек
  * @retval
  */
void SYS_EraseFlashSector(void)
{
  FLASH_Status status;

  if ((status = FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3)) != FLASH_COMPLETE) {
      DBG printf("SYS_EraseFlashSector error: %d\r\n", status);
  }
}
