/* 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 pwm_output.c
 *
 * @brief This file is for pwm output
 */
/* ===========================================  Includes  =========================================== */
#include "pwm_sample.h"
/* ============================================  Define  ============================================ */

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

/* ==========================================  Variables  =========================================== */
uint32_t g_overFlowCount;   /*PWM1 count overflow interrupt*/
uint8_t g_fautlCnt = 0;     /*PWM fault count*/

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

/* ======================================  Functions define  ======================================== */
/**
* PWM1_CallBack
*
* @param[in] device: device pointer
* @param[in] wpara: callback parameter
* @param[in] lpara: callback parameter
* @return none
* @brief PWM CallBack
*/
void PWM1_Callback(void *device, uint32_t wpara, uint32_t lpara)
{
    //PWM counter overflow interrupt
    if (wpara & PWM_INIT_CNTOF_Msk)
    {
        g_overFlowCount ++;
        /* user add */

    }
    /* PWM channel interrupt */
    /* By determining the corresponding PWM of the lpara returned by the callback_ STR_ CHnSF_ Msk bit status judgment whether channel interruption has occurred */
    if (lpara & PWM_STR_CHSF_Msk)
    {

        /* user add */
        /* Channel 0 interrupt */
        if (lpara & PWM_STR_CH0SF_Msk)
        {

        }
        /* Channel 1 interrupt */
        if (lpara & PWM_STR_CH1SF_Msk)
        {

        }

    }

    if (PWM_GetFaultChannelFlag(PWM1, PWM_FAULT_CH_0))
    {
        /*If equipped with manual fault clearing, PWM will continue to output after clearing the flag.*/
        g_fautlCnt ++;
        printf("\npwm fault triger. falut count: %d\r\n", g_fautlCnt);
        PWM_ClearFaultChannelFlag(PWM1, PWM_FAULT_CH_0); /*When configured to manually clear the fault flag, software needs to clear the flag, otherwise the interrupt will be triggered continuously */
    }
}

