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


EBUS_Init_T eBusStruct;


#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  This function is implemented for led toggle.
  * @retval None
  */
void led_toggle(void)
{
	BSP_LEDx_Twinkle(LED_S1);
	BSP_LEDx_Twinkle(LED_S2);
}


/**
  * @brief  This function is implemented for TIMA0 PWM PinMux configuration.
  * @param  None
  * @retval None
  */
void TIMA0_PinMux_Config(void)
{
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_4, GPIOC4_AF4_TIMA0_CH0);
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_1, GPIOC1_AF4_TIMA0_CH0N);
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_3, GPIOC3_AF4_TIMA0_CH1);
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_0, GPIOC0_AF4_TIMA0_CH1N);
	DDL_GPIO_Config2AltFunc(GPIOC, GPIO_PIN_2, GPIOC2_AF4_TIMA0_CH2);
	DDL_GPIO_Config2AltFunc(GPIOB, GPIO_PIN_15, GPIOB15_AF4_TIMA0_CH2N);
	DDL_GPIO_Config2AltFunc(GPIOD, GPIO_PIN_12, GPIOD12_AF4_TIMA0_CH3);
}


/**
  * @brief  This function is implemented for tim8 basetimer.
  * @retval None
  */
void tima_pwm_init(void)
{
	TIMA_BaseInit_T tmrStruct;
	TIMA_Deadtime_T deadtimeStruct;
	/* base init */
	DDL_TIMA_PWM_StructInit(&tmrStruct);
	tmrStruct.period = 3124;
	DDL_TIMA_PWM_Init(TIMA0,&tmrStruct);

	/* ch0 init config */
	DDL_TIMA_Ch0_HighImpedanceState_Config(TIMA0, 0, 0);
	DDL_TIMA_Ch0_BrkIdelState_Config(TIMA0, 0, 0);
	DDL_TIMA_Ch0_Duty_Config(TIMA0, 1, 3000, 3000);
	DDL_TIMA_Ch0_PWM_Polar_Config(TIMA0,0,0);
	DDL_TIMA_Ch0_PWM_Mode_Config(TIMA0,TIMA_OCMODE_ASYM_PWM0_CH0);

	/* ch1 init config */
	DDL_TIMA_Ch1_HighImpedanceState_Config(TIMA0, 0, 0);
	DDL_TIMA_Ch1_BrkIdelState_Config(TIMA0, 0, 0);
	DDL_TIMA_Ch1_Duty_Config(TIMA0, 1, 2000, 2000);
	DDL_TIMA_Ch1_PWM_Polar_Config(TIMA0,0,0);
	DDL_TIMA_Ch1_PWM_Mode_Config(TIMA0,TIMA_OCMODE_ASYM_PWM0_CH1);

	/* ch2 init config */
	DDL_TIMA_Ch2_HighImpedanceState_Config(TIMA0, 0, 0);
	DDL_TIMA_Ch2_BrkIdelState_Config(TIMA0, 0, 0);
	DDL_TIMA_Ch2_Duty_Config(TIMA0, 1, 1000, 1000);
	DDL_TIMA_Ch2_PWM_Polar_Config(TIMA0,0,0);
	DDL_TIMA_Ch2_PWM_Mode_Config(TIMA0,TIMA_OCMODE_ASYM_PWM0_CH2);

	/* ch3 init config */
	DDL_TIMA_Ch3_HighImpedanceState_Config(TIMA0, 0);
	DDL_TIMA_Ch3_BrkIdelState_Config(TIMA0, 0);
	DDL_TIMA_Ch3_Duty_Config(TIMA0, 1, 1499, 1499);
	DDL_TIMA_Ch3_PWM_Polar_Config(TIMA0,0,0);
	DDL_TIMA_Ch3_PWM_Mode_Config(TIMA0,TIMA_OCMODE_ASYM_PWM0_CH3);

	/* ch4 init config */
	DDL_TIMA_Ch4_Duty_Config(TIMA0, 1, 1499);
	DDL_TIMA_Ch4_PWM_Mode_Config(TIMA0,TIMA_OCMODE_PWM0_CH4);
	/* ch5 init config */
	DDL_TIMA_Ch5_Duty_Config(TIMA0, 1, 1499);
	DDL_TIMA_Ch5_PWM_Mode_Config(TIMA0,TIMA_OCMODE_PWM0_CH5);

	/* deadtime config */
	DDL_TIMA_DeadTime_StructInit(&deadtimeStruct);
	DDL_TIMA_DeadTime_Init(TIMA0,&deadtimeStruct);

	DDL_TIMA_PWM_Brake_Config(TIMA0, TIMA_BRK_SOURCE_EBUS_CH8, 0);
	/* channel enable */
	DDL_TIMA_PWM_Enable(TIMA0, TIMA_CHANNEL0|TIMA_CHANNEL0N|TIMA_CHANNEL1|TIMA_CHANNEL1N|TIMA_CHANNEL2|TIMA_CHANNEL2N|TIMA_CHANNEL3|TIMA_CHANNEL4|TIMA_CHANNEL5);

	/* interrupt config */
	NVIC_SetPriority(TIMA0_IRQn, 0);
	NVIC_EnableIRQ(TIMA0_IRQn);
	DDL_TIMA_IntEnable(TIMA0,TIMA_DIER_UIE);
}


/**
  * @brief  This function is implemented for ioport.
  * @retval None
  */
void ioport_init(void)
{
	IOPORT_Init_T ioPortInit;

	/* PIN0 */
	ioPortInit.ioPortPin   = IOPORT_PIN_0;
	ioPortInit.edgeDect    = IOPORT_EDGEDECT_FALLING;
	ioPortInit.ioSelect    = IOPORT_BITB;//PB0

    __DDL_RCC_EBUS_ACTIVE();
    __DDL_RCC_EBUS_CLK_RELEASE();

	DDL_IOPort_Config(IOPORT, &ioPortInit);
    NVIC_EnableIRQ(INTP0_IRQn);
	NVIC_SetPriority(INTP0_IRQn, __PREEMPT_INTRERRUPT_PRIORITY_2__);
}


/**
  * @brief  This function is implemented for ebus.
  * @retval None
  */
void ebus_init(void)
{
	DDL_EBUS_Instance_Active();

    DDL_EBUS_StructInit(&eBusStruct);
	eBusStruct.syncMode     = EBUS_CHN_SYNC_MODE;
	eBusStruct.detSrc       = EBUS_CHN_DETSRC_FALLING;
    eBusStruct.mstrSrc      = EBUS_CHN_MSTR_IO0_SOURCE;
    eBusStruct.channel      = EBUS_CHN_8;
	DDL_EBUS_Init(EBUS, &eBusStruct);
}


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	DDL_Init();
	SystemClock_Config();

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

	BSP_LEDx_Init(LED_S1);
	BSP_LEDx_Init(LED_S2);

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


    printf("It's a tima basetimer demo(100M 16K) ... \n");
	DDL_TIMA_Instance_Active(TIMA0);
	TIMA0_PinMux_Config();
	tima_pwm_init();
	ioport_init();
	ebus_init();
	DDL_TIMA_PWM_Start(TIMA0);

	DDL_GPIO_Config2Output(GPIOC, GPIO_PIN_9, 0, 0);
    while (1)
    {
		DDL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
		DDL_Delay(500);
    }
}






