/**
  ******************************************************************************
  * @file    ys32md211_lptim.c
  * @author  YSPRING Application Team
  * @version V1.0.1
  * @date    2023.6.14
  * @brief   This file provides firmware functions to manage the following 
  *          functionalities of the LPTIM peripheral:
  *           + LPTIM Configuration
  * 
  *  @verbatim
================================================================================
                   ##### How to use this driver #####
================================================================================

           Basic configuration:
           --------------------
           - Use LPTIM_SetAutoReload() to set the auto-reload value
           
           - Configure clock sorce by using LPTIM_SelectClockSource() function. 4 clock sorce
             are available:
               + PCLK.
               + LSI.
               + No clock.
               + LSE.               
            - Enable the peripheral by calling LPTIM_Cmd.

           Timeout function:
           -----------------
           In this case, the counter counts up from the set value and generates 
           an overflow interrupt after counting up to a maximum of 0XFFFF. 
           After the interrupt is generated, the value of the overloaded register
           ARR is overloaded to the counter, counting up. In heavy load mode, 
           the initial value of the counter CNT is automatically loaded 
           by the ARR when the timer is started
           - To active this feature use LPTIM_TimoutCmd.

           Interrupt configuration:
           ------------------------
           - Use LPTIM_ITConfig to configure an interruption.
           - Call LPTIM_GetFlagStatus to get a flag status.
           - Call LPTIM_GetITStatus to get an interrupt status.
           - Use LPTIM_ClearFlag to clear a flag.
  @endverbatim
  *
  ******************************************************************************
  */
  
/* Includes ------------------------------------------------------------------*/
#include "ys32md211_lptim.h"

/** @addtogroup YS32MD211_StdPeriph_Driver
  * @{
  */
  
/** @defgroup LPTIM 
  * @brief LPTIM driver modules
  * @{
  */
  
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup LPTIM_Private_Functions
  * @{
  */
  
  /** @defgroup LPTIM_Group1 Initialization functions
  *  @brief   Initialization functions
  *
@verbatim
 ===============================================================================
                             Initialization functions
 ===============================================================================
  This section provides functions allowing to:
   - Deinitialize  the LPTimer
   - Initialize the value of timing clock cycles

@endverbatim
  * @{
  */

/**
  * @brief  Deinitializes the LPTIM peripheral registers to their default reset values.
  * @retval None
  */
void LPTIM_DeInit(void)
{
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_LPTIM, ENABLE);
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_LPTIM, DISABLE);
}

/**
  * @brief  Set the LPTIM Auto Reload Value
  * @note The LPTIMx_ARR register content must only be modified when the WT_FLAG was set
  * @note After a write to the LPTIMx_ARR register a new write operation to the
  *       same register can only be performed when the previous write operation
  *       is completed. Any successive write before WT_FLAG is set, will
  *       lead to unpredictable results.  
  * @param Value: between Min_Data=0x00 and Max_Data=0xFFFF
  * @note   Set the timer period (0xFFFF - ARR + 0x0001)
  * @retval None
  */
void LPTIM_SetAutoReload(uint16_t Value)
{
    while(!(LPTIM->CR & LPTIM_CR_WT_FLAG))
    {
    }
    
    LPTIM->ARR = (65535 - Value) + 1;
}

/**
  * @}
  */

/** @defgroup LPTIM_Group2 Configuration functions
  *  @brief   Configuration functions
  *
@verbatim
 ===============================================================================
                       Configuration functions
 ===============================================================================
    This section provides functions allowing to configure the Low Power Timer:
    - Select the Clock source.
    - Get the Counter value.
    - Enable or disable the peripheral.

@endverbatim
  * @{
  */

/**
  * @brief  Enable or Disable the LPTIM peripheral.
  * @param  NewState: This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void LPTIM_Cmd(FunctionalState NewState)
{
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if(NewState == ENABLE)
    {
        LPTIM->CR |= LPTIM_CR_TR;
    }
    else
    {
        LPTIM->CR &= (~LPTIM_CR_TR);
    }
}

/**
  * @brief  Selects the Clock source of the LPTIM counter.
  * @note   Enable the RCC clock first, and then call this function.
  * @param  CLK_SRC: Clock source Config
  *            @arg LPTIM_CLK_SRC_PCLK: Clock come from PCLK
  *            @arg LPTIM_CLK_SRC_LSI: Clock come from LSI
  *            @arg LPTIM_CLK_SRC_NO:  No Clock
  *            @arg LPTIM_CLK_SRC_LSE: Clock come from LSE
  * @retval None
  */
