//example_gptimer_pwm_N.c

include "example.h"

/*
以下样例实现的功能:
使用gptimer4_ch0的一路channal输出三路波形:
第一路:pwm输出,
第二路:反向pwm输出,
第三路:单向 中断(io toggle)输出
(其中pwm占空比可调,频率可调,触发中断上下边可调,死区可调)

上边使用到3个IO引脚(要在ve文件中映射到pin):
GPTIMER4_CH0 PIN_7
GPTIMER4_CHN0 PIN_15
GPIO4_1 PIN_17

*/

void setTestGpio() //gpio init first
{
SYS_EnableAPBClock(APB_MASK_GPIO4);
GPIO_SetOutput(GPIO4, GPIO_BIT1);
}

void GPTIMER4_isr() //timer interrupt
{
GPIO_Toggle(GPIO4, GPIO_BIT1);
GPTIMER_ClearFlagCC0(GPTIMER4);
}

void TestGpTimerPwm2()
{
setTestGpio(); //init io 用于中断函数中的IO翻转(第三路输出)

SYS_EnableAPBClock(APB_MASK_GPTIMER4);

GPTIMER_InitTypeDef tm_init;
GPTIMER_StructInit(&tm_init);
const uint32_t frequency = 10000; //In Hz
const float pwm_ratio = 0.2; //占空比比例
tm_init.Autoreload = SYS_GetPclkFreq() / frequency;
tm_init.CounterMode = GPTIMER_COUNTERMODE_CENTER_UP;//GPTIMER_COUNTERMODE_CENTER_BOTH; // 触发中断的方式,仅上升时触发。
GPTIMER_Init(GPTIMER4, &tm_init);

//OC正向,OCN反向
GPTIMER_OC_InitTypeDef oc_init;
oc_init.OCState = GPTIMER_OCSTATE_ENABLE;
oc_init.OCNState = GPTIMER_OCSTATE_ENABLE;
oc_init.OCPolarity = GPTIMER_OC_POLARITY_INVERTED;
oc_init.OCNPolarity = GPTIMER_OC_POLARITY_INVERTED;
oc_init.OCIdleState = GPTIMER_OCIDLESTATE_LOW;
oc_init.OCNIdleState = GPTIMER_OCIDLESTATE_LOW;

oc_init.OCMode = GPTIMER_OCMODE_PWM1;
oc_init.CompareValue = tm_init.Autoreload * pwm_ratio; //设置比较值,用于比较中断
GPTIMER_OC_Init(GPTIMER4, GPTIMER_CHANNEL_CH0, &oc_init);

GPIO_AF_ENABLE(GPTIMER4_CH0); //输出IO
GPIO_AF_ENABLE(GPTIMER4_CHN0); //输出IO2(反向)

GPTIMER_SetDeadTimeGenerator(GPTIMER4, 30); //死区时间宽度
GPTIMER_SetBreakState(GPTIMER4, GPTIMER_BREAK_ENABLE);
GPTIMER_ConfigBreak(GPTIMER4, GPTIMER_BREAK_POLARITY_HIGH, GPTIMER_BREAK_FILTER_FDIV1_N2);

INT_EnableIRQ(GPTIMER4_IRQn, TIMER_PRIORITY); //开中断
GPTIMER_EnableIntCC0(GPTIMER4); //使能channal0的比较中断

GPTIMER_EnableAllOutputs(GPTIMER4);
GPTIMER_EnableCounter(GPTIMER4); //打开timer4

while(1);
}