/******************************************************************************
 * @file     main.c
 * @brief    Main program body
 * @version  V4.0.0
 * @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<stdio.h>
#if defined(SPC1158)
#include "spc1158.h"
#elif defined(SPD1148)
#include "spd1148.h"
#elif defined(SPD1178)
#include "spd1178.h"
#elif defined(SPD1188)
#include "spd1188.h"
#elif defined(SPD1163)
#include "spd1163.h"
#else
#include "spc1168.h"
#endif

#define               PWM_U                   PWM0
#define               PWM_V                   PWM1
#define               PWM_W                   PWM2
#define               LINK_PWM_U              SEL_PWM0
#define               INC_PWM_U               INC_PWM0
#define               INC_PWM_V               INC_PWM1
#define               INC_PWM_W               INC_PWM2

#if defined(SPC1158) || defined(SPC1168)
    #define                 PWM0A_GPIO             GPIO_18
    #define                 PWM0B_GPIO             GPIO_21
    #define                 PWM0A_GPIO_FUNC        GPIO18_PWM0A
    #define                 PWM0B_GPIO_FUNC        GPIO21_PWM0B
    
    #define                 PWM1A_GPIO             GPIO_36
    #define                 PWM1B_GPIO             GPIO_37
    #define                 PWM1A_GPIO_FUNC        GPIO36_PWM1A
    #define                 PWM1B_GPIO_FUNC        GPIO37_PWM1B
    
    #define                 PWM2A_GPIO             GPIO_22
    #define                 PWM2B_GPIO             GPIO_23
    #define                 PWM2A_GPIO_FUNC        GPIO22_PWM2A
    #define                 PWM2B_GPIO_FUNC        GPIO23_PWM2B

#elif defined(SPD1178) || defined(SPD1188) || defined(SPD1148) 
    #define                 PWM0A_GPIO             GPIO_30
    #define                 PWM0B_GPIO             GPIO_31
    #define                 PWM0A_GPIO_FUNC        GPIO30_PWM0A
    #define                 PWM0B_GPIO_FUNC        GPIO31_PWM0B
    
    #define                 PWM1A_GPIO             GPIO_36
    #define                 PWM1B_GPIO             GPIO_37
    #define                 PWM1A_GPIO_FUNC        GPIO36_PWM1A
    #define                 PWM1B_GPIO_FUNC        GPIO37_PWM1B
    
    #define                 PWM2A_GPIO             GPIO_16
    #define                 PWM2B_GPIO             GPIO_17
    #define                 PWM2A_GPIO_FUNC        GPIO16_PWM2A
    #define                 PWM2B_GPIO_FUNC        GPIO17_PWM2B
    
#endif

#define                PWM_FREQ                20000                              /* 20kHz PWM */
#define                PWM_DB_NS               1000                               /* 1000ns */
#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_H_Level_mV         2650                               /* 2650mV */
#define                COMP_L_Level_mV         650                                /* 650mV */
#define                COMP_FilterWIN          300                                /* 300ns */
#define                THRESHOLD_VAL           2200                               /* 2200mV */

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

uint32_t               u32PWMPeriod;
uint32_t               u32status = 0;


