/**
*   @file    Base_Task.c
*   @version 1.0.0
*
*   @brief   Base task init and runtime
*   @details The base task includes the following:
*            1) toggling LED1(PTF8) every 100ms;
*            2) sample ADC0/ADC1/ADC2 channels;
*            3) use PTF11_EMIOS2_CH11 to control PWM duty for LED4(PTF11);
*            4) monitor user buttons and toggle LED2(PTF9)/LED3(PTF10) respectively;
*               Btn1=PTC20_SIUL2_EIRQ16,
*               Btn2=PTC21_SIUL2_EIRQ17,
*
*   This file contains sample code only. It is not part of the production code deliverables.
*
*   @addtogroup Base_Task
*   @{
*/

#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************
 * The base task includes the following:
 * 1) toggling LED1(PTF8) every 100ms;
 * 2) sample ADC0/ADC1/ADC2 channels;
 * 3) use PTF11_EMIOS2_CH11 to control PWM duty for LED4(PTF11);
 * 4) monitor user buttons and toggle LED2(PTF9)/LED3(PTF10) respectively;
 *    Btn1=PTC20_SIUL2_EIRQ16,
 *    Btn2=PTC21_SIUL2_EIRQ17,
 ************************************************************/

/*==================================================================================================
*                                        INCLUDE FILES
* 1) Basic RTD modules includes
* 2) MCU registers definitions includes
* 3) needed interfaces from external units
==================================================================================================*/
#include "bsp.h"
#include "Base_Task.h"
#include "I2C_Task.h"


/*==================================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/

/*==================================================================================================
*                                       LOCAL MACROS
==================================================================================================*/

/*==================================================================================================
*                                      LOCAL CONSTANTS
==================================================================================================*/

/*==================================================================================================
*                                      LOCAL VARIABLES
==================================================================================================*/

/*==================================================================================================
*                                      GLOBAL CONSTANTS
==================================================================================================*/


/*==================================================================================================
*                                      GLOBAL VARIABLES
==================================================================================================*/
/**********************************************************
 * The 12 channels selected in ADC0 are:
 * ADC0_P2		channel 2
 * ADC0_P3		channel 3	Touch sense sw5
 * ADC0_P5		channel 5	Touch sense sw4
 * ADC0_P6		channel 6	MSDI_AMUX
 * ADC0_S8		channel 32	POT2
 * ADC0_S9		channel 33	POT1
 * ADC0_S21		channel 45	D_IN_1
 * Bandgap		channel 48
 * Tempsensor	channel 49
 * ANAMUX_OUT	channel 50
 * VREFL		channel 54
 * VREFH		channel 55
 **********************************************************/
uint16_t adc0RsltArray[12];

/**********************************************************
 * The 10 channels selected in ADC0 are:
 * ADC1_P4		channel 4	touch sense sw6
 * ADC1_S10		channel 34	Touch sense sw6
 * ADC1_S19		channel 43	D_IN_2
 * ADC1_S20		channel 44	touch sense sw6
 **********************************************************/
uint16_t adc1RsltArray[4];

/**********************************************************
 * The 11 channels selected in ADC0 are:
 * ADC2_P2		channel 2	vpwr monitor
 * ADC2_P3		channel 3	A_IN_1
 * ADC2_P4		channel 4	A_IN_2
 * ADC2_P5		channel 5	HB2001_CFB
 * ADC2_P6		channel 6	XS6500_CSNS
 * ADC2_P7		channel 7	FS26_AMUX
 * ADC2_S17		channel 41	Touch sense sw6
 * ADC2_S21		channel 45	1.2V LDO Monitor
 * ADC2_S22		channel 46	Touch sense sw5
 * ADC2_S23		channel 47	Touch sense sw4
 **********************************************************/
uint16_t adc2RsltArray[10];

uint32_t BaseTask_Cnt = 0;
uint16_t usrBtn1Status = 0;
uint16_t usrBtn2Status = 0;

/*==================================================================================================
*                                   LOCAL FUNCTION PROTOTYPES
==================================================================================================*/

