Skip to content
Snippets Groups Projects
Select Git revision
  • e0d0014f5f1827a5a7c5bdee4f73275c0d8a775b
  • master default
  • slow-lib-int
  • ti-sample-project
  • working-spi-in-main
  • working-timera1-delay-fast-wdt
  • working-timer-a1
  • working-uart-isr-lib
  • working-uart-wdt-report
9 results

hal_fr5_timer.c

Blame
  • hal_fr5_timer.c 8.75 KiB
    /******************************************************************************
     *  Filename: hal_fr5_timer.c
     *
     *  Description: Timer abstration layer api for FR5994
     *
     *  Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
     *
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT
     *  OWNER OR 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.
     *
     *  Modified by Edward Longman for the MSP430FR5994
     *
     *******************************************************************************/
    
    #if defined (__MSP430FR5994__)
    #include "msp430.h"
    #include "hal_timer.h"
    
    #include "../radio_drv/hal_types.h"
    
    
    unsigned char volatile timer_event;
    unsigned long volatile time_counter = 0;
    
    unsigned char get_reset_timer_wake_event(){
      unsigned char temp_event = timer_event;
      timer_event = 0;
      return temp_event;
    }
    
    /******************************************************************************
     * @fn         hal_timer_init
     *
     * @brief      Start packet timer using Timer using ACLK as reference
     *
     *
     * input parameters
     *
     * @param       unsigned int master_count - master packet timer value
     *
     * output parameters
     *
     * @return      void
     *
     */
    
    void hal_timer_init(unsigned int master_count) {
    
      // Start Timer 0 using the ACLK as a source (this enables the use of
      // various low power modes). Timer 0 will be used to keep RF burst time
      TA0CCR0  = master_count - 1;              // Seting for MASTER SCHEDULE
      TA0CCR1  = 0;                             // will be used for burst alignnment
      TA0CCR2  = 0;                             // will be used for expiration counter
      TA0CTL   = TASSEL_2 + MC_1 + TACLR + ID_3;// SMCLK, Up to CCR0, clear TB0R, div/8
    
      return;
    }
    
    
    /******************************************************************************
     * @fn         hal_timer_adjust
     *
     * @brief      Align packet timer by modifying the main count value
     *
     *
     * input parameters
     *
     * @param       unsigned int adjust - modify the timer count value
     *
     * output parameters
     *
     * @return      void
     *
     */
    void hal_timer_adjust(unsigned int adjust) {
    
      TA0R = adjust;
    
      return;
    }
    
    /******************************************************************************
     * @fn         hal_timer_get
     *
     * @brief      Get the current timer count value
     *
     *
     * input parameters
     *
     * @param       void
     *
     * output parameters
     *
     * @return      unsigned int timer count value
     *
     */
    unsigned int hal_timer_get(void) {
    
    	return(TA0R);
    }
    
    
    /******************************************************************************
     * @fn         hal_timer_get_time
     *
     * @brief      Calculate the time in seconds and milliseconds after last reset
     *
     *
     * input parameters
     *
     * @param       unsigned long *sec - pointer to seconds counter value
     *              unsigned long *ms  - pointer to millisecond count value
     *
     * output parameters
     *
     * @return      unsigned int timer count value
     *
     */
    unsigned int hal_timer_get_time(unsigned long *sec, unsigned long *ms) {
    
    	unsigned int ms_uint;
    	unsigned long ms_long;
    
    	/* grap the time counter values from the global value */
    	*sec = time_counter;
    
    	/* grap the time counter value (1/250000) second resolution */
    	ms_uint = TA0R;
    
    	/* convert information to milliseconds */
    	ms_long = (unsigned long)ms_uint * 1000;
    	ms_long = ms_long>>18;
    	*ms = ms_long;
    
    	/* return count value */
    	return(ms_uint);
    }
    
    /******************************************************************************
     * @fn         hal_timer_stop
     *
     * @brief      Stop the timer
     *
     *
     * input parameters
     *
     * @param       void
     *
     * output parameters
     *
     * @return      void
     *
     */
    
    void hal_timer_stop(void) {
    
      /* clear timer configuration register, stopping the timer */
      TA0CTL = 0;
    
      return;
    }
    
    /******************************************************************************
     * @fn         hal_timer_expire
     *
     * @brief      wait until the timer master count expires (for packet alignment)
     *
     *
     * input parameters
     *
     * @param       void
     *
     * output parameters
     *
     * @return      void
     *
     */
    void hal_timer_expire(void) {
    
      /* enable timer interrupt */
      TA0CCTL1 = CCIE;
    
      /* enter low power mode and wait */
      _BIS_SR(LPM0_bits + GIE);
    
      /* disable interrupt again */
      TA0CCTL1 = 0;
    
      return;
    }
    
    /******************************************************************************
     * @fn         hal_timer_wait
     *
     * @brief      wait an asigned amount of time or until a GPIO event (packet)
     *
     *
     * input parameters
     *
     * @param       unsigned int time  - maximum time to wait
     *
     * output parameters
     *
     * @return      unsigned int time - actual time waited
     *
     */
    unsigned int hal_timer_wait(unsigned int time) {
      unsigned int wait_count, TAR_init;
    
      TAR_init = TA0R;   // store the current value of the timer register
      wait_count = TAR_init + time;
    
      // if the requested wait time exceeds the TACCR0 (max value) then make a loop
      while(wait_count > TA0CCR0) {
    	  // configure the timeout for 1 less than the master clock
    	  TA0CCR2  = TA0CCR0-1;
    
    	  // calculate the remaining wait time remaining
    	  wait_count = wait_count - (TA0CCR2 - TAR_init);
    
    	  // do not count the initial timer values more that once, zero it out
    	  timer_event = 0;
    	  TAR_init = 0;
    
    	  // enable interupts and wait for timer (or CC1x GDO ISR)
    	  TA0CCTL2 = CCIE;                       // interrupt enabled
    	  _BIS_SR(LPM0_bits + GIE);             // Enter LPM0
    
          // check to see if the timer woke us up or not
    	  if (timer_event == 0)
    		  // it did not, return imidiately and note time actual delay
    		  return (time - (wait_count - TA0R));
      }
    
      // in the case of loop, this executes the remaining wait, in the case of no
      // loop this is the only wait that gets executed
    
      /* define maximum timeout by using timer counter 2 */
      TA0CCR2  = wait_count;
    
      /* enable interrupt */
      TA0CCTL2 = CCIE;
    
      /* enter low power mode and wait for event (timer or radio) */
      _BIS_SR(LPM0_bits + GIE);
    
      /* disable interupts on CCR2 */
      TA0CCTL2 = 0;
    
      /* return the time spend in sleep */
      return (time - (wait_count-TA0R));
    }
    
    /******************************************************************************
     * @fn         TIMERA0_ISR
     *
     * @brief      Timer interrupt service routine
     *
     *
     * input parameters
     *
     * @param       void
     *
     * output parameters
     *
     * @return      void
     *
     */
    HAL_ISR_FUNC_DECLARATION(timer_a1_isr,TIMER0_A1){
    //void __attribute__((interrupt(TIMER0_A1_VECTOR),used)) timer_a1_isr(void){
    //#pragma vector=TIMERA0_VECTOR
    //__interrupt void TIMERA0_ISR(void) {
    	/* Any access, read or write, of the TA0IV register automatically
    	 * resets the highest "pending" interrupt flag. */
    	switch( __even_in_range(TA0IV,14) ) {
        case  TA0IV_NONE: break;               // No interrupt
        case  TA0IV_TACCR1:                    // Used to wake up radio from sleep
          timer_event = TA0IV_TACCR1;
          _BIC_SR_IRQ(LPM3_bits);              // Clear LPM3 bits from 0(SR)
          break;
        case  TA0IV_TACCR2:                    // Use as secondary timer function
          timer_event = TA0IV_TACCR2;
          _BIC_SR_IRQ(LPM3_bits);              // Clear LPM3 bits from 0(SR)
          break;
    /*    case  TA0IV_TACCR3:                    // CCR3 not used
        	break;
        case  TA0IV_TACCR4:                    // CCR4 not used
        	break;
        case  TA0IV_TACCR5:                    // CCR5 not used
        	break;
        case  TA0IV_TACCR6:                    // CCR6 not used
        	break;
        case  TA0IV_TAIFG:                     // IFG not used
        	break;*/
        default:
        	break;
      }
    }
    
    #endif