⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hplcc2430timer1alarmcounterp.nc

📁 Develop Zigbee network real-time Os
💻 NC
字号:
/* * Copyright (c) 2007 University of Copenhagen * All rights reserved. * * 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 University of Copenhagen 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 STANFORD * UNIVERSITY 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. *//** * * @author Martin Leopold <leopold@diku.dk> *//** * Exports Timer1 as Alarm/Counter interfaces *   *   The frequency is just there for show - it doesnt really do anything * * Note: The byte order of the registers i very important: the low * byte must always be read or written first! */generic module HplCC2430Timer1AlarmCounterP( typedef frequency ) {  provides interface Counter<frequency, uint16_t> as Counter;  provides interface Alarm<frequency, uint16_t> as Alarm0;  provides interface Alarm<frequency, uint16_t> as Alarm1;  provides interface Alarm<frequency, uint16_t> as Alarm2;  provides interface Init;} implementation {  /*   * Argh.. Do we know if Timer1.init() has finished by this point?   */  command error_t Init.init() {    T1CCTL1 = 0;    T1CCTL2 = 0;    T1CNTL = 0; T1CNTH = 0;    //T1CTL  = ((T1CTL & ~CC2430_T1CTL_DIV_MASK) | CC2430_TIMER1_DIV_8);    //T1CTL  = ((T1CTL & ~CC2430_T1CTL_DIV_MASK) | CC2430_TIMER1_DIV_32);    //T1CTL  = ((T1CTL & ~CC2430_T1CTL_DIV_MASK) | CC2430_TIMER1_DIV_128);    T1CTL  = ((T1CTL & ~CC2430_T1CTL_DIV_MASK) | CC2430_TIMER1_DIV_1);    // Clear all interrupt flags    T1CTL &= ~(CC2430_T1_CH0IF) & ~(CC2430_T1_CH1IF) & ~(CC2430_T1_CH2IF) & ~(CC2430_T1_OVFIF);    // Compare register 0    T1CCTL0 |= (1 << CC2430_T1CCTLx_MODE); // Mode = compare    //T1CCTL0 |= (1 << CC2430_T1CCTLx_IM) | (1 << CC2430_T1CCTLx_MODE);    // Start compare running    T1IE   = 1;   // enable events    TIMIF |= _BV(CC2430_TIMIF_OVFIM); // Enable overflow int    T1CCTL0 |= 0x40; // Compare int on    T1CTL  = (T1CTL & ~CC2430_T1CTL_MODE_MASK) | CC2430_TIMER1_MODE_FREE;    //T1CCTL0 &= ~0x40; // Compare int off    //T1CTL |= 1; //CC2430_TIMER1_MODE_FREE    //T1CTL &= ~2; //CC2430_TIMER1_MODE_FREE    return SUCCESS;  } // ORDER IS IMPORTANT HERE! Allways read Low register first!!#define GET_NOW(p) ((uint8_t*)&p)[1]=T1CNTL;\                   ((uint8_t*)&p)[0]=T1CNTH/********************************************************************* *                              Alarm 0                              * *********************************************************************/   async command void Alarm0.stop(){   T1CCTL0 &= ~_BV(CC2430_T1CCTLx_IM) ;  }  async command bool Alarm0.isRunning(){ return (T1CCTL0 & _BV(CC2430_T1CCTLx_IM)); }  async command uint16_t Alarm0.getAlarm(){    uint16_t r;    // Order is important!! Read low first!!    ((uint8_t*)&r)[1] = T1CC0L;    ((uint8_t*)&r)[0] = T1CC0H;    return (r);   }  async command uint16_t Alarm0.getNow(){    uint16_t r;    /*    ((uint8_t*)&r)[1] = T1CNTL;      ((uint8_t*)&r)[0] = T1CNTH;*/    GET_NOW(r);    return r;  }  async command void Alarm0.start(uint16_t dt){    uint16_t now;    /*now = call Alarm0.getNow();    ((uint8_t*)&now)[1] = (uint8_t) T1CNTL;    ((uint8_t*)&now)[0] = (uint8_t) T1CNTH;*/    GET_NOW(now);    call Alarm0.startAt( now, dt );  }  async command void Alarm0.startAt(uint16_t t0, uint16_t dt){    uint16_t set, now, elapsed;    atomic {      GET_NOW(now);      /*((uint8_t*)&now)[1] = (uint8_t) T1CNTL;    ((uint8_t*)&now)[0] = (uint8_t) T1CNTH;*/      elapsed = now - t0; // This number wraps if counter has wrapped         if( elapsed >= dt )  {    set = now + 5; // elapse in 5 tics      } else {    uint16_t remaining = dt - elapsed;    if( remaining <= 5 )  {      set = now + 5; // elapse in 5 tics    } else {      set = remaining + now;    }      }    // Order is important!! Allways write Low byte first!!    T1CC0L = (uint8_t) ((uint8_t*)&set)[1];    T1CC0H = (uint8_t) ((uint8_t*)&set)[0];    T1CCTL0 |= _BV(CC2430_T1CCTLx_IM);  // Enable interrupt mask    }    return;  }/********************************************************************* *                              Alarm 1                              * *********************************************************************/   async command void Alarm1.stop(){   T1CCTL1 &= ~_BV(CC2430_T1CCTLx_IM) ;  }  async command bool Alarm1.isRunning(){ return (T1CCTL1 & _BV(CC2430_T1CCTLx_IM)); }  async command uint16_t Alarm1.getAlarm(){    uint16_t r;    // Order is important!! Read low first!!    ((uint8_t*)&r)[1] = T1CC1L;    ((uint8_t*)&r)[0] = T1CC1H;    return (r);   }  async command uint16_t Alarm1.getNow(){    uint16_t r;    GET_NOW(r);    return r;  }  async command void Alarm1.start(uint16_t dt){    uint16_t now;    GET_NOW(now);    call Alarm1.startAt( now, dt );  }  async command void Alarm1.startAt(uint16_t t0, uint16_t dt){    uint16_t set, now, elapsed;    atomic {      GET_NOW(now);      elapsed = now - t0; // This number wraps if counter has wrapped         if( elapsed >= dt )  {    set = now + 5; // elapse in 5 tics      } else {    uint16_t remaining = dt - elapsed;    if( remaining <= 5 )  {      set = now + 5; // elapse in 5 tics    } else {      set = remaining + now;    }      }    // Order is important!! Allways write Low byte first!!    T1CC1L = (uint8_t) ((uint8_t*)&set)[1];    T1CC1H = (uint8_t) ((uint8_t*)&set)[0];    T1CCTL1 |= _BV(CC2430_T1CCTLx_IM);  // Enable interrupt mask    }    return;  }/********************************************************************* *                              Alarm 2                              * *********************************************************************/   async command void Alarm2.stop(){   T1CCTL2 &= ~_BV(CC2430_T1CCTLx_IM) ;  }  async command bool Alarm2.isRunning(){ return (T1CCTL2 & _BV(CC2430_T1CCTLx_IM)); }  async command uint16_t Alarm2.getAlarm(){    uint16_t r;    // Order is important!! Read low first!!    ((uint8_t*)&r)[1] = T1CC2L;    ((uint8_t*)&r)[0] = T1CC2H;    return (r);   }  async command uint16_t Alarm2.getNow(){    uint16_t r;    GET_NOW(r);    return r;  }  async command void Alarm2.start(uint16_t dt){    uint16_t now;    GET_NOW(now);    call Alarm2.startAt( now, dt );  }  async command void Alarm2.startAt(uint16_t t0, uint16_t dt){    uint16_t set, now, elapsed;    atomic {      GET_NOW(now);      elapsed = now - t0; // This number wraps if counter has wrapped         if( elapsed >= dt )  {    set = now + 5; // elapse in 5 tics      } else {    uint16_t remaining = dt - elapsed;    if( remaining <= 5 )  {      set = now + 5; // elapse in 5 tics    } else {      set = remaining + now;    }      }    // Order is important!! Allways write Low byte first!!    T1CC2L = (uint8_t) ((uint8_t*)&set)[1];    T1CC2H = (uint8_t) ((uint8_t*)&set)[0];    T1CCTL2 |= _BV(CC2430_T1CCTLx_IM);  // Enable interrupt mask    }    return;  }/********************************************************************* *                              Junk                                 * *********************************************************************/       /*    now = GET_NOW();    elapsed now - t0;    //((uint8_t*)&now)[0] = (uint8_t) T1CNTH;    //((uint8_t*)&now)[1] = (uint8_t) T1CNTL;    stor = now + dt; //t0 + dt;    set = (uint16_t) (stor % 0xFFFF);       T1CC0H = (uint8_t) ((uint8_t*)&set)[0];       T1CC0L = (uint8_t) ((uint8_t*)&set)[1];       T1CCTL0 |= _BV(CC2430_T1CCTLx_IM);  // Enable interrupt mask     return;      */          /* This stuff is stolen from the atm128 platfom (David Gay) */     /* Leave it here for now ...*/    //    uint32_t expires, guardedExpires, stor;    //uint16_t compare, more_now;    //const uint8_t mindt = 2;    //now = call Alarm0.getNow();//    ((uint8_t*)&now)[0] = (uint8_t) T1CNTH;//    ((uint8_t*)&now)[1] = (uint8_t) T1CNTL;////    if (dt < mindt)//      dt = mindt;////    expires = t0 + dt;////    guardedExpires = expires - mindt;//    if (t0 <= now)     {//      //if it's in the past or the near future, fire now (i.e., test//      //     guardedExpires <= now in wrap-around arithmetic).//  if (guardedExpires >= t0 && // if it wraps, it's > now//      guardedExpires <= now) {//    //compare = call Alarm0.getNow() + mindt;//    ((uint8_t*)&more_now)[0] = (uint8_t) T1CNTH;//    ((uint8_t*)&more_now)[1] = (uint8_t) T1CNTL;//    compare = more_now + mindt;//  }//  else//    compare = expires;//      }//    else//      {//  // again, guardedExpires <= now in wrap-around arithmetic//  if (guardedExpires >= t0 || // didn't wrap so < now//      guardedExpires <= now) {//    //compare = call Alarm0.getNow() + mindt ;//    ((uint8_t*)&more_now)[0] = (uint8_t) T1CNTH;//    ((uint8_t*)&more_now)[1] = (uint8_t) T1CNTL;//    compare = more_now + mindt;//  }//  else//    compare = expires;//      }//    T1CC0H = (uint8_t) ((uint8_t*)&compare)[0];//    T1CC0L = (uint8_t) ((uint8_t*)&compare)[1];//    //T1CTL  &= ~CC2430_T1_CH0IF;          // Clear IF//    //T1CCTL0 |= _BV(CC2430_T1CCTLx_IM);  // Enable interrupt mask (IM)////    return;///********************************************************************* *                              Counter                              * *********************************************************************/   async command uint16_t Counter.get() {    uint16_t r;    ((uint8_t*)&r)[1] = T1CNTL;    ((uint8_t*)&r)[0] = T1CNTH;    return r;  }  async command bool Counter.isOverflowPending() {    return( T1CTL & CC2430_T1_OVFIF );  }  async command void Counter.clearOverflow()     {    T1CTL &= ~CC2430_T1_OVFIF;  }/********************************************************************* *                              Interrupts                           * *********************************************************************/   /*   * The interrupt handler will be executed regardless of which   * interrupt has been issued. Since the compare registers are likely   * to fire with masks off - we need to check that this particular   * interrupt is actually enabled.   */  MCS51_INTERRUPT(SIG_T1) {     atomic{      if ( (T1CCTL2 & _BV(CC2430_T1CCTLx_IM)) && (T1CTL & CC2430_T1_CH2IF) ) {    T1CTL   &= ~_BV(CC2430_T1CTL_CH2IF);   // Clear IF    T1CCTL2 &= ~_BV(CC2430_T1CCTLx_IM);    // Clear IM - startAt sets it    signal Alarm2.fired();      }      if ( (T1CCTL1 & _BV(CC2430_T1CCTLx_IM)) && (T1CTL & CC2430_T1_CH1IF) ) {    T1CTL   &= ~_BV(CC2430_T1CTL_CH1IF);   // Clear IF    T1CCTL1 &= ~_BV(CC2430_T1CCTLx_IM);    // Clear IM - startAt sets it    signal Alarm1.fired();      }      if ( (T1CCTL0 & _BV(CC2430_T1CCTLx_IM)) && (T1CTL & CC2430_T1_CH0IF) ) {    T1CTL   &= ~_BV(CC2430_T1CTL_CH0IF);    // Clear IF    T1CCTL0 &= ~_BV(CC2430_T1CCTLx_IM);     // Clear IM - startAt sets it    signal Alarm0.fired();      }      if (T1CTL & CC2430_T1_OVFIF) {    T1CTL   &= ~_BV(CC2430_T1CTL_OVFIF);   // Clear IF    signal Counter.overflow();      }    }  } default async event void Counter.overflow() { } default async event void Alarm0.fired() { } default async event void Alarm1.fired() { } default async event void Alarm2.fired() { }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -