Select Git revision
-
Adam Procter authoredAdam Procter authored
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