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

📄 hplatm128timer0asyncp.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
/* * "Copyright (c) 2005 Stanford University. All rights reserved. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose, without fee, and without written * agreement is hereby granted, provided that the above copyright * notice, the following two paragraphs and the author appear in all * copies of this software. *  * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS." *//** * The TOSSIM implementation of the Atm128 Timer0 counter. It handles * overflow, scaling, and phase considerations. * * @date November 22 2005 * * @author Philip Levis <pal@cs.stanford.edu> * @author Martin Turon <mturon@xbow.com> * @author David Gay <dgay@intel-research.net> */// $Id: HplAtm128Timer0AsyncP.nc,v 1.1 2008/06/12 14:02:20 klueska Exp $/// $Id: HplAtm128Timer2C.nc,#include <Atm128Timer.h>#include <hardware.h>module HplAtm128Timer0AsyncP {  provides {    interface HplAtm128Timer<uint8_t>   as Timer0;    interface HplAtm128TimerCtrl8       as Timer0Ctrl;    interface HplAtm128Compare<uint8_t> as Compare;    interface HplAtm128TimerAsync       as TimerAsync;  }  uses interface ThreadScheduler;}implementation {  bool inOverflow = 0;  uint8_t savedCounter = 0;  void adjust_zero(uint8_t currentCounter);  void cancel_overflow();  sim_event_t* allocate_overflow();  void configure_overflow(sim_event_t* e);  void schedule_new_overflow();  sim_time_t clock_to_sim(sim_time_t t);  sim_time_t sim_to_clock(sim_time_t t);  uint16_t shiftFromScale();  /* lastZero keeps track of the phase of the clock. It denotes the sim   * time at which the underlying clock started, which is needed to   * calculate when compares will occur. */  sim_time_t lastZero = 0;  /** This variable is needed to keep track of when the underlying   *  timer starts, in order to reset lastZero. When oldScale is   *  AVR_CLOCK_OFF and the scale is set to something else, the   *  clock starts ticking. */  uint8_t oldScale = AVR_CLOCK_OFF;    void adjust_zero(uint8_t currentCounter);    void cancel_compare();  sim_event_t* allocate_compare();  void configure_compare(sim_event_t* e);  void schedule_new_compare();  sim_time_t clock_to_sim(sim_time_t t);  sim_time_t sim_to_clock(sim_time_t t);  uint16_t shiftFromScale();  default async event void Compare.fired() { }  AVR_ATOMIC_HANDLER(SIG_OUTPUT_COMPARE0) {    //stabiliseTimer0();    signal Compare.fired();    call ThreadScheduler.interruptPostAmble();  }   default async event void Timer0.overflow() { }  AVR_ATOMIC_HANDLER(SIG_OVERFLOW0) {    inOverflow = TRUE;    signal Timer0.overflow();    inOverflow = FALSE;    call ThreadScheduler.interruptPostAmble();  }    sim_time_t last_zero() {    if (lastZero == 0) {      lastZero = sim_mote_start_time(sim_node());    }    return lastZero;  }  void notify_changed() {    uint8_t newScale = call Timer0.getScale();    if (newScale != AVR_CLOCK_OFF &&	oldScale == AVR_CLOCK_OFF) {      lastZero = sim_time();    }    oldScale = newScale;        schedule_new_compare();  }  sim_time_t notify_clockTicksPerSec() {    return ATM128_TIMER0_TICKSPPS;  }    /**   * If the clock was stopped and has restarted, then   * we need to move the time when the clock was last   * zero to a time that reflects the current settings.   * For example, if the clock was stopped when the counter   * was 52 and then later restarted, then <tt>lastZero</tt>   * needs to be moved forward in time so that the 52   * reflects the current time.   */   void adjust_zero(uint8_t currentCounter) {    sim_time_t now = sim_time();    sim_time_t adjust = currentCounter;    adjust = adjust << shiftFromScale();    adjust = clock_to_sim(adjust);    lastZero = now - adjust;  }    sim_time_t clock_to_sim(sim_time_t t) {    t *= sim_ticks_per_sec();    t /= notify_clockTicksPerSec();    return t;  }  sim_time_t sim_to_clock(sim_time_t t) {    t *= notify_clockTicksPerSec();    t /= sim_ticks_per_sec();    return t;  }    uint16_t shiftFromScale() {    uint8_t scale = call Timer0.getScale();    switch (scale) {    case 0:      return 0;    case 1:      return 0;    case 2:      return 3;    case 3:      return 5;    case 4:      return 6;    case 5:      return 7;    case 6:      return 8;    case 7:      return 10;    default:      return 255;    }      }  sim_event_t* compare;  void timer0_compare_handle(sim_event_t* evt) {    dbg("HplAtm128Timer0AsyncP", "Beginning compare 0x%p at %s\n", evt, sim_time_string());    if (evt->cancelled) {      return;    }    else {      char timeStr[128];      sim_print_now(timeStr, 128);      dbg("HplAtm128Timer0AsyncP", "Handling compare at 0x%p @ %s\n", evt, sim_time_string());            if (READ_BIT(ATM128_TCCR0, WGM01) && !READ_BIT(ATM128_TCCR0, WGM00)) {	dbg("HplAtm128Timer0AsyncP", "%s: CTC is set, clear timer.\n", __FUNCTION__);	call Timer0.set(0);      }      else {	dbg("HplAtm128Timer0AsyncP", "%s: TCCR is 0x%hhx, %i, %i\n", __FUNCTION__, TCCR0, (int)READ_BIT(ATM128_TCCR0, WGM01), (int)READ_BIT(ATM128_TCCR0, WGM00));      }            if (READ_BIT(ATM128_TIMSK, OCIE0)) {	dbg("HplAtm128Timer0AsyncP", "TIFR is %hhx\n", TIFR);	CLR_BIT(ATM128_TIFR, OCF0);	dbg("HplAtm128Timer0AsyncP", "TIFR is %hhx\n", TIFR);	dbg("HplAtm128Timer0AsyncP", "Compare interrupt @ %s\n", timeStr);	SIG_OUTPUT_COMPARE0();      }      else {	SET_BIT(ATM128_TIFR, OCF0);      }      // If we haven't been cancelled      if (!evt->cancelled) {	configure_compare(evt);	sim_queue_insert(evt);      }    }  }  sim_event_t* allocate_compare() {    sim_event_t* newEvent = sim_queue_allocate_event();    dbg("HplAtm128Timer0AsyncP", "Allocated compare at 0x%p\n", newEvent);    newEvent->handle = timer0_compare_handle;    newEvent->cleanup = sim_queue_cleanup_none;    return newEvent;  }    void configure_compare(sim_event_t* evt) {    sim_time_t compareTime = 0;    sim_time_t phaseOffset = 0;    uint8_t timerVal = call Timer0.get();    uint8_t compareVal = call Compare.get();    // Calculate how many counter increments until timer    // hits compare, considering wraparound, and special    // case of complete wraparound.    compareTime = ((compareVal - timerVal) & 0xff);    if (compareTime == 0) {      compareTime = 256;    }    // Now convert the compare time from counter increments    // to simulation ticks, considering the fact that the    // increment actually has a phase offset.    // The +1 is from the timer behavior: if you set OCR0 to be X,    // it will actually fire when TCNT is X+1    compareTime = (compareTime + 1) << shiftFromScale();    compareTime = clock_to_sim(compareTime);    compareTime += sim_time();    // How long into a timer tick was the clock actually reset?    // This covers the case when the compare is set midway between    // a tick, so it will go off a little early    phaseOffset = sim_time();    phaseOffset -= last_zero();    phaseOffset %= clock_to_sim(1 << shiftFromScale());    compareTime -= phaseOffset;          dbg("HplAtm128Timer0AsyncP", "Configuring new compare of %i for %i at time %llu  (@ %llu)\n", (int)compareVal, sim_node(), compareTime, sim_time());        evt->time = compareTime;      }    void schedule_new_compare() {    if (compare != NULL) {      cancel_compare();    }    if (call Timer0.getScale() != AVR_CLOCK_OFF) {      sim_event_t* newEvent = allocate_compare();      configure_compare(newEvent);      compare = newEvent;      sim_queue_insert(newEvent);    }  }    //=== Read the current timer value. ===================================  async command uint8_t  Timer0.get() {    uint8_t rval;    sim_time_t elapsed = sim_time() - last_zero();    elapsed = sim_to_clock(elapsed);    elapsed = elapsed >> shiftFromScale();    rval = (uint8_t)(elapsed & 0xff);    dbg("HplAtm128Timer0AsyncP", "HplAtm128Timer0AsyncP: Getting timer: %hhu\n", rval);    return rval;  }  //=== Set/clear the current timer value. ==============================  /**   * Set/clear the current timer value.   *

⌨️ 快捷键说明

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