/*==================================================================================================
* Project : RTD AUTOSAR 4.7
* Platform : CORTEXM
* Peripheral : S32K3XX
* Dependencies : none
*
* Autosar Version : 4.7.0
* Autosar Revision : ASR_REL_4_7_REV_0000
* Autosar Conf.Variant :
* SW Version : 4.0.0
* Build Version : S32K3_RTD_4_0_0_D2311_ASR_REL_4_7_REV_0000_20231128
*
* Copyright 2020 - 2023 NXP
*
* NXP Confidential. This software is owned or controlled by NXP and may only be
* used strictly in accordance with the applicable license terms. By expressly
* accepting such terms or by downloading, installing, activating and/or otherwise
* using the software, you are agreeing that you have read, and that you agree to
* comply with and are bound by, such license terms. If you do not agree to be
* bound by the applicable license terms, then you may not retain, install,
* activate or otherwise use the software.
==================================================================================================*/

/**
*   @file main.c
*
*   @addtogroup main_module main module documentation
*   @{
*/

/* Including necessary configuration files. */
#include "main.h"

volatile int exit_code = 0;
/* User includes */
/**
* @brief        Define data buffers
*/
uint8_t uartrxBuffer[256];
uint8_t uarttxBuffer[256];
SemaphoreHandle_t LogMutexInput;


void Power_Ip_DCM_GPR_EnableStandbyClockOut(void)
{
    uint32_t TempValue = 0U;

    TempValue = IP_DCM_GPR->DCMRWP1;
    TempValue &= ~((uint32_t)0x00000008);
    TempValue |= 0x00000008;
    IP_DCM_GPR->DCMRWP1 = TempValue;
}

static void Emios_Driver_Init(void)
{
    /* Initialize Emios_Mcl driver */
    Emios_Mcl_Ip_Init(0, &Emios_Mcl_Ip_0_Config_BOARD_INITPERIPHERALS);
	Emios_Mcl_Ip_Init(1, &Emios_Mcl_Ip_1_Config_BOARD_INITPERIPHERALS);

    /* Initialize Emios_Pwm_Ip driver */
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I0_CH0_CFG, &Emios_Pwm_Ip_I0_Ch0);
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I0_CH1_CFG, &Emios_Pwm_Ip_I0_Ch1);
	Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I0_CH2_CFG, &Emios_Pwm_Ip_I0_Ch2);
	Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I0_CH3_CFG, &Emios_Pwm_Ip_I0_Ch3);
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I1_CH19_CFG, &Emios_Pwm_Ip_I1_Ch19);
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I1_CH20_CFG, &Emios_Pwm_Ip_I1_Ch20);
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I1_CH17_CFG, &Emios_Pwm_Ip_I1_Ch17);
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I1_CH18_CFG, &Emios_Pwm_Ip_I1_Ch18);
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I1_CH21_CFG, &Emios_Pwm_Ip_I1_Ch21);
    Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_I1_CH23_CFG, &Emios_Pwm_Ip_I1_Ch23);
}

static void AdcDriverInit(void)
{
	Adc_Sar_Ip_StatusType status;
	uint8_t Index;

	Adc_Sar_Ip_Init(ADCHWUNIT_0_INSTANCE, &AdcHwUnit_0);
	Adc_Sar_Ip_Init(ADCHWUNIT_1_INSTANCE, &AdcHwUnit_1);

	/* Call Calibration function multiple times, to mitigate instability of board source */
	for(Index = 0; Index <= 5; Index++)
	{
		status = Adc_Sar_Ip_DoCalibration(ADCHWUNIT_0_INSTANCE);
		status = Adc_Sar_Ip_DoCalibration(ADCHWUNIT_1_INSTANCE);
		if(status == E_OK)
		{
			Shell_Printk("[INIT]ADC Calibration completed successfully!index:%d\r\n", Index);
			break;
		}
	}

	/* Enable end of conversion interrupt */
	// Adc_Sar_Ip_EnableNotifications(ADCHWUNIT_0_INSTANCE, ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN);
	// Adc_Sar_Ip_EnableNotifications(ADCHWUNIT_1_INSTANCE, ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN);
}

static void MutexCreate_ALL(void)
{
	LogMutexInput = xSemaphoreCreateMutex();
	xSemaphoreGive(LogMutexInput);
}

static void Timer_Driver_Init(void)
{
	/* STM configuration, STM clock is determined by CGM settings - default is AIPS_PLAT_CLK 60MHz,STM prescaler = 200, so 3cnt=10uS */
	Stm_Ip_Init(0, &STM_0_InitConfig_PB);

	/* Initialize STM0 compare channel 0 */
	Stm_Ip_InitChannel(0, &STM_0_ChannelConfig_PB[0]);

	/* Start STM0 channel 0 - set compare value, enable this channel */
	Stm_Ip_StartCounting(0, 0, 100);
}

/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
	/* Init clock  */
	Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);

	/* Initialize Dma */
    Dma_Ip_Init(&Dma_Ip_xDmaInitPB); // DMA

	/* Initialize Rm driver for using DmaMux*/
    Rm_Init(&Rm_Config);

    /* Init Pins  */
    Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS_PortContainer_0_BOARD_InitPeripherals, g_pin_mux_InitConfigArr_PortContainer_0_BOARD_InitPeripherals); //Init Hardware Version pin GPIO2

    IntCtrl_Ip_Init(&IntCtrlConfig_0);

	Lpuart_Uart_Ip_Init(UART_LPUART_INTERNAL_CHANNEL, &Lpuart_Uart_Ip_xHwConfigPB_2);

    // Lpuart_Uart_Ip_AsyncReceive(UART_LPUART_INTERNAL_CHANNEL,uartrxBuffer,1);
	Lpuart_Uart_AsyncReceive(UART_LPUART_INTERNAL_CHANNEL, uartrxBuffer, 20);

	Power_Ip_DCM_GPR_EnableStandbyClockOut();

	/* Initialize Emios PWM driver */
	Emios_Driver_Init();
	/* ADC driver init */
	AdcDriverInit();

	MutexCreate_ALL();

	vLogInit();
	
	/* Initialize STM driver */
	Timer_Driver_Init();

    /* Write your code here */
	vAllTaskCreateProcess();
	

    for(;;);
    
    return exit_code;
}

/** @} */
