/******************** (C) COPYRIGHT 2020 SONiX *******************************
* COMPANY:		SONiX
* DATE:				2020/11
* AUTHOR:			SA1
* IC:					SN32F780/790
*____________________________________________________________________________
*	REVISION	Date				User		Description
*	1.0				2020/06/24	SA1			1. First version released
*																2. Compatible to CMSIS DFP Architecture in Keil MDK v5.X (http://www.keil.com/dd2/pack/)
*																3. Run HexConvert to generate bin file and show checksum after building.
*	1.1				2020/11/30	SA1			1. Modify "ISP_TARGET_ADDR" address to last page
*																2. Update Flash.h and system_SN32F780.c
*____________________________________________________________________________
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS TIME TO MARKET.
* SONiX SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL 
* DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE
* AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN 
* IN CONNECTION WITH THEIR PRODUCTS.
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/
#include <SN32F780.h>
#include <SN32F700_Def.h>
#include ".\Interface\CRC\CRC.h"
#include ".\Interface\Flash\Flash.h"

/*_____ D E C L A R A T I O N S ____________________________________________*/
void PFPA_Init(void);
void NotPinOut_GPIO_init(void);

volatile uint32_t wCRC_RomResult[1];
volatile uint32_t wFlashBackup[256];

/*_____ D E F I N I T I O N S ______________________________________________*/
#ifndef	SN32F788					//Do NOT Remove or Modify!!!
	#error Please install SONiX.SN32F7_DFP.1.5.0.pack or version >= 1.5.0
#endif
#define	PKG						SN32F788				//User SHALL modify the package on demand (SN32F788)

#define	ISP_TARGET_ADDR		0x0001FC00				//Word-alignment

/*_____ M A C R O S ________________________________________________________*/

/*_____ F U N C T I O N S __________________________________________________*/

/*****************************************************************************
* Function		: main
* Description	: Demo codes of CRC. 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
int	main(void)
{
	volatile uint32_t i, index = 0;
	volatile uint32_t CRC_BKP;
	
	//User can configure System Clock with Configuration Wizard in system_SN32F780.c
	SystemInit();
	SystemCoreClockUpdate();				//Must call for SN32F780, Please do NOT remove!!!

	//Note: User can refer to ClockSwitch sample code to switch various HCLK if needed.

	PFPA_Init();										//User shall set PFPA if used, do NOT remove!!!

	//1. User SHALL define PKG on demand.
	//2. User SHALL set the status of the GPIO which are NOT pin-out to input pull-up.
	NotPinOut_GPIO_init();

	//--------------------------------------------------------------------------
	//User Code starts HERE!!!

	//1. Calucation for ROM CRC
	CRC_Enable();
	
	SN_CRC->CTRL = (mskCRC_RESET | mskCRC_TYPE);

	if ((mskCRC_CALC_MODE >> 3) == CRC_CALC_ROM)
	{
		SN_CRC->CTRL |= mskCRC_RESET;
		wCRC_RomResult[0] = CRC_Calc_ROM();
	}

	//2. Backup data @ISP_TARGET_ADDR		
	for (i = ISP_TARGET_ADDR; i < (ISP_TARGET_ADDR + FLASH_PAGE_SIZE); i += 4)
	{
		wFlashBackup[index++] = *((uint32_t *)i);
		
		__nop();
	}

	//3. Erase page address @ISP_TARGET_ADDR
	FLASH_EraseSector(ISP_TARGET_ADDR);
	
	//4. Program content of CRC data to User ROM address ISP_TARGET_ADDR
	wFlashBackup[12] = wCRC_RomResult[0];

	if (FLASH_ProgramPage(ISP_TARGET_ADDR, 1024, (uint8_t *)wFlashBackup) == FAIL)
	{
		while (1);	//Program Fail
	}
	
	CRC_BKP = *(volatile unsigned long *)(ISP_TARGET_ADDR + 0x30);
	if (CRC_BKP != wCRC_RomResult[0])
	{
		while (1); //CRC check Fail
	}

	while (1); //CRC check Pass
}

/*****************************************************************************
* Function		: NotPinOut_GPIO_init
* Description	: Set the status of the GPIO which are NOT pin-out to input pull-up. 
* Input				: None
* Output			: None
* Return			: None
* Note				: 1. User SHALL define PKG on demand.
*****************************************************************************/
void NotPinOut_GPIO_init(void)
{
#if (PKG == SN32F788)
	//set P0.8~P0.9, P0.16~P0.19 to input pull-up
	SN_GPIO0->CFG = 0xAAA0AAAA;
	SN_GPIO0->CFG1 = 0x0;
	//set P1.16~P1.19 to input pull-up
	SN_GPIO1->CFG1 = 0x0;
	//set P3.14~P3.19 to input pull-up
	SN_GPIO3->CFG = 0x0AAAAAAA;
	SN_GPIO3->CFG1 = 0x0;
#endif
}

/*****************************************************************************
* Function		: HardFault_Handler
* Description	: ISR of Hard fault interrupt
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
__irq void HardFault_Handler(void)
{
	NVIC_SystemReset();
}
