/******************************************************************************
 *
 * Freescale Semiconductor Inc.
 * (c) Copyright 2004-2013 Freescale Semiconductor, Inc.
 * ALL RIGHTS RESERVED.
 *
 ******************************************************************************
 *
 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 **************************************************************************//*!
 *
 * @file lptmr.c
 *
 * @author  
 *
 * @version 2.0
 *
 * @date Apr-19-2013
 *
 * @brief Low Power Timer driver functions
 *
 *****************************************************************************/

/*******************************************************************
*                           Header Files
********************************************************************/
#include "lptmr.h"
#include "fsl_types.h"
#include "nvic.h"

/*******************************************************************
*                             Globals
*******************************************************************/
unsigned char u8LptStatus = 0;

/********************************************************************
* Function: vfnTimeDelayms
*
* Description: Uses the LPT timer as a ms delay generator using the LPO.
*              No interrupt is needed here but MCU does nothing until delay
*              has been completed
*
* Input: unsigned short u16CountVal
*        This is the time in mS for the delay
*
* Output: void
**********************************************************************/
void vfnTimeDelayms(unsigned short u16CountVal)
{
  /* Make sure the clock to the LPTMR is enabled */
  SIM_SCGC5|=SIM_SCGC5_LPTIMER_MASK; 
  
  //Reset the Low Power Timer
  LPTMR0_CSR = 0x00;
  
  /* Set the compare value to the number of ms to delay */
  LPTMR0_CMR = u16CountVal; 
  
  /* Set up LPTMR to use 1kHz LPO with no prescaler as its clock source */
  LPTMR0_PSR = LPTMR_PSR_PCS(1)|LPTMR_PSR_PBYP_MASK; 
  
  /* Start the timer */
  LPTMR0_CSR |= LPTMR_CSR_TEN_MASK | LPTMR_CSR_TCF_MASK; 

  /* Wait for counter to reach compare value */
  while (!(LPTMR0_CSR & LPTMR_CSR_TCF_MASK));
  
  /* Clear Timer Compare Flag */
  LPTMR0_CSR &= ~LPTMR_CSR_TEN_MASK;
  
  return;
}

/********************************************************************
* Function: vfnLptTimerInit
*
* Description: Initializes LPT as timer
*
* Input: unsigned short u16CompareVal
*        Value to be set in the LPTMR0_CMR register. When the LPT counter reaches this value
*         the counter is reset and interrupt is called if enabled.
*
* Input: unsigned char u8ClkSource
*        Clock source for the LPT. Select one of the four clock sources above.
*
* Input: unsigned char u8Prescaler
*        Prescaler value to divide the LPT clock source. Select one of the 16 preescaler options
*        above
*
* Input: unsigned char u8IntEn
*        Selects interrupt status
*        TRUE = Interrupts enabled
*        FALSE = Interrupts disabled, use polling
*
* Output: void
*
* Warning: Desired clock source must be configured before calling this function.
**********************************************************************/

void vfnLptTimerInit(unsigned short u16CompareVal, unsigned char u8ClkSource, unsigned char u8Prescaler, unsigned char u8IntEn)
{
 /* Enables clock on LPT */
 SIM_SCGC5 |= SIM_SCGC5_LPTIMER_MASK;
 
  //Reset the Low Power Timer
  LPTMR0_CSR = 0x00;
 
 /* Configure LPT clock source and prescaler */
 if(u8Prescaler == LPT_PRE_1)
 {
  LPTMR0_PSR = (LPTMR_PSR_PBYP_MASK | LPTMR_PSR_PCS(u8ClkSource));
 }
 else
 {
  LPTMR0_PSR = (LPTMR_PSR_PRESCALE(u8Prescaler-1) | LPTMR_PSR_PCS(u8ClkSource));
 }
 
 /* Load compare value to compare register */
 LPTMR0_CMR = u16CompareVal;
 
 if(u8IntEn == TRUE)
 {
   LPTMR0_CSR = (LPTMR_CSR_TIE_MASK | LPTMR_CSR_TEN_MASK);
   u8NvicEnableIrq(INT_LPTimer - 16);
 }
 else
 {
   LPTMR0_CSR = LPTMR_CSR_TEN_MASK;
 }
 
 /* LPT Timer is now enabled */
}

/********************************************************************
* Function: vfnLptTimerDeinit
*
* Description: Disables the LPT
*
* Input: void
*
* Output: void
**********************************************************************/

void vfnLptTimerDeinit(void)
{
 LPTMR0_CSR = 0;  //Turn Off LPT
 SIM_SCGC5 &= (~SIM_SCGC5_LPTIMER_MASK); //Disable clock on LPT 
 
 /* LPT Timer is now disabled */
}
 
/********************************************************************
* Function: vfnLptTimerIsr
*
* Description: Interrupt service function for LPT interrupts
*
* Input: void
*
* Output: void
*
* Warning: Function must be registered in the vector table.
**********************************************************************/
 
 void vfnLptTimerIsr(void)
 {
  LPTMR0_CSR |= LPTMR_CSR_TCF_MASK; //Clears Flag
  
  /* Implement your ISR action here!! */
  LPT_INTERRUPT_EVENT;
 }
