/******************************************************************************
 * @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>

#define               PWM_U                   PWM5
#define               PWM_V                   PWM1
#define               PWM_W                   PWM2
#define               LINK_PWM_U              SEL_PWM5
#define               INC_PWM_U               INC_PWM5
#define               INC_PWM_V               INC_PWM1
#define               INC_PWM_W               INC_PWM2

#define               PWM_FREQ                20000                              /* 20kHz PWM */
#define               PWM_DB_NS               1000                               /* 1ns */
#define               PWM_CMPA                2500                               /* the CPMA value for all three */

#define               PWM_BlankWIN_Size       100                                /* 100 TBCNT CLK */
#define               PWM_Blank_Offset        50                                 /* 50 TBCNT CLK */
#define               COMP_FilterWIN          300                                /* 300ns */
#define               SampleRgisterNVol       1650                               /* Sampler register negtive voltage : 1650mV */
#define               VolOffsetmV             550                                /* COMP monitor voltage range offset */

void PWMx_Set_Digiter_Compare(PWM_REGS *PWMx)
{
  /* Affected by results monitored from all three phases */
  PWM_EnableDCAHTripEvent(PWMx, DC_TRIP_COMP0H |
                          DC_TRIP_COMP1H |
                          DC_TRIP_COMP2H |
                          DC_TRIP_COMP0L |
                          DC_TRIP_COMP1L |
                          DC_TRIP_COMP2L);

  PWM_SetOneShotTripEvent(PWMx, TRIP_EVENT_DCAEVT, TRIP_OUTPUT_LATCH);

  /*
   * 1.Configure DC event filter
   *
   * 2.Input is DCAEVT0, apply blank window with original polarity
   *
   * 3.Set the blank window position relative to TBCNT=0
   */
  PWM_SetDCFilter(PWMx, DCF_FROM_RAW_DCAEVT0, DCF_ALIGN_ON_ZERO);

  /* Enbale PWM DC filter blank function */
  PWM_EnableDCFilterBlank(PWMx);

  /* Set blank window size as 100 TBCLK and offset as 50 TBCLK */
  PWM_SetDCFilterBlankWindow(PWMx, PWM_BlankWIN_Size, PWM_Blank_Offset);

  /* Set the filtered event as the final DCAEVT0, and trigger TZ sb-model when DCH is high */
  PWM_SetDCAEVT0(PWMx, DCEVT_FILTERED);
  PWM_SetRawDCAEVT0(PWMx, DCH_HIGH_DCL_X);

  /* Set output to tri-state upon DCAEVT0 trip event */
  PWM_SetCHAOutputWhenTrip(PWMx, TZU_TRIP_DO_NOTHING |
                           TZD_TRIP_DO_NOTHING |
                           DCEVT0U_TRIP_AS_TRI_STATE |
                           DCEVT0D_TRIP_AS_TRI_STATE |
                           DCEVT1U_TRIP_DO_NOTHING |
                           DCEVT1D_TRIP_DO_NOTHING);

  PWM_SetCHBOutputWhenTrip(PWMx, TZU_TRIP_DO_NOTHING |
                           TZD_TRIP_DO_NOTHING |
                           DCEVT0U_TRIP_AS_TRI_STATE |
                           DCEVT0D_TRIP_AS_TRI_STATE |
                           DCEVT1U_TRIP_DO_NOTHING |
                           DCEVT1D_TRIP_DO_NOTHING);

  PWM_EnableDCAEVT0TripInt(PWMx);
}

/*
 * This function output Trip-Phase waveform for BLDC(Brushless Derect Current)
 */
void PWM_Output_Trip_Phase(void)
{
  /*
   * Init PWM5/1/2 and output 20kHz waveform on both channel A and channel B.
   */
  PWM_ComplementaryPairChannelInit(PWM_U, PWM_FREQ, PWM_DB_NS);
  PWM_ComplementaryPairChannelInit(PWM_V, PWM_FREQ, PWM_DB_NS);
  PWM_ComplementaryPairChannelInit(PWM_W, PWM_FREQ, PWM_DB_NS);

  /* Start counting */
  PWM_RunCounter(PWM_U);
  PWM_RunCounter(PWM_V);
  PWM_RunCounter(PWM_W);

  /* PWM5 set CMPA and loading the same value to PWM1/2 synchronously */
  PWM_LinkCMPA(PWM_V, LINK_PWM_U);
  PWM_LinkCMPA(PWM_W, LINK_PWM_U);
  PWM_SetCMPA(PWM_U, PWM_CMPA);
}


