source: trunk/firmware/openos/bsp/telosb/radiotimer.c @ 1461

Revision 1461, 4.0 KB checked in by thomas, 15 months ago (diff)

place CPU in sleep mode while waiting for bsp modules to be ready

RevLine 
[1455]1/**
2\brief TelosB-specific definition of the "radiotimer" bsp module.
3
4\author Thomas Watteyne <watteyne@eecs.berkeley.edu>, February 2012.
5*/
6
7#include "msp430f1611.h"
[1457]8#include "stdio.h"
9#include "string.h"
[1455]10#include "radiotimer.h"
11
12//=========================== variables =======================================
13
[1457]14typedef struct {
[1459]15   radiotimer_compare_cbt    overflowCb;
16   radiotimer_compare_cbt    compareCb;
17   radiotimer_capture_cbt    startFrameCb;
18   radiotimer_capture_cbt    endFrameCb;
[1457]19} radiotimer_vars_t;
20
21radiotimer_vars_t radiotimer_vars;
22
[1455]23//=========================== prototypes ======================================
24
25//=========================== public ==========================================
26
[1457]27void radiotimer_init() {
28   // clear local variables
29   memset(&radiotimer_vars,0,sizeof(radiotimer_vars_t));
30}
31
[1459]32void radiotimer_setOverflowCb(radiotimer_compare_cbt cb) {
33   radiotimer_vars.overflowCb     = cb;
[1457]34}
35
[1459]36void radiotimer_setCompareCb(radiotimer_compare_cbt cb) {
37   radiotimer_vars.compareCb      = cb;
[1457]38}
39
[1459]40void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb) {
41   radiotimer_vars.startFrameCb = cb;
[1457]42}
43
[1459]44void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb) {
45   radiotimer_vars.endFrameCb   = cb;
46}
47
[1457]48void radiotimer_start(uint16_t period) {
49   // radio's SFD pin connected to P4.1
50   P4DIR   &= ~0x02; // input
51   P4SEL   |=  0x02; // in CCI1a/B mode
[1455]52   
[1457]53   // CCR0 contains period of counter
54   // do not interrupt when counter reaches TBCCR0, but when it resets
55   TBCCR0   =  period;
[1455]56   
[1457]57   // CCR1 in capture mode
58   TBCCTL1  =  CM_3+SCS+CAP+CCIE;
59   TBCCR1   =  0;
[1455]60   
[1457]61   // CCR2 in compare mode
62   TBCCTL2  =  0;
63   TBCCR2   =  0;
[1455]64   
65   // start counting
[1457]66   TBCTL    =  TBIE+TBCLR;                       // interrupt when counter resets
67   TBCTL   |=  MC_1+TBSSEL_1;                    // up mode, clocked from ACLK
[1455]68}
69
70void radiotimer_schedule(uint16_t offset) {
71   // offset when to fire
[1457]72   TACCR2   =  offset;
73   
74   // enable compare interrupt (this also cancels any pending interrupts)
75   TACCTL2  =  CCIE;
[1455]76}
77
78void radiotimer_cancel() {
[1457]79   // reset compare value (also resets interrupt flag)
80   TACCR2   =  0;
81   
82   // disable compare interrupt
83   TACCTL2 &= ~CCIE;
[1455]84}
85
86inline uint16_t radiotimer_getCapturedTime() {
[1457]87   return TACCR1;
[1455]88}
89
90//=========================== private =========================================
[1457]91
92//=========================== interrupt handlers ==============================
93
94/**
95\brief TimerB CCR1-6 interrupt service routine
96*/
97#pragma vector=TIMERB1_VECTOR
98__interrupt void timerb1_ISR (void) {
99   uint16_t tbiv_local;
100   
101   // reading TBIV returns the value of the highest pending interrupt flag
102   // and automatically resets that flags. We therefore copy its value to the
103   // tbiv_local local variable exactly once. If there is more than one
104   // interrupt pending, we will reenter this function after having just left
105   // it.
106   tbiv_local = TBIV;
107   
108   switch (tbiv_local) {
109      case 0x0002: // CCR1 fires
[1460]110         if (TBCCTL1 & CCI) {
[1457]111            // SFD pin is high: this was the start of a frame
[1459]112            if (radiotimer_vars.startFrameCb!=NULL) {
113               radiotimer_vars.startFrameCb(TBCCR1);
[1457]114            }
115         } else {
116            // SFD pin is low: this was the end of a frame
[1459]117            if (radiotimer_vars.endFrameCb!=NULL) {
118               radiotimer_vars.endFrameCb(TBCCR1);
[1457]119            }
120         }
121         break;
122      case 0x0004: // CCR2 fires
[1459]123         if (radiotimer_vars.compareCb!=NULL) {
124            radiotimer_vars.compareCb();
125         }
[1457]126         break;
127      case 0x0006: // CCR3 fires
128         break;
129      case 0x0008: // CCR4 fires
130         break;
131      case 0x000a: // CCR5 fires
132         break;
133      case 0x000c: // CCR6 fires
134         break;
135      case 0x000e: // timer overflow
136         if (radiotimer_vars.overflowCb!=NULL) {
137            radiotimer_vars.overflowCb();
138         }
139         break;
140   }
[1461]141   
142   __bic_SR_register_on_exit(CPUOFF);  // restart CPU
[1457]143}
144
145
Note: See TracBrowser for help on using the repository browser.