void PWMx_Set_Digiter_Compare(PWM_REGS * PWMx)
{
    /* Set DCAH from COMP0H */
    PWM_EnableDCAHTripEvent(PWMx, DC_TRIP_COMP0H);

    /* Set raw DCAEVT1 event */
    PWM_SetRawDCAEVT1(PWMx, DCH_HIGH_DCL_X);

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

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

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

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

    PWM_SetCBCTripEvent(PWMx, TRIP_EVENT_DCAEVT, TRIP_OUTPUT_LATCH);

    /* Set output to tri-state upon TZ trip event */
    PWM_SetCHAOutputWhenTrip(PWMx, TZU_TRIP_AS_TRI_STATE |
                                  TZD_TRIP_AS_TRI_STATE |
                                  DCEVT0U_TRIP_AS_LOW |
                                  DCEVT0D_TRIP_AS_LOW |
                                  DCEVT1U_TRIP_DO_NOTHING |
                                  DCEVT1D_TRIP_DO_NOTHING);
    PWM_SetCHBOutputWhenTrip(PWMx, TZU_TRIP_AS_TRI_STATE |
                                  TZD_TRIP_AS_TRI_STATE |
                                  DCEVT0U_TRIP_AS_LOW |
                                  DCEVT0D_TRIP_AS_LOW |
                                  DCEVT1U_TRIP_DO_NOTHING |
                                  DCEVT1D_TRIP_DO_NOTHING);

    /* Enbale DCAEVT1 trigger  interrupt */
    PWM_EnableDCAEVT1TripInt(PWMx);

    /* Enable PWM synchronization */
    PWM_EnableSync(PWMx);

}

/*
 * This function output Three-Phase waveform for BLDC(Brushless Derect Current)
 */
void PWM_Output_Three_Phase(void)
{
    /*
    * Init PWM0/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);

    /* PWM0 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, we use the compare module to trigger the TZ

 *             1.Check if the voltage is over 2.2V, this module has a filter to filter the probable noise.
 *
 *             2.In the DC sub-module of the PWM, we sent the corresponding event signal to the TZ sub-module to judge if
 *               there is a need to stop PWM or not, this module with a filter too in order to eliminate the probable noise.
 *               
 *
 *************************************************************************************************************************/

int main()
{
    FLASH_WALLOW();

#if defined(SPC1158)
    FLASH_SetTiming(100000000);
    /* Disable flash write access after flash operation had done */
    FLASH_WDIS();

    CLOCK_InitWithRCO(100000000UL);
#else
    FLASH_SetTiming(200000000);
    /* Disable flash write access after flash operation had done */
    FLASH_WDIS();

    CLOCK_InitWithRCO(200000000UL);
#endif

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

    /*
    * Set the GPIOs as ADCs.
    */
    GPIO_SetPinChannel(GPIO_9, GPIO9_ADC9);

    /* Choose the output GPIO */
    /* Select output of PWM0/1/2 respectively */
    GPIO_SetPinChannel(PWM0A_GPIO, PWM0A_GPIO_FUNC);
    GPIO_SetPinChannel(PWM0B_GPIO, PWM0B_GPIO_FUNC);
    GPIO_SetPinChannel(PWM1A_GPIO, PWM1A_GPIO_FUNC);
    GPIO_SetPinChannel(PWM1B_GPIO, PWM1B_GPIO_FUNC);
    GPIO_SetPinChannel(PWM2A_GPIO, PWM2A_GPIO_FUNC);
    GPIO_SetPinChannel(PWM2B_GPIO, PWM2B_GPIO_FUNC);

    /* Init PWM on both channel A and B */
    PWM_SingleChannelInit(PWM_U, PWM_CHA, PWM_FREQ);
    PWM_SingleChannelInit(PWM_U, PWM_CHB, PWM_FREQ);

    PWM_SingleChannelInit(PWM_V, PWM_CHA, PWM_FREQ);
    PWM_SingleChannelInit(PWM_V, PWM_CHB, PWM_FREQ);

    PWM_SingleChannelInit(PWM_W, PWM_CHA, PWM_FREQ);
    PWM_SingleChannelInit(PWM_W, PWM_CHB, PWM_FREQ);

    /* Generate a three-phase waveform */
    PWM_Output_Three_Phase();

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

    /*
    * 1. Initialize comparator with 300ns deglitch filtering window.
    * 2. Set DAC 2 & 3 as the comparator too-High trigger input and too-low trigger input.
    * 3. Set the threshold voltage to 2.2V.
    */
    COMP_Init(COMP_0_HI, COMP0_FROM_ADC8, THRESHOLD_VAL, COMP_FilterWIN);

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

  while(1)
  {

  }
}



