X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=doc%2Fhtml%2Ftep102.html;h=3e7e8dc2773dda5cf73bf2f514d259b906d7a76c;hb=d30405c532321fd306f685545094c57132123e94;hp=48f1aff21c2d1917d0808a05d1e0532439ccdb71;hpb=826bb539a6c489db5b216e7326bf693ec67d15e5;p=tinyos-2.x.git diff --git a/doc/html/tep102.html b/doc/html/tep102.html index 48f1aff2..3e7e8dc2 100644 --- a/doc/html/tep102.html +++ b/doc/html/tep102.html @@ -3,7 +3,7 @@ - + Timers +

Timers

@@ -295,22 +291,13 @@ ul.auto-toc { - + - - - - - - - -
Type:Documentary
Status:Draft
Final
TinyOS-Version:2.x
Author: Cory Sharp, Martin Turon, David Gay
Draft-Created:22-Sep-2004
Draft-Version:1.7
Draft-Modified:2006-12-12
Draft-Discuss:TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu>
-

Note

This memo documents a part of TinyOS for the TinyOS Community, and @@ -318,15 +305,15 @@ requests discussion and suggestions for improvements. Distribution of this memo is unlimited. This memo is in full compliance with TEP 1.

-
-

Abstract

+
+

Abstract

This TEP proposes a Timer design that supports common timing requirements both in precision and width across common hardware configurations. This TEP focuses on aligning the Timer abstraction with the three-layer Hardware Abstraction Architecture (HAA).

-
-

1. Introduction

+
+

1. Introduction

Most microcontrollers offer a rich timer system, with features like:

  • several counters, possibly of different widths, with multiple clocking options
  • @@ -340,7 +327,7 @@ the timer hardware on some current TinyOS platforms.

    platform-independent fashion. Instead, following the principles of the HAA[_tep2], each microcontroller should expose all this functionality via components and interfaces at the HPL and, where appropriate, HAL levels. -However, two aspects of timers are sufficiently common and important +However, two aspects of timers are sufficiently common and important that they should be made available in a well-defined way: measuring time, and triggering (possibly repeating) events at specific times. The rest of this TEP specifies:

    @@ -349,7 +336,7 @@ of this TEP specifies:

    events (2. Interfaces)
  • guidelines on how each microcontroller's HAL SHOULD expose its timer hardware in terms of the above interfaces (3. HAL guidelines)
  • -
  • what components a microcontroller's timer HIL MUST implement +
  • what components a microcontroller's timer HIL MUST implement (4. HIL requirements)
  • a set of utility components whose use simplifies building the components specified by the HAL guidelines and HIL requirements (5. Utility components)
  • @@ -357,13 +344,13 @@ specified by the HAL guidelines and HIL requirements (This TEP ends with appendices documenting, as an example, the mica2 timer subsystem implementation.

-
-

2. Interfaces

+
+

2. Interfaces

Before presenting the interfaces (2.2), we start with a general discussion of the issues of precision, width and accuracy in timer interfaces (2.1).

-
-

2.1 Precision, Width and Accuracy.

+
+

2.1 Precision, Width and Accuracy

Three fundamental properties of timers are precision, width and accuracy.

Examples of precision are millisecond, a cycle of a 32kHz clock, and @@ -371,18 +358,19 @@ microseconds. All precisions presented in this TEP are in "binary" units with respect to one second. That is, one second contains 1024 binary milliseconds, 32768 32kHz ticks, or 1048576 microseconds. This TEP emphasizes millisecond and 32kHz tick precisions while -reasonably accommodating other precisions.

+reasonably accommodating other precisions. The use of "binary" units +is motivated by the common availability of hardware clocks driven +by a 32768Hz crystal.

Examples of widths are 8-bit, 16-bit, 32-bit, and 64-bit. The width -for timer interfaces and components SHOULD be 32-bits. That is, for -lack of a good reason, timer interfaces should expose a 32-bit -interface. In a number of circumstances there are good reasons not -to expose a 32-bit interface. This TEP emphasizes 32-bit widths -while reasonably accommodating other widths.

+for timer interfaces and components SHOULD be 32-bits. This TEP +emphasizes 32-bit widths while reasonably accommodating other widths - +a particular platform may have good reasons not to expose a 32-bit +interface.

Accuracy reflects how closely a component conforms to the precision it claims to provide. Accuracy is affected by issues such as clock drift (much higher for internal vs crystal oscillators) and hardware limitations. As an example of hardware limitations, a mica2 clocked at 7.37MHz cannot offer an -exact microsecond timer -- the closest it can come is 7.37MHz/8. Rather +exact binary microsecond timer -- the closest it can come is 7.37MHz/8. Rather than introduce a plethora of precisions, we believe it is often best to pick the existing precision closest to what can be provided, along with appropriate documentation. However, the accuracy MUST remain reasonable: @@ -394,18 +382,18 @@ interfaces with different precision or width mutually incompatible. It also allows user code to clearly express and understand the precision and width for a given timer interface. Accuracy is not reflected in the interface type.

-

Precision is expressed as an empty type -- TMilli, T32khz, and +

Precision is expressed as a dummy type -- TMilli, T32khz, and TMicro -- written in the standard Timer.h header like this:

-typedef struct { } TMilli; // 1024 ticks per second
-typedef struct { } T32khz; // 32768 ticks per second
-typedef struct { } TMicro; // 1048576 ticks per second
+typedef struct { int notUsed; } TMilli; // 1024 ticks per second
+typedef struct { int notUsed; } T32khz; // 32768 ticks per second
+typedef struct { int notUsed; } TMicro; // 1048576 ticks per second
 

Note that the precision names are expressed as either frequency or period, whichever is convenient.

-
-

2.2 Timer interfaces

+
+

2.2 Timer interfaces

This TEP proposes these timer interfaces:

 interface Counter< precision_tag, size_type >
@@ -419,13 +407,9 @@ applications and use a fixed width of 32-bits.  The Alarm, BusyWait,
 and Counter interfaces are used by the TinyOS timer system and
 advanced user components.

-
-

Counter

-

A Counter component will increase the width of a low-level hardware timer -by wrapping the overflow event and incrementing its higher order bits. -These higher order bits are considered extra state over the HPL register -layer, and therefore qualify all Counters as HAL components. -The Counter interface returns the current time and provides commands +

+

Counter

+

The Counter interface returns the current time and provides commands and an event for managing overflow conditions. These overflow commands and events are necessary for properly deriving larger width Counters from smaller widths.

@@ -439,24 +423,22 @@ interface Counter<precision_tag,size_type> }
-
get()
+
get()
return the current time.
-
isOverflowPending()
+
isOverflowPending()
return TRUE if the overflow flag is set for this counter, i.e., if and -only if an overflow interrupt will occur after the outermost atomic +only if an overflow event will occur after the outermost atomic block exits. Return FALSE otherwise. This command only returns the -state of the overflow flag and causes no side effect. It is expected -that the underlying hardware platform sets the overflow flag when -appropriate.
-
clearOverflow()
-
cancel the pending overflow interrupt clearing the overflow flag.
-
overflow()
+state of the overflow flag and causes no side effect. +
clearOverflow()
+
cancel the pending overflow event clearing the overflow flag.
+
overflow()
signals that an overflow in the current time. That is, the current time has wrapped around from its maximum value to zero.
-
-

Alarm

+
+

Alarm

Alarm components are extensions of Counters that signal an event when their compare register detects the alarm time has been hit. All commands and events of the Alarm interface are asynchronous (or @@ -479,29 +461,33 @@ interface Alarm<precision_tag,size_type> }

-
start(dt)
+
start(dt)
cancel any previously running alarm and set to fire in dt time units from the time of invocation. The alarm will only fire once then stop.
-
stop()
+
stop()
cancel any previously running alarm.
-
fired()
-
signals that the alarm has occurred.
-
isRunning()
+
fired()
+
signals that the alarm has expired.
+
isRunning()
return TRUE if the alarm has been started and has not been cancelled or has not yet fired. FALSE is returned otherwise.

startAt(t0,dt)

-cancel any previously running alarm and set to fire at time t1 = +

cancel any previously running alarm and set to fire at time t1 = t0+dt. This form allows a delay to be anchored to some time t0 taken before the invocation of startAt. The timer subsystem uses this form internally, to be able to use of the full width of an alarm while also -detecting when a short alarm elapses prematurely.

+detecting when a short alarm elapses prematurely.

+

The time t0 is always assumed to be in the past. A value of t0 +numerically greater than the current time (returned by getNow()) +represents a time from before the last wraparound.

+
-
getNow()
+
getNow()
return the current time in the precision and width of the alarm.
-
getAlarm()
+
getAlarm()
return the time the currently running alarm will fire or the time that the previously running alarm was set to fire. getAlarm can be used with startAt to set an alarm from the previous alarm time, @@ -509,15 +495,15 @@ as in startAt(getAlarm(),dt). This pattern is used within the fired() event to construct periodic alarms.
-
-

BusyWait

+
+

BusyWait

The BusyWait interface allows for very short synchronous delays. BusyWait should be used sparingly and when an Alarm would not be reasonably efficient or accurate. The BusyWait interface replaces the TOSH_uwait macro from TinyOS 1.x.

BusyWait blocks for no less than the specified amount of time. No explicit upper bound is imposed on the enacted delay, though it is -expected the underlying implementation spins in a busy loop until +expected that the underlying implementation spins in a busy loop until the specified amount of time has elapsed.

 interface BusyWait<precision_tag,size_type>
@@ -530,8 +516,8 @@ interface BusyWait<precision_tag,size_type>
 
block until at least dt time units have elapsed
-
-

LocalTime

+
+

LocalTime

The LocalTime interface exposes a 32-bit counter without overflow utilities. This is primarily for application code that does not care about overflow conditions.

@@ -542,12 +528,12 @@ interface LocalTime<precision_tag> }
-
get()
+
get()
return the current time.
-
-

