/**
  *****************************************************************************************************
  * @file    main.c
  * @author  Kiwi Software Team
  * @brief   This example code demonstrates how TIMH output PWM waveform.
  * @note
  *          V1.0.0, 2024/12/20. 
  *
  * 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 <string.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) ;
	}
}


/**
  * @brief  Pin Configuration
  * @param  None
  * @retval None
  */
static void GpioPA0_Init(void)
{
	DDL_GPIO_Config2Output(GPIOA, GPIO_PIN_0, 1, GPIO_NOPULL);
}


static void GpioAF_TIMH_Init(void)
{
	/* PC5(TIMH_CH0) & PC8(TIMH_CH0N) */
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_5, GPIOC5_AF3_TIMH_CH0);
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_8, GPIOC8_AF3_TIMH_CH0N);
	
	/* PC6(TIMH_CH1) & PC9(TIMH_CH1N) */
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_6, GPIOC6_AF3_TIMH_CH1);
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_9, GPIOC9_AF3_TIMH_CH1N);	
	
	/* PC7(TIMH_CH2) & PC10(TIMH_CH2N) */
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_7, GPIOC7_AF3_TIMH_CH2);
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_10, GPIOC10_AF3_TIMH_CH2N);	
}


/**
  * @brief  Initialization of TIMH0 to TIMH2
  * @param  None  
  * @retval None
  * @note           T = 0x7FFF / 100,000,000 = 327.67us
  *                 f = 3.051Khz
  *         DutyCycle = 50%
  */
void TIMH_0_to_2_Init(void)
{
	TIMH_ClkInit_T    timhClkStruct  = {0};
	TIMH_BaseInit_T   timh0_BaseInit = {0},
	                  timh1_BaseInit = {0},
	                  timh2_BaseInit = {0};
	
	/* Make TIMH active */
	DDL_TIMH_Instance_Activate();
	
	/* Config TIMH's clock by setting general functions register */
	DDL_TIMH_ClkStructInit(&timhClkStruct);
	DDL_TIMH_Clock_Init(&timhClkStruct);
	
	/* TIMHx's init struct reset to default value */
	DDL_TIMH_BaseStructInit(&timh0_BaseInit);
	DDL_TIMH_BaseStructInit(&timh1_BaseInit);
	DDL_TIMH_BaseStructInit(&timh2_BaseInit);
	
	/* config TIMH_0's init struct */
	timh0_BaseInit.dutyCycle	= 0x3FFF;
	timh0_BaseInit.period		= 0x7FFF;
	timh0_BaseInit.phase		= 0;	
	timh0_BaseInit.clockSource	= TIMHx_CLOCKSOURCE_CLK_IN;
	timh0_BaseInit.counterMode 	= TIMH_CNT_MODE_INDEPENDENT_EDGE;
	timh0_BaseInit.outputMode   = TIMH_OUTPUT_COMPLEMENTARY;
	
	/* Copy TIMH_0's Init struct to TIMH_1 and TIMH_2 */
	memcpy(&timh1_BaseInit, &timh0_BaseInit, (sizeof(TIMH_BaseInit_T)/sizeof(uint8_t)));
	memcpy(&timh2_BaseInit, &timh0_BaseInit, (sizeof(TIMH_BaseInit_T)/sizeof(uint8_t)));
	
	/* Init TIMH_0 to TIMH_2 */
	DDL_TIMH_Init(TIMH0, &timh0_BaseInit);
	DDL_TIMH_Init(TIMH1, &timh1_BaseInit);
	DDL_TIMH_Init(TIMH2, &timh2_BaseInit);
	
	/* Only TIMH0 enable EOC_Interrupt */
	NVIC_SetPriority(TIMH0_IRQn, 0);
	NVIC_EnableIRQ(TIMH0_IRQn);
	DDL_TIMH_IntEnable(TIMH0,TIMH_IT_EOC);
}


/**
  * @brief  The application entry point.
  * @param  None
  * @retval None
  */
int main(void)
{
	/* Reset of all peripherals. */
	DDL_Init();
	DDL_Delay(1000);
	SystemClock_Config();

	/* To make GPIO active */
	DDL_GPIO_Instance_Active();
	BSP_LEDx_Init(LED_S2);
	GpioPA0_Init();
	
#if defined (__DEBUG_CONSOLE_PRINT__)
	DebugConsole_PinMux_Config();
	DDL_SCI_Instance_Active(SCI1);
	DDL_SCIUart_DebugConsole_Init(SCI1);
#endif
	
	printf("TIMH demo start.. \n");
	
	GpioAF_TIMH_Init();
	
	TIMH_0_to_2_Init();

	DDL_TIMH_PWM_Start(TIMH0);
	DDL_Delay(10);
	DDL_TIMH_PWM_Start(TIMH1);
	DDL_Delay(10);
	DDL_TIMH_PWM_Start(TIMH2);

	while (1)
	{
		/* LED Twinkle */
		BSP_LEDx_Twinkle(LED_S2);
		DDL_Delay(200);
	}
}