/**
* PWM1_GenerateFrequency
*
* @param[in] none
* @return none
*
* @brief
*      PWM1 module is initialized, PWM1_CH0 and PWM1_CH1 are configured as combined channel output PWM.
*      up-counting mode, CH0 and CH1 are not complementary, frequency is 10KHz, duty cycle is 25%
*
*/
void PWM1_GenerateFrequency(void)
{
    PWM_ConfigType config;
    PWM_ModulationConfigType pwmConfig;
    PWM_CombineChConfig combineChConfig[1];
    PWM_FaultConfig  faultConfig;

    memset(&config, 0U, sizeof(config));
    memset(&pwmConfig, 0U, sizeof(pwmConfig));
    memset(&combineChConfig, 0U, sizeof(combineChConfig));
    memset(&faultConfig, 0U, sizeof(faultConfig));

    GPIO_SetFunc(GPIOC, GPIO_PIN7, GPIO_FUN5);                  /* PC7 PWM1_CH0 */
    GPIO_SetFunc(GPIOC, GPIO_PIN6, GPIO_FUN5);                  /* PC6 PWM1_CH1 */

    combineChConfig[0].pairChannel = PWM_CH_0;                  /* Combined output channel selection, here CH0 and CH1 are combined, so CH0 is selected */
    combineChConfig[0].ch1stValue = (PWM1_MAX_VALUE >> 2) - 1;  /* Channel n match value */
    combineChConfig[0].ch2ndValue = (PWM1_MAX_VALUE >> 1) - 1;  /* Channel n+1 match value */
    combineChConfig[0].levelMode = PWM_HIGH_TRUE;               /* Output level polarity after reaching the first matching value */
    combineChConfig[0].deadtimeEn = DISABLE;                    /* Dead zone insertion enable bit */
    combineChConfig[0].deadtime = NULL;                         /* Dead time value, dead time function is only valid in combined mode */
    combineChConfig[0].deadtimePsc = PWM_DEADTIME_DIVID_1;      /* Dead time clock divider */
    combineChConfig[0].complementEn = DISABLE;                  /* The complementary output enable bit */
    combineChConfig[0].ch1stMatchDir = PWM_MATCH_DIR_UP;        /* Channel n matches the point effective direction and is only valid in up-down counting mode */
    combineChConfig[0].ch2ndMatchDir = PWM_MATCH_DIR_UP;        /* Channel n+1 matches the point effective direction and is only valid in up-down counting mode */

    /* Channel output polarity, which affects the level after mask, the level after triggering fault control,
       and the level for deadzone insertion. Here, the polarity is configured to be high, that is, low output after mask */
    combineChConfig[0].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;
    combineChConfig[0].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;

    combineChConfig[0].ch1stInterruptEn = ENABLE;               /* Channel n matches the interrupt enable bit */
    combineChConfig[0].ch2ndInterruptEn = ENABLE;               /* Channel n+1 matches the interrupt enable bit */
    combineChConfig[0].ch1stInitLevel = PWM_HIGH_LEVEL;         /* Channel n initial level configuration, which affects the level before channel matching after initialization */
    combineChConfig[0].ch2ndInitLevel = PWM_HIGH_LEVEL;         /* Channel n+1 initial level configuration, which affects the level before channel matching after initialization */
    combineChConfig[0].ch1stTriggerEn = DISABLE;                /* After matching the channel values, trigger signals can be generated for other modules */
    combineChConfig[0].ch2ndTriggerEn = DISABLE;                /* After matching the channel values, trigger signals can be generated for other modules */

    pwmConfig.countMode = PWM_UP_COUNT;                         /* PWM counter mode Settings */
    pwmConfig.independentChannelNum = 0;                        /* Number of independent channels */
    pwmConfig.combineChannelNum = 1;                            /* Combined channel logarithm */
    pwmConfig.independentChConfig = NULL;                       /* Independent channel configuration struct assignment */
    pwmConfig.combineChConfig = combineChConfig;                /* Combined channel configuration struct assignment */
    pwmConfig.initChOutputEn = ENABLE;                          /* Initialize the channel output enable bit */
    pwmConfig.initTriggerEn = DISABLE;                          /* The PWM initial value triggers the enable bit */

    config.mode = PWM_MODE_MODULATION;                          /* PWM mode configuration */
    config.initModeStruct = &pwmConfig;                         /* Different modes initialize configuration struct assignments accordingly */
    config.clkSource = PWM_CLK_SOURCE_APB;                      /* PWM clock source selection */
    config.clkPsc = PWM1_CLK_PSC - 1;                           /* Clock division factor */
    config.initValue = 0;                                       /* Initial count value */
    config.maxValue = PWM1_MAX_VALUE - 1;                       /* Maximum count value. Determines the output waveform frequency */
    config.overflowInterrupEn = ENABLE;                         /* Overflow interrupts the enable bit */
    config.cntOverflowFreq = 0;                                 /* The frequency at which overflow interrupts are generated, 0 means that each overflow produces an interrupt */
    config.interruptEn = ENABLE;                                /* PWM total interrupt enable bit */
    config.callback = PWM1_Callback;                            /* PWM interrupts user callback function */
    PWM_Init(PWM1, &config);

    faultConfig.mode = PWM_FAULT_CTRL_MANUAL_ALL;                                              /* Fault Clearing Mode Selection. */
    faultConfig.channelConfig[PWM_FAULT_CH_0].faultInputEn = ENABLE;                           /* Enable FAULT1 channel, the pin PWM_FLT0 corresponds to the internal FAULT1 channel. */
    faultConfig.channelConfig[PWM_FAULT_CH_0].faultFilterEn = DISABLE;                         /* Enable filtering for FAULT1 channel. */
    faultConfig.channelConfig[PWM_FAULT_CH_0].faultPolarity = PWM_INPUT_POLARITY_ACTIVE_LOW;   /* ///Configure the input fault active state as low-active. */
    faultConfig.filterValue = 0;                                                               /* Fault filter value, ranging from 0 to 255. */
    faultConfig.faultCtrlOutputEn[0] = ENABLE;                                                 /* Enable fault detection for PWM channels CH0 and CH1. */
    faultConfig.faultCtrlOutputEn[1] = ENABLE;                                                 /* Enable fault detection for PWM channels CH2 and CH3.*/
    faultConfig.interruptEn = ENABLE;                                                          /* Enable fault interrupt. */
    PWM_InitFaultControl(PWM1, &faultConfig);
    NVIC_SetPriority(PWM1_IRQn, 0);

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