/*==================================================================================================
*                                       External FUNCTIONS
==================================================================================================*/
extern ISR(Adc_Sar_0_Isr);
extern ISR(Adc_Sar_1_Isr);
extern ISR(Adc_Sar_2_Isr);
extern ISR(SIUL2_EXT_IRQ_0_7_ISR);
extern ISR(SIUL2_EXT_IRQ_8_15_ISR);
extern ISR(SIUL2_EXT_IRQ_16_23_ISR);
extern ISR(SIUL2_EXT_IRQ_24_31_ISR);

/*==================================================================================================
*                                       LOCAL FUNCTIONS
==================================================================================================*/

/*==================================================================================================
*                                       Interrupts callback FUNCTIONS
==================================================================================================*/
/*================================================================================================*/
/**
 * @brief          ADC0 normal conversion end callback function
 * @details        It's invoked when ADC0 normal channels conversion completed.
 * @param[in]      none.
 * @return         none
 */
void Adc0NormalCallback(void){
	//Adc_Sar_Ip_GetConvDataToArray(ADC0_INST, ADC_SAR_IP_CONV_CHAIN_NORMAL, ADC_SAR_IP_ADCHWUNIT0_CHAN_NUM, adc0RsltArray);
	Adc_Sar_Ip_GetConvDataToArray(ADC0_INST, ADC_SAR_IP_CONV_CHAIN_NORMAL, 12, adc0RsltArray);
}

/*================================================================================================*/
/**
 * @brief          ADC1 normal conversion end callback function
 * @details        It's invoked when ADC1 normal channels conversion completed.
 * @param[in]      none.
 * @return         none
 */
void Adc1NormalCallback(void){
	Adc_Sar_Ip_GetConvDataToArray(ADC1_INST, ADC_SAR_IP_CONV_CHAIN_NORMAL, 4, adc1RsltArray);
}

/*================================================================================================*/
/**
 * @brief          ADC2 normal conversion end callback function
 * @details        It's invoked when ADC2 normal channels conversion completed.
 * @param[in]      none.
 * @return         none
 */
void Adc2NormalCallback(void){
	Adc_Sar_Ip_GetConvDataToArray(ADC2_INST, ADC_SAR_IP_CONV_CHAIN_NORMAL, 10, adc2RsltArray);
}

/*================================================================================================*/
/**
 * @brief          User button1  callback function
 * @details        It's invoked when user button1 is pressed - SIUL2_IRQ16 rising edge.
 * @param[in]      none.
 * @return         none
 */
void Icu_User_Btn1_Callback(void){
	Siul2_Dio_Ip_TogglePins(LED2_PORT, (1<<LED2_PIN));
	usrBtn1Status = 1;
	return;
}

/*================================================================================================*/
/**
 * @brief          User button2  callback function
 * @details        It's invoked when user button2 is pressed - SIUL2_IRQ17 rising edge.
 * @param[in]      none.
 * @return         none
 */
void Icu_User_Btn2_Callback(void){
	Siul2_Dio_Ip_TogglePins(LED3_PORT, (1<<LED3_PIN));
	usrBtn2Status = 1;
	return;
}

/*================================================================================================*/
/**
 * @brief          FS26 IRQ callback function
 * @details        It's invoked when FS26 pulls INTB low - SIUL2_IRQ25 falling edge.
 * @param[in]      none.
 * @return         none
 */
void __attribute__((weak)) Icu_Fs26_Int_Callback(void){
	return;
}

/*================================================================================================*/
/**
 * @brief          FS26 IRQ callback function
 * @details        It's invoked when CD1030 pulls INTB low - SIUL2_IRQ11 falling edge.
 * @param[in]      none.
 * @return         none
 */
void __attribute__((weak)) Icu_Msdi_Int_Callback(void){
	return;
}

/*==================================================================================================
*                                       GLOBAL FUNCTIONS
==================================================================================================*/

/*================================================================================================*/
/**
 * @brief          Base Task initialization
 * @details        Base Task initialization
 * @param[in]      none.
 * @return         E_OK or E_NOT_OK
 */
