/* 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) 2022. 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.c
*
* @brief This file contains the user pwm function..
*
*/

/* ===========================================  Includes  =========================================== */
#include "pwm.h"
#include "ac780x_gpio.h"
#include "string.h"

/* ============================================  Define  ============================================ */

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


/* ==========================================  Variables  =========================================== */
uint8_t g_pwm1_overflag = 0;
uint8_t g_pwm2_overflag = 0;
/* ====================================  Functions declaration  ===================================== */


/* ======================================  Functions define  ======================================== */
/*!
 * @brief   PWM1_Callback
 *          PWM1模块中断回调函数
 * @param   wpara:溢出中断标志参数
 *          lpara：通道中断标志参数
 * @return  none
 */
void PWM1_Callback(void *device, uint32_t wpara, uint32_t lpara)
{
    if (0 != wpara)
    {
        g_pwm1_overflag = 1;
    }
}

/*!
 * @brief   PWM2_Callback
 *          PWM2模块中断回调函数
 * @param   wpara:溢出中断标志参数
 *          lpara：通道中断标志参数
 * @return  none
 */
void PWM2_Callback(void *device, uint32_t wpara, uint32_t lpara)
{
    if (0 != wpara)
    {
        g_pwm2_overflag = 1;
    }
}

/*!
 * @brief   PWM1_OutputCombine_Init
 *          PWM1模块初始化，PWM1_CH0和PWM1_CH1配置为组合通道输出PWM，向上计数模式，CH0和CH1互补输出，插入1us死区
 *          频率为20KHz,CH0占空比为30%
 * @param   none
 * @return  none
 */
