/**
  *****************************************************************************************************
  * @file    main.c
  * @author  Kiwi Software Team
  * @brief   This example code demonstrates how SPI works.
  *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *
  *   3. Neither the name of the copyright holder nor the names of its contributors
  *      may be used to endorse or promote products derived from this software without
  *      specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************************************
  */

#include "main.h"
#include "kpm32xx_demoboard_ddl.h"
#include "spi_norflash.h"


uint8_t rdBuf[__MAX_PP_DATE_LENGTH__] = {0};
uint8_t wrBuf[__MAX_PP_DATE_LENGTH__] = {0};



#if defined (__DEBUG_CONSOLE_PRINT__)
/**
  * @brief  This function is implemented for UART print PinMux configuration.
  * @param  None
  * @retval None
  */
void DebugConsole_PinMux_Config(void)
{
	/* SCI1 UART Tx */
	DDL_GPIO_Config2AltFunc(GPIOA, GPIO_PIN_7, GPIOA7_AF1_SCI1_TX_SDA_MOSI);
}
#endif


void SPI_PinMux_Config(void)
{
	/* MOSI */
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_9, GPIOC9_AF2_SPI_MOSI);
	/* MISO */
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_10, GPIOC10_AF2_SPI_MISO);
	/* SCK */
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_8, GPIOC8_AF2_SPI_SCK);
	/* CS */
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_7, GPIOC7_AF2_SPI_SS0);
}


/**
  * @brief  This function is implemented for system clock configuration.
  *         where:
  *         System Clock source            = PLL (HIRC)
  *         System Clock frequency         = 100MHz
  * @param  None
  * @retval None
  */
void SystemClock_Config(void)
{
	RCC_PLLInit_T pllInitStruct    = {0};
	RCC_ClkInit_T rccClkInitStruct = {0};

	DDL_RCC_PllStructInit(&pllInitStruct);
	/* FCLK : 100MHz */
	pllInitStruct.pllPrescaler  = 4;
	if (DDL_RCC_PllConfig(&pllInitStruct) != DDL_OK)
	{
		while(1) ;
	}

	/* Select PLL as system clock source */
	rccClkInitStruct.sysClkSource  = RCC_SYSCLKSOURCE_PLLCLK;
	rccClkInitStruct.sysClkDivider = 0;
	if (DDL_RCC_ClkSrcConfig(&rccClkInitStruct) != DDL_OK)
	{
		while(1) ;
	}
}


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
	uint8_t nfStatus = 0;
	uint8_t cont     = 0;
	uint8_t wrValue  = 0;
	uint8_t times    = 0;

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	DDL_Init();
	SystemClock_Config();

	/* To make GPIO active */
	DDL_GPIO_Instance_Active();

#if defined (__DEBUG_CONSOLE_PRINT__)
	DebugConsole_PinMux_Config();
	DDL_SCI_Instance_Active(SCI1);
	DDL_SCIUart_DebugConsole_Init(SCI1);
#endif

	SPI_PinMux_Config();
	DDL_SPI_Instance_Active(SPI);

	if (DDL_SPI_NorFlash_Init() != DDL_OK)
	{
		printf("Initialize Serial Unit CSI module failed \n");
		return -1;
	}

	if (DDL_SPI_NorFlash_RDID(rdBuf, 3, 1000) != DDL_OK)
	{
		printf("Read SPI Norflash ID failed \n");
		return -1;
	}
	printf("Nor Flash ID: 0x%02x, 0x%02x, 0x%02x \n", rdBuf[0], rdBuf[1], rdBuf[2]);

	if (DDL_SPI_NorFlash_RMES(rdBuf, 2, 1000) != DDL_OK)
	{
		printf("Read SPI Manufacture and Device ID failed \n");
		return -1;
	}
	printf("Manufacture and Device ID: 0x%02x, 0x%02x \n", rdBuf[0], rdBuf[1]);

	if (DDL_SPI_NorFlash_RDSR(&nfStatus, 1, 1000) != DDL_OK)
	{
		printf("Read SPI Nor Flash Status failed \n");
		return -1;
	}
	printf("Nor Flash Status: 0x%02x \n", nfStatus);

	if (DDL_SPI_NorFlash_RDDT(0x000000, rdBuf, sizeof(rdBuf)/sizeof(uint8_t), 1000) != DDL_OK)
	{
		printf("Read SPI Nor Flash data failed \n");
		return -1;
	}

	printf("Start erasing sector \n");
	/* Now, sector Ease */
	if (DDL_SPI_NorFlash_SE(0x000000, 1000) != DDL_OK)
	{
		printf("Read SPI Nor Flash sector-Erase failed \n");
		return -1;
	}
	printf("Erasing sector Completes \n");

	printf("Start Nor Flash writing and reading...\n");

	while(times *  __MAX_PP_DATE_LENGTH__ < __NF_SECTOR_SIZE_INBYTE__)
	{
		for(cont = 0; cont < sizeof(wrBuf)/sizeof(wrBuf[0]); cont ++)
		{
			wrBuf[cont] = wrValue;
			wrValue ++;
		}

		if (DDL_SPI_NorFlash_PP(0x000000 + times * __MAX_PP_DATE_LENGTH__, wrBuf, sizeof(wrBuf)/sizeof(uint8_t), 2000) != DDL_OK)
		{
			printf("Read SPI Nor Flash Page-Program failed \n");
			return -1;
		}

		memset(rdBuf, 0x00, sizeof(rdBuf)/sizeof(uint8_t));
		if (DDL_SPI_NorFlash_RDDT(0x000000 + times * __MAX_PP_DATE_LENGTH__, rdBuf, sizeof(rdBuf)/sizeof(uint8_t), 2000) != DDL_OK)
		{
			printf("Read SPI Nor Flash data failed \n");
			return -1;
		}

		if (memcmp(wrBuf, rdBuf, __MAX_PP_DATE_LENGTH__) != 0)
		{
			printf("Nor Flash Write or Read Comparison failed \n");
			while (1)
			{
				__asm volatile ("nop");
			}
		}
		times ++;
	}

	printf("SPI Nor Flash Access Completes successfully !!!\n");
	times = 0;

	while (1)
	{
		__asm volatile ("nop");
	}

}