void LPTIM_SelectClockSource(uint32_t CLK_SRC)
{
    assert_param(IS_LPTIM_CLK_SRC(CLK_SRC));

    RCC->CCIPR &= (~RCC_CCIPR_LPTIMSEL);
    RCC->CCIPR |= CLK_SRC;
}

/**
  * @brief  Gets the LPTIM counter value.
  * @retval Counter Register value
  */
uint32_t LPTIM_GetCounterValue(void)
{ 
  /* Get the Counter Register value */
  return LPTIM->CNT;
}

/**
  * @brief  Gets the LPTIM Autoreload value.
  * @retval Counter Register value
  */
uint32_t LPTIM_GetAutoreloadValue(void)
{
  /* Get the Counter Register value */
  return LPTIM->ARR;
}

/**
  * @}
  */

/** @defgroup LPTIM_Group3 Interrupts and flags management functions
  *  @brief    Interrupts and flags management functions
  *
@verbatim
 ===============================================================================
                  Interrupts and flags management functions
 ===============================================================================
  This section provides functions allowing to configure the LPTIM Interrupts, get
  the status and clear flags bits.

  The LPTIM provides 1 Flags and Interrupts sources

  Flags and Interrupts sources:
  =============================
  1. counter overflow

  - To enable a specific interrupt source, use "LPTIM_ITConfig" function.
  - To check if an interrupt was occurred, call "LPTIM_GetITStatus" function and read
    the returned value.
  - To get a flag status, call the "LPTIM_GetFlagStatus" function and read the returned
    value.
  - To clear a flag or an interrupt, use LPTIM_ClearFlag function with the
    corresponding flag (interrupt).

@endverbatim
  * @{
  */


/**
  * @brief  Enable or Disable the LPTIM interrupt.
  * @param  NewState: This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void LPTIM_ITConfig(FunctionalState NewState)
{
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if(NewState == ENABLE)
    {
        LPTIM->CR |= LPTIM_CR_IE;
    }
    else
    {
        LPTIM->CR &= ~(LPTIM_CR_IE);
    }
}

/**
  * @brief  Checks whether the LPTIM overflow flag has occurred or not.
  * @param  LPTIM_FLAG:specifies the flag to check.
  *            @arg LPTIM_FLAG_OVFR: LPTIM over flag
  * @retval SET(1) or RESET(0)
  */
FlagStatus LPTIM_GetFlagStatus(uint32_t LPTIM_FLAG)
{
    FlagStatus bitstatus = RESET; 
    
   /* Check the parameters */
    assert_param(IS_LPTIM_FLAG(LPTIM_FLAG));

    if (LPTIM->OVFR & LPTIM_FLAG)
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }
    
    return bitstatus;
}

/**
  * @brief  Checks whether the LPTIM overflow interrupt has occurred or not.
  * @param  LPTIM_IT:specifies the LPTIM interrupt source to check.
  *            @arg LPTIM_IT_OVFR: LPTIM overflow interrupt
  * @retval SET(1) or RESET(0)
  */
ITStatus LPTIM_GetITStatus(uint32_t LPTIM_IT)
{
    ITStatus bitstatus = RESET; 
    uint32_t enablestatus = 0;
    
   /* Check the parameters */
    assert_param(IS_LPTIM_IT(LPTIM_IT));

    if (LPTIM_IT == LPTIM_IT_OVFR)
        enablestatus = LPTIM->CR & LPTIM_CR_IE;

    if ((LPTIM->OVFR & LPTIM_IT) && (enablestatus != 0))
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }
    
    return bitstatus;
}



/**
  * @brief  Clears the LPTIM overflow flag
  * @param  LPTIM_CLEARF: specifies the pending bit to clear.
  *         This parameter can be any combination of the following values:
  *            @arg LPTIM_CLEARF_OVFR: LPTIM overflow clear flag
  * @retval None
  */
void LPTIM_ClearFlag(uint32_t LPTIM_CLEARF)
{
   /* Check the parameters */    
    assert_param(IS_LPTIM_CLEAR_FLAG(LPTIM_CLEARF));

    LPTIM->OCLR &= (~LPTIM_CLEARF);
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