void PWM1_OutputCombine_Init(void)
{
    PWM_ConfigType config;
    PWM_ModulationConfigType pwmConfig;
    PWM_CombineChConfig combineChConfig[1];

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

    GPIO_SetFunc(GPIOB, GPIO_PIN0, GPIO_FUN2);  /* PB0--PWM1_CH1.该引脚只在32pin封装上有 */
    GPIO_SetFunc(GPIOB, GPIO_PIN1, GPIO_FUN2);  /* PB1--PWM1_CH0,该引脚只在32pin封装上有.*/

    /*
    组合模式下：
    向上计数模式：
    周期=(MCVR-CNTIN+1)*PWM计数器时钟周期
    脉宽=|CH(n+1)V - CH(n)V|*PWM计数器时钟周期
    向上-向下计数模式：
    周期=2*(MCVR-CNTIN)*PWM计数器时钟周期
    */
    combineChConfig[0].pairChannel = PWM_CH_0;                         /*组合输出通道选择，（PWM_CH_0/2),这里将CH0H和CH1组合，所以选择CH0 */
    combineChConfig[0].ch1stValue = 0;                                 /*通道 n channel值 */
    combineChConfig[0].ch2ndValue = 240;                               /*通道 n+1 channel值 */
    combineChConfig[0].levelMode = PWM_HIGH_TRUE;                      /*输出PMW高有效，可配置高有效或低有效 */
    combineChConfig[0].deadtimeEn = ENABLE;                            /*死区插入使能位 */
    combineChConfig[0].complementEn = ENABLE;                          /*互补输出使能位，使能时CHn和CHn+1波形互补，不使能时CHn和CHn+1波形同相 */
    combineChConfig[0].ch1stMatchDir = PWM_MATCH_DIR_UP;               /*通道n 匹配点生效方向，仅在向上-向下计数模式下有效 */
    combineChConfig[0].ch2ndMatchDir = PWM_MATCH_DIR_UP;               /*通道n+1 匹配点生效方向，仅在向上-向下计数模式下有效*/
    combineChConfig[0].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;/*通道n输出极性配置，PWM Mask后输出该配置的无效电平 */
    combineChConfig[0].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;/*通道n+1输出极性配置，PWM Mask后输出该配置的无效电平 */
    combineChConfig[0].ch1stInterruptEn = DISABLE;                     /*通道n 匹配中断使能位 */
    combineChConfig[0].ch2ndInterruptEn = DISABLE;                     /*通道n+1 匹配中断使能位 */
    combineChConfig[0].ch1stInitLevel = PWM_LOW_LEVEL;                 /*通道n初始电平输出配置，该配置受initChOutputEn 控制，决定PWM计数器未工作前PWM通道的输出电平 */
    combineChConfig[0].ch2ndInitLevel = PWM_LOW_LEVEL;                 /*通道n+1初始电平输出配置，该配置受initChOutputEn 控制，决定PWM计数器未工作前PWM通道的输出电平 */
    combineChConfig[0].ch1stTriggerEn = DISABLE;                       /*通道n 匹配触发使能位，在通道值与计数器值匹配时，可产生触发信号，用于其他模块的触发信号 */
    combineChConfig[0].ch2ndTriggerEn = DISABLE;                       /*通道n+1 匹配触发使能位，在通道值与计数器值匹配时，可产生触发信号，用于其他模块的触发信号*/

    pwmConfig.countMode = PWM_UP_COUNT;                    /*PWM计数器模式，PWM_UP_COUNT--向上计数模式；PWM_UP_DOWN_COUNT-- 向上/向下计数模式 */
    pwmConfig.independentChannelNum = 0;                   /*独立通道数目*/
    pwmConfig.combineChannelNum = 1;                       /*组合通道对数 */
    pwmConfig.independentChConfig = NULL;                  /*独立通道配置赋值 */
    pwmConfig.combineChConfig = combineChConfig;           /*组合通道配置赋值 */
    pwmConfig.deadtime = 16;                               /*死区时间值，死区功能仅在组合模式下有效  */
    pwmConfig.deadtimePsc = PWM_DEADTIME_DIVID_1;          /*死区时间时钟分频系数，死区功能仅在组合模式下有效 */
    pwmConfig.initChOutputEn = ENABLE;                     /*初始化通道输出使能位，使能后独立PWM模式的 initLevel 和组合模式的ch1stInitLevel和ch2ndInitLevel配置才会生效*/
    pwmConfig.initTriggerEn = DISABLE;                     /*PWM初始值触发使能位 */

    /*
    向上计数模式下，频率计算为：
    freq = pwm_clk/(maxValue - initValue +1))
    16000000/(800-1+1) = 20K
    */
    config.mode = PWM_MODE_MODULATION;            /*PWM模式配置，PWM_MODE_MODULATION--PWM调制模式 */
    config.initModeStruct = &pwmConfig;           /*不同模式相应初始化配置结构体赋值 */
    config.clkSource = PWM_CLK_SOURCE_APB;        /*PWM时钟源选择 */
    config.clkPsc = 0;                            /*时钟分频系数 */
    config.initValue = 0;                         /*初始计数值 */
    config.maxValue = 800 - 1;                    /*最大计数值，决定输出波形频率 */
    config.overflowInterrupEn = ENABLE;           /*溢出中断使能位 */
    config.cntOverflowFreq = 0;                   /*溢出中断产生的频率与计数器频率的关系，0表示每次计数器溢出都产生中断，1表示间隔一次，以此类推 */
    config.interruptEn = ENABLE;                  /*PWM总中断使能位  */
    config.callBack = PWM1_Callback;              /*中断回调函数 */

    PWM_Init(PWM1, &config);

}

/*!
 * @brief   PWM2_OutputCombine_Init
 *          PWM2模块初始化，PWM2_CH0和PWM2_CH1配置为组合通道输出PWM，向上/向下计数模式，CH0和CH1不互补输出，插入1us死区
 *          频率为20KHz,CH0占空比为30%
 * @param   none
 * @return  none
 */
