/**
  *****************************************************************************************************
  * @file    main.c
  * @author  Kiwi Software Team
  * @brief   This example code demonstrates how low power mode 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"


#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


/**
  * @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) ;
	}
}


/**
  * After exit stop mode, need to re-configure system clock.
  */
static void PWR_ExitStopModeClockConfig(void)
{
	SystemClock_Config();
#if defined (__DEBUG_CONSOLE_PRINT__)
	DDL_SCIUart_DebugConsole_Init(SCI1);
#endif
}


/**
  * Init base timer, used as wake up source of low power mode.
  * wake up period : 2000ms
  */
static void PWR_BaseTimer_Init(void)
{
	BTM_BaseInit_T btm00Struct;

	DDL_BTM_Instance_Active();

	/* Config wake up source : per 2000ms. */
	DDL_BTM_StructInit(&btm00Struct);
	btm00Struct.loadValue  = 0xFA0;
	DDL_BTM_Init(BTIM00, &btm00Struct);

	DDL_BTM_IntEnable(BTIM00);
	NVIC_SetPriority(BASETIMER0_IRQn, 0);
	NVIC_EnableIRQ(BASETIMER0_IRQn);
	DDL_BTM_Start(BTIM00);
}


/**
  * Demo how to enter into different low power mode.
  */
static int PWR_BaseTimer_WakeUpSrcDemo(PWR_Init_T * config, PWR_SleepMode_T mode)
{
	printf("	Ready to enter into mode (%d)......\n", mode);

	switch (mode)
	{
	case PWR_SLEEP_MODE:
		DDL_PWR_EnterSleepMode(config);
		break;
	case PWR_DEEPSLEEP_MODE:
		DDL_PWR_EnterDeepSleepMode(config);
		break;
	case PWR_STOP_MODE:
		/* The following API will (1)set FCLK to HIRC; (2) close pll and HOSC. */
		DDL_PWR_EnterStopMode(config);

		/* Restore OSC and Clock config */
		PWR_ExitStopModeClockConfig();
		break;
	default:
		break;
	}

	if (config->sevOnPendEnable != RESET)
	{
		if (BTIM0_COMM->ST & BTIM_ST_TM0INT)
	    {
	        WRITE_REG(BTIM0_COMM->ST, BTIM_ST_TM0INT);
			NVIC_ClearPendingIRQ(BASETIMER1_IRQn);
	    }
	}

	printf("	I am back!!!\n");

	return 0;
}


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
	uint8_t cnt = 0;
	PWR_Init_T pPwrStruct;

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	DDL_Init();
	DDL_Delay(2000);
	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

    printf("Power demo start:\n");
	PWR_BaseTimer_Init();
	/* Enable stop mode */
	DDL_PWR_StructInit(&pPwrStruct);

	while (1)
	{
		PWR_BaseTimer_WakeUpSrcDemo(&pPwrStruct, PWR_STOP_MODE);

		cnt++;
		if (cnt >= 100)
		{
			break;
		}
	}

    printf("Power demo end.\n");
}