Std_ReturnType BaseTask_Init(void){
	Std_ReturnType retCode = E_OK;

	/* ADC_0 initialization. */
	/* Initialize ADC module */
	retCode |= Adc_Sar_Ip_Init(ADC0_INST, &AdcHwUnit_0_BOARD_INITPERIPHERALS);
	/* Perform ADC self-test */
	retCode |= Adc_Sar_Ip_SelfTest(ADC0_INST);
	/* Clear all ADC flags */
	Adc_Sar_Ip_ClearStatusFlags(ADC0_INST, 0xFFFFFFFF);
	/* Initialize ADC module */
	retCode |= Adc_Sar_Ip_Init(ADC0_INST, &AdcHwUnit_0_BOARD_INITPERIPHERALS);
	/* Perform ADC calibration */
	retCode |= Adc_Sar_Ip_DoCalibration(ADC0_INST);
	/* Enable tempsensor connection to ADC */
	Adc_Sar_Ip_TempSenseEnable(ADC0_INST);
	/* Enable end of injected conversion chain interrupt */
	Adc_Sar_Ip_EnableNotifications(ADC0_INST, ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN);

	/* route POT1 / POT2 to ADC0_S8 / ADC0_S9  */
	IP_DCM_GPR->DCMRWF4 |= DCM_GPR_DCMRWF4_MUX_MODE_EN_ADC0_S8_MASK|DCM_GPR_DCMRWF4_MUX_MODE_EN_ADC0_S9_MASK;
	/* enable supply monitor, route VDD_2.5 to supply monitor  */
	IP_DCM_GPR->DCMRWF1 |= DCM_GPR_DCMRWF1_SUPPLY_MON_EN_MASK|DCM_GPR_DCMRWF1_SUPPLY_MON_SEL(3);

	/* ADC_1 initialization. */
	retCode |= Adc_Sar_Ip_Init(ADC1_INST, &AdcHwUnit_1_BOARD_INITPERIPHERALS);
	retCode |= Adc_Sar_Ip_SelfTest(ADC1_INST);
	Adc_Sar_Ip_ClearStatusFlags(ADC1_INST, 0xFFFFFFFF);
	retCode |= Adc_Sar_Ip_Init(ADC1_INST, &AdcHwUnit_1_BOARD_INITPERIPHERALS);
	retCode |= Adc_Sar_Ip_DoCalibration(ADC1_INST);
	Adc_Sar_Ip_EnableNotifications(ADC1_INST, ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN);

	/* ADC_2 initialization. */
	retCode |= Adc_Sar_Ip_Init(ADC2_INST, &AdcHwUnit_2_BOARD_INITPERIPHERALS);
	retCode |= Adc_Sar_Ip_SelfTest(ADC2_INST);
	Adc_Sar_Ip_ClearStatusFlags(ADC2_INST, 0xFFFFFFFF);
	retCode |= Adc_Sar_Ip_Init(ADC2_INST, &AdcHwUnit_2_BOARD_INITPERIPHERALS);
	retCode |= Adc_Sar_Ip_DoCalibration(ADC2_INST);
	Adc_Sar_Ip_EnableNotifications(ADC2_INST, ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN);

	/* SIUL2 IRQ initialization for push button SW2 and SW3 on the White Board */
	retCode |= Siul2_Icu_Ip_Init(SIUL2_ICU_IP_INSTANCE, &Siul2_Icu_Ip_0_Config_PB_BOARD_InitPeripherals);
	/* Enable notification function call */
	Siul2_Icu_Ip_EnableNotification(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[0].hwChannel);
	Siul2_Icu_Ip_EnableNotification(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[1].hwChannel);
	Siul2_Icu_Ip_EnableNotification(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[2].hwChannel);
	Siul2_Icu_Ip_EnableNotification(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[3].hwChannel);
	Siul2_Icu_Ip_EnableNotification(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[4].hwChannel);
	/* Enable SIUL2 IRQ on corresponding input channel */
	Siul2_Icu_Ip_EnableInterrupt(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[0].hwChannel);
	Siul2_Icu_Ip_EnableInterrupt(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[1].hwChannel);
	Siul2_Icu_Ip_EnableInterrupt(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[2].hwChannel);
	Siul2_Icu_Ip_EnableInterrupt(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[3].hwChannel);
	Siul2_Icu_Ip_EnableInterrupt(SIUL2_ICU_IP_INSTANCE, Siul2_Icu_Ip_0_ChannelConfig_PB_BOARD_InitPeripherals[4].hwChannel);

	/* Init EMIOS2 counter bus */
	retCode |= Emios_Mcl_Ip_Init(EMIOS_PWM_IP_BOARD_InitPeripherals_I2_CH11_CFG, &Emios_Mcl_Ip_2_Config_BOARD_INITPERIPHERALS);

	/* Init EMIOS2 Ch11 for PWM output */
	Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_BOARD_InitPeripherals_I2_CH11_CFG, &Emios_Pwm_Ip_BOARD_InitPeripherals_I2_Ch11);

	/* Install ISR into vector table */
	IntCtrl_Ip_InstallHandler(SIUL_2_IRQn, SIUL2_EXT_IRQ_16_23_ISR, NULL_PTR);
	IntCtrl_Ip_EnableIrq(SIUL_2_IRQn);
	IntCtrl_Ip_InstallHandler(SIUL_3_IRQn, SIUL2_EXT_IRQ_24_31_ISR, NULL_PTR);
	IntCtrl_Ip_EnableIrq(SIUL_3_IRQn);
	IntCtrl_Ip_InstallHandler(SIUL_1_IRQn, SIUL2_EXT_IRQ_8_15_ISR, NULL_PTR);
	IntCtrl_Ip_EnableIrq(SIUL_1_IRQn);
	IntCtrl_Ip_InstallHandler(SIUL_0_IRQn, SIUL2_EXT_IRQ_0_7_ISR, NULL_PTR);
	IntCtrl_Ip_EnableIrq(SIUL_0_IRQn);
	IntCtrl_Ip_InstallHandler(ADC0_IRQn, Adc_Sar_0_Isr, NULL_PTR);
	IntCtrl_Ip_EnableIrq(ADC0_IRQn);
	IntCtrl_Ip_InstallHandler(ADC1_IRQn, Adc_Sar_1_Isr, NULL_PTR);
	/* Either clean the data cache or invalidate the instruction cache */
	//Cache_Ip_CleanByAddr(CACHE_IP_DATA, FALSE, (S32_SCB->VTOR)+((ADC1_IRQn+16)*4), 32);
	//Cache_Ip_InvalidateByAddr(CACHE_IP_INSTRUCTION, (S32_SCB->VTOR)+((ADC1_IRQn+16)*4), 32);
	IntCtrl_Ip_EnableIrq(ADC1_IRQn);
	IntCtrl_Ip_InstallHandler(ADC2_IRQn, Adc_Sar_2_Isr, NULL_PTR);
	IntCtrl_Ip_EnableIrq(ADC2_IRQn);

	if(E_OK == retCode)
		printf("Base task init OK.\r\n");
	else
		printf("Base task init fail.\r\n");
	return retCode;
}