Timer

+
+

Timer

All commands and events of the Timer interface are synchronous (or in "task context"). The Timer interface provides a set of "basic" commands for common usage and provides a set of "extended" commands @@ -572,44 +558,50 @@ interface Timer<precision_tag> }

-
startPeriodic(dt)
+
startPeriodic(dt)
cancel any previously running timer and set to fire in dt time units from the time of invocation. The timer will fire periodically every dt time units until stopped.
-
startOneShot(dt)
+
startOneShot(dt)
cancel any previously running timer and set to fire in dt time units from the time of invocation. The timer will only fire once then stop.
-
stop()
+
stop()
cancel any previously running timer.
fired()
-
signals that the timer has occurred.
-
isRunning()
+
signals that the timer has expired (one-shot) or repeated (periodic).
+
isRunning()
return TRUE if the timer has been started and has not been cancelled -and has not fired for the case of one-shot timers. One a periodic +and has not fired for the case of one-shot timers. Once a periodic timer is started, isRunning will return TRUE until it is cancelled.
-
isOneShot()
+
isOneShot()
return TRUE if the timer is a one-shot timer. Return FALSE otherwise if the timer is a periodic timer.
-
startPeriodicAt(t0,dt)
-
cancel any previously running timer and set to fire at time t1 = +
startPeriodicAt(t0,dt)
+

