/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */
/******************************************************************************
 * @version: V1.0.0 demo
 ******************************************************************************/

/*!
 * @file pwdt.c
 *
 * @brief This file contains the user pwdt function..
 *
 */

/* ===========================================  Includes  =========================================== */
#include "pwdt.h"
#include "ac780x_gpio.h"
#include "ac780x_pwdt.h"
#include "ac780x_pwdt_reg.h"
#include <string.h>

/* ============================================  Define  ============================================ */
#define PRESCALER    (PWDT_CLK_PRESCALER_1)        /*!< PWDT clock source frequency division */
#define PWDT_DIVIDER (1 << PRESCALER)              /*!< clock frequency division */
#define PWDT_CLK     (APB_BUS_FREQ / PWDT_DIVIDER) /*!< APB bus clock is 32MHz by default */

#define PWDT_GPIO (GPIOB)
#define PWDT_PIN  (GPIO_PIN8)

/* ===========================================  Typedef  ============================================ */

/* ==========================================  Variables  =========================================== */
uint32_t g_freq;         /*!< pulse width period value*/
float g_duty;            /*!< pulse duty value*/
uint8_t g_hallStatus[6]; /*!< hall status value*/

/* ====================================  Functions declaration  ===================================== */

/* ======================================  Functions define  ======================================== */

/*!
 * @brief Print PWDT Information
 *
 * @param[in]  none
 *
 * @return none
 */
void PWDT_PrintInfo(void)
{
    uint8_t i = 0;

    printf("g_freq=%d, g_duty =%f.\r\n", g_freq, g_duty);

    for (i = 0; i < 6; i++)
    {
        printf("g_hallStatus[%d]=%x  ", i, g_hallStatus[i]);
    }
    printf("\r\n");

    g_freq = 0;
    g_duty = 0;
}

/*!
 * @brief  PWDT0 Capture Callback
 *
 * @param[in] device: pwdt module
 * @param[in] wpara: interrupt flag
 * @param[in] lpara: interrupt parameter
 *
 * @return none
 */
void PWDT0_Callback(void *device, uint32_t wpara, uint32_t lpara)
{
    static uint32_t positvePulse  = 0; /*!< pulse width positive value*/
    static uint32_t negativePulse = 0; /*!< pulse width negative value*/
    static uint8_t i              = 0; /*!< pulse width negative value*/

    /*PWDT overflow interrupt*/
    if (wpara & PWDT_INIT0_OVF_Msk)
    {
    }

    /*Pulse Width Data Ready Interrupt*/
    if (wpara & PWDT_INIT0_RDY_Msk)
    {
        g_hallStatus[i] = (uint8_t)(PWDT_GetHallStatus(PWDT0) & 0x07);
        i++;
        if (i >= 6)
        {
            i = 0;
        }

        positvePulse  = PWDT_GetPositivePulseWidth(PWDT0) + 1; /*Get positive pulse width count value*/
        negativePulse = PWDT_GetNegativePulseWidth(PWDT0) + 1; /*Get negative pulse width count value*/
        if (0 != (positvePulse + negativePulse))
        {
            /*
            Calculate Frequency and Duty Cycle:
            Frequency = PWDT clock source / PWDT clock frequency division / positive + negative pulse width count value
            Duty cycle = positive pulse width count value / positive + negative pulse width count value
            */
            g_freq = PWDT_CLK / (positvePulse + negativePulse);
            g_duty = (float)(((float)positvePulse * 100) / (float)(positvePulse + negativePulse));
        }
    }
}

/*!
 * @brief   PWDT initialization
 *
 * @param[in] none
 *
 * @return  none
 */
void PWDT_Initalize(void)
{
    PWDT_ConfigType pwdtConfig;
    memset(&pwdtConfig, 0, sizeof(pwdtConfig));

    /* Configuring PWDT GPIO */
    GPIO_SetFunc(GPIOB, GPIO_PIN2, GPIO_FUN3);  /*PWDT0 channel 0*/
    GPIO_SetFunc(GPIOA, GPIO_PIN11, GPIO_FUN3); /*PWDT0 channel 1*/
    GPIO_SetFunc(GPIOA, GPIO_PIN10, GPIO_FUN3); /*PWDT0 channel 2*/

    /* General parameters */
    pwdtConfig.clkPsc              = PRESCALER;                     /* PWDT clock source frequency division */
    pwdtConfig.edgeType            = PWDT_RISING_START_CAPTURE_ALL; /* First rising-edge start to measure, all edge capture */
    pwdtConfig.channel             = PWDT_INPUT_CH_0;               /* Select measure input channel(This configuration is invalid in HALL mode) */
    pwdtConfig.overflowInterruptEn = ENABLE;                        /* Overflow interrupt enable/disable */
    pwdtConfig.readyInterruptEn    = ENABLE;                        /* Data ready interrupt enable/disable */
    pwdtConfig.interruptEn         = ENABLE;                        /* PWDT module interrupt enable/disable */
    pwdtConfig.callback            = PWDT0_Callback;                /* Set PWDT interrupt callback function */
    pwdtConfig.cmpModeEn           = DISABLE;                       /* Comparator mode enable/disable */
    pwdtConfig.hallModeEn          = ENABLE;                        /* Hall mode enable/disable */
    pwdtConfig.mode                = PWDT_MEASURE_MODE;             /* PWDT working mode */

    /* Filter parameters(Only valid in Measure mode) */
    pwdtConfig.filterPsc   = PWDT_FILTER_PRESCALER_1; /* filter frequency division */
    pwdtConfig.filterValue = 15;                      /* Filter value range 0-15; Filter width = filterPsc*filterValue*bclk */
    pwdtConfig.filterEn    = ENABLE;                  /* Enable PWDT filtering,Can filter out interference signals smaller than pwdtFilterValue * (1 << pwdtFilterPsc)*bclk */

    /* Timer parameters(Only valid in Timer mode) */
    pwdtConfig.periodValue = 0; /* Timer period value */

    PWDT_Init(PWDT0, &pwdtConfig);
}

/* =============================================  EOF  ============================================== */