void PWM2_OutputCombine_Init(void)
{
    PWM_ConfigType config;
    PWM_ModulationConfigType pwmConfig;
    PWM_CombineChConfig combineChConfig[1];

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

    GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN1); /* PA2--PWM2_CH1.*/
    GPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN1); /* PA3--PWM2_CH0.*/

    /*
    组合模式下：
    向上计数模式：
    周期=(MCVR-CNTIN+1)*PWM计数器时钟周期
    脉宽=|CH(n+1)V - CH(n)V|*PWM计数器时钟周期
    向上-向下计数模式：
    周期=2*(MCVR-CNTIN)*PWM计数器时钟周期
    */
    combineChConfig[0].pairChannel = PWM_CH_0;                         /*组合输出通道选择，（PWM_CH_0/2),这里将CH0H和CH1组合，所以选择CH0 */
    combineChConfig[0].ch1stValue = 120;                               /*通道 n channel值 */
    combineChConfig[0].ch2ndValue = 120;                               /*通道 n+1 channel值 */
    combineChConfig[0].levelMode = PWM_LOW_TRUE;                       /*输出PMW高有效，可配置高有效或低有效 */
    combineChConfig[0].deadtimeEn = ENABLE;                            /*死区插入使能位 */
    combineChConfig[0].complementEn = DISABLE;                         /*互补输出使能位，使能时CHn和CHn+1波形互补，不使能时CHn和CHn+1波形同相 */
    combineChConfig[0].ch1stMatchDir = PWM_MATCH_DIR_UP;               /*通道n 匹配点生效方向，仅在向上-向下计数模式下有效 */
    combineChConfig[0].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;             /*通道n+1 匹配点生效方向，仅在向上-向下计数模式下有效 */
    combineChConfig[0].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;/*通道n输出极性配置，PWM Mask后输出该配置的无效电平 */
    combineChConfig[0].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW; /*通道n+1输出极性配置，PWM Mask后输出该配置的无效电平 */
    combineChConfig[0].ch1stInterruptEn = DISABLE;                     /*通道n 匹配中断使能位 */
    combineChConfig[0].ch2ndInterruptEn = DISABLE;                     /*通道n+1 匹配中断使能位 */
    combineChConfig[0].ch1stInitLevel = PWM_LOW_LEVEL;                 /*通道n初始电平输出配置，该配置受initChOutputEn 控制，决定PWM计数器未工作前PWM通道的输出电平 */
    combineChConfig[0].ch2ndInitLevel = PWM_HIGH_LEVEL;                /*通道n+1初始电平输出配置，该配置受initChOutputEn 控制，决定PWM计数器未工作前PWM通道的输出电平 */
    combineChConfig[0].ch1stTriggerEn = DISABLE;                       /*通道n 匹配触发使能位，在通道值与计数器值匹配时，可产生触发信号，用于其他模块的触发信号 */
    combineChConfig[0].ch2ndTriggerEn = DISABLE;                       /*通道n+1 匹配触发使能位，在通道值与计数器值匹配时，可产生触发信号，用于其他模块的触发信号 */


    pwmConfig.countMode = PWM_UP_DOWN_COUNT;               /*PWM计数器模式，PWM_UP_COUNT--向上计数模式；PWM_UP_DOWN_COUNT-- 向上/向下计数模式 */
    pwmConfig.independentChannelNum = 0;                   /*独立通道数目*/
    pwmConfig.combineChannelNum = 1;                       /*组合通道对数 */
    pwmConfig.independentChConfig = NULL;                  /*独立通道配置赋值 */
    pwmConfig.combineChConfig = combineChConfig;           /*组合通道配置赋值 */
    pwmConfig.deadtime = 16;                               /*死区时间值，死区功能仅在组合模式下有效  */
    pwmConfig.deadtimePsc = PWM_DEADTIME_DIVID_1;          /*死区时间时钟分频系数，死区功能仅在组合模式下有效 */
    pwmConfig.initChOutputEn = ENABLE;                     /*初始化通道输出使能位，使能后独立PWM模式的 initLevel 和组合模式的ch1stInitLevel和ch2ndInitLevel配置才会生效*/
    pwmConfig.initTriggerEn = DISABLE;                     /*PWM初始值触发使能位 */

    /*
    向上-向下技术模式下，频率计算为：
    freq = pwm_clk/(2*(maxValue - initValue))
    16000/(2*400) = 20K
    */
    config.mode = PWM_MODE_MODULATION;            /*PWM模式配置，PWM_MODE_MODULATION--PWM调制模式 */
    config.initModeStruct = &pwmConfig;           /*不同模式相应初始化配置结构体赋值 */
    config.clkSource = PWM_CLK_SOURCE_APB;        /*PWM时钟源选择 */
    config.clkPsc = 0;                            /*时钟分频系数 */
    config.initValue = 0;                         /*初始计数值 */
    config.maxValue = 400;                        /*最大计数值，决定输出波形频率 */
    config.overflowInterrupEn = ENABLE;           /*溢出中断使能位 */
    config.cntOverflowFreq = 0;                   /*溢出中断产生的频率与计数器频率的关系，0表示每次计数器溢出都产生中断，1表示间隔一次，以此类推 */
    config.interruptEn = ENABLE;                  /*PWM总中断使能位  */
    config.callBack = PWM2_Callback;              /*中断回调函数 */

    PWM_Init(PWM2, &config);

}

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