/*************************************************************************************************************************
*
* @brief      In this case, The aim is to protect the trip-phase waveform from over/below current, but current is hard to
*             test, so we test the current sampling register instead. The step can be described as below:
*
*             1.Gain the current sampling register voltage through PGA.
*
*             2.Comparing the Output of the PGA to judge if the voltage is between 1.1V ~ 2.2V.
*
*             3.In the DC sub-module of the PWM, we accept and process the COMP module signal woth a filter in order to
*               eliminate the probable noise, then sent the corresponding event signal to the TZ sub-module to judge if
*               there is a need to stop PWM or not.
*
*             (In this demo, the current sampling resistor is GPIO8/10/12 and the sample register is 5.5ohm and go through
*              current is 0.1A, connectting PAG negtive to DAC1 which output 1.65V and divider resistor to positive which
*              voltage is 1.65V-0.55V < Vol <1.65V+0.55V)
*
*
*
*                                                  ---3.3V
*                                                   -
*                                                   |
*                                                   |
*                            |                     ---
*                            |                    |   |
*                            |                     ---
*                            |                      |
*                            |                      |
*                       |    |-----------           |---  1.65V-0.55V < Vol <1.65V+0.55V   ----------------
*                       |    |           |         ---  |                                 |   PWM module   |
*                0.1A   |   ---           --------|   |  ------|\          |\             |   ----    ---  |
*              current \|/ |5.5|                   ---         | \---------| \------------|--|    |  |   |-------PWMA
*                       |  |ohm|current sampling               |  \        |  \           |  |DC  |  |TZ | |
*                       |  |   |  resistor                     |PGA/       |  /           |  |sub |--|sub| |
*                       |   ---                      ----------|  /--------| /------------|--|    |  |   |-------PWMB
*                       |    |                      |          | /         |/             |   ----    ---  |
*                       |    |                      |                  Comparator         |                |
*                            |                      |                                      ----------------
*                            |                     ----
*                            |                    |DAC1| 1.65V
*                            |                     --- -
*                         -------
*                          ----GND
*                           --
*
*
*             Key point:
*                       When selecting the GAIN value of PGA, keep in mind that the positive output of PGA(OUTP)
*                       must be lowwer then 3V, and negtive output of PGA(OUTN) must be bigger then 0.3V, otherwise,
*                       the PGA output is not accurate.
*
*************************************************************************************************************************/


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);

  /*
   * As the title described, we suppose GPIO8/10/12(ADC8/10/12) can be used to sample the voltage
   * of current sampling resistor in the BLDC circuit. so, we need to set the GPIOs as ADCs.
   */
  GPIO_SetPinChannel(GPIO_8, GPIO8_ADC8);
  GPIO_SetPinChannel(GPIO_10, GPIO10_ADC10);
  GPIO_SetPinChannel(GPIO_12, GPIO12_ADC12);

  /*
   * Set PGA in differetial ended mode.
   *
   * 1.Set the GPIO8(ADC8)/GPIO10(ADC10)/GPIO12(ADC12) as the P-input of the PGA0/PGA1/PGA2.
   *
   * 2.Set the DAC1 as the N-input of the PGA0/PGA1/PGA2.
   *
   * 3.Set the PGA0/PGA1/PGA2 amplitue scale as 4x.
   *
   * 4.Enable the PGA0/PGA1/PGA2.
   */
  PGA_DifferentialInit(PGA0, PGA0_CH_P_ADC8, PGA0_CH_N_DAC1, PGA_SCALE_4X);
  PGA_DifferentialInit(PGA1, PGA1_CH_P_ADC10, PGA1_CH_N_DAC1, PGA_SCALE_4X);
  PGA_DifferentialInit(PGA2, PGA2_CH_P_ADC12, PGA2_CH_N_DAC1, PGA_SCALE_4X);

  /* Set DAC1 output 1.65V */
  COMP_SetDACVoltage(DAC1, SampleRgisterNVol);

  /*
   * 1. Initialize comparator with 300ns deglitch filtering window and set over
   *    current value as 2.2V.
   * 2. Set DAC 2 & 3 as the comparator too-High trigger input and too-low trigger input.
   * 3. Set DAC 2 (too-high trigger input) output 1.65V + 0.55V = 2.2V
   */
  COMP_Init(COMP_0_HI, COMP0_FROM_PGA0P_OUT, SampleRgisterNVol + VolOffsetmV, COMP_FilterWIN);
  COMP_Init(COMP_0_LO, COMP0_FROM_PGA0P_OUT, SampleRgisterNVol - VolOffsetmV, COMP_FilterWIN);
  COMP_Init(COMP_1_HI, COMP1_FROM_PGA1P_OUT, SampleRgisterNVol + VolOffsetmV, COMP_FilterWIN);
  COMP_Init(COMP_1_LO, COMP1_FROM_PGA1P_OUT, SampleRgisterNVol + VolOffsetmV, COMP_FilterWIN);
  COMP_Init(COMP_2_HI, COMP2_FROM_PGA2P_OUT, SampleRgisterNVol + VolOffsetmV, COMP_FilterWIN);
  COMP_Init(COMP_2_LO, COMP2_FROM_PGA2P_OUT, SampleRgisterNVol + VolOffsetmV, COMP_FilterWIN);

  /* Generate a tri-phase waveform */
  PWM_Output_Trip_Phase();

  /* Set the DC sub-module for PWM_U */
  PWMx_Set_Digiter_Compare(PWM_U);

  /* Set the DC sub-module for PWM_V */
  PWMx_Set_Digiter_Compare(PWM_V);

  /* Set the DC sub-module for PWM_W */
  PWMx_Set_Digiter_Compare(PWM_W);

  while(1)
  {

  }
}
