/******************************************************************************
 * @file     main.c
 * @brief    Main program body
 * @version  V1.8.0
 * @date     31-Dec-2021
 *
 * @note
 * Copyright (C) 2021 Spintrol Limited Corporation. 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"spc1168.h"
#include<stdio.h>

/* As descripted below, ADC result convert to voltage can calculate as the follow */
#define ValueToVoltage(x)   ((x * 3657) / 8192) /1000

/* This macro is used to get the PWM period with a specified frequency */
#define                PWMPeriod(u32PWMFreqHz)              ((CLOCK_GetModuleClock(PWM_MODULE))/u32PWMFreqHz)/2;

#define                PWM_FREQ                             20000                                             /* 20kHz PWM */
#define                PWM_DB_NS                            1000                                              /* 1ns */

uint32_t               u32PWMPeriod;
int                    i32result;
int                    i32result0, i32result1, i32result2;


 /*************************************************************************************************************************
 *
 * @brief      In this case, PWM0SOCA trigger the ADC SOC0 event with three sampler(A/B/C) is working, but only the configuration
 *             itme of channel selecting is valid in the configuration of SOC1 and SOC2, other configuration informations
 *             coming from SOC0, The ADC will start convertion base on the configuration of SOC0, sys will not start SOC1/2
 *             convertion, after all convertion is done, ADC0 INT assert.
 *
 *             In order to get the right result, you need to give a voltage to GPIO10/12/14 simultaneously.
 *
 *************************************************************************************************************************/


int main()
{
  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);
    
  /* Initial Basic Complementary PWM */
  PWM_ComplementaryPairChannelInit(PWM0, PWM_FREQ, PWM_DB_NS);

  /* Set PWM5B output 50% duty waveform */
  u32PWMPeriod = PWMPeriod(PWM_FREQ);
  PWM_SetCMPA(PWM0, (u32PWMPeriod * 3)/ 4);

  /* Start counting */
  PWM_RunCounter(PWM0);

  /* PWM trigger timing selecting */
  PWM_SetSOCATiming(PWM0, EQU_ZERO);

  /* PWM trigger period selecting */
  PWM_SetSOCAPeriod(PWM0, ON_15TH_EVENT);

  /* Enable PWM SOCA trigger */
  PWM_EnableSOCA(PWM0);

  /* ADC initial */
  ADC_EasyInit1(ADC_SOC_0, GPIO_14, ADCTRIG_PWM0SOCA);
  ADC_EasyInit1(ADC_SOC_1, GPIO_10, ADCTRIG_Software);
  ADC_EasyInit1(ADC_SOC_2, GPIO_12, ADCTRIG_Software);

  /* SOC0 averaging 4 times (2^2), SOC1/2 will follow the configureation of SOC0 */
  ADC_SetAverageCnt(ADC_SOC_0, ADCSOCCTL0_BIT_AVGCNT_AVG_4);

  /* Set simultaneous sampling */
  ADC_SetSOCSH(ADC_SOC_0, SHA_AND_SHB_SHC);

  /* INT service routine configuration */
  NVIC_SetPriority(ADC0_IRQn,1);
  NVIC_EnableIRQ(ADC0_IRQn);

  while(1)
  {

  }
}

void ADC0_IRQHandler(void)
{
  /* The result of SHA/B/C is stored in RESULT0/1/2 respectively */
  /* Result gotten from 'ADC_GetResult()' can be a negtive value or a positive value*/
  i32result0 = ADC_GetResult(ADC_SOC_0);
  i32result1 = ADC_GetResult(ADC_SOC_1);
  i32result2 = ADC_GetResult(ADC_SOC_2);
  printf("ADC SOC0 Voltage = %2fV(Raw data is %d)\n", (double)ValueToVoltage(i32result0),i32result0);

  printf("ADC SOC1 Voltage = %2fV(Raw data is %d)\n", (double)ValueToVoltage(i32result1),i32result1);

  printf("ADC SOC2 Voltage = %2fV(Raw data is %d)\n", (double)ValueToVoltage(i32result2),i32result2);

  /* Clear SOC0 INT */
  ADC_ClearInt0();

  Delay_Ms(3000);
}
