/*
 * The Clear BSD License
 * Copyright 2019 NXP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted (subject to the limitations in the disclaimer below) provided
 * that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o 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.
 *
 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
 * 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 "board.h"
#include "fsl_gpio.h"
#include "fsl_pit.h"
#include "fsl_port.h"
#include "fsl_uart.h"
#include "pin_mux.h"
#include "freemaster.h"
#include "freemaster_cfg.h"


/*******************************************************************************
 * Definitions
 ******************************************************************************/

/* MKV3x chip specific defines */
/* PDB Input Trigger Options */
#define PDB0_TRG_EXT0	(uint16_t)0		
#define PDB0_TRG_CMP0	(uint16_t)1
#define PDB0_TRG_CMP1	(uint16_t)2

#define PDB0_PIT0		(uint16_t)4
#define PDB0_PIT1		(uint16_t)5
#define PDB0_PIT2		(uint16_t)6
#define PDB0_PIT3		(uint16_t)7
#define PDB0_TRG_FTM0	(uint16_t)8
#define PDB0_TRG_FTM1	(uint16_t)9
#define PDB0_TRG_FTM2	(uint16_t)10
#define PDB0_TRG_FTM3	(uint16_t)11

#define PDB0_TRG_LPTMR	(uint16_t)14
#define PDB0_TRG_SW		(uint16_t)15

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/

uint8_t ui8CmpHyster;
uint8_t ui8CmpFilter;
uint8_t ui8CmpLevel;
uint16_t ui16Ftm0Modulo;
uint16_t ui16Ftm0Ch0Duty;
uint8_t ui8CmpToFtmTriggerEnable;
uint16_t ui16PulseOutDly1;
uint16_t ui16PulseOutDly2;

/*******************************************************************************
 * Code
 ******************************************************************************/

/*!
 * @brief Main function
 */