cancel any previously running timer and set to fire at time t1 = t0+dt. The timer will fire periodically every dt time units until -stopped.

-
startOneShotAt(t0,dt)
-
cancel any previously running timer and set to fire at time t1 = -t0+dt. The timer will fire once then stop.
-
getNow()
+stopped.

+

As with alarms, the time t0 is always assumed to be in the past. A +value of t0 numerically greater than the current time (returned by +getNow()) represents a time from before the last wraparound.

+ +
startOneShotAt(t0,dt)
+

cancel any previously running timer and set to fire at time t1 = +t0+dt. The timer will fire once then stop.

+

t0 is as in startPeriodicAt.

+
+
getNow()
return the current time in the precision and width of the timer.
-
gett0()
+
gett0()
return the time anchor for the previously started timer or the time of the previous event for periodic timers.
-
getdt()
+
getdt()
return the delay or period for the previously started timer.
-
-

3. HAL guidelines

+
+

3. HAL guidelines

Platforms SHOULD expose their relevant timing capabilities using standard Alarm and Counter interfaces. The design pattern presented here defines a component naming convention to allow platform @@ -629,12 +621,12 @@ generic configuration Alarm${P}${W}C() provides interface Alarm< T${P}, uint${W}_t >; } -

Instantiating an Alarm${P}${W}C component provides a new and -independent Alarm. If the platform presents a limited number of -Alarm resources, then allocating more Alarms in an application than -are available for the platform SHOULD produce a compile-time error. -See Appendix B for an example of how to make allocatable Alarms that -are each implemented on independent hardware timers.

