/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright (c) 2016-2021, NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "EEPROMDriver.h"
#include "EEPROMAddrs.h"
#include "ComPortDriver.h"
#include "MeteringLPRT.h"
#include "MeteringInterface3Ph.h"
#include "lcd.h"
#include "RTCDriver.h"
#include "AppCommon.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*******************************************************************************
* Prototypes
******************************************************************************/
/** Defines NV memory address */
static uint32 NVmemAddr = 0;

/** Defines page number */
static uint16 PageNumber = 0;

/** Defines no. of bytes to write */
static uint16 NoOfBytesWrite = 0;

/** Defines no. of bytes, pending */
static uint16 NoOfBytesPending = 0;

/** Pointer to write buffer */
static uint8  *Buffer = NULL;


/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Writes NBytes bytes of data to I2C EEPROM.
 */
uint8 NVWriteIIC(uint32 DstAddress, uint8 *pucBuffer, uint16 NBytes)
{
  uint8  ucReturnValue;

  NoOfBytesWrite = 0;
  NoOfBytesPending = NBytes;
  ucReturnValue = SUCCESS;

  /* this check assumes NVMEM_FU_MAX_ADDR > NVMEM_MAX_ADDR */
  if ((DstAddress + NBytes) > (NVMEM_FU_MAX_ADDR+1))
  {
    ucReturnValue = FAIL;
    NoOfBytesPending = 0;
  }

  while (NoOfBytesPending != 0)
  {
    /* Increment the address */
    NVmemAddr = DstAddress + NoOfBytesWrite;
    Buffer = pucBuffer + NoOfBytesWrite;
    PageNumber = (uint16)(NVmemAddr / PAGE_BOUNDARY);

    /* Compute the number of bytes to be written in 1st
    * write operation to EEPROM
    */
    if ((((PageNumber + 1) * PAGE_BOUNDARY) - NVmemAddr) >= (NoOfBytesPending))
    {
      NoOfBytesWrite = NoOfBytesPending;
    }
    else
    {
      NoOfBytesWrite = (uint16)((((PageNumber + 1) * PAGE_BOUNDARY)) - NVmemAddr);
    }
        
    I2CStuck = FALSE;
    IICWriteData(NVmemAddr, Buffer, NoOfBytesWrite);
    if (I2CStuck == TRUE)
    {
      I2CModuleInit();
      I2CStuck = FALSE;
      IICWriteData(NVmemAddr, Buffer, NoOfBytesWrite);
    }

    /* Manipulate the number of bytes has to be written */
    NoOfBytesPending -= NoOfBytesWrite;
    SDK_DelayAtLeastUs(500, SYSTEM_CLOCK);
  }
  return ucReturnValue;
}

/*!
 * @brief Reads NBytes bytes of data from I2C EEPROM.
 */
uint8 NVReadIIC(uint32 SrcAddress,uint8 *pucBuffer,uint16 NBytes)
{
  uint16 i;
  uint16 j;
  uint8 ucReturnValue;

  if ((SrcAddress + NBytes) > (NVMEM_FU_MAX_ADDR+1))
  {
    ucReturnValue = FAIL;
  }
  else
  {
    /* Initiate the IIC read operation */
    I2CStuck = FALSE;
    IICReadData(SrcAddress,pucBuffer,NBytes);

    /* Check the data */
    j = 0;
    for (i = 0; i < NBytes; i++)
    {
      if ((pucBuffer[i] == 0xA0) || (pucBuffer[i] == 0xA1))
      {
        j++;
      }
    }
    if ((NBytes == j) && (NBytes >= 2))
    {
      I2CStuck = TRUE;
    }

    if (I2CStuck == TRUE)
    {
      I2CModuleInit();
      I2CStuck = FALSE;
      IICReadData(SrcAddress,pucBuffer,NBytes);
    }
    ucReturnValue = SUCCESS;
  }
  return ucReturnValue;
}

