]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - doc/html/tep109.html
fixed html validation error in docs
[tinyos-2.x.git] / doc / html / tep109.html
index ac263e9b3015ea2fb9ca8e668fb566dac5878109..2ff9e4383e7d515baa9f2146375c4e5dac782ff6 100644 (file)
@@ -41,11 +41,6 @@ blockquote.epigraph {
 dd {
   margin-bottom: 0.5em }
 
-/* Uncomment (& remove this text!) to get bold-faced definition list terms
-dt {
-  font-weight: bold }
-*/
-
 div.abstract {
   margin: 2em 5em }
 
@@ -325,7 +320,7 @@ that provide access to sensors.</p>
 <h1><a id="principles" name="principles">1. Principles</a></h1>
 <p>This section describes the basic organization principles for sensor
 drivers in TinyOS.</p>
-<p>For background, a sensor may be attached to the microcontroller on a
+<p>For background, a sensor can be attached to the microcontroller on a
 TinyOS platform through a few different types of connections:</p>
 <blockquote>
 <ul class="simple">
@@ -336,40 +331,43 @@ TinyOS platform through a few different types of connections:</p>
 <li>Connected through a standard digital bus protocol (1-Wire, I2C, SPI)</li>
 </ul>
 </blockquote>
-<p>Physically, these connections may also be decoupled by attaching the
+<p>Physically, these connections can also be decoupled by attaching the
 sensors to a <cite>sensor board</cite>, which can be removed from the TinyOS
-platform, and may fit multiple different TinyOS platforms.</p>
+platform, and could attach to multiple different TinyOS platforms.</p>
 <p>The capabilities of a physical sensor are made available to a TinyOS
 application through a <cite>sensor driver</cite>.</p>
-<p>According to the HAA <a class="citation-reference" href="#tep2" id="id1" name="id1">[TEP2]</a>, TinyOS devices should provide both
+<p>According to the HAA <a class="citation-reference" href="#tep2" id="id1" name="id1">[TEP2]</a>, TinyOS devices SHOULD provide both
 simple hardware-independent interfaces for common-case use (HIL) and
 rich hardware-dependent interfaces for special-case use (HAL). Sensor
-drivers should follow this spirit as well.</p>
+drivers SHOULD follow this spirit as well.</p>
 <p>TinyOS 2.x represents each sensor as an individual component. This
 allows the compilation process to minimize the amount of code
-included. A sensor board containing multiple sensors should be
+included. A sensor board containing multiple sensors SHOULD be
 represented as a collection of components, one for each sensor,
 contained within a sensor board directory.</p>
-<p>Sensors, being physical devices that may be shared, can benefit from
+<p>Sensors, being physical devices that can be shared, can benefit from
 virtualization and arbitration. This document describes a design
-pattern for sensor virtualization that may be followed by sensor
+pattern for sensor virtualization that SHOULD be followed by sensor
 drivers.</p>
-<p>The same physical sensor may be attached to multiple different TinyOS
+<p>The same physical sensor can be attached to multiple different TinyOS
 platforms, through platform-dependent interconnections. The common
-logic of sensor driver should be factored into chip-dependent,
-platform-independent components, and those components should be bound
+logic of sensor driver SHOULD be factored into chip-dependent,
+platform-independent components, and those components SHOULD be bound
 to the hardware resources on a platform by platform-dependent
 components, and to the hardware resources on a sensor board by
 sensorboard-dependent components.</p>
 <p>A physical sensor has a general class and a specific set of
 performance characteristics, captured by the make and model of the
-sensor itself. The naming of the sensor driver components should
-reflect the specifc name of the sensor, and optionally provide a
-component with a generic name for application authors who only care
-about the general class of the sensor.</p>
-<p>This document assumes that sensors return uninterpreted values of
-arbitrary size or datatype. Conversion of sensor values to something
-with actual physical meaning is beyond the scope of this document.</p>
+sensor itself. The naming of the sensor driver components SHOULD
+reflect the specifc name of the sensor, and MAY provide a component
+with a generic name for application authors who only care about the
+general class of the sensor.</p>
+<p>This document takes no position on the meaning of the values returned
+by sensor drivers. They MAY be raw uninterpreted values or they MAY
+have some physical meaning. If a driver returns uninterpreted values,
+the driver MAY provide additional interfaces that would allow
+higher-level clients to obtain information needed to properly
+interpret the value.</p>
 </div>
 <div class="section">
 <h1><a id="sensor-hil-components" name="sensor-hil-components">2. Sensor HIL Components</a></h1>
@@ -386,16 +384,19 @@ writing calibration coefficients or control registers.</li>
 access to the sensor. A sensor device driver can provide such
 virtualization for itself by defining a nesC generic client
 component. When a client component is being used, a call to a
-top-level SID interface should be delayed when the device is busy,
-rather than failing. This virtualization may be easier to accomplish
-by using one of the arbiters provided by the system.</p>
+top-level SID interface SHOULD be delayed when the device is busy,
+rather than failing. Using one of the system arbiters can make the
+implementation of this requirement easier to accomplish.</p>
 <p>For example:</p>
 <pre class="literal-block">
 generic configuration SensirionSht11C() {
   provides interface Read&lt;uint16_t&gt; as Temperature;
   provides interface ReadStream&lt;uint16_t&gt; as TemperatureStream;
+  provides interface DeviceMetadata as TemperatureDeviceMetadata;
+
   provides interface Read&lt;uint16_t&gt; as Humidity;
   provides interface ReadStream&lt;uint16_t&gt; as HumidityStream;
+  provides interface DeviceMetadata as HumidityDeviceMetadata;
 }
 implementation {
   // connect to the ADC HIL, GPIO HAL, or sensor's HAL
@@ -410,30 +411,22 @@ automatically. For sensors without a constant power draw, the sensor
 MAY be started once at boot time by wiring to the <cite>MainC.Boot</cite>
 interface. Sensors that draw appreciable power MUST be started in
 response to a call to one of the top-level SID interfaces, and stopped
-some time after that call completes. One of the power-management
-components described in <a class="citation-reference" href="#tep115" id="id4" name="id4">[TEP115]</a> may be useful for this purpose.</p>
+some time after that call completes. Using one of the power-management
+components described in <a class="citation-reference" href="#tep115" id="id4" name="id4">[TEP115]</a> can make this implementation easier.</p>
 <p>Generally, simple types are made up of octets. However, sensor values
-often have levels of precision besides a multiple of 8. A device MAY
-specify the precision of one of its interfaces with the DeviceMetadata
-interface:</p>
+often have levels of precision besides a multiple of 8. To account for
+such cases, each device MUST specify the precision of each one of its
+interfaces by providing the DeviceMetadata interface:</p>
 <pre class="literal-block">
 interface DeviceMetadata {
   command uint8_t getSignificantBits();
 }
 </pre>
-<p>The name of the instance of DeviceMetadata SHOULD clearly indicate
-which interface it corresponds to.</p>
-<p>A value contained returned from the device through a SID interface
-MAY be left shifted so that it covers as much of the type's range as
-possible. For example, if a 12-bit ADC reading is presented as a
-16-bit Read interface:</p>
-<pre class="literal-block">
-component DemoSensorC {
-  provides interface Read&lt;uint16_t&gt;;
-}
-</pre>
-<p>then the driver MAY shift the 12-bit value left so that its range is
-0x0000 - 0xfff0, rather than 0x0000 - 0x0fff.</p>
+<p>The name of the instance of DeviceMetadata MUST clearly indicate which
+interface it corresponds to.</p>
+<p>The getSignificantBits() call MUST return the number of significant
+bits in the reading. For example, a sensor reading taken from a 12-bit
+ADC MUST return the value &quot;12&quot;.</p>
 <p>Sensor driver components SHOULD be named according to the make and
 model of the sensing device being presented. Using specific names
 gives the developer the option to bind to a particular sensor, which
@@ -442,26 +435,30 @@ components using &quot;common&quot; names MAY also be provided by the driver
 author, to support application developers who are only concerned with
 the particular type of the sensor and not its make, model, or detailed
 performance characteristics.</p>
-<p>A &quot;common&quot; naming layer atop a HIL may look like this:</p>
+<p>A &quot;common&quot; naming layer atop a HIL might look like this:</p>
 <pre class="literal-block">
 generic configuration TemperatureC() {
   provides interface Read&lt;uint16_t&gt;;
   provides interface ReadStream&lt;uint16_t&gt;;
+  provides interface DeviceMetadata;
 }
 implementation {
   components new SensirionSht11C();
   Read = SensirionSht11C.Temperature;
   ReadStream = SensirionSht11C.TemperatureStream;
+  DeviceMetadata = SensirionSht11C.TemperatureDeviceMetadata;
 }
 
 generic configuration HumidityC() {
   provides interface Read&lt;uint16_t&gt;;
   provides interface ReadStream&lt;uint16_t&gt;;
+  provides interface DeviceMetadata;
 }
 implementation {
   components new SensirionSht11C();
   Read = SensirionSht11C.Humidity;
   ReadStream = SensirionSht11C.HumidityStream;
+  DeviceMetadata = SensirionSht11C.HumidityDeviceMetadata;
 }
 </pre>
 </div>
@@ -496,33 +493,9 @@ implementation {
 </pre>
 </div>
 <div class="section">
-<h1><a id="sensor-hpl-components" name="sensor-hpl-components">4. Sensor HPL Components</a></h1>
-<p>A sensor HPL is necessarily platform-dependent or
-sensorboard-dependent. These components should provide access to the
-physical resources needed by the sensor, in a platform-independent
-manner that can be used by the shared logic of the sensor HAL
-components. In the case of bus-based sensors, this HPL may be nothing
-more than wiring to the appropriate bus interface for use by the HAL
-component.</p>
-<p>For example:</p>
-<pre class="literal-block">
-configuration HplSensirionSht11C {
-  provides interface Init;
-  provides interface Resource[ uint8_t id ];
-  provides interface GeneralIO as DATA;
-  provides interface GeneralIO as SCK;
-  provides interface GpioInterrupt as InterruptDATA;
-}
-implementation {
-  // connect to platform or sensorboard-dependent resources
-  // power-manage the sensor through platform-specific means
-}
-</pre>
-</div>
-<div class="section">
-<h1><a id="directory-organization-guidelines" name="directory-organization-guidelines">5. Directory Organization Guidelines</a></h1>
-<p>Because the same physical sensor may be attached to TinyOS platforms
-in many different ways, the organization of sensor drivers should
+<h1><a id="directory-organization-guidelines" name="directory-organization-guidelines">4. Directory Organization Guidelines</a></h1>
+<p>Because the same physical sensor can be attached to TinyOS platforms
+in many different ways, the organization of sensor drivers SHOULD
 reflect the distinction between sensor and sensor interconnect.</p>
 <p>Sensor components commonly exist at three levels:
 platform-independent, sensorboard-dependent, and
@@ -560,7 +533,7 @@ nescc. For instance, you might add an include directive to &#64;new_args
 with push &#64;new_args, <cite>-Isomedir</cite>. This could be used to include
 subdirectories.</li>
 <li>&#64;commonboards: This can be set to a list of sensor board names which
-should be added to the include path list. These sensor boards must be
+will be added to the include path list. These sensor boards MUST be
 in tinyos-2.x/tos/sensorboards.</li>
 </ul>
 <p>If the sensor board wishes to define any C types or constants, it
@@ -570,13 +543,13 @@ board's directory.</p>
 subdirectories for each of the sensors connected to the sensor board.
 If a &quot;chips&quot; subdirectory is used, sensorboard-dependent driver
 components needed to connect platform-independent logic to a
-particular attachment for that sensor should be placed in
+particular attachment for that sensor SHOULD be placed in
 &quot;&lt;sensorboard&gt;/chips/&lt;sensor&gt;&quot;.</p>
 <p>Components needed to connect the platform-independent sensor driver
 components or sensorboard-dependent components to the hardware
 resources available on a particular platform SHOULD be placed in
 &quot;tos/&lt;platform&gt;/chips/&lt;sensor&gt;&quot;. In addition, components for a sensor
-that only exists on a particular platform should be placed in a such a
+that only exists on a particular platform SHOULD be placed in a such a
 directory.</p>
 <p>Sensors that exist as part of a larger chip, like a MCU internal
 voltage sensor, SHOULD be placed in a subdirectory of the chip's
@@ -586,11 +559,11 @@ directives to locate all of the necessary components needed to support
 the sensors on a platform and/or sensorboard.</p>
 <p>All of these directory organization guidelines are only intended for
 code that will enter the core source tree. In general, sensor
-components may be placed anywhere as long as the nesC compiler
+components can be placed anywhere as long as the nesC compiler
 receives enough <cite>-I</cite> directives to locate all of the necessary pieces.</p>
 </div>
 <div class="section">
-<h1><a id="authors-addresses" name="authors-addresses">6. Authors' Addresses</a></h1>
+<h1><a id="authors-addresses" name="authors-addresses">5. Authors' Addresses</a></h1>
 <div class="line-block">
 <div class="line">David Gay</div>
 <div class="line">2150 Shattuck Ave, Suite 1300</div>
@@ -634,7 +607,7 @@ receives enough <cite>-I</cite> directives to locate all of the necessary pieces
 </div>
 </div>
 <div class="section">
-<h1><a id="citations" name="citations">7. Citations</a></h1>
+<h1><a id="citations" name="citations">6. Citations</a></h1>
 <table class="docutils citation" frame="void" id="tep2" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
@@ -654,6 +627,432 @@ receives enough <cite>-I</cite> directives to locate all of the necessary pieces
 </tbody>
 </table>
 </div>
+<div class="section">
+<h1><a id="appendix-a-sensor-driver-examples" name="appendix-a-sensor-driver-examples">Appendix A: Sensor Driver Examples</a></h1>
+<div class="section">
+<h2><a id="analog-adc-connected-sensor" name="analog-adc-connected-sensor">1. Analog ADC-Connected Sensor</a></h2>
+<p>The Analog sensor requires two components</p>
+<ul class="simple">
+<li>a component to present the sensor itself (HamamatsuS1087ParC)</li>
+<li>a component to select the appropriate hardware resources, such as
+ADC port 4, reference voltage 1.5V, and a slow sample and hold time
+(HamamatsuS1087ParP).</li>
+</ul>
+<p>The AdcReadClientC component and underlying machinery handles all of
+the arbitration and access to the ADC.</p>
+<pre class="literal-block">
+tos/platforms/telosa/chips/s1087/HamamatsuS1087ParC.nc
+
+generic configuration HamamatsuS1087ParC() {
+  provides interface Read&lt;uint16_t&gt;;
+  provides interface ReadStream&lt;uint16_t&gt;;
+  provides interface DeviceMetadata;
+}
+implementation {
+  components new AdcReadClientC();
+  Read = AdcReadClientC;
+
+  components new AdcReadStreamClientC();
+  ReadStream = AdcReadStreamClientC;
+
+  components HamamatsuS1087ParP;
+  DeviceMetadata = HamamatsuS1087ParP;
+  AdcReadClientC.AdcConfigure -&gt; HamamatsuS1087ParP;
+  AdcReadStreamClientC.AdcConfigure -&gt; HamamatsuS1087ParP;
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/s1087/HamamatsuS1087ParP.nc
+
+#include &quot;Msp430Adc12.h&quot;
+
+module HamamatsuS1087ParP {
+  provides interface AdcConfigure&lt;const msp430adc12_channel_config_t*&gt;;
+  provides interface DeviceMetadata;
+}
+implementation {
+
+  msp430adc12_channel_config_t config = {
+    inch: INPUT_CHANNEL_A4,
+    sref: REFERENCE_VREFplus_AVss,
+    ref2_5v: REFVOLT_LEVEL_1_5,
+    adc12ssel: SHT_SOURCE_ACLK,
+    adc12div: SHT_CLOCK_DIV_1,
+    sht: SAMPLE_HOLD_4_CYCLES,
+    sampcon_ssel: SAMPCON_SOURCE_SMCLK,
+    sampcon_id: SAMPCON_CLOCK_DIV_1
+  };
+
+  async command const msp430adc12_channel_config_t* AdcConfigure.getConfiguration() {
+    return &amp;config;
+  }
+
+  command uint8_t DeviceMetadata.getSignificantBits() { return 12; }
+}
+</pre>
+</div>
+<div class="section">
+<h2><a id="binary-pin-connected-sensor" name="binary-pin-connected-sensor">2. Binary Pin-Connected Sensor</a></h2>
+<p>The Binary sensor gets a bit more complex, because it has three
+components:</p>
+<ul class="simple">
+<li>one to present the sensor (UserButtonC)</li>
+<li>one to execute the driver logic (UserButtonLogicP)</li>
+<li>one to select the appropriate hardware resources, such as MSP430
+Port 27 (HplUserButtonC).</li>
+</ul>
+<p>Note that the presentation of this sensor is not arbitrated because
+none of the operations are split-phase.</p>
+<pre class="literal-block">
+tos/platforms/telosa/UserButtonC.nc
+
+configuration UserButtonC {
+  provides interface Get&lt;bool&gt;;
+  provides interface Notify&lt;bool&gt;;
+  provides interface DeviceMetadata;
+}
+implementation {
+
+  components UserButtonLogicP;
+  Get = UserButtonLogicP;
+  Notify = UserButtonLogicP;
+  DeviceMetadata = UserButtonLogicP;
+
+  components HplUserButtonC;
+  UserButtonLogicP.GpioInterrupt -&gt; HplUserButtonC.GpioInterrupt;
+  UserButtonLogicP.GeneralIO -&gt; HplUserButtonC.GeneralIO;
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/UserButtonLogicP.nc
+
+module UserButtonLogicP {
+  provides interface Get&lt;bool&gt;;
+  provides interface Notify&lt;bool&gt;;
+  provides interface DeviceMetadata;
+
+  uses interface GeneralIO;
+  uses interface GpioInterrupt;
+}
+implementation {
+  norace bool m_pinHigh;
+
+  task void sendEvent();
+
+  command bool Get.get() { return call GeneralIO.get(); }
+
+  command error_t Notify.enable() {
+    call GeneralIO.makeInput();
+
+    if ( call GeneralIO.get() ) {
+      m_pinHigh = TRUE;
+      return call GpioInterrupt.enableFallingEdge();
+    } else {
+      m_pinHigh = FALSE;
+      return call GpioInterrupt.enableRisingEdge();
+    }
+  }
+
+  command error_t Notify.disable() {
+    return call GpioInterrupt.disable();
+  }
+
+  async event void GpioInterrupt.fired() {
+    call GpioInterrupt.disable();
+
+    m_pinHigh = !m_pinHigh;
+
+    post sendEvent();
+  }
+
+  task void sendEvent() {
+    bool pinHigh;
+    pinHigh = m_pinHigh;
+
+    signal Notify.notify( pinHigh );
+
+    if ( pinHigh ) {
+      call GpioInterrupt.enableFallingEdge();
+    } else {
+      call GpioInterrupt.enableRisingEdge();
+    }
+  }
+
+  command uint8_t DeviceMetadata.getSignificantBits() { return 1; }
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/HplUserButtonC.nc
+
+configuration HplUserButtonC {
+  provides interface GeneralIO;
+  provides interface GpioInterrupt;
+}
+implementation {
+
+  components HplMsp430GeneralIOC as GeneralIOC;
+
+  components new Msp430GpioC() as UserButtonC;
+  UserButtonC -&gt; GeneralIOC.Port27;
+  GeneralIO = UserButtonC;
+
+  components HplMsp430InterruptC as InterruptC;
+
+  components new Msp430InterruptC() as InterruptUserButtonC;
+  InterruptUserButtonC.HplInterrupt -&gt; InterruptC.Port27;
+  GpioInterrupt = InterruptUserButtonC.Interrupt;
+}
+</pre>
+</div>
+<div class="section">
+<h2><a id="digital-bus-connected-sensor" name="digital-bus-connected-sensor">3. Digital Bus-Connected Sensor</a></h2>
+<p>The Digital sensor is the most complex out of the set, and includes
+six components:</p>
+<ul class="simple">
+<li>one to present the sensor (SensirionSht11C)</li>
+<li>one to request arbitrated access and to transform the sensor HAL
+into the sensor HIL (SensirionSht11P)</li>
+<li>one to present the sensor HAL (HalSensirionSht11C)</li>
+<li>one to perform the driver logic needed to support the HAL, which
+twiddles pins according to a sensor-specific protocol
+(SensirionSht11LogicP).</li>
+<li>one to select the appropriate hardware resources, such as the clock,
+data, and power pins, and to provide an arbiter for the sensor
+(HplSensirionSht11C).</li>
+<li>one to perform the power control logic needed to support the power
+manager associated with the arbiter (HplSensirionSht11P).</li>
+</ul>
+<p>This bus-connected sensor is overly complex because it does not rely
+on a shared framework of bus manipulation components. A sensor built
+on top of the I2C or SPI bus would likely require fewer components.</p>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/SensirionSht11C.nc
+
+generic configuration SensirionSht11C() {
+  provides interface Read&lt;uint16_t&gt; as Temperature;
+  provides interface DeviceMetadata as TemperatureDeviceMetadata;
+  provides interface Read&lt;uint16_t&gt; as Humidity;
+  provides interface DeviceMetadata as HumidityDeviceMetadata;
+}
+implementation {
+  components new SensirionSht11ReaderP();
+
+  Temperature = SensirionSht11ReaderP.Temperature;
+  TemperatureDeviceMetadata = SensirionSht11ReaderP.TemperatureDeviceMetadata;
+  Humidity = SensirionSht11ReaderP.Humidity;
+  HumidityDeviceMetadata = SensirionSht11ReaderP.HumidityDeviceMetadata;
+
+  components HalSensirionSht11C;
+
+  enum { TEMP_KEY = unique(&quot;Sht11.Resource&quot;) };
+  enum { HUM_KEY = unique(&quot;Sht11.Resource&quot;) };
+
+  SensirionSht11ReaderP.TempResource -&gt; HalSensirionSht11C.Resource[ TEMP_KEY ];
+  SensirionSht11ReaderP.Sht11Temp -&gt; HalSensirionSht11C.SensirionSht11[ TEMP_KEY ];
+  SensirionSht11ReaderP.HumResource -&gt; HalSensirionSht11C.Resource[ HUM_KEY ];
+  SensirionSht11ReaderP.Sht11Hum -&gt; HalSensirionSht11C.SensirionSht11[ HUM_KEY ];
+}
+</pre>
+<pre class="literal-block">
+tos/chips/sht11/SensirionSht11ReaderP.nc
+
+generic module SensirionSht11ReaderP() {
+  provides interface Read&lt;uint16_t&gt; as Temperature;
+  provides interface DeviceMetadata as TemperatureDeviceMetadata;
+  provides interface Read&lt;uint16_t&gt; as Humidity;
+  provides interface DeviceMetadata as HumidityDeviceMetadata;
+
+  uses interface Resource as TempResource;
+  uses interface Resource as HumResource;
+  uses interface SensirionSht11 as Sht11Temp;
+  uses interface SensirionSht11 as Sht11Hum;
+}
+implementation {
+  command error_t Temperature.read() {
+    call TempResource.request();
+    return SUCCESS;
+  }
+
+  event void TempResource.granted() {
+    error_t result;
+    if ((result = call Sht11Temp.measureTemperature()) != SUCCESS) {
+      call TempResource.release();
+      signal Temperature.readDone( result, 0 );
+    }
+  }
+
+  event void Sht11Temp.measureTemperatureDone( error_t result, uint16_t val ) {
+    call TempResource.release();
+    signal Temperature.readDone( result, val );
+  }
+
+  command uint8_t TemperatureDeviceMetadata.getSignificantBits() { return 14; }
+
+  command error_t Humidity.read() {
+    call HumResource.request();
+    return SUCCESS;
+  }
+
+  event void HumResource.granted() {
+    error_t result;
+    if ((result = call Sht11Hum.measureHumidity()) != SUCCESS) {
+      call HumResource.release();
+      signal Humidity.readDone( result, 0 );
+    }
+  }
+
+  event void Sht11Hum.measureHumidityDone( error_t result, uint16_t val ) {
+    call HumResource.release();
+    signal Humidity.readDone( result, val );
+  }
+
+  command uint8_t HumidityDeviceMetadata.getSignificantBits() { return 12; }
+
+  event void Sht11Temp.resetDone( error_t result ) { }
+  event void Sht11Temp.measureHumidityDone( error_t result, uint16_t val ) { }
+  event void Sht11Temp.readStatusRegDone( error_t result, uint8_t val ) { }
+  event void Sht11Temp.writeStatusRegDone( error_t result ) { }
+
+  event void Sht11Hum.resetDone( error_t result ) { }
+  event void Sht11Hum.measureTemperatureDone( error_t result, uint16_t val ) { }
+  event void Sht11Hum.readStatusRegDone( error_t result, uint8_t val ) { }
+  event void Sht11Hum.writeStatusRegDone( error_t result ) { }
+
+  default event void Temperature.readDone( error_t result, uint16_t val ) { }
+  default event void Humidity.readDone( error_t result, uint16_t val ) { }
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/HalSensirionSht11C.nc
+
+configuration HalSensirionSht11C {
+  provides interface Resource[ uint8_t client ];
+  provides interface SensirionSht11[ uint8_t client ];
+}
+implementation {
+  components new SensirionSht11LogicP();
+  SensirionSht11 = SensirionSht11LogicP;
+
+  components HplSensirionSht11C;
+  Resource = HplSensirionSht11C.Resource;
+  SensirionSht11LogicP.DATA -&gt; HplSensirionSht11C.DATA;
+  SensirionSht11LogicP.CLOCK -&gt; HplSensirionSht11C.SCK;
+  SensirionSht11LogicP.InterruptDATA -&gt; HplSensirionSht11C.InterruptDATA;
+
+  components new TimerMilliC();
+  SensirionSht11LogicP.Timer -&gt; TimerMilliC;
+
+  components LedsC;
+  SensirionSht11LogicP.Leds -&gt; LedsC;
+}
+</pre>
+<pre class="literal-block">
+tos/chips/sht11/SensirionSht11LogicP.nc
+
+generic module SensirionSht11LogicP() {
+  provides interface SensirionSht11[ uint8_t client ];
+
+  uses interface GeneralIO as DATA;
+  uses interface GeneralIO as CLOCK;
+  uses interface GpioInterrupt as InterruptDATA;
+
+  uses interface Timer&lt;TMilli&gt;;
+
+  uses interface Leds;
+}
+implementation {
+
+  ... bus protocol details omitted for brevity ...
+
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/HplSensirionSht11C.nc
+
+configuration HplSensirionSht11C {
+  provides interface Resource[ uint8_t id ];
+  provides interface GeneralIO as DATA;
+  provides interface GeneralIO as SCK;
+  provides interface GpioInterrupt as InterruptDATA;
+}
+implementation {
+  components HplMsp430GeneralIOC;
+
+  components new Msp430GpioC() as DATAM;
+  DATAM -&gt; HplMsp430GeneralIOC.Port15;
+  DATA = DATAM;
+
+  components new Msp430GpioC() as SCKM;
+  SCKM -&gt; HplMsp430GeneralIOC.Port16;
+  SCK = SCKM;
+
+  components new Msp430GpioC() as PWRM;
+  PWRM -&gt; HplMsp430GeneralIOC.Port17;
+
+  components HplSensirionSht11P;
+  HplSensirionSht11P.PWR -&gt; PWRM;
+  HplSensirionSht11P.DATA -&gt; DATAM;
+  HplSensirionSht11P.SCK -&gt; SCKM;
+
+  components new TimerMilliC();
+  HplSensirionSht11P.Timer -&gt; TimerMilliC;
+
+  components HplMsp430InterruptC;
+  components new Msp430InterruptC() as InterruptDATAC;
+  InterruptDATAC.HplInterrupt -&gt; HplMsp430InterruptC.Port15;
+  InterruptDATA = InterruptDATAC.Interrupt;
+
+  components new FcfsArbiterC( &quot;Sht11.Resource&quot; ) as Arbiter;
+  Resource = Arbiter;
+
+  components new SplitControlPowerManagerC();
+  SplitControlPowerManagerC.SplitControl -&gt; HplSensirionSht11P;
+  SplitControlPowerManagerC.ArbiterInit -&gt; Arbiter.Init;
+  SplitControlPowerManagerC.ArbiterInfo -&gt; Arbiter.ArbiterInfo;
+  SplitControlPowerManagerC.ResourceDefaultOwner -&gt; Arbiter.ResourceDefaultOwner;
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/HplSensirionSht11P.nc
+
+module HplSensirionSht11P {
+  provides interface SplitControl;
+  uses interface Timer&lt;TMilli&gt;;
+  uses interface GeneralIO as PWR;
+  uses interface GeneralIO as DATA;
+  uses interface GeneralIO as SCK;
+}
+implementation {
+  task void stopTask();
+
+  command error_t SplitControl.start() {
+    call PWR.makeOutput();
+    call PWR.set();
+    call Timer.startOneShot( 11 );
+    return SUCCESS;
+  }
+
+  event void Timer.fired() {
+    signal SplitControl.startDone( SUCCESS );
+  }
+
+  command error_t SplitControl.stop() {
+    call SCK.makeInput();
+    call SCK.clr();
+    call DATA.makeInput();
+    call DATA.clr();
+    call PWR.clr();
+    post stopTask();
+    return SUCCESS;
+  }
+
+  task void stopTask() {
+    signal SplitControl.stopDone( SUCCESS );
+  }
+}
+</pre>
+</div>
+</div>
 </div>
 </body>
 </html>