+

Instantiating an Alarm${P}${W}C component provides a new and independent +Alarm. If the platform presents a limited number of Alarm resources, +then allocating more Alarms in an application than are available for the +platform SHOULD produce a compile-time error. See Appendices B and C +for an example of how to make allocatable Alarms that are each +implemented on independent hardware timers.

For example, if a platform has an 8-bit 32kHz counter and three 8-bit 32kHz alarms, then the Counter and Alarm interfaces for ${P}=32khz and ${W}=16 are:

@@ -649,35 +641,40 @@ generic configuration Alarm32khz8C() provides interface Alarm< T32khz, uint8_t >; } -

This pattern MAY be used to defined components for the platform that -are mutually incompatible in single application. Incompatible +

This pattern MAY be used to define components for the platform that +are mutually incompatible in a single application. Incompatible components SHOULD produce compile-time errors when compiled together.

-
-

4. HIL requirements

-
-
The following component MUST be provided on all platforms::
-
HilTimerMilliC -BusyWaitMicroC
-
-
-

HilTimerMilliC

+
+

4. HIL requirements

+

The following component MUST be provided on all platforms

+
+HilTimerMilliC
+BusyWaitMicroC
+
+

Both of these components use "binary" units, i.e., 1/1024s for +HilTimerMilliC and 1/1048576s for BusyWaitMicroC. Components using +other precisions (e.g., regular, non-binary milliseconds) MAY also be +provided.

+
+

HilTimerMilliC

 configuration HilTimerMilliC
 {
   provides interface Init;
   provides interface Timer<TMilli> as TimerMilli[ uint8_t num ];
+  provides interface LocalTime<TMilli>;
 }
 

A new timer is allocated using unique(UQ_TIMER_MILLI) to obtain a new unique timer number. This timer number is used to index the TimerMilli parameterised interface. UQ_TIMER_MILLI is defined in -Timer.h. HilTimerMilliC is used by the generic component -TimerMilliC found in tos/system/.

+Timer.h. HilTimerMilliC is used by the LocalTimeMilliC component and the +TimerMilliC generic component, both found in tos/system/

-
-

BusyWaitMicroC

+
+

BusyWaitMicroC

 configuration BusyWaitMicroC
 {
@@ -690,8 +687,8 @@ delay is small and setting a timer or alarm would be impractical,
 inefficient or insufficiently precise.

-
-

5. Utility components

+
+

5. Utility components

A number of platform independent generic components are provided to help implementers and advanced users of the TinyOS timer system:

    @@ -704,8 +701,8 @@ help implementers and advanced users of the TinyOS timer system:

Appendices B and C show how these can be used to help implement the timer HAL and HIL.

-
-

AlarmToTimerC

+
+

AlarmToTimerC

AlarmToTimerC converts a 32-bit Alarm to a Timer.

 generic component AlarmToTimerC( typedef precision_tag )
@@ -715,8 +712,8 @@ generic component AlarmToTimerC( typedef precision_tag )
 }
 
-
-

BusyWaitCounterC

+
+

BusyWaitCounterC

BusyWaitCounterC uses a Counter to block until a specified amount of time elapses.

@@ -728,8 +725,8 @@ generic component BusyWaitC( typedef precision_tag,
 }
 
-
-

CounterToLocalTimeC

+
+

CounterToLocalTimeC

CounterToLocalTimeC converts from a 32-bit Counter to LocalTime.

 generic component CounterToLocalTimeC( precision_tag )