/*================================================================================================*/
/**
 * @brief          Base Task runtime function
 * @details        Base Task runtime function
 * @param[in]      none.
 * @return         none.
 */
void BaseTask_Runtime(void){
	BaseTask_Cnt++;

	Siul2_Dio_Ip_TogglePins(LED1_PORT, (1<<LED1_PIN));

	Adc_Sar_Ip_StartConversion(ADC0_INST, ADC_SAR_IP_CONV_CHAIN_NORMAL);
	Adc_Sar_Ip_StartConversion(ADC1_INST, ADC_SAR_IP_CONV_CHAIN_NORMAL);
	Adc_Sar_Ip_StartConversion(ADC2_INST, ADC_SAR_IP_CONV_CHAIN_NORMAL);

	/* set PWM duty for emios2_ch11 in OPWMB mode, controlling LED4, counter bus is EMIOS2 Ch8 */
	Emios_Pwm_Ip_SetDutyCycle(EMIOS2_INST, EMIOS2_CH11, (uint32_t)adc0RsltArray[4]*10000/0xFFF);

	/* handle user button events*/
	if(usrBtn1Status){
		usrBtn1Status = 0;
		printf("User button 1 pressed.\r\n");
		printf("POT1=%dmV, POT2=%dmV.\r\n", adc0RsltArray[4]*5000/0xFFF, adc0RsltArray[5]*5000/0xFFF);
	}
}


#ifdef __cplusplus
}
#endif

/** @} */
