
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "app.h" 

volatile uint32_t g_Inc;
volatile uint32_t g_Pulse;
volatile uint32_t g_MaxPulse;
volatile uint32_t g_Period;


/******************************************************************************
*@brief : app test
*@param : none
*@return: none
******************************************************************************/
void APP_Test(void)
{
    uint32_t freq;
    GPIO_InitTypeDef  GPIO_InitStruct = {0};
    LPTIM_InitTypeDef LPTIM_InitStruct = {0};
    
	printfS("SPL LPTIM Demo: PWM Output\r\n");
	printfS("\r\n");
    
	BSP_LED_Init();
    BSP_LED_On();
    DelayMs(500);
    BSP_LED_Off();
    DelayMs(500);
    BSP_LED_On();
    DelayMs(500);
    BSP_LED_Off();
    DelayMs(500);
    
    // Enable NVIC IRQ
    NVIC_ClearPendingIRQ(LPTIM1_IRQn);
    NVIC_SetPriority(LPTIM1_IRQn, 0x00);
    NVIC_EnableIRQ(LPTIM1_IRQn);
    
    LPTIM_DeInit(LPTIM1);
    __RCC_LPTIM1_CLK_ENABLE();
    LPTIM_Reset(LPTIM1);
    
    // PWM: PB2
    __RCC_GPIOB_CLK_ENABLE();
    
    GPIO_InitStruct.Pin       = GPIO_PIN_2;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    GPIO_InitStruct.Drive     = GPIO_DRIVE_LEVEL3;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_2;

    GPIO_Init(GPIOB, &GPIO_InitStruct);
    
    LPTIM_InitStruct.ClockSource = LPTIM_CLOCKSOURCE_INTERNAL_PCLK;
    LPTIM_InitStruct.Prescaler = LPTIM_CLOCKPRESCALER_DIV1;
    LPTIM_InitStruct.Waveform = LPTIM_WAVEFORM_PWM_ONEPULSE;
    LPTIM_InitStruct.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
    
    LPTIM_Init(LPTIM1, &LPTIM_InitStruct);
    
    LPTIM_SelectSoftwareStart(LPTIM1);
    LPTIM_ConfigUpdate(LPTIM1, LPTIM_UPDATE_ENDOFPERIOD);
    LPTIM_SelectCounterMode(LPTIM1, DISABLE);
    
    LPTIM_ClearFlag(LPTIM1, LPTIM_FLAG_CMPM);
    LPTIM_ITConfig(LPTIM1, LPTIM_IT_CMPM, ENABLE);
    
    LPTIM_Cmd(LPTIM1, ENABLE);
    
    freq = 2000;
    g_Period = RCC_GetPCLK1Freq() / freq;
    g_Inc = g_Period * 10 / 100;
    g_Pulse = g_Inc;
    
    LPTIM_ClearFlag(LPTIM1, LPTIM_FLAG_CMPOK);
    LPTIM_SetCompareValue(LPTIM1, g_Pulse);
    while (LPTIM_GetFlagStatus(LPTIM1, LPTIM_FLAG_CMPOK) == RESET);
    
    LPTIM_ClearFlag(LPTIM1, LPTIM_FLAG_ARROK);
    LPTIM_SetAutoreloadValue(LPTIM1, g_Period);
    while (LPTIM_GetFlagStatus(LPTIM1, LPTIM_FLAG_ARROK) == RESET);
    
    LPTIM_SelectOperatingMode(LPTIM1, LPTIM_MODE_CONTINUOUS);
    
    printfS("PWM( PB2 ), Frequency: %u KHz.\r\n", freq);
    printfS("The duty cycle is reduced from 90%% to 10%% in steps of 10%%.\r\n");
    printfS("\r\n");
    
    while(1)
    {
        BSP_LED_Toggle();
        DelayMs(500);
    };
}

void lptim1_irq_handle(void)
{
    
    if ((LPTIM1->IER & LPTIM_IT_CMPM) && (LPTIM1->ISR & LPTIM_FLAG_CMPM))
    {
        LPTIM1->ICR = LPTIM_FLAG_CMPM;
        
        g_Pulse += g_Inc;
        if (g_Pulse >= g_Period)
            g_Pulse = g_Inc;
        
        LPTIM1->CMP = (LPTIM1->CMP & ~LPTIM_CMP_CMP) | g_Pulse;
        
    }
}