@@ -739,12 +736,12 @@ generic component CounterToLocalTimeC( precision_tag )
 }
 
-
-

TransformAlarmC

+
+

TransformAlarmC

TransformAlarmC decreases precision and/or widens an Alarm. An already widened Counter component is used to help.

-generic component TransformAlarmC( 
+generic component TransformAlarmC(
   typedef to_precision_tag,
   typedef to_size_type @integer(),
   typedef from_precision_tag,
@@ -772,8 +769,8 @@ TransformAlarmC to ensure that all five of its arguments are self
 consistent.  No compile errors are generated if the parameters
 passed to TransformAlarmC are inconsistent.

-
-

TransformCounterC

+
+

TransformCounterC

TransformCounterC decreases precision and/or widens a Counter.

 generic component TransformCounterC(
@@ -791,7 +788,7 @@ generic component TransformCounterC(
 

to_precision_tag and to_size_type describe the final precision and final width for the provided Counter. from_precision_tag and from_size_type describe the precision and width for the source -AlarmFrom. bit_shift_right describes the bit-shift necessary to +CounterFrom. bit_shift_right describes the bit-shift necessary to convert from the used precision to the provided precision. upper_count_type describes the numeric type used to store the additional counter bits. upper_count_type MUST be a type with width @@ -804,8 +801,8 @@ created:

new TransformCounterC( TMilli, uint32_t, T32khz, uint16_t, 5, uint32_t )
-
-

VirtualizeTimerC

+
+

VirtualizeTimerC

VirtualizeTimerC uses a single Timer to create up to 255 virtual timers.

@@ -818,8 +815,8 @@ generic component VirtualizeTimerC( typedef precision_tag, int max_timers )
 
-
-

6. Implementation

+
+

6. Implementation

The definition of the HIL interfaces are found in tinyos-2.x/tos/lib/timer:

    @@ -839,13 +836,12 @@ generic component VirtualizeTimerC( typedef precision_tag, int max_timers )
  • BusyWaitCounterC.nc
  • CounterToLocalTimeC.nc
  • TransformAlarmC.nc
  • -
  • TransformAlarmCounterC.nc
  • TransformCounterC.nc
  • VirtualizeAlarmC.nc
  • VirtualizeTimerC.nc
-

The implementation of Timers for the MSP430 is in +

The implementation of timers for the MSP430 is in tinyos-2.x/tos/chips/msp430/timer:

    @@ -860,7 +856,8 @@ generic component VirtualizeTimerC( typedef precision_tag, int max_timers )
  • CounterMilli16C.nc provides Counter<TMilli,uint16_t>
  • CounterMilli32C.nc provides Counter<TMilli,uint32_t>
  • GpioCaptureC.nc
  • -
  • HilTimerMilliC.nc provides Timer<TMilli> as TimerMilli[uint8_t num]
  • +
  • HilTimerMilliC.nc provides LocalTime<TMilli> and +Timer<TMilli> as TimerMilli[uint8_t num]
  • Msp430AlarmC.nc is generic and converts an MSP430 timer to a 16-bit Alarm
  • Msp430Capture.nc HPL interface definition for MSP430 timer captures
  • Msp430ClockC.nc exposes MSP430 hardware clock initialization
  • @@ -888,9 +885,12 @@ capture/compare special function registers special function registers
+

Implementation of timers for the ATmega128 and PXA27x may be found in +tinyos-2.x/tos/chips/atm128/timer and +tinyos-2.x/tos/chips/pxa27x/timer respectively.

-
-

7. Author's Address

+
+

7. Author's Address

Cory Sharp
Moteiv Corporation
@@ -918,8 +918,8 @@ special function registers
-
-

Appendix A: Timer hardware on various microcontrollers

+
+

Appendix A: Timer hardware on various microcontrollers

  1. Atmega128
  2. @@ -995,8 +995,8 @@ output pin, clear counter, generate interrupt, etc)
-
-

Appendix B: a microcontroller: Atmega 128 timer subsystem

+
+

Appendix B: a microcontroller: Atmega 128 timer subsystem

The Atmega128 exposes its four timers through a common set of interfaces:

    @@ -1026,7 +1026,7 @@ interface HplAtm128Timer<timer_size> async command bool isOn(); //<! Is overflow interrupt on? /// Clock initialization interface - async command void off(); //<! Turn off the clock + async command void off(); //<! Turn off the clock async command void setScale( uint8_t scale); //<! Turn on the clock async command uint8_t getScale(); //<! Get prescaler setting } @@ -1057,7 +1057,7 @@ interface HplAtm128Capture<size_type> /// Interrupt signals async event void captured(size_type t); //<! Signalled on capture int - /// Interrupt flag utilites: Bit level set/clr + /// Interrupt flag utilites: Bit level set/clr async command void reset(); //<! Clear the capture interrupt flag async command void start(); //<! Enable the capture interrupt async command void stop(); //<! Turn off capture interrupts @@ -1067,8 +1067,32 @@ interface HplAtm128Capture<size_type> async command void setEdge(bool up); //<! True = detect rising edge } -

    These interfaces are provided by four components, corresponding to -each hardware timer: HplAtm128Timer0C through HplAtm128Timer3C.

    +

    These interfaces are provided by four components, corresponding to each +hardware timer: HplAtm128Timer0AsyncC, and HplAtm128Timer0C through +HplAtm128Timer3C. Timers 1 and 3 have three compare registers, so offer +a parameterised HplAtm128Compare interface:

    +
    +configuration HplAtm128Timer1C
    +{
    +  provides {
    +    // 16-bit Timers
    +    interface HplAtm128Timer<uint16_t>   as Timer;
    +    interface HplAtm128TimerCtrl16       as TimerCtrl;
    +    interface HplAtm128Capture<uint16_t> as Capture;
    +    interface HplAtm128Compare<uint16_t> as Compare[uint8_t id];
    +  }
    +}
    +...
    +
    +

    where the id corresponds to the compare register number. The parameterised +interface is only connected for id equal to 0, 1 or 2. Attempts to use +another value cause a compile-time error. This is achieved as follows (code +from the implementation of HplAtm128Timer1C)

    +
    +Compare[0] = HplAtm128Timer1P.CompareA;
    +Compare[1] = HplAtm128Timer1P.CompareB;
    +Compare[2] = HplAtm128Timer1P.CompareC;
    +

    The Atmega128 chip components do not define a HAL, as the timer configuration choices (frequencies, use of input capture or compare output, etc) are platform-specific. Instead, it provides a few generic components @@ -1094,9 +1118,23 @@ generic module Atm128CounterC(typedef frequency_tag, uses interface HplTimer<timer_size> as Timer; } ... +

    As a result of issues arising from using timer 0 in asynchronous mode, +the HAL also offers the following component:

    +
    +generic configuration Atm128AlarmAsyncC(typedef precision, int divider) {
    +  provides {
    +    interface Init @atleastonce();
    +    interface Alarm<precision, uint32_t>;
    +    interface Counter<precision, uint32_t>;
    +  }
    +}
    +...
    +
    +

    which builds a 32-bit alarm and timer over timer 0. divider is used +to initialise the timer0 scaling factor.

-
-

Appendix C: a mote: Mica family timer subsystem

+
+

Appendix C: a mote: Mica family timer subsystem

Members of the mica family (mica2, mica2dot, micaz) use the Atmega128 microprocessor and have external crystals at 4 or 7.37MHz. Additionally, they can be run from an internal oscillator at 1, 2, 4, or 8 MHz. The @@ -1110,21 +1148,23 @@ If undefined, it defaults to a platform-dependent value (4 for mica2dot,

The mica family configures its four timers in part based on the value of this MHZ symbol:

    -
  • Timer 0: divides the external 32768Hz crystal by 32 to build AlarmMilli8C -and AlarmMilli32C (see Section 3). As timer 0 has a single compare -register, these can only be instantiated once. -Timing accuracy is as good as the external crystal.

    +
  • Timer 0: uses Atm128AlarmAsyncC to divide the external 32768Hz crystal +by 32, creating a 32-bit alarm and counter. This alarm and counter is +used to build HilTimerMilliC, using the AlarmToTimerC, +VirtualizeTimerC and CounterToLocalTimeC utility components.

    +

    Timing accuracy is as good as the external crystal.

  • Timer 1: the 16-bit hardware timer 1 is set to run at 1MHz if possible. However, the set of dividers for timer 1 is limited to 1, 8, 64, 256 and 1024. So, when clocked at 2 or 4MHz, a divider of 1 is -selected and timer 1 runs at 2 or 4MHz. To reflect this fact, the +selected and timer 1 runs at 2 or 4MHz. To reflect this fact, the HAL components exposing timer 1 are named CounterOne16C and AlarmOne16C (rather than the CounterMicro16C AlarmMicro16C as suggested in Section 3).

    -

    When building the 32-bit counter and 32-bit alarms, the rate of -timer 1 is adjusted in software to 1MHz. Thus the 32-bit HAL components -for timer are named CounterMicro32C and AlarmMicro32C.

    +

    32-bit microsecond Counters and Alarms, named CounterMicro32C and +AlarmMicro32C, are created from CounterOne16C and +AlarmOne16C using the TransformAlarmC and TransformCounterC +utility components.

    Three compare registers are available on timer1, so up to three instances of AlarmOne16C and/or AlarmMicro32C can be created. The timing accuracy depends on how the mote is clocked:

    @@ -1139,9 +1179,9 @@ accuracy depends on how the mote is clocked:

  • Timer 3: the 16-bit hardware timer 3 is set to run at a rate close to 32768Hz, if possible. As with timer 1, the limited set of dividers makes this impossible at some clock frequencies, so the 16-bit timer 3 HAL -components are named CounterThree16C and AlarmThree16C. As -with timer 1, the rate of timer 3 is adjusted in software when -building the 32-bit counter and 32-bit alarms, giving components +components are named CounterThree16C and AlarmThree16C. As +with timer 1, the rate of timer 3 is adjusted in software to +build 32-bit counter and 32-bit alarms, giving components Counter32khz32C and Alarm32khz32C. As with timer 1, three compare registers, hence up to three instances of Alarm32khz32C and/or AlarmThree16C are available.

    @@ -1150,6 +1190,31 @@ at 31.25kHz (plus clock rate inaccuracy). At 7.37MHz, they run at ~28.8kHz.

+

The automatic allocation of compare registers to alarms (and +corresponding compile-time error when too many compare registers are +used) is achieved as follows. The implementations of AlarmOne16C +and AlarmThree16C use the Atm128AlarmC generic component and +wire it, using unique, to one of the compare registers offered by +HplAtm128Timer1C and HplAtm128Timer3C:

+
+generic configuration AlarmOne16C()
+{
+  provides interface Alarm<TOne, uint16_t>;
+}
+implementation
+{
+  components HplAtm128Timer1C, InitOneP,
+    new Atm128AlarmC(TOne, uint16_t, 3) as NAlarm;
+
+  Alarm = NAlarm;
+  NAlarm.HplAtm128Timer -> HplAtm128Timer1C.Timer;
+  NAlarm.HplAtm128Compare -> HplAtm128Timer1C.Compare[unique(UQ_TIMER1_COMPARE)];
+}
+
+

On the fourth creation of an AlarmOne16C, unique(UQ_TIMER1_COMPARE) +will return 3, causing a compile-time error as discussed in Appendix B +(HplAtm128Timer1C's Compare interface is only defined for values +from 0 to 2).

When an Atmega128 is in any power-saving mode, hardware timers 1, 2 and 3 stop counting. The default Atmega128 power management will enter these power-saving modes even when timers 1 and 3 are enabled, so time as @@ -1158,8 +1223,7 @@ alarms built on timers 1 or 3 are active, the Atmega128 power management will not enter power-saving modes.

The mica family HIL components are built as follows:

    -
  • TimerMilliC: built using AlarmMilli32C (consuming its single compare -register)
  • +
  • HilTimerMilliC: built as described above from hardware timer 0.
  • BusyWaitMicroC: implemented using a simple software busy-wait loop which waits for MHZ cycles per requested microsecond. Accuracy is the same as Timer 1.