/*******************************************************************************
  Main Source File

  Company:
    Microchip Technology Inc.

  File Name:
    main.c

  Summary:
    This file contains the "main" function for a project.

  Description:
    This file contains the "main" function for a project.  The
    "main" function calls the "SYS_Initialize" function to initialize the state
    machines of all modules in the system
 *******************************************************************************/

// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include <stddef.h>      // Defines NULL
#include <stdbool.h>     // Defines true
#include <stdlib.h>      // Defines EXIT_FAILURE
#include "definitions.h" // SYS function prototypes
#include "OsekCom/OsekCom.h"
#include "Speaker/Speaker.h"
#include "P417_SWTR_App_ert_rtw/P417_SWTR_App.h"
#include "TouchPanel/TouchPanel.h"
#include "forceSnsr/forcedetect.h"
#include "TLE9263/TLE926x_Main.h"
#include "TLE926x.h"
#include "core_cm4.h"
#include "RTE.h"
#include "DiagnosticR/Comp_ISO_15765_2/TP.h"
#include "DiagnosticR/Comp_ISO_15765_3/Iso15765_3.h"
#include "DiagnosticR/UDS/UDS_Services_Common.h"
#include "DiagnosticR/Dem/Dem.h"

#include "calib_public.h"
#include "smartee.h"
#include "FunctionState.h"
#include "SysDiagDetect.h"
/* System tick */
uint32_t SysTick_1ms_Period = 0;
uint32_t SysTick_Cur_Counter = 0;
volatile uint32_t SysTick_Elapse = 0;
uint32_t CyclicTskSchM_CurTime = 0;
uint8_t Test_frame_On = 0;
uint8_t SDZ_init_flag = 0;
uint8_t SDZ_first_delay = 0;

void OS_TimerCallback(uintptr_t context)
{
    SysTick_Elapse++;
}

void CyclicTskSchM_TimerSync(void)
{
    CyclicTskSchM_CurTime += 1;

    while (SysTick_Elapse < CyclicTskSchM_CurTime)
    {
        /* TimerSync */
    }

    CyclicTskSchM_CurTime = SysTick_Elapse;
}
/* PWM */
uint32_t counter = 0;
uint32_t duty = 7999;
uint32_t period = 0;

/* ADC1 */
#define ADC1_CH_AD_LDO_SNS 0
#define ADC1_CH_LD_OUT_SNS 1
#define ADC1_CH_MAX 2

uint8_t adc_ch_sel = 0;
uint16_t adc_result = 0;
uint16_t adc[ADC1_CH_MAX] = {0};

void ADC1_ConversionCallback(ADC_STATUS status, uintptr_t context)
{
    if (status == ADC_STATUS_RESRDY)
    {
        adc_result = ADC1_ConversionResultGet();
        // adc[adc_ch_sel - 1] = adc_result & 0xFFF;
        adc[adc_ch_sel] = adc_result & 0xFFF;

        switch (adc_ch_sel)
        {
        case ADC1_CH_AD_LDO_SNS:
            ADC1_ChannelSelect(ADC_POSINPUT_AIN6, ADC_NEGINPUT_GND);
            adc_ch_sel = ADC1_CH_LD_OUT_SNS;
            ADC1_ConversionStart();
            break;
        case ADC1_CH_LD_OUT_SNS:
            ADC1_ChannelSelect(ADC_POSINPUT_AIN7, ADC_NEGINPUT_GND);
            adc_ch_sel = ADC1_CH_AD_LDO_SNS;
            ADC1_Disable();
            break;
        default:
            break;
        }
        // adc_ch_sel++;
        // if (adc_ch_sel > ADC1_CH_MAX) {
        //     adc_ch_sel = ADC1_CH_AD_LDO_SNS + 1;
        // }
        ADC1_ConversionStart();
    }
}

/* CAN1 */
bool Can1BusErrFlag = false;
uint8_t Can1MessageRAM[CAN1_MESSAGE_RAM_CONFIG_SIZE] __attribute__((aligned(32)));
uint32_t Received_id[8] = {0};
typedef struct
{
    /* id */
    uint32_t id;
    /* Data field */
    uint8_t data[8];

} CAN_Received_Buffer;
CAN_Received_Buffer Received_buf[8] = {0};

#define WRITE_ID(id) (id << 18)
#define READ_ID(id) (id >> 18)
static uint8_t canTxBuffer[CAN1_TX_FIFO_BUFFER_SIZE];
static uint8_t canRxBuffer[CAN1_RX_FIFO0_SIZE];

CAN_RX_BUFFER *CanRxBuf_t = NULL;
CAN_TX_BUFFER *CanTxBuffer = NULL;

uint32_t CanBufQueryIdTp(void)
{
    return Received_buf[0].id;
}

uint32_t CanBufQueryIdTp_Tx(void)
{
    return CanTxBuffer->id;
}

uint8_t CanBufQueryDataByte(uint8_t hdl, uint8_t index)
{
    uint8_t byte;

    byte = (uint8_t)Received_buf[0].data[index];

    return byte;
}

void CAN_Rx_FIFO0_CALLBACK(uint8_t numberOfMessage, uintptr_t context)
{
    uint8_t MessageNumer = 0;
    CAN1_MessageReceiveFifo(CAN_RX_FIFO_0, numberOfMessage, (CAN_RX_BUFFER *)canRxBuffer);
    CanRxBuf_t = (CAN_RX_BUFFER *)canRxBuffer;
    for (; MessageNumer < numberOfMessage; MessageNumer++)
    {
        Received_buf[MessageNumer].id = READ_ID(CanRxBuf_t[MessageNumer].id);
        memcpy(Received_buf[MessageNumer].data, CanRxBuf_t[MessageNumer].data, 8);
    }
    OsekComRxNotifCallbackSWTR(0);
}