int main(void)
{
  	__disable_irq();
	
	BOARD_BootClockRUN();
    BOARD_InitPins();
	/* Variables init */
	ui16Ftm0Modulo = 2500;
	ui16Ftm0Ch0Duty = 500;
	ui8CmpLevel = 16;
	ui8CmpToFtmTriggerEnable = 0;
	ui16PulseOutDly1 = 600;
    ui16PulseOutDly2 = 0xFFFF;
	
	/* Enable clock to peripherals */
	CLOCK_EnableClock(kCLOCK_Ftm0);
	CLOCK_EnableClock(kCLOCK_Cmp0);
	CLOCK_EnableClock(kCLOCK_Pdb0);
	
	/* UART init */
	uart_config_t config;
    UART_GetDefaultConfig(&config);
    config.baudRate_Bps = 19200;
    config.enableTx = true;
    config.enableRx = true;
    UART_Init(UART0, &config, CLOCK_GetFreq(kCLOCK_CoreSysClk));
	
	/* Comparator init */
    CMP0->CR0 = CMP_CR0_FILTER_CNT(ui8CmpFilter)	/* Filter Sample Count */
			  | CMP_CR0_HYSTCTR(ui8CmpHyster);		/* Comparator hard block hysteresis control */		
    CMP0->DACCR = CMP_DACCR_VOSEL(ui8CmpLevel) 		/* DAC output level */
		        | CMP_DACCR_VRSEL(1)				/* Reference voltage will be VDD */
			    | CMP_DACCR_DACEN(1);				/* Enable DAC */
    CMP0->MUXCR = CMP_MUXCR_PSEL(0)	 				/* Plus is CMP0_IN0 */
		        | CMP_MUXCR_MSEL(7);				/* Minus is CMP0_IN7 ~ 6bit reference */
    CMP0->CR1 = CMP_CR1_EN(1) 						/* Comparator Module Enable */
		      | CMP_CR1_OPE(1)  					/* Output pad enable */
		      | CMP_CR1_INV(1)						/* Inverts the comparator output */
	          | CMP_CR1_WE(1);						/* Window mode enable */
	
	/* FlexTimer init */
	FTM0->CONF	= FTM_CONF_BDMMODE(0x3);  		
	FTM0->FMS = 0x00;  
	FTM0->MODE |= FTM_MODE_WPDIS_MASK			/* Write protect disable */
			   |  FTM_MODE_FTMEN_MASK;			/* Flextimer mode */		
	FTM0->MOD = ui16Ftm0Modulo;					/* Set modulo */
	FTM0->CONTROLS[0].CnSC = FTM_CnSC_ELSB_MASK	/* Edge aligned PWM - clear on match */
		                   | FTM_CnSC_MSB_MASK;	/* Edge aligned PWM - clear on match */
	FTM0->COMBINE = FTM_COMBINE_SYNCEN0_MASK;	/* CH0 Sync enable */ 
	FTM0->CONTROLS[0].CnV = ui16Ftm0Ch0Duty;	/* CH0 compare val */
	FTM0->CNTIN = 0x00;							/* Counter init val */
	FTM0->SYNC = FTM_SYNC_TRIG0_MASK			/* Enable the HW TRIG CMP0 */
		       | FTM_SYNC_REINIT_MASK;			/* Reinit on trigger */
	FTM0->SYNCONF |= FTM_SYNCONF_HWWRBUF_MASK	/* HW trigger enable */
		 	      |  FTM_SYNCONF_HWRSTCNT_MASK
				  |  FTM_SYNCONF_HWTRIGMODE_MASK
				  |  FTM_SYNCONF_SYNCMODE_MASK;	
	/* Enable FTM0 CH0 trigger out */
	FTM0->EXTTRIG |= FTM_EXTTRIG_CH0TRIG_MASK;
	FTM0->SC = FTM_SC_CLKS(0x1);				/* By selecting clock FTM starts count */
	FTM0->PWMLOAD = FTM_PWMLOAD_LDOK_MASK;		/* Load OK - update compare, modulo registers */
	
	/* PDB init*/
	/* PDB modulo */
	PDB0->MOD = 0xFFFF; 
    /* Pulse out delay */
    PDB0->PODLY[0] = PDB_PODLY_DLY1(ui16PulseOutDly1)
		           | PDB_PODLY_DLY2(ui16PulseOutDly2);
	PDB0->POEN = PDB_POEN_POEN(1);
   	/* Status and control */
    PDB0->SC = PDB_SC_TRGSEL(PDB0_TRG_FTM0)		/* Select hw trigger */ 
             | PDB_SC_PDBEN(1);               	/* PDB enable */
	
    PDB0->SC |= PDB_SC_LDMOD(0);				/* Load immediately */ 
	PDB0->SC |= PDB_SC_LDOK_MASK;            	/* LDOK needed for update of MOD&DLY values */
	
	/* SysTick init */
	SysTick_Config(BOARD_BOOTCLOCKRUN_CORE_CLOCK/10);
	NVIC_EnableIRQ(SysTick_IRQn);
	NVIC_SetPriority(SysTick_IRQn, 2);             
	
	FMSTR_Init();
	
	__enable_irq();
	
    while (1)
    {
	  	FMSTR_Poll();
    }
}


void SysTick_Handler()
{
	FTM0->MOD = ui16Ftm0Modulo;						/* Modulo define the PFC PWM period when ZCD will not occur or is masked by Toffmin */
	FTM0->CONTROLS[0].CnV = ui16Ftm0Ch0Duty;		/* PFC duty */
	FTM0->PWMLOAD = FTM_PWMLOAD_LDOK_MASK;			/* Load OK */
	CMP0->DACCR = CMP_DACCR_VOSEL(ui8CmpLevel)		/* Adjust CMP DAC compare value */									
				| CMP_DACCR_VRSEL(1)
				| CMP_DACCR_DACEN(1);		
	CMP0->CR0 = CMP_CR0_FILTER_CNT(ui8CmpFilter)	/* Adjust CMP Filter value */
			  | CMP_CR0_HYSTCTR(ui8CmpHyster);		/* Adjust CMP hysteresis */	
	
	PDB0->PODLY[0] = PDB_PODLY_DLY1(ui16PulseOutDly1)
		           | PDB_PODLY_DLY2(ui16PulseOutDly2);
	PDB0->POEN = PDB_POEN_POEN(1);
	PDB0->SC |= PDB_SC_LDOK_MASK;            	    /* LDOK needed for update of MOD&DLY values */
}

