/******************************* (C) LiteMesh **********************************
* @module  crc
 * @file    crc.c
 * @version 1.0.0
 * @date    XX.XX.XXXX
 * $brief   crc
 *******************************************************************************
 * @history     Version  Author         Comment
 * XX.XX.XXXX   1.0.0    kim  First release.
 *******************************************************************************
 */
   
#include "stm32f4xx.h"
#include "crc.h"
#include "common_config.h"
#include <stddef.h>
#include <stdint.h>

/**
  * @brief  
  * @retval 
  */
void CRC_Init(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  CRC->CR |= CRC_CR_RESET;  
}

/**
  * @brief  
  * @retval 
  */
void CRC_DeInit(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, DISABLE);
}
/**
  * @brief Читаем crc из последних 4х байт записанной прошивки
  * @retval 
  */
uint32_t CRC_Read(void) {
  uint32_t* ptr = (uint32_t*)USER_FLASH_CRC_ADDRESS;
  return *ptr;
}

/**
  * @brief Считаем crc для записанной прошивки
  * @retval 
  */
uint32_t CRC_Calculate(void (* periodic_handler)(uint8_t)) {
  uint32_t res;
  static uint32_t last_progress = 0;
  /* Reset CRC */
  CRC->CR = ((uint8_t)0x01);
  for (uint32_t* ptr = (uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS; ptr != (uint32_t*)USER_FLASH_CRC_ADDRESS; ptr++) {
    CRC->DR = *ptr; // добавляем всю прошивку в CRC
    if (periodic_handler != NULL) {
      uint32_t progress = ((uint32_t)ptr - USER_FLASH_FIRST_PAGE_ADDRESS) * 100 /
        (USER_FLASH_CRC_ADDRESS - USER_FLASH_FIRST_PAGE_ADDRESS);
      if (progress > last_progress) {
        last_progress = progress;
        periodic_handler(progress);
      }
    }
  }
  res = CRC->DR;
  return res;
}
 /******************************* (C) SWITRON *********************************/