void CAN_Tx_FIFO0_CALLBACK(uintptr_t context)
{
    OsekComTxNotifCallbackSWTR(0);
}

/* CAN handlers definition */
void CanTx(t_can_handler can_handler, bool notif, uint32_t idtp, uint16_t len, t_can_data can_data)
{
    uint8_t loop_count = 0;

    memset(canTxBuffer, 0x00, CAN1_TX_FIFO_BUFFER_ELEMENT_SIZE);
    CanTxBuffer = (CAN_TX_BUFFER *)canTxBuffer;
    CanTxBuffer->id = WRITE_ID(idtp);
    CanTxBuffer->dlc = len;
    for (loop_count = 0; loop_count < len; loop_count++)
    {
        CanTxBuffer->data[loop_count] = can_data[loop_count];
    }
    if (CAN1_MessageTransmitFifo(1, CanTxBuffer) == true)
    {
        ;
    }
    else
    {
        ;
    }
}
void IhuPrivateDHUCanFr01_CALLBACK(void)
{
    ;
}

void IhuPrivateDHUCanFr01_Timeout_CALLBACK(void)
{
    ;
}

// *****************************************************************************
// *****************************************************************************
// Section: Main Entry Point
// *****************************************************************************
// *****************************************************************************
static uint32_t status = 0;
uint8_t g_SBC_STATUS[8] = {0};
void GetResetSource(void)
{
    g_SBC_STATUS[0] = (uint8_t)sbc_read_reg(SBC_SUP_STAT_2);
    g_SBC_STATUS[1] = (uint8_t)sbc_read_reg(SBC_SUP_STAT_1);
    g_SBC_STATUS[2] = (uint8_t)sbc_read_reg(SBC_DEV_STAT);
    g_SBC_STATUS[3] = RSTC_REGS->RSTC_RCAUSE;
    g_SBC_STATUS[4] = RSTC_REGS->RSTC_BKUPEXIT;
    g_SBC_STATUS[5] = 0x00;
    g_SBC_STATUS[6] = 0x00;
    g_SBC_STATUS[7] = 0x00;
    CanTx(0, true, 0x421, 8, g_SBC_STATUS);
}

int main(void)
{
    uint32_t loop_counter = 0;
    /* Initialize all modules */
    SYS_Initialize(NULL);
    // Tle9263_Init();
    Calib_Init();
    WDT_TimeoutPeriodSet(3);
    SysTick_1ms_Period = SYSTICK_TimerPeriodGet() + 1;
    SYSTICK_TimerCallbackSet(OS_TimerCallback, 0);
    SYSTICK_TimerStart();

    TCC0_PWMStart();

    CAN1_RxFifoCallbackRegister(CAN_RX_FIFO_0, &CAN_Rx_FIFO0_CALLBACK, (uintptr_t)NULL);
    CAN1_TxFifoCallbackRegister(&CAN_Tx_FIFO0_CALLBACK, (uintptr_t)NULL);
    CAN1_MessageRAMConfigSet(Can1MessageRAM);
    StartCom(COM_NORMAL_MODE);
    RTE_Set_All_UB();
    StartPeriodic();

    speaker_Init();
    forcedetect_Init();
    TouchPanel_init();
    Tle9263_Init();

    ADC1_Enable();
    ADC1_CallbackRegister(ADC1_ConversionCallback, 0);
    ADC1_ChannelSelect(ADC_POSINPUT_AIN6, ADC_NEGINPUT_GND);
    // adc_ch_sel++;
    ADC1_ConversionStart();

    P417_SWTR_App_initialize();

    WDT_Enable();
    InicialitzaTPTask(ISO15765_2_REPROGONCAN_HANDLER);
    InicialitzaIso15765_3Task();
    Dem_Init();
    UDS_DID_initNVM();
    PORT_PinWrite(PORT_PIN_PB02, 1); // battery voltage detection on
    PORT_PinWrite(PORT_PIN_PA13, 0); /*init turn off SDZ*/
    SmartEE_Read(0x783, &Test_frame_On, 1);
    if (Test_frame_On > 1)
    {
        Test_frame_On = 1;
    }

    GetResetSource();
    Fuction_State = Function_State_A;
    while (true)
    {
        /* Maintain state machines of all polled MPLAB Harmony modules. */
        SYS_Tasks();

        if (!(loop_counter % 2))
        {
            //(void)TCC0_PWM24bitDutySet(TCC0_CHANNEL0, duty);
            OsekComTask();
            Tle9263_MainTask();
            /* call touch process function */
            if (Fuction_State == Function_State_A)
            {
                TouchPanel_MainFunction();
                speaker_MainTask();
                forcedetect_MainTask();

                RTE_Set_All_Test_Value();
            }
            else
            {
                //(void)TCC0_PWM24bitDutySet(TCC0_CHANNEL0, 0);//Turn off LED
            }
            // TCC0_PWM24bitDutySet(TCC0_CHANNEL0,6999);
            if (Fuction_State != Function_State_C)
            {
                TPTask(ISO15765_2_REPROGONCAN_HANDLER);
                Iso15765_3Task();
                Dem_MainFunction();
            }
            Calib_Task();

            // SBC VCC2 always on Setting
            sbc_write_reg(SBC_M_S_CTRL, 0x18, 0);
        }

        if (!(loop_counter % 5))
        {
            FunctionState_Task();
            Sys_Diag_Detcet_Task();
        }

        /* Check CAN Status */
        status = CAN1_ErrorGet();
        WDT_Clear();
        P417_SWTR_App_step();
        CyclicTskSchM_TimerSync();
        loop_counter++;
    }

    /* Execution should not come here during normal operation */

    return (EXIT_FAILURE);
}

/*******************************************************************************
 End of File
*/
