/*
 * @brief LPC15xx In-Application Programming Example
 *
 * @note
 * Copyright(C) NXP Semiconductors, 2014
 * All rights reserved.
 *
 * @par
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * LPC products.  This software is supplied "AS IS" without any warranties of
 * any kind, and NXP Semiconductors and its licensor disclaim any and
 * all warranties, express or implied, including all implied warranties of
 * merchantability, fitness for a particular purpose and non-infringement of
 * intellectual property rights.  NXP Semiconductors assumes no responsibility
 * or liability for the use of the software, conveys no license or rights under any
 * patent, copyright, mask work right, or any other intellectual property rights in
 * or to any products. NXP Semiconductors reserves the right to make changes
 * in the software without notification. NXP Semiconductors also makes no
 * representation or warranty that such application will be suitable for the
 * specified use without further testing or modification.
 *
 * @par
 * Permission to use, copy, modify, and distribute this software and its
 * documentation is hereby granted, under NXP Semiconductors' and its
 * licensor's relevant copyrights in the software, without fee, provided that it
 * is used in conjunction with NXP Semiconductors microcontrollers.  This
 * copyright, permission, and disclaimer notice must appear in all copies of
 * this code.
 */

#include "board.h"
#include "eeprom.h"
#include <stdio.h>

/*****************************************************************************
 * Private types/enumerations/variables
 ****************************************************************************/

#define TICKRATE_HZ1 (15)	/* 15 ticks per second */

/*****************************************************************************
 * Public types/enumerations/variables
 ****************************************************************************/

/*****************************************************************************
 * Private functions
 ****************************************************************************/

/*****************************************************************************
 * Public functions
 ****************************************************************************/

volatile uint32_t i = 0, j = 0; 
#define TEST_INTERRUPT 1
#define SYSTICK_DELAY		(SystemCoreClock/1000)

//#define SRC1 0x02001000 // source address of RAM
#define DST1 0x20000		// destination address of flash
#define EEPROM_SIZE   		4096 - 64
uint8_t eeprom_result_data_array[4096]={0};
uint8_t buffer[256];

/*********************************************************************//**
 * @brief        Copy the interrupt vector on the Flash to SRAM
 *
 * @param[in]    void
 *
 * @return       void
 *
 **********************************************************************/
void CopyInterruptToSRAM(void)
{
	unsigned int * flashPtr, * ramPtr;
  unsigned int * uLimit = (unsigned int *) 0x200;

		ramPtr = (unsigned int *)0x2000000;	//load RAM starting at 0x2000000,
		flashPtr = (unsigned int *)0x00;			//start of interrupt vector table
	  while(flashPtr < uLimit)
			{
				*ramPtr = *flashPtr;
				ramPtr++;
				flashPtr++;
			}
}

/*********************************************************************//**
 *
 * @brief	main routine for IAP example
 *
 * @return	Function should not exit.
 *
  **********************************************************************/
int main(void)
{
	uint32_t status;
	uint32_t command[5], result[4];


	SystemCoreClockUpdate();
		LPC_SYSCTL->SYSAHBCLKCTRL[0] |= (1<<9);
	Board_Init();
	Board_LED_Set(0, false);        // LED Number 0 - Red, LED is in off state
	Board_LED_Set(1, false);        // LED number 1 - Green, LED is in off state        

#if TEST_INTERRUPT
	CopyInterruptToSRAM();		//remap interrupt vector to SRAM
	LPC_SYSCON->SYSMEMREMAP = 0x1;	//change memory map

	/* Called for system library in core_cmx.h(x=0 or 3). */
  SysTick_Config( SYSTICK_DELAY );
#endif


	for (i = 0;i < sizeof(buffer);i++)
  {
    buffer[i] = (uint8_t)i;
  }

	/* Read Part ID */
	i = Chip_IAP_ReadPID();
	 if ((i & 0x0001549) != 0x0001549) 
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	
	/* Read Boot code version */
	 i = Chip_IAP_ReadBootCode();
	if ((i & 0x00000E02)!= 0x00000E02) 
	{
		Board_LED_Set(0, true);        // RED LED glows if error  
		while(1);
	}

	
	/* Read UID */
	command[0] = IAP_READ_UID_CMD;
	iap_entry(command, result);
	status = result[0];
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}

	/* Prepare Sector */
	/* Prepare sector 24 */
	status = Chip_IAP_PreSectorForReadWrite(24,24);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	
	/* Erase Sector */
	/* Erase sectors 25 to 28 */
	status = Chip_IAP_PreSectorForReadWrite(25,28);
	status = Chip_IAP_EraseSector(25,28);              // Erase sectors 25 to 28
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	
	/* Blank Check Sectors */
	/* Blank check sectors 25 to 28 */
	status = Chip_IAP_BlankCheckSector(25,28);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	
		/* Erase flash page */
	 /* page 256 */
	status = Chip_IAP_PreSectorForReadWrite(16,16);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	status = Chip_IAP_ErasePage(256,256);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	
	
	/* Program Flash */
	//program 256 bytes to address 0x20000

	status = Chip_IAP_CopyRamToFlash(DST1, buffer, 256);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	
/* Compare the copied contents in Flash and RAM */
	status = Chip_IAP_Compare(DST1, buffer, 256);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}

	
	
	//check 32-bit EEPROM program
	
	for(i = 0; i < EEPROM_SIZE; i++)
	{
			 eeprom_result_data_array[i] = (uint8_t)i;
  }
	
	status = Chip_EEPROM_Write(0x0,eeprom_result_data_array,EEPROM_SIZE);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error
		while(1);
	}
	
	
	//check 32-bit EEPROM read

	status = Chip_EEPROM_Read(0x0,eeprom_result_data_array,EEPROM_SIZE);
	if (status!= IAP_CMD_SUCCESS)
	{
		Board_LED_Set(0, true);        // RED LED glows if error  
		while(1);
	}
	

	if(status==IAP_CMD_SUCCESS)
	{
		Board_LED_Set(1, true);        // GREEN LED glows if success 
		while(1);
	}

	return 0;
}
