/******************************************************************************
 * @file     main.c
 * @brief    Main program body
 * @version  V4.0.3
 * @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

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

/* Usd the count to calculate the period */
#define CNTTOFREQ(x) (CLOCK_GetModuleClock(ECAP_MODULE) / (x))

#define PWM_FREQ                                     10000                                      /* 10kHz PWM */

uint32_t u32PWMPeriod;
uint32_t TStamp0, TStamp1, TStamp2, TStamp3;


/*************************************************************************************************************************
*
* @brief      In this case, GPIO28 used as PWM output and ECAP input, and ECAP work in continue difference operation mode .
*
*            -------                            GPIO28                       -------
*           |       |                               -                       |       |
*           | ECAP  |<-----------------------------| |<---------------------|  PWM  |
*           |       |  ECAP captured pin           | |    PWM output        |       |
*           |       |                               -                        -------
*            -------                               / \
*                                                   |
*                                                   |
*                                                    -------GPIO28 used as PWM output, also as the ECAP captured pin
*
*             Key Point:
*                     <1>:If user do not care about exactly each incoming event, do not add extra 4
*                         event cycle to initialize the divider.
*
*                     <2>:Please keep in mind that don't do to much in the Int function, which can cause captured value over-write.
*
*************************************************************************************************************************/


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

    /* Init PWM5, PWM freq will be set as 20kHz in this function */
    PWM_SingleChannelInit(PWM5, PWM_CHA, PWM_FREQ);

    /* Set PWM5A output 50% duty waveform */
    u32PWMPeriod = PWMPeriod(PWM_FREQ);
    PWM_SetCMPA(PWM5, u32PWMPeriod / 2);

    /* Select GPIO28 as the channel A output of PWM5 */
    GPIO_SetPinChannel(GPIO_28, GPIO28_PWM5A);

    /* Enable Pin input deglitch filter */
    GPIO_EnableDeglitch(GPIO_28);

    /* The smaller the value, the more accurate the measurement result, but the more susceptible to interference */
    GPIO_SetDeglitchWindow(DGCLKCTL_ALL_DIV_(0x0));

    /* Start PWM5 */
    PWM_RunCounter(PWM5);

    /* ECAP Init */
    ECAP_CaptureModeInit(ECAP, GPIO_28);

    /* Set the count reset back to zero when event happened */
    ECAP_EnableEventResetCounter(ECAP, ECAP_CEVT0);
    ECAP_EnableEventResetCounter(ECAP, ECAP_CEVT1);
    ECAP_EnableEventResetCounter(ECAP, ECAP_CEVT2);
    ECAP_EnableEventResetCounter(ECAP, ECAP_CEVT3);

    /* Enable global INT of EACP */
    NVIC_EnableIRQ(ECAP_IRQn);
    
    /* Enable EVT3 Interrupt */
    ECAP_EnableInt(ECAP, ECAP_INT_CEVT3);

    /* Start ECAP */
    ECAP_RunCounter(ECAP);

    while (1)
    {

    }
}

void ECAP_IRQHandler(void)
{
    uint32_t cnt;

    TStamp0 = ECAP->CAP0.all;
    TStamp1 = ECAP->CAP1.all;
    TStamp2 = ECAP->CAP2.all;
    TStamp3 = ECAP->CAP3.all;

    cnt = ((TStamp2 + TStamp1) + (TStamp3 + TStamp2)) / 2;
    printf("Frequency = %dHz\n", CNTTOFREQ(cnt));

    /* Clear CEVT3 */
    ECAP_ClearCEVT3Int(ECAP);

    /* Clear global INT of ECAP */
    ECAP_ClearGlobalInt(ECAP);
}
