<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" />
<title>Analog-to-Digital Converters (ADCs)</title>
<meta name="author" content="Jan-Hinrich Hauer, Philip Levis, Vlado Handziski, David Gay" />
<style type="text/css">
</style>
</head>
<body>
-<div class="document" id="analog-to-digital-converters-adcs">
<h1 class="title">Analog-to-Digital Converters (ADCs)</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
-<td>Draft</td></tr>
+<td>Final</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Jan-Hinrich Hauer, Philip Levis, Vlado Handziski, David Gay</td></tr>
-<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">20-Dec-2004</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.9</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-10-12</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu></td>
-</tr>
</tbody>
</table>
+<div class="document" id="analog-to-digital-converters-adcs">
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">This memo documents a part of TinyOS for the TinyOS Community, and
of this memo is unlimited. This memo is in full compliance with
<a class="citation-reference" href="#tep1" id="id1" name="id1">[TEP1]</a>.</p>
</div>
-<div class="section">
-<h1><a id="abstract" name="abstract">Abstract</a></h1>
+<div class="section" id="abstract">
+<h1><a name="abstract">Abstract</a></h1>
<p>This TEP proposes a hardware abstraction for analog-to-digital converters (ADCs)
in TinyOS 2.x, which is aligned to the three-layer Hardware Abstraction
-Architecture (HAA) specified in [TEP2]. It describes some design principles and
+Architecture (HAA) specified in <a class="citation-reference" href="#tep2" id="id2" name="id2">[TEP2]</a>. It describes some design principles and
documents the set of hardware-independent interfaces to an ADC.</p>
</div>
-<div class="section">
-<h1><a id="introduction" name="introduction">1. Introduction</a></h1>
+<div class="section" id="introduction">
+<h1><a name="introduction">1. Introduction</a></h1>
<p>Analog-to-digital converters (ADCs) are devices that convert analog input
signals to discrete digital output signals, typically voltage to a binary
number. The interested reader can refer to Appendix A for a brief overview of
programatically, even though the semantics and forms of operation were
completely different. To compensate for the difference non-ADC sensors
introduced additional interfaces, such as <tt class="docutils literal"><span class="pre">ADCError</span></tt>, that were tightly bound
-to sensor acquisition but separate in wiring. The separation between the ADC and
-<tt class="docutils literal"><span class="pre">ADCError</span></tt> interface is bug prone and problematic, as is the equation of a
-sensor and an ADC. TinyOS 2.x separates the structure and interfaces of an ADC
-from those of sensors (which may be on top of an ADC, but this fact is hidden
-from higher level components). This TEP presents how TinyOS 2.x structures ADC
-software. TEP 109 (Sensor Boards) shows how a platform can present actual named
-sensors <a class="citation-reference" href="#tep109" id="id2" name="id2">[TEP109]</a>.</p>
+to sensor acquisition but separate in wiring. The separation between the ADC
+and <tt class="docutils literal"><span class="pre">ADCError</span></tt> interface is bug prone and problematic, as is the equation of
+a sensor and an ADC. TinyOS 2.x separates the structure and interfaces of an
+ADC from those of sensor drivers (which may be on top of an ADC stack, but
+this fact is hidden from higher level components). This TEP presents how TinyOS
+2.x structures ADC software. <a class="citation-reference" href="#tep109" id="id3" name="id3">[TEP109]</a> (Sensor Boards) shows how a platform can
+present actual named sensors.</p>
<p>As can be seen in Appendix A the ADC hardware used on TinyOS platforms differ
in many respects, which makes it difficult to find a chip independent
representation for an ADC. Even if there were such a representation, the
actual configuration details may be different the procedure of configuring an
ADC can be unified on all ADCs with the help of <strong>hardware independent
interfaces</strong>: in a similar way as the <tt class="docutils literal"><span class="pre">Read</span></tt> interface definition does not
-predefine the type or semantics of the exchanged data (see <a class="citation-reference" href="#tep114" id="id3" name="id3">[TEP114]</a>), a
+predefine the type or semantics of the exchanged data (see <a class="citation-reference" href="#tep114" id="id4" name="id4">[TEP114]</a>), a
configuration interface definition can abstract from the data type and
semantics of the involved configuration settings. For example, like a
-component can provide a <tt class="docutils literal"><span class="pre">Read<uint8_t></span></tt> or <tt class="docutils literal"><span class="pre">Read<uint16_t></span></tt> interface
-depending on the data it can offer, a component can also use a
-<tt class="docutils literal"><span class="pre">AdcConfigure<atm128_adc_config_t></span></tt> or
+component can provide a <tt class="docutils literal"><span class="pre">Read<uint8_t></span></tt> or <tt class="docutils literal"><span class="pre">Read<uint16_t></span></tt> interface, it
+can also provide a <tt class="docutils literal"><span class="pre">AdcConfigure<atm128_adc_config_t></span></tt> or
<tt class="docutils literal"><span class="pre">AdcConfigure<msp430adc12_channel_config_t></span></tt> interface depending on what ADC
it represents. This TEP proposes the (typed) <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface as the
standard interface for configuring an ADC in TinyOS 2.x.</p>
<p>In spite of their hardware differences, one aspect represents a common
-denominator of all ADCs: they produce conversion results. To facilitate sensor
-software development conversion results are returned by the ADC hardware stack
-using the standard TinyOS interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt>
-(see <a class="reference" href="#interfaces">2. Interfaces</a> and <a class="citation-reference" href="#tep114" id="id4" name="id4">[TEP114]</a>). Conversion results are returned as
-uninterpreted values and translating them to engineering units can only be done
-with the configuration knowledge of the respective platform, for example, the
-reference voltage or the resistance of a reference resistor in ratiometric
-measurements. Translating uninterpreted values to engineering units is
-performed by components located on top of the ADC hardware stack and out of the
-scope of this TEP.</p>
+denominator of ADCs: they all produce conversion results. To facilitate sensor
+software development conversion results are returned by the ADC stack through
+the interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadStream</span></tt> and <tt class="docutils literal"><span class="pre">ReadNow</span></tt> (see <a class="reference" href="#interfaces">2. Interfaces</a>
+and <a class="citation-reference" href="#tep114" id="id5" name="id5">[TEP114]</a>). Conversion results are returned as uninterpreted values and
+translating them to engineering units can only be done with the configuration
+knowledge of the respective platform, for example, the reference voltage or the
+resistance of a reference resistor in ratiometric measurements. Translating
+uninterpreted values to engineering units may be performed by components
+located on top of the ADC stack and is out of the scope of this TEP.</p>
<p>The top layer of abstraction of an ADC - the Hardware Interface Layer (HIL) -
-thus provides the standard TinyOS interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and
-<tt class="docutils literal"><span class="pre">ReadStream</span></tt> and uses the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface for hardware
-configuration (why it <strong>uses</strong> and does not <strong>provide</strong> <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> is
-explained below). Since the type and semantics of the parameters passed
-through these interfaces is dependent on the actual ADC implementation, it is
-only a "weak" HIL (see <a class="citation-reference" href="#tep2" id="id5" name="id5">[TEP2]</a>).</p>
-<p>Following the principles of the HAA <a class="citation-reference" href="#tep2" id="id6" name="id6">[TEP2]</a> the Hardware Adaptation Layer (HAL,
+thus provides the interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt> and uses
+the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface for hardware configuration (why it <strong>uses</strong> and
+does not <strong>provide</strong> <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> is explained below). Since the type and
+semantics of the parameters passed through these interfaces is dependent on the
+actual ADC implementation, it is only a "weak" HIL (see <a class="citation-reference" href="#tep2" id="id6" name="id6">[TEP2]</a>).</p>
+<p>Following the principles of the HAA <a class="citation-reference" href="#tep2" id="id7" name="id7">[TEP2]</a> the Hardware Adaptation Layer (HAL,
which resides below the HIL) of an ADC should expose all the chip-specific
capabilities of the chip. For example, the ADC12 on the MSP430 MCU supports a
"Repeat-Sequence-of-Channels Mode" and therefore this function should be
-accessible on the HAL of the <strong>MSP430 ADC12</strong> hardware abstraction. Other ADCs
+accessible on the HAL of the MSP430 ADC12 hardware abstraction. Other ADCs
might not exhibit such functionality and might therefore - on the level of HAL
- provide only an interface to perform single conversions. Since all ADCs have
-the same HIL representation it may thus be necessary to perform some degree of
+the same HIL representation it may be necessary to perform some degree of
software emulation in the HIL implementation. For example, a <tt class="docutils literal"><span class="pre">ReadStream</span></tt>
command can be emulated by multiple single conversion commands. Below the HAL
resides the Hardware Presentation Layer (HPL), a stateless component that
-provides access to the hardware registers (see <a class="citation-reference" href="#tep2" id="id7" name="id7">[TEP2]</a>). The general structure
-(without virtualization) of the ADC hardware stack is as follows</p>
+provides access to the hardware registers (see <a class="citation-reference" href="#tep2" id="id8" name="id8">[TEP2]</a>). The general structure
+(without virtualization) of the ADC stack is as follows</p>
<pre class="literal-block">
^ |
| |
<ul class="simple">
<li>the set of standard TinyOS interfaces for collecting ADC conversion
results and for configuring an ADC (<a class="reference" href="#interfaces">2. Interfaces</a>)</li>
-<li>guidelines on how an ADC's HAL should expose chip-specific
+<li>guidelines on how an ADC's HAL should expose chip-specific
interfaces (<a class="reference" href="#hal-guidelines">3. HAL guidelines</a>)</li>
<li>what components an ADC's HIL MUST implement (<a class="reference" href="#hil-requirements">4. HIL requirements</a>)</li>
-<li>guidelines on how the HIL should be implemented
+<li>guidelines on how the HIL should be implemented
(<a class="reference" href="#hil-guidelines">5. HIL guidelines</a>)</li>
<li>a section pointing to current implementations (<a class="reference" href="#implementation">6. Implementation</a>)</li>
</ul>
<p>This TEP ends with appendices documenting, as an example, the ADC implementation
for the TI MSP430 MCU.</p>
</div>
-<div class="section">
-<h1><a id="interfaces" name="interfaces">2. Interfaces</a></h1>
+<div class="section" id="interfaces">
+<h1><a name="interfaces">2. Interfaces</a></h1>
<p>This TEP proposes the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface for ADC hardware configuration
-and the <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interfaces to acquire
-conversion results. A <tt class="docutils literal"><span class="pre">Read[Now|Stream]</span></tt> interface is always provided in
-conjunction with a <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
-<div class="section">
-<h2><a id="interface-for-configuring-the-adc-hardware" name="interface-for-configuring-the-adc-hardware">Interface for configuring the ADC hardware</a></h2>
+and the <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadStream</span></tt> and <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interfaces to acquire
+conversion results. The <tt class="docutils literal"><span class="pre">Read</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interfaces are documented
+in <a class="citation-reference" href="#tep114" id="id9" name="id9">[TEP114]</a> and the <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is documented in this TEP. A
+<tt class="docutils literal"><span class="pre">Read[Now|Stream]</span></tt> interface is always provided in conjunction with a
+<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
+<div class="section" id="interface-for-configuring-the-adc-hardware">
+<h2><a name="interface-for-configuring-the-adc-hardware">Interface for configuring the ADC hardware</a></h2>
<p>The <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is defined as follows:</p>
<pre class="literal-block">
-interface AdcConfigure< config_type >
+interface AdcConfigure< config_type >
{
- async command config_type getConfiguration();
+ async command config_type getConfiguration();
}
</pre>
-<p>This interface is used by the ADC implementation to retrieve the hardware
-configuration of an ADC client. <tt class="docutils literal"><span class="pre">config_type</span></tt> is a chip-specific data type
-(simple or structured) that contains all information necessary to configure the
-respective ADC hardware. For example, on the ADC12 of the MSP430 the
-<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface will be instantiated with the <tt class="docutils literal"><span class="pre">const</span>
-<span class="pre">msp430adc12_channel_config_t*</span></tt> data type. A client MUST always return the same
-configuration through a <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface and, if configuration data
-is passed as a pointer, the HIL component (see <a class="reference" href="#hil-requirements">4. HIL requirements</a>) MUST NOT
-reference it after the return of the <tt class="docutils literal"><span class="pre">getConfiguration()</span></tt> command. If a
-client wants to use the ADC with different configurations it must provide
-multiple instances of the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
+<p>This interface is used by the ADC stack to retrieve the hardware configuration
+of an ADC HIL client. <tt class="docutils literal"><span class="pre">config_type</span></tt> is a chip-specific data type (simple or
+structured) that contains all information necessary to configure the respective
+ADC hardware. For example, on the ADC12 of the MSP430 the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt>
+interface will be instantiated with the <tt class="docutils literal"><span class="pre">const</span> <span class="pre">msp430adc12_channel_config_t*</span></tt>
+data type. A client MUST always return the same configuration through a
+<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface and, if configuration data is passed as a pointer,
+the HIL component (see <a class="reference" href="#hil-requirements">4. HIL requirements</a>) MUST NOT reference it after the
+return of the <tt class="docutils literal"><span class="pre">getConfiguration()</span></tt> command. If a client wants to use the ADC
+with different configurations it must provide multiple instances of the
+<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
+<p>Note that the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is <strong>provided</strong> by an ADC HIL client
+and it is <strong>used</strong> by the ADC HIL implementation. Therefore an ADC HIL client
+cannot initiate the configuration of the ADC hardware itself. Instead it is the
+ADC HIL implementation that can "pull" the client's ADC configuration just
+before it initates a conversion based on the respective client's configuration.
+The rationale is that the ADC HIL implementation does not have to store an ADC
+configuration per client - instead the ADC client can, for example, store its
+configuration in program memory.</p>
</div>
-<div class="section">
-<h2><a id="interfaces-for-acquiring-conversion-results" name="interfaces-for-acquiring-conversion-results">Interfaces for acquiring conversion results</a></h2>
-<p>This TEP proposes to adopt the following three generic, source-independent data
-collection interfaces from <a class="citation-reference" href="#tep114" id="id8" name="id8">[TEP114]</a> for the collection of ADC conversion
+<div class="section" id="interfaces-for-acquiring-conversion-results">
+<h2><a name="interfaces-for-acquiring-conversion-results">Interfaces for acquiring conversion results</a></h2>
+<p>This TEP proposes to adopt the following two source-independent data
+collection interfaces from <a class="citation-reference" href="#tep114" id="id10" name="id10">[TEP114]</a> for the collection of ADC conversion
results on the level of HIL:</p>
<pre class="literal-block">
interface Read< size_type >
-interface ReadNow< size_type >
interface ReadStream< size_type >
</pre>
+<p>In addition it proposes the following data collection interface for low-latency
+reading of conversion results:</p>
+<pre class="literal-block">
+interface ReadNow< size_type >
+</pre>
<p>Every data collection interface is associated with an <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt>
interface (how this association is realized is explained in Section <a class="reference" href="#hil-requirements">4. HIL
requirements</a>). As the resolution of conversion results is chip-specific, the
<tt class="docutils literal"><span class="pre">size_type</span></tt> parameter reflects an upper bound for the chip-specific
resolution of the conversion results - the actual resolution may be smaller
-(e.g. uint16_t for a 12-bit ADC). The above interfaces are specified in
-<a class="citation-reference" href="#tep114" id="id9" name="id9">[TEP114]</a>, in the following their usage is explained with respect to ADCs.</p>
-<div class="section">
-<h3><a id="read" name="read">Read</a></h3>
-<p>The <tt class="docutils literal"><span class="pre">Read</span></tt> interface can be used to sample an ADC channel and return a single
-conversion result as an uninterpreted value. The meaning of the <tt class="docutils literal"><span class="pre">Read</span></tt>
-interface is explained in <a class="citation-reference" href="#tep114" id="id10" name="id10">[TEP114]</a>.</p>
+(e.g. uint16_t for a 12-bit ADC).</p>
+<div class="section" id="read">
+<h3><a name="read">Read</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">Read</span></tt> interface can be used to sample an ADC channel once and return a
+single conversion result as an uninterpreted value. The <tt class="docutils literal"><span class="pre">Read</span></tt> interface is
+documented in <a class="citation-reference" href="#tep114" id="id11" name="id11">[TEP114]</a>.</p>
</div>
-<div class="section">
-<h3><a id="readnow" name="readnow">ReadNow</a></h3>
-<p>The <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is similar to the <tt class="docutils literal"><span class="pre">Read</span></tt> interface. The difference
-is that if a call to <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> succeeds, the ADC starts to sample the
-channel immediately (precisely: when <tt class="docutils literal"><span class="pre">SUCCESS</span></tt> is returned the hardware has
-started the sampling process). Due to its timing constraints the <tt class="docutils literal"><span class="pre">ReadNow</span></tt>
-interface is always provided in conjunction with an instance of the
-<tt class="docutils literal"><span class="pre">Resource</span></tt> interface (a client must reserve the ADC before the client may
-call <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt>). Please refer to <a class="citation-reference" href="#tep108" id="id11" name="id11">[TEP108]</a> on how the <tt class="docutils literal"><span class="pre">Resource</span></tt>
-interface should be used by a client component.</p>
+<div class="section" id="readstream">
+<h3><a name="readstream">ReadStream</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface can be used to sample an ADC channel multiple
+times with a specified sampling period. The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface is
+documented in <a class="citation-reference" href="#tep114" id="id12" name="id12">[TEP114]</a> .</p>
</div>
-<div class="section">
-<h3><a id="readstream" name="readstream">ReadStream</a></h3>
-<p>The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface can be used to sample an ADC channel multiple times
-with a specified sampling period. The meaning of the <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface
-is explained in <a class="citation-reference" href="#tep114" id="id12" name="id12">[TEP114]</a> .</p>
+<div class="section" id="readnow">
+<h3><a name="readnow">ReadNow</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is intended for split-phase low-latency
+reading of small values:</p>
+<pre class="literal-block">
+interface ReadNow<val_t>
+{
+ async command error_t read();
+ async event void readDone( error_t result, val_t val );
+}
+</pre>
+<p>This interface is similar to the <tt class="docutils literal"><span class="pre">Read</span></tt> interface, but works in asynchronous
+context. A successful call to <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> means that the ADC hardware
+has started the sampling process and that <tt class="docutils literal"><span class="pre">ReadNow.readDone()</span></tt> will be
+signalled once it has finished (note that the asynchronous
+<tt class="docutils literal"><span class="pre">ReadNow.readDone()</span></tt> might be signalled even before the call to
+<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> has returned). Due to its timing constraints the
+<tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is always provided in conjunction with an instance of the
+<tt class="docutils literal"><span class="pre">Resource</span></tt> interface and a client must reserve the ADC through the
+<tt class="docutils literal"><span class="pre">Resource</span></tt> interface before the client may call <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt>. Please
+refer to <a class="citation-reference" href="#tep108" id="id13" name="id13">[TEP108]</a> on how the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface should be used by a client
+component.</p>
</div>
</div>
</div>
-<div class="section">
-<h1><a id="hal-guidelines" name="hal-guidelines">3. HAL guidelines</a></h1>
+<div class="section" id="hal-guidelines">
+<h1><a name="hal-guidelines">3. HAL guidelines</a></h1>
<p>As explained in <a class="reference" href="#introduction">1. Introduction</a> the HAL exposes the full capabilities of the
ADC hardware. Therefore only chip- and platform-dependent clients can wire to
the HAL. Although the HAL is chip-specific, both, in terms of implementation
-and representation, its design should follow the guidelines described below to
-facilitate the mapping to the HIL representation. Appendix B shows the
-signature of the HAL for the MSP430.</p>
-<div class="section">
-<h2><a id="resource-reservation" name="resource-reservation">Resource reservation</a></h2>
+and representation, its design should follow the guidelines described in this
+section to facilitate the mapping to the HIL representation. Appendix B shows
+the signature of the HAL for the MSP430.</p>
+<div class="section" id="resource-reservation">
+<h2><a name="resource-reservation">Resource reservation</a></h2>
<p>As the ADC hardware is a shared resource that is usually multiplexed between
several clients some form of access arbitration is necessary. The HAL should
therefore provide a parameterized <tt class="docutils literal"><span class="pre">Resource</span></tt> interface, instantiate a
standard arbiter component and connect the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface to the
-arbiter as described in <a class="citation-reference" href="#tep108" id="id13" name="id13">[TEP108]</a>. To ensure fair and uniform arbitration on
+arbiter as described in <a class="citation-reference" href="#tep108" id="id14" name="id14">[TEP108]</a>. To ensure fair and uniform arbitration on
all platforms the standard round robin arbiter is recommended. Resource
-arbiters and the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface are the topic of <a class="citation-reference" href="#tep108" id="id14" name="id14">[TEP108]</a>.</p>
+arbiters and the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface are the topic of <a class="citation-reference" href="#tep108" id="id15" name="id15">[TEP108]</a>.</p>
</div>
-<div class="section">
-<h2><a id="configuration-and-sampling" name="configuration-and-sampling">Configuration and sampling</a></h2>
+<div class="section" id="configuration-and-sampling">
+<h2><a name="configuration-and-sampling">Configuration and sampling</a></h2>
<p>As the ADC hardware is a shared resource the HAL should support hardware
configuration and sampling per client (although per-port configuration is
possible, it is not recommended, because it forces all clients to use the same
it after the return of the respective command. Appendix B shows the HAL
interfaces for the MSP430.</p>
</div>
-<div class="section">
-<h2><a id="hal-virtualization" name="hal-virtualization">HAL virtualization</a></h2>
+<div class="section" id="hal-virtualization">
+<h2><a name="hal-virtualization">HAL virtualization</a></h2>
<p>In order to hide wiring complexities and/or export only a subset of all ADC
functions generic ADC wrapper components may be provided on the level of HAL.
Such components can also be used to ensure that a sampling interface is always
client ID if this is required by the HAL implementation.</p>
</div>
</div>
-<div class="section">
-<h1><a id="hil-requirements" name="hil-requirements">4. HIL requirements</a></h1>
+<div class="section" id="hil-requirements">
+<h1><a name="hil-requirements">4. HIL requirements</a></h1>
<p>The following generic components MUST be provided on all platforms that have an
ADC:</p>
<pre class="literal-block">
-AdcReadClientC
-AdcReadNowClientC
-AdcReadStreamClientC
+AdcReadClientC
+AdcReadNowClientC
+AdcReadStreamClientC
</pre>
<p>These components provide virtualized access to the HIL of an ADC. They are
instantiated by an ADC client and provide/use the four interfaces described in
platform (the question of how to deal with multiple devices of the same class
is a general one in TinyOS 2.x). Appendix C shows the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt> for
the MSP430.</p>
-<div class="section">
-<h2><a id="adcreadclientc" name="adcreadclientc">AdcReadClientC</a></h2>
+<div class="section" id="adcreadclientc">
+<h2><a name="adcreadclientc">AdcReadClientC</a></h2>
<pre class="literal-block">
generic configuration AdcReadClientC() {
provides {
placeholders and will be instantiated by the respective HIL implementation (for
an example, see the AdcReadClientC for the MSP430 in Appendix C).</p>
</div>
-<div class="section">
-<h2><a id="adcreadnowclientc" name="adcreadnowclientc">AdcReadNowClientC</a></h2>
+<div class="section" id="adcreadnowclientc">
+<h2><a name="adcreadnowclientc">AdcReadNowClientC</a></h2>
<pre class="literal-block">
generic configuration AdcReadNowClientC() {
provides {
acquiring single conversion results. In contrast to <tt class="docutils literal"><span class="pre">Read.read()</span></tt> when a call
to <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> succeeds, the ADC starts to sample the channel
immediately (a successful <tt class="docutils literal"><span class="pre">Read.read()</span></tt> command may not have this
-implication, see <a class="citation-reference" href="#tep114" id="id15" name="id15">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>). A client MUST reserve the ADC
+implication, see <a class="citation-reference" href="#tep114" id="id16" name="id16">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>). A client MUST reserve the ADC
through the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface before the client may call
-<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> and it must release the ADC through the <tt class="docutils literal"><span class="pre">Resource</span></tt>
-interface when it no longer needs to access it (for more details on the
-<tt class="docutils literal"><span class="pre">Resource</span></tt> interface please refer to <a class="citation-reference" href="#tep108" id="id16" name="id16">[TEP108]</a>). The associated ADC channel
-(port) and further configuration details are returned by the
+<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> and it MUST release the ADC through the <tt class="docutils literal"><span class="pre">Resource</span></tt>
+interface when it no longer needs to access it (for more details on how to use
+the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface please refer to <a class="citation-reference" href="#tep108" id="id17" name="id17">[TEP108]</a>). The associated ADC
+channel (port) and further configuration details are returned by the
<tt class="docutils literal"><span class="pre">AdcConfigure.getConfiguration()</span></tt> command. It is the task of the client to
wire this interface to a component that provides the client's ADC
configuration. The HIL implementation will use the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface
instantiated by the respective HIL implementation (for an example how this is
done for the AdcReadClientC see Appendix C).</p>
</div>
-<div class="section">
-<h2><a id="adcreadstreamclientc" name="adcreadstreamclientc">AdcReadStreamClientC</a></h2>
+<div class="section" id="adcreadstreamclientc">
+<h2><a name="adcreadstreamclientc">AdcReadStreamClientC</a></h2>
<pre class="literal-block">
generic configuration AdcReadStreamClientC() {
provides {
</pre>
<p>The <tt class="docutils literal"><span class="pre">AdcReadStreamClientC</span></tt> component provides a <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface for
acquiring multiple conversion results at once. The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface is
-explained in <a class="citation-reference" href="#tep114" id="id17" name="id17">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>. The <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is
+explained in <a class="citation-reference" href="#tep114" id="id18" name="id18">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>. The <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is
used in the same way as described in the section on the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt>.
Note that both, <tt class="docutils literal"><span class="pre">size_type</span></tt> and <tt class="docutils literal"><span class="pre">config_type</span></tt>, are only placeholders and
will be instantiated by the respective HIL implementation (for an example how
this is done for the AdcReadClientC see Appendix C).</p>
</div>
</div>
-<div class="section">
-<h1><a id="hil-guidelines" name="hil-guidelines">5. HIL guidelines</a></h1>
+<div class="section" id="hil-guidelines">
+<h1><a name="hil-guidelines">5. HIL guidelines</a></h1>
<p>The HIL implementation of an ADC stack has two main tasks: it translates a
<tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> or <tt class="docutils literal"><span class="pre">ReadStream</span></tt> request to a chip-specific HAL sampling
command and it abstracts from the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface (the latter only for
check can also be done in the HAL implementation). Once the HIL is signalled
the conversion result(s) it forwards it to the respective <tt class="docutils literal"><span class="pre">ReadNow</span></tt> client.</p>
</div>
-<div class="section">
-<h1><a id="implementation" name="implementation">6. Implementation</a></h1>
+<div class="section" id="implementation">
+<h1><a name="implementation">6. Implementation</a></h1>
+<div class="section" id="testadc-application">
+<h2><a name="testadc-application">TestAdc application</a></h2>
+<p>An ADC HIL test application can be found in <tt class="docutils literal"><span class="pre">tinyos-2.x/apps/tests/TestAdc</span></tt>.
+Note that this application instantiates generic DemoSensorC, DemoSensorStreamC
+and DemoSensorNowC components (see <a class="citation-reference" href="#tep114" id="id19" name="id19">[TEP114]</a>) and assumes that these components
+are actually wired to an ADC HIL. Please refer to
+<tt class="docutils literal"><span class="pre">tinyos-2.x/apps/tests/TestAdc/README.txt</span></tt> for more information.</p>
+</div>
+<div class="section" id="haa-on-the-msp430-and-atmega-128">
+<h2><a name="haa-on-the-msp430-and-atmega-128">HAA on the MSP430 and Atmega 128</a></h2>
<p>The implementation of the ADC12 stack on the MSP430 can be found in
<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/msp430/adc12</span></tt>:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">HplAtm128AdcC.nc</span></tt> is the HPL implementation</li>
<li><tt class="docutils literal"><span class="pre">Atm128AdcP.nc</span></tt> is the HAL implementation</li>
-<li><tt class="docutils literal"><span class="pre">WireAdcP.nc</span></tt> and the library components for arbitrating 'Read',
-'ReadNow' and 'ReadStream', <tt class="docutils literal"><span class="pre">ArbitratedReadC</span></tt> and
+<li><tt class="docutils literal"><span class="pre">AdcP.nc</span></tt>, <tt class="docutils literal"><span class="pre">WireAdcP.nc</span></tt> and the library components for arbitrating
+'Read', 'ReadNow' and 'ReadStream', <tt class="docutils literal"><span class="pre">ArbitratedReadC</span></tt> and
<tt class="docutils literal"><span class="pre">ArbitratedReadStreamC</span></tt> (in <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/system</span></tt>), realize
-the HAL</li>
+the HIL</li>
<li><tt class="docutils literal"><span class="pre">AdcReadClientC.nc</span></tt>, <tt class="docutils literal"><span class="pre">AdcReadNowClientC.nc</span></tt> and
<tt class="docutils literal"><span class="pre">AdcReadStreamClientC.nc</span></tt> provide virtualized access to the HIL</li>
</ul>
</blockquote>
</div>
-<div class="section">
-<h1><a id="appendix-a-hardware-differences-between-platforms" name="appendix-a-hardware-differences-between-platforms">Appendix A: Hardware differences between platforms</a></h1>
+</div>
+<div class="section" id="appendix-a-hardware-differences-between-platforms">
+<h1><a name="appendix-a-hardware-differences-between-platforms">Appendix A: Hardware differences between platforms</a></h1>
<p>The following table compares the characteristics of two microcontrollers
commonly used in TinyOS platforms:</p>
<table border="1" class="docutils">
<col width="32%" />
</colgroup>
<thead valign="bottom">
-<tr><th class="head"> </th>
-<th class="head">Atmel Atmega 128</th>
-<th class="head">TI MSP430 ADC12</th>
+<tr><th> </th>
+<th>Atmel Atmega 128</th>
+<th>TI MSP430 ADC12</th>
</tr>
</thead>
<tbody valign="top">
</tbody>
</table>
</div>
-<div class="section">
-<h1><a id="appendix-b-a-hal-representation-msp430-adc12" name="appendix-b-a-hal-representation-msp430-adc12">Appendix B: a HAL representation: MSP430 ADC12</a></h1>
+<div class="section" id="appendix-b-a-hal-representation-msp430-adc12">
+<h1><a name="appendix-b-a-hal-representation-msp430-adc12">Appendix B: a HAL representation: MSP430 ADC12</a></h1>
<p>This section shows the HAL signature for the ADC12 of the TI MSP430 MCU. It
reflects the four MSP430 ADC12 conversion modes as it lets a client sample an
ADC channel once ("Single-channel-single-conversion") or repeatedly
<tt class="docutils literal"><span class="pre">DMAExtension</span></tt> interface is used to reset the state machine when the DMA is
responsible for data transfer (managed in an exterior component):</p>
<pre class="literal-block">
-configuration Msp430Adc12P
-{
+configuration Msp430Adc12P
+{
provides {
- interface Resource[uint8_t id];
- interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
+ interface Resource[uint8_t id];
+ interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
interface AsyncStdControl as DMAExtension[uint8_t id];
}
}
-interface Msp430Adc12SingleChannel
-{
+interface Msp430Adc12SingleChannel
+{
async command error_t configureSingle(const msp430adc12_channel_config_t *config);
async command error_t configureSingleRepeat(const msp430adc12_channel_config_t *config, uint16_t jiffies);
async command error_t configureMultiple( const msp430adc12_channel_config_t *config, uint16_t buffer[], uint16_t numSamples, uint16_t jiffies);
async command error_t configureMultipleRepeat(const msp430adc12_channel_config_t *config, uint16_t buffer[], uint8_t numSamples, uint16_t jiffies);
async command error_t getData();
async event error_t singleDataReady(uint16_t data);
- async event uint16_t* multipleDataReady(uint16_t buffer[], uint16_t numSamples);
+ async event uint16_t* multipleDataReady(uint16_t buffer[], uint16_t numSamples);
}
-typedef struct {
- unsigned int inch: 4; // input channel
- unsigned int sref: 3; // reference voltage
- unsigned int ref2_5v: 1; // reference voltage level
- unsigned int adc12ssel: 2; // clock source sample-hold-time
- unsigned int adc12div: 3; // clock divider sample-hold-time
+typedef struct
+{
+ unsigned int inch: 4; // input channel
+ unsigned int sref: 3; // reference voltage
+ unsigned int ref2_5v: 1; // reference voltage level
+ unsigned int adc12ssel: 2; // clock source sample-hold-time
+ unsigned int adc12div: 3; // clock divider sample-hold-time
unsigned int sht: 4; // sample-hold-time
- unsigned int sampcon_ssel: 2; // clock source sampcon signal
+ unsigned int sampcon_ssel: 2; // clock source sampcon signal
unsigned int sampcon_id: 2; // clock divider sampcon signal
} msp430adc12_channel_config_t;
</pre>
</div>
-<div class="section">
-<h1><a id="appendix-c-a-hil-representation-msp430-adc12" name="appendix-c-a-hil-representation-msp430-adc12">Appendix C: a HIL representation: MSP430 ADC12</a></h1>
+<div class="section" id="appendix-c-a-hil-representation-msp430-adc12">
+<h1><a name="appendix-c-a-hil-representation-msp430-adc12">Appendix C: a HIL representation: MSP430 ADC12</a></h1>
<p>The signature of the AdcReadClientC component for the MSP430 ADC12 is as
follows:</p>
<pre class="literal-block">
<table class="docutils citation" frame="void" id="tep2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a name="tep2">[TEP2]</a></td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id6">2</a>, <a class="fn-backref" href="#id7">3</a>)</em> TEP 2: Hardware Abstraction Architecture.</td></tr>
+<tr><td class="label"><a name="tep2">[TEP2]</a></td><td><em>(<a class="fn-backref" href="#id2">1</a>, <a class="fn-backref" href="#id6">2</a>, <a class="fn-backref" href="#id7">3</a>, <a class="fn-backref" href="#id8">4</a>)</em> TEP 2: Hardware Abstraction Architecture.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep108" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a name="tep108">[TEP108]</a></td><td><em>(<a class="fn-backref" href="#id11">1</a>, <a class="fn-backref" href="#id13">2</a>, <a class="fn-backref" href="#id14">3</a>, <a class="fn-backref" href="#id16">4</a>)</em> TEP 108: Resource Arbitration.</td></tr>
+<tr><td class="label"><a name="tep108">[TEP108]</a></td><td><em>(<a class="fn-backref" href="#id13">1</a>, <a class="fn-backref" href="#id14">2</a>, <a class="fn-backref" href="#id15">3</a>, <a class="fn-backref" href="#id17">4</a>)</em> TEP 108: Resource Arbitration.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep109" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id2" name="tep109">[TEP109]</a></td><td>TEP 109: Sensor Boards.</td></tr>
+<tr><td class="label"><a class="fn-backref" href="#id3" name="tep109">[TEP109]</a></td><td>TEP 109: Sensor Boards.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep114" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a name="tep114">[TEP114]</a></td><td><em>(<a class="fn-backref" href="#id3">1</a>, <a class="fn-backref" href="#id4">2</a>, <a class="fn-backref" href="#id8">3</a>, <a class="fn-backref" href="#id9">4</a>, <a class="fn-backref" href="#id10">5</a>, <a class="fn-backref" href="#id12">6</a>, <a class="fn-backref" href="#id15">7</a>, <a class="fn-backref" href="#id17">8</a>)</em> TEP 114: SIDs: Source and Sink Independent Drivers.</td></tr>
+<tr><td class="label"><a name="tep114">[TEP114]</a></td><td><em>(<a class="fn-backref" href="#id4">1</a>, <a class="fn-backref" href="#id5">2</a>, <a class="fn-backref" href="#id9">3</a>, <a class="fn-backref" href="#id10">4</a>, <a class="fn-backref" href="#id11">5</a>, <a class="fn-backref" href="#id12">6</a>, <a class="fn-backref" href="#id16">7</a>, <a class="fn-backref" href="#id18">8</a>, <a class="fn-backref" href="#id19">9</a>)</em> TEP 114: SIDs: Source and Sink Independent Drivers.</td></tr>
</tbody>
</table>
</div>