/**
 *******************************************************************************
 * @file    dpm32m0xx_lptim.c
 *
 * @brief   Source file for LPTIM firmware driver.
 *          This file provides firmware functions to manage the following
 *           functionalities of the Low Power Timer (LPT) peripheral:
 *            + Initialization functions.
 *            + Configuration functions.
 *            + Interrupts and flags management functions.
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 * @verbatim
 ===============================================================================
                       ##### How to use this driver #####
 ===============================================================================
    [..]
      (#) To use LPTIM, you need to turn on the LSCK clock and first configure
          the LSI or LSE uisng RCC_OscConfig(), Then select a clock source for
          LSCLK using RCC_ClockConfig().

      (#) Program the required configuration through following parameters:
          Set period value using the LPTIM_Init() function.

      (#) Enable the NVIC and the corresponding interrupt(s) using the function
          LPTIM_IntCmd() if you need to use LPTIM interrupts.

      (#) Enable the LPTIM using the LPTIM_Cmd() function.

      (#) To control LPTIM events you can use one of the following two methods:
        (+) Check on LPTIM counter using the function LPTIM_GetCount().
        (+) Use LPTIM interrupts through the function LPTIM_IntCmd() at
            initialization phase and LPTIM_GetIntFlagStatus() function into
            interrupt routines in communication phase.After checking on a flag
            you should clear it using LPTIM_ClearIntFlag() function.

 * @endverbatim
 *******************************************************************************/

#include "dpm32m0xx_lptim.h"


/**
 *******************************************************************************
 * @brief   Deinitializes the LPTIM peripheral registers to their default reset values.
 * @param   None.
 * @retval  None.
 ******************************************************************************/
void LPTIM_DeInit(void)
{
  /* Reset LPTIM control register. */
  LPTIM->CR = (uint32_t)0x00000000;

  /* Reset LPTIM period register. */
  LPTIM->WAKEUP_PERIOD = (uint32_t)0x00000000;

  /* Clear LPTIM wakeup interrupt flag. */
  LPTIM->SR = LPTIM_SR_WK_IF_Msk;
}

/**
 *******************************************************************************
 * @brief   Initializes the LPTIM peripheral according to the specified parameters
 *          in the LPTIM_InitStruct.
 * @param   [in]   LPTIM_InitType  Structure pointer of LPTIM configuration.
 * @retval  None.
 ******************************************************************************/
void LPTIM_Init(LPTIM_InitTypeStruct *LPTIM_InitType)
{
  /* Set lptim period value*/
  LPTIM->WAKEUP_PERIOD = LPTIM_InitType->LPTIM_PeriodValue;
}

/**
 *******************************************************************************
 * @brief   Enables or disables the specified LPTIM peripheral.
 * @param   [in]  NewState: New state of LPTIM.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void LPTIM_Cmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable LPTIM. */
    LPTIM->CR |= (uint32_t)LPTIM_CR_WK_EN_Msk;

    /* Wait enable finish, need 2 LSCLK clock. */
    //while((LPTIM->CR & LPTIM_CR_WK_EN_Msk) != SET);
  }
  else
  {
    /* Disable LPTIM. */
    LPTIM->CR &= ~(uint32_t)LPTIM_CR_WK_EN_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Enables or disables the LPTIM interrupt.
 * @param   [in]  NewState: New state of LPTIM interrupt.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void LPTIM_IntCmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable LPTIM. */
    LPTIM->CR |= LPTIM_CR_WK_IE_Msk;
  }
  else
  {
    /* Disable LPTIM. */
    LPTIM->CR &= ~LPTIM_CR_WK_IE_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Get the LPTIM Interrup enable value.
 * @retval  FunctionalState: LPTIM Interrup enable status.
 ******************************************************************************/
FunctionalState LPTIM_GetIntCmdStatus(void)
{

  return (FunctionalState)((LPTIM->CR & LPTIM_CR_WK_IE_Msk) ? ENABLE : DISABLE);
}

/**
 *******************************************************************************
 * @brief   Get the LPTIM Interrup Flag.
 * @retval  uint8_t: LPTIM Interrup Flag.
 ******************************************************************************/
FlagState LPTIM_GetIntFlagStatus(void)
{
  FlagState State = RESET;

  if((LPTIM->SR & LPTIM_SR_WK_IF_Msk) != RESET)
  {
    State = SET;
  }
  else
  {
    State = RESET;
  }

  return State;
}

/**
 *******************************************************************************
 * @brief   Clear the specified LPTIM interrupt state.
 * @retval  None.
 ******************************************************************************/
void LPTIM_ClearIntFlag(void)
{
  /* Clear LPTIM IF bit. */
  LPTIM->SR = LPTIM_SR_WK_IF_Msk;
}

/**
 *******************************************************************************
 * @brief   Get the LPTIM count value.
 * @retval  uint32_t: LPTIM count value.
 ******************************************************************************/
uint32_t LPTIM_GetCount(void)
{
  /* Get count value. */
  return (LPTIM->WAKEUP_CR & LPTIM_WAKEUP_CR_CNT_Msk);
}

/**
 *******************************************************************************
 * @brief   Set the LPTIM period value.
 * @param   Period_Value: LPTIM period value.
 * @retval  None.
 ******************************************************************************/
void LPTIM_SetPeriod(uint32_t Period_Value)
{
  /* Set the period value. */
  LPTIM->WAKEUP_PERIOD = Period_Value;
}
