/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright (c) 2016-2021, NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include "common.h"
#include "fsl_wdog.h"
#include "fsl_flash.h"
#include "Defines.h"
#include "UpgradeFW.h"
#include "flash_FTFL.h"
#include "EEPROMDriver.h"
#include "EEPROMAddrs.h"
#include "MeteringInterface3Ph.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define SIZE_OF_PROG_BUFF		0x300
#define FW_BUFFER_LEN   128 
/*******************************************************************************
* Prototypes
******************************************************************************/
uint8  fw_buffer[FW_BUFFER_LEN];
uint8  fw_buffer_bl[FW_BUFFER_LEN];
uint8  *fw_buffer_ptr;
uint32 fw_buffer_checksum;
uint32 remaining_bytes;
uint8 locresult;
uint8 flashByteProgStatus;
uint8 ImageVerifyTO = 0;
uint32 flash_start_address;
uint32 binDesc[(MAX_DESC*8)/4];
uint32 source_address;

extern uint32 recv_timeout_flag;

extern unsigned char Flash_ByteProgram(unsigned long int *FlashStartAddress,unsigned long int *DataSrcPtr,unsigned long int NumberOfBytes);

unsigned char EraseSectors(unsigned long int FlashStartAddress, unsigned long int NumberOfBytes);
/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Upgrades firmware depending on input flag usae
   Param: 
    - dest_start_address = NV memory address
    - length = image length
    - ret_val = -1, 
*/
void VerifyFW(uint32 dest_start_address, uint32 length, uint32 *calc_checksum, int16 *ret_val)
{
  uint32 this_size, i;
  uint8 last_block = 0;
  uint32 image_checksum = 0;
  
  locresult=0;
  /* 
  flag = IMAGE_VERIFY: Should only verify_bin() for complete image and return.
  flag = IMAGE_ACTIVATE: Should only verify_bin() and then upgrade_bin() for complete image and return.
  */
  remaining_bytes = length;
  
  *ret_val = -1;
  
  
  while(remaining_bytes)
  {
    fw_buffer_checksum = 0;
    /* Verify */
    this_size = (remaining_bytes>FW_BUFFER_LEN)?FW_BUFFER_LEN:remaining_bytes;
#ifdef FlashMemFOTA
    fw_buffer_ptr = (uint8 *)(dest_start_address+(length-remaining_bytes));
#else
    NVReadIIC((dest_start_address+(length-remaining_bytes)) , (void *)fw_buffer, this_size);
    fw_buffer_ptr = fw_buffer;
#endif
    
    if(this_size == remaining_bytes)
    {
      last_block = 1;
      this_size -= 4; /* reducing as last 4 bytes are uint32 checksum */
    }
    
    for(i=0; i<this_size; i++)
    {
      *(calc_checksum) += *(fw_buffer_ptr + i);
    }
    
    if(last_block)
    {
      /* Now compare the calculated checksum with image checksum */
      image_checksum = *(fw_buffer_ptr + this_size) << 24;
      image_checksum |= *(fw_buffer_ptr + this_size + 1) << 16;
      image_checksum |= *(fw_buffer_ptr + this_size + 2) << 8;
      image_checksum |= *(fw_buffer_ptr + this_size + 3);
      
      *ret_val = (image_checksum == *(calc_checksum))?1:(-1);
      
      remaining_bytes = 0;
    }
    else
    {
      remaining_bytes -= this_size;
    }
    
    /* keep servicing the WDOG */
    WDOG_Refresh(WDOG);
  }
  //MeteringInit();
  /* start a time-check so that metering values can stabilize */
  ImageVerifyTO = IMAGE_VERIFY_TIMEOUT;
}
