/**************************************************************************//**
 * @file     main.c
 * @brief    Main program body
 * @version  V4.0.1
 * @date     30-July-2026
 *
 * @note
 * Copyright (C) 2022 Spintrol Electronic Technology (Shanghai) Co., Ltd.. All rights reserved.
 *
 * @attention
 * THIS SOFTWARE JUST PROVIDES CUSTOMERS WITH CODING INFORMATION REGARDING 
 * THEIR PRODUCTS, WHICH AIMS AT SAVING TIME FOR THEM. SPINTROL SHALL NOT BE
 * LIABLE FOR THE USE OF THE SOFTWARE. SPINTROL DOES NOT GUARANTEE THE 
 * CORRECTNESS OF THIS SOFTWARE AND RESERVES THE RIGHT TO MODIFY THE SOFTWARE 
 * WITHOUT NOTIFICATION.
 *
 ******************************************************************************/

#include "spd1188.h"
#include <stdio.h>
#include <math.h>

#define ADC_SAMPLE_TIME_NS     6400    //If ADC moudle work 50MHz, then the max sample we can set is 6.4us.

/* As descripted below, ADC result convert to voltage can calculate as the follow */
#define                     CodeToVoltage(x)                              ((((float)(x) * 3657) / 8192) /1000)
#define                     VoltageToTemperatue(x)                        (((float)(x) * (-551.3f)) + 400.8f)

int16_t                     i16VSP                                        = 0;
float                       vol                                           = 0.0;
float                       temperature                                   = 0.0;
uint32_t                    u32PWMPeriod;
uint8_t                     u8PREDRIID                                    = 0;                 /* PRE-DRIVER mode ID */
uint8_t                     u8PREDRIDATA;                                                       /* Data read from PRE-DRIVER */
ErrorStatus                 eErrorState;
uint32_t                    u32SSPBaundrate                               = 1000000;           /* The baundrate of SSP communicating with PRE-DRIVER mode */
uint32_t                    u32Timeout                                    = 500;               /* The number of times try to get PRE-DRIVER mode ID */
ErrorStatus                 eStatus                                       = ERROR;

 /*************************************************************************************************************************
 *
 * @brief      This case show how to use ADC to measure High-Voltage part temperature.
 *             
 *              Key Point:
 *                      ADC sample time count num is 256, If ADC clock is too fast(eg. 200MHz), even if
 *                      the max sample count can be set is 256, the sample is also too shot(if ADC clock is 
 *                      200MHz, max sample time is 1000000000/200000000 * 256 ns= 5 *256ns = 1280ns = 1.28us,
 *                      1.28ns is too shot for ATEST measurement, the min time is 5~6 us, so we must slow
 *                      down ADC module clock).
 *
 *************************************************************************************************************************/


int main(void)
{
    FLASH_WALLOW();
    FLASH_SetTiming(200000000);
    /* Disable flash write access after flash operation had done */
    FLASH_WDIS();

    CLOCK_InitWithRCO(CLOCK_HCLK_200MHZ);

    Delay_Init();

    /*
    * Init the UART
    *
    * 1.Set the GPIO34/35 as UART FUNC
    *
    * 2.Enable the UART CLK
    *
    * 3.Set the rest para
    */
    GPIO_SetPinChannel(GPIO_34,GPIO34_UART_TXD);
    GPIO_SetPinChannel(GPIO_35,GPIO35_UART_RXD);
    CLOCK_EnableModule(UART_MODULE);
    UART_Init(UART,38400);
    
    /* Init PRE-DRIVER module(this step means 'Init PRE-DRIVER module') and get the ID */
    eErrorState = HV_Init(u32SSPBaundrate, &u8PREDRIID, u32Timeout);
    if(eErrorState == ERROR)
    {
        printf("Init PRE-DRIVER mode FAIL\n");
        return 0;
    }
    else
    {
        printf("Init PRE-DRIVER mode SUCCESS[ID:%d]\n",u8PREDRIID);
    }
    
    /* Step1: */
    /* Connect ATEST of high voltage part to MCU bus */
    HV_ConnectAnalogTestToADC();
    
    /* Step 2&3: */
    /* 
     * Before call 'HV_ConnectTSensorToAnalogTest()', Make sure Supply voltage monitor are disabled firstly!!! 
     */
    /* Read out the register value of HV_REG_SYSCTL */
    eErrorState = HV_ReadReg(HV_REG_SYSCTL, &u8PREDRIDATA);
    if(eErrorState == ERROR)
    {
        printf("Read HV_REG_SYSCTL FAIL\n");
        return 0;
    }

    /* Disable VBAT/30 voltage monitored by ADC */
    eErrorState = HV_WriteReg(HV_REG_SYSCTL, (u8PREDRIDATA & (~0x18)) | SYSCTL_ALL_VMONEN_DISABLE);
    if(eErrorState == ERROR)
    {
        printf("Enbale VBAT voltage monitored by ADC FAIL\n");
        return 0;
    }

    /* Config ATEST function of high voltage part */
    HV_ConnectTSensorToAnalogTest();

    /*
    * There is no need to enable the pre-driver.
    */
    
    /* Step 4: */
    /* Iinit ADC module to measure the ATEST voltage */
    eStatus = ADC_EasyInit1(ADC_SOC_0,ADCx_ATEST,ADCTRIG_Software);
    if (ERROR != eStatus)
    {
        printf("ADC_Init ERROR\n");
        return 1;
    }
    
    /* 
    * Set ADC module clock 40MHz and set the ADC sample time as 6.4us(ATEST need at least 5~6us to be stable).
    * Keep in mind:
    *           ADC sample time count num is 256, If ADC clock is too fast(eg. 200MHz), even if
    *           the max sample count can be set is 256, the sample is also too shot(if ADC clock is 
    *           200MHz, max sample time is 1000000000/200000000 * 256 ns= 5 *256ns = 1280ns = 1.28us,
    *           1.28ns is too shot for ATEST measurement, the min time is 5~6 us, so we must slow
    *           down ADC module clock).
    */
    CLOCK_SetModuleDiv(ADC_MODULE, 5);
    ADC_SetSampleAndConvertTime(ADC_SOC_0, ADC_SAMPLE_TIME_NS, ADC_DEFAULT_CONVERSION_TIME_NS);
    
    /* set ADC result average count max to make sure the result is stable */
    ADC_SetAverageCnt(ADC_SOC_0, ADCSOCCTL0_BIT_AVGCNT_AVG_128);

    while(1)
    {
        /* Use software to trigger ADC SOC0 start to work */
        ADC_SoftwareTrigger(ADC_SOC_0);

        /* Wait until ADC conversion finished (Interrupt flag was set) */
        while(!ADC_GetIntFlag(ADC_SOC_0));

        /* Get result */ 
        i16VSP = ADC_GetTrimResult1(ADC_SOC_0);

        /* Clear ADC SOC0 INT flag */
        ADC_ClearInt(ADC_SOC_0);

        /* Calculate the voltage value */
        vol = (float)CodeToVoltage((float)((float)i16VSP));
        
        /* Calculate the temperature */
        temperature = (float)VoltageToTemperatue(ABS(vol));
        printf("High voltage part (PRE-DRIVER) temperature is [%f]\n",temperature);
        
        Delay_Ms(1000);
    }
}
