]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Swapping HEAD and DEVEL branches
authorvlahan <vlahan>
Tue, 12 Dec 2006 18:22:48 +0000 (18:22 +0000)
committervlahan <vlahan>
Tue, 12 Dec 2006 18:22:48 +0000 (18:22 +0000)
126 files changed:
apps/RadioSenseToLeds/RadioSenseToLedsC.nc
doc/html/install-tinyos.html
doc/html/tep106.html
doc/html/tep109.html
doc/html/tutorial/lesson1.html
doc/html/tutorial/lesson10.html
doc/html/tutorial/lesson11.html
doc/html/tutorial/lesson12.html
doc/html/tutorial/lesson6.html
doc/html/tutorial/lesson8.html
doc/txt/tep106.txt
doc/txt/tep109.txt
doc/txt/tep114.txt
doc/txt/tep119.txt
support/sdk/java/net/tinyos/comm/package.html [new file with mode: 0644]
support/sdk/java/net/tinyos/message/package.html [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/package.html [new file with mode: 0644]
support/sdk/java/net/tinyos/packet/package.html [new file with mode: 0644]
support/sdk/java/net/tinyos/sf/package.html [new file with mode: 0644]
support/sdk/java/net/tinyos/sim/package.html [new file with mode: 0644]
support/sdk/java/net/tinyos/tools/package.html [new file with mode: 0644]
support/sdk/java/net/tinyos/util/package.html [new file with mode: 0644]
tos/chips/cc1000/CC1000ControlP.nc
tos/chips/cc1000_lpl/CC1000ControlP.nc
tos/chips/max136x/HalMAX136xControlP.nc
tos/chips/max136x/HplMAX136xLogicP.nc
tos/chips/msp430/McuSleepC.nc
tos/chips/msp430/adc12/HplAdc12.nc
tos/chips/msp430/adc12/HplAdc12P.nc
tos/chips/msp430/adc12/Msp430Adc12.h
tos/chips/msp430/adc12/Msp430Adc12ClientC.nc
tos/chips/msp430/adc12/Msp430Adc12ImplP.nc
tos/chips/msp430/adc12/Msp430Adc12MultiChannel.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430Adc12Overflow.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430Adc12P.nc
tos/chips/msp430/adc12/Msp430Adc12SingleChannel.nc
tos/chips/msp430/adc12/Msp430RefVoltGeneratorP.nc
tos/chips/msp430/adc12/README.txt
tos/chips/msp430/msp430hardware.h
tos/chips/msp430/usart/HplMsp430I2C.nc
tos/chips/msp430/usart/HplMsp430I2C0P.nc
tos/chips/msp430/usart/HplMsp430Usart.nc
tos/chips/msp430/usart/HplMsp430Usart0P.nc
tos/chips/msp430/usart/HplMsp430Usart1P.nc
tos/chips/msp430/usart/Msp430I2CConfigure.nc
tos/chips/msp430/usart/Msp430I2CP.nc
tos/chips/msp430/usart/Msp430SpiConfigure.nc
tos/chips/msp430/usart/Msp430SpiDmaP.nc
tos/chips/msp430/usart/Msp430SpiNoDmaP.nc
tos/chips/msp430/usart/Msp430Uart0P.nc
tos/chips/msp430/usart/Msp430Uart1C.nc
tos/chips/msp430/usart/Msp430Uart1P.nc
tos/chips/msp430/usart/Msp430UartConfigure.nc
tos/chips/msp430/usart/Msp430UartControl.nc [deleted file]
tos/chips/msp430/usart/Msp430UartP.nc
tos/chips/msp430/usart/msp430usart.h
tos/chips/pxa27x/timer/HalPXA27xSleep.nc
tos/chips/pxa27x/timer/HalPXA27xSleepM.nc
tos/chips/stm25p/Stm25pLogP.nc
tos/chips/tda5250/HplTda5250ConfigP.nc
tos/chips/tda5250/HplTda5250DataP.nc
tos/chips/tda5250/Tda5250RadioC.nc
tos/chips/tda5250/Tda5250RadioP.nc
tos/chips/tda5250/mac/ChannelCongestion.nc [new file with mode: 0644]
tos/chips/tda5250/mac/CsmaMacC.nc
tos/chips/tda5250/mac/CsmaMacP.nc
tos/chips/tda5250/mac/RedMac.h [new file with mode: 0644]
tos/chips/tda5250/mac/RedMacC.nc [new file with mode: 0644]
tos/chips/tda5250/mac/RedMacP.nc [new file with mode: 0644]
tos/chips/tda5250/mac/SleepTime.nc [new file with mode: 0644]
tos/chips/tda5250/mac/Teamgeist.nc [new file with mode: 0644]
tos/interfaces/Leds.nc
tos/interfaces/State.nc [new file with mode: 0644]
tos/lib/tossim/HilTimerMilliC.nc
tos/lib/tossim/sim_gain.c
tos/platforms/eyesIFX/Msp430Timer32khzMapC.nc [deleted file]
tos/platforms/eyesIFX/RadioDataLinkC.nc
tos/platforms/eyesIFX/byte_radio/RssiFixedThresholdCMC.nc
tos/platforms/eyesIFX/byte_radio/Uart4b6bPhyP.nc
tos/platforms/eyesIFX/byte_radio/UartPhyC.nc [deleted file]
tos/platforms/eyesIFX/byte_radio/UartPhyP.nc [deleted file]
tos/platforms/eyesIFX/chips/msp430/Msp430Uart0C.nc
tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataC.nc [deleted file]
tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOC.nc
tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOP.nc
tos/platforms/eyesIFX/chips/tda5250/tda5250BusResourceId.h [deleted file]
tos/platforms/eyesIFX/chips/tda5250/tda5250BusResourceSettings.h
tos/platforms/eyesIFX/eyesIFXSerialP.nc
tos/platforms/eyesIFX/platform_message.h
tos/platforms/eyesIFX/sensors/RssiSensorVccC.nc
tos/platforms/eyesIFX/sensors/RssiSensorVccP.nc [deleted file]
tos/platforms/telosa/.platform
tos/platforms/telosa/TelosSerialP.nc
tos/platforms/tinynode/TinyNodeSerialP.nc
tos/sensorboards/im2sb/HalSensirionSht11C.nc
tos/sensorboards/im2sb/HplSensirionSht11C.nc
tos/sensorboards/im2sb/HplSensirionSht11P.nc
tos/sensorboards/im2sb/MAX136xInternalC.nc
tos/sensorboards/im2sb/MAX136xInternalP.nc
tos/sensorboards/im2sb/README.txt [new file with mode: 0644]
tos/sensorboards/im2sb/SensirionSht11C.nc
tos/sensorboards/im2sb/Tsl2561InternalC.nc
tos/sensorboards/im2sb/Tsl2561InternalP.nc
tos/sensorboards/im2sb/examples/Makefile [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestLis3l02dq/Makefile [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestLis3l02dq/TestSensorC.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestLis3l02dq/TestSensorM.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestMax136/Makefile [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestMax136/TestSensorC.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestMax136/TestSensorM.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestSensor.h [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestSensor.java [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestSensorMsg.java [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestSht11/README.txt [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestSht11/TestSensorC.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestSht11/TestSensorM.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestTmp175/Makefile [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestTmp175/TestSensorC.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestTmp175/TestSensorM.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestTsl2561/Makefile [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestTsl2561/TestSensorC.nc [new file with mode: 0644]
tos/sensorboards/im2sb/examples/TestTsl2561/TestSensorM.nc [new file with mode: 0644]
tos/sensorboards/im2sb/im2sb.h
tos/system/LedsP.nc
tos/system/State.nc [deleted file]
tos/system/tos.h

index 0d1fc0caa5053e45dc843ad0cd3949ab2bf38e43..fab38b1392884aa4a1f2dd27c3c933adcea00ef1 100644 (file)
@@ -101,19 +101,18 @@ implementation {
     else {
       radio_sense_msg_t* rsm = (radio_sense_msg_t*)payload;
       uint16_t val = rsm->data;
-      call Leds.led0Toggle();
-      if (val & 0x8000) {
-       call Leds.led1On();
-      }
-      else {
-       call Leds.led1Off();
-      }
-      if (val & 0x4000) {
-       call Leds.led2On();
-      }
-      else {
-       call Leds.led2Off();
-      }
+      if (val & 0x0004)
+        call Leds.led2On();
+      else
+        call Leds.led2Off();
+      if (val & 0x0002)
+        call Leds.led1On();
+      else
+        call Leds.led1Off();
+      if (val & 0x0001)
+        call Leds.led0On();
+      else
+        call Leds.led0Off();
       return bufPtr;
     }
   }
index f75cded63e5aa3ddb3427252d33f80a1a1c5195c..8ff7c1522fe40f6fca429128d7d742ab0d4cb9c4 100644 (file)
@@ -72,6 +72,8 @@ work.
 
 <p>
 <ol>
+<li> Download and install Cygwin from <A HREF="http://www.cygwin.com">www.cygwin.com</A>.</li>
+<p>
 <li> Download the confirmed-compatible cygwin packages from the tinyos web site <a href="http://www.tinyos.net/dist-1.2.0/tools/windows/cygwin-1.2a.tgz">here</a>.
 <p>
 <li> In a cygwin shell, unzip the above package into some directory. In these instructions the directory is /cygdrive/c/newcygpkgs.
@@ -290,8 +292,8 @@ bypass the erroneous error by using 'rpm -ivh --ignoreos
 
 <tr>
   <td>TinyOS</td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0-1.cygwin.noarch.rpm">tinyos-2.0.0-1.cygwin.noarch.rpm</a></td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0-1.noarch.rpm">tinyos-2.0.0-1.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0-3.cygwin.noarch.rpm">tinyos-2.0.0-3.cygwin.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0-3.noarch.rpm">tinyos-2.0.0-3.noarch.rpm</a></td>
 </tr>
 
 </tbody></table>
index d65a035a650aaa60dcb412829da57249881fbd23..a444e4af0c17a5f92c6a86111940fdd4b470b7af 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis and Cory Sharp</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">10-Dec-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.10</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.11</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-08-17</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-11-07</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -627,7 +627,12 @@ implementation {
 TaskEdf interface. Its configuration SHOULD wire it to TinySchedulerC.
 The key used for task unique identifiers MUST be &quot;TinySchedulerC.TaskInterface&quot;,
 where <em>TaskInterface</em> is the name of the new task interface as presented
-by the scheduler.  For example, the module SomethingP requires two EDF
+by the scheduler.  A common way to make sure a consistent string is used
+is to #define it. For example, TaskEdf.nc might include:</p>
+<pre class="literal-block">
+#define UQ_TASK_EDF &quot;TinySchedulerC.TaskEdf&quot;
+</pre>
+<p>In this example, the module SomethingP requires two EDF
 tasks:</p>
 <pre class="literal-block">
 configuration SomethingC {
@@ -635,8 +640,8 @@ configuration SomethingC {
 }
 implementation {
   components SomethingP, TinySchedulerC;
-  SomethingP.SendTask -&gt; TinySchedulerC.TaskEdf[&quot;TinySchedulerC.TaskEdf&quot;];
-  SomethingP.SenseTask -&gt; TinySchedulerC.TaskEdf[&quot;TinySchedulerC.TaskEdf&quot;];
+  SomethingP.SendTask -&gt; TinySchedulerC.TaskEdf[unique(UQ_TASK_EDF)];
+  SomethingP.SenseTask -&gt; TinySchedulerC.TaskEdf[unique(UQ_TASK_EDF)];
 }
 </pre>
 <p>The module SomethingP also has a basic task. The nesC compiler
index dec7d902550c9a7271a903d8ca210fb31f652848..0de30da7eb3559dcbf10961e5ee859a7c0a8f9a5 100644 (file)
@@ -3,7 +3,7 @@
 <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.10: http://docutils.sourceforge.net/" />
 <title>Sensors and Sensor Boards</title>
 <meta name="author" content="David Gay, Phil Levis, Wei Hong, Joe Polastre, and Gilman Tolle" />
 <style type="text/css">
 /*
 :Author: David Goodger
 :Contact: goodger@users.sourceforge.net
-:date: $Date$
-:version: $Revision$
-:copyright: This stylesheet has been placed in the public domain.
+:Date: $Date$
+:Revision: $Revision$
+:Copyright: This stylesheet has been placed in the public domain.
 
 Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
 */
-body {
-  font-family: Times;
-  font-size: 16px;
-}
 
+/* "! important" is used here to override other ``margin-top`` and
+   ``margin-bottom`` styles that are later in the stylesheet or 
+   more specific.  See http://www.w3.org/TR/CSS1#the-cascade */
 .first {
   margin-top: 0 ! important }
 
-.last {
+.last, .with-subtitle {
   margin-bottom: 0 ! important }
 
 .hidden {
@@ -38,11 +40,11 @@ a.toc-backref {
 blockquote.epigraph {
   margin: 2em 5em ; }
 
-dd {
+dl.docutils dd {
   margin-bottom: 0.5em }
 
-/* Uncomment (& remove this text!) to get bold-faced definition list terms
-dt {
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
   font-weight: bold }
 */
 
@@ -53,12 +55,18 @@ div.abstract p.topic-title {
   font-weight: bold ;
   text-align: center }
 
-div.attention, div.caution, div.danger, div.error, div.hint,
-div.important, div.note, div.tip, div.warning, div.admonition {
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
   margin: 2em ;
   border: medium outset ;
   padding: 1em }
 
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+  font-weight: bold ;
+  font-family: sans-serif }
+
 div.attention p.admonition-title, div.caution p.admonition-title,
 div.danger p.admonition-title, div.error p.admonition-title,
 div.warning p.admonition-title {
@@ -66,11 +74,14 @@ div.warning p.admonition-title {
   font-weight: bold ;
   font-family: sans-serif }
 
-div.hint p.admonition-title, div.important p.admonition-title,
-div.note p.admonition-title, div.tip p.admonition-title,
-div.admonition p.admonition-title {
-  font-weight: bold ;
-  font-family: sans-serif }
+/* Uncomment (and remove this text!) to get reduced vertical space in
+   compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+  margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+  margin-top: 0.5em }
+*/
 
 div.dedication {
   margin: 2em 5em ;
@@ -85,6 +96,7 @@ div.figure {
   margin-left: 2em }
 
 div.footer, div.header {
+  clear: both;
   font-size: smaller }
 
 div.line-block {
@@ -100,7 +112,7 @@ div.line-block div.line-block {
 div.sidebar {
   margin-left: 1em ;
   border: medium outset ;
-  padding: 0em 1em ;
+  padding: 1em ;
   background-color: #ffffee ;
   width: 40% ;
   float: right ;
@@ -127,32 +139,28 @@ div.system-message p.system-message-title {
 div.topic {
   margin: 2em }
 
-h1 {
-  font-family: Arial, sans-serif;
-  font-size: 20px;
-}
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+  margin-top: 0.4em }
 
 h1.title {
- text-align: center;
- font-size: 32px;
-}
-
-h2 {
- font-size: 16px;
- font-family: Arial, sans-serif;
-}
+  text-align: center }
 
 h2.subtitle {
   text-align: center }
 
-h3 {
- font-size: 12px;
- font-family: Arial, sans-serif;
-}
-
-hr {
+hr.docutils {
   width: 75% }
 
+img.align-left {
+  clear: left }
+
+img.align-right {
+  clear: right }
+
+img.borderless {
+  border: 0 }
+
 ol.simple, ul.simple {
   margin-bottom: 1em }
 
@@ -216,11 +224,7 @@ pre.line-block {
 pre.literal-block, pre.doctest-block {
   margin-left: 2em ;
   margin-right: 2em ;
-  background-color: #eeeeee;
-  border-color: #000000;
-  border-width: thin; 
-  font-size: 14px
-}
+  background-color: #eeeeee }
 
 span.classifier {
   font-family: sans-serif ;
@@ -236,46 +240,47 @@ span.interpreted {
 span.option {
   white-space: nowrap }
 
-span.option-argument {
-  font-style: italic }
-
 span.pre {
   white-space: pre }
 
 span.problematic {
   color: red }
 
-table {
-  margin-top: 0.5em ;
-  margin-bottom: 0.5em }
+span.section-subtitle {
+  /* font-size relative to parent (h1..h6 element) */
+  font-size: 80% }
 
 table.citation {
-  border-left: solid thin gray ;
-  padding-left: 0.5ex }
+  border-left: solid thin gray }
 
 table.docinfo {
-  margin: 2em 4em;
-}
+  margin: 2em 4em }
+
+table.docutils {
+  margin-top: 0.5em ;
+  margin-bottom: 0.5em }
 
 table.footnote {
-  border-left: solid thin black ;
-  padding-left: 0.5ex }
+  border-left: solid thin black }
 
-td, th {
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
   padding-left: 0.5em ;
   padding-right: 0.5em ;
   vertical-align: top }
 
-th.docinfo-name, th.field-name {
+table.docutils th.field-name, table.docinfo th.docinfo-name {
   font-weight: bold ;
   text-align: left ;
-  white-space: nowrap;
-  }
+  white-space: nowrap ;
+  padding-left: 0 }
 
-h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
   font-size: 100% }
 
-tt {}
+tt.docutils {
+  background-color: #eeeeee }
 
 ul.auto-toc {
   list-style-type: none }
@@ -325,7 +330,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,42 +341,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>
+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
+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 interpret the value properly.</p>
+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>
@@ -388,16 +394,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
@@ -412,30 +421,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
@@ -444,26 +445,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>
@@ -499,8 +504,8 @@ implementation {
 </div>
 <div class="section">
 <h1><a id="directory-organization-guidelines" name="directory-organization-guidelines">4. 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
+<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
@@ -538,7 +543,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
@@ -548,13 +553,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
@@ -564,7 +569,7 @@ 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">
@@ -651,6 +656,7 @@ 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();
@@ -660,34 +666,38 @@ implementation {
   ReadStream = AdcReadStreamClientC;
 
   components HamamatsuS1087ParP;
-  AdcReadClientC.Msp430Adc12Config -&gt; HamamatsuS1087ParP;
-  AdcReadStreamClientC.Msp430Adc12Config -&gt; 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 Msp430Adc12Config;
+  provides interface AdcConfigure&lt;const msp430adc12_channel_config_t*&gt;;
+  provides interface DeviceMetadata;
 }
 implementation {
 
-  async command msp430adc12_channel_config_t
-    Msp430Adc12Config.getChannelSettings() {
-
-    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
-    };
-
-    return config;
+  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>
@@ -709,17 +719,18 @@ 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;
-
-  Get = UserButtonLogicP;
-  Notify = UserButtonLogicP;
 }
 </pre>
 <pre class="literal-block">
@@ -728,9 +739,10 @@ 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;
+  uses interface GpioInterrupt; 
 }
 implementation {
   norace bool m_pinHigh;
@@ -766,15 +778,17 @@ implementation {
   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">
@@ -824,15 +838,19 @@ 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() {
+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;
 
@@ -850,8 +868,10 @@ 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;
@@ -876,6 +896,8 @@ implementation {
     signal Temperature.readDone( result, val );
   }
 
+  command uint8_t TemperatureDeviceMetadata.getSignificantBits() { return 14; }
+
   command error_t Humidity.read() {
     call HumResource.request();
     return SUCCESS;
@@ -894,6 +916,8 @@ implementation {
     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 ) { }
@@ -924,7 +948,7 @@ implementation {
   SensirionSht11LogicP.DATA -&gt; HplSensirionSht11C.DATA;
   SensirionSht11LogicP.CLOCK -&gt; HplSensirionSht11C.SCK;
   SensirionSht11LogicP.InterruptDATA -&gt; HplSensirionSht11C.InterruptDATA;
-
+  
   components new TimerMilliC();
   SensirionSht11LogicP.Timer -&gt; TimerMilliC;
 
@@ -963,7 +987,7 @@ configuration HplSensirionSht11C {
 }
 implementation {
   components HplMsp430GeneralIOC;
-
+  
   components new Msp430GpioC() as DATAM;
   DATAM -&gt; HplMsp430GeneralIOC.Port15;
   DATA = DATAM;
@@ -990,7 +1014,7 @@ implementation {
 
   components new FcfsArbiterC( &quot;Sht11.Resource&quot; ) as Arbiter;
   Resource = Arbiter;
-
+  
   components new SplitControlPowerManagerC();
   SplitControlPowerManagerC.SplitControl -&gt; HplSensirionSht11P;
   SplitControlPowerManagerC.ArbiterInit -&gt; Arbiter.Init;
@@ -1017,7 +1041,7 @@ implementation {
     call Timer.startOneShot( 11 );
     return SUCCESS;
   }
-
+  
   event void Timer.fired() {
     signal SplitControl.startDone( SUCCESS );
   }
index d0343687aed9e4da7d15ef86bec96699507adcb0..b4df69526421979689faa6aeddf6a4be3ad04813 100644 (file)
@@ -47,7 +47,11 @@ $ tos-check-env
          useful.</p>
 
       <p>If your system says some command is not available, then
-         chances are you need to install the TinyOS tools (tos-*).
+         chances are you need to install the TinyOS tools (tos-*) RPM.
+         Please refer to your installation instructions. If you have
+         installed the RPM, then look in /usr/bin and /usr/local/bin
+         for tos-check-env. If you have downloaded from CVS rather than
+         used RPMs, then you need to compile and build the tools.
          Go to <code>tinyos-2.x/tools/tinyos</code> and type:</p>
 
 <pre>
index 3c84d999e467191cb8a4b17652bbaf7dcdbbee99..a159b9b22addb152f4f835cf884bd6262391e0bd 100644 (file)
@@ -548,7 +548,11 @@ and you will see the Leds of your impersonated (by a telos) yamp node Blinking!
 <br>
 <hr>
 <center>
-<p>&lt;&nbsp;<b><a href="index.html">Top</a></b> 
+                                             <p>&lt;&nbsp;<b><a href="lesson8.html">Previous Lesson</a></b> |&nbsp; <b><a
+ href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson11.html">Next
+Lesson </a>&nbsp;&gt;</b>
+</p>
+
 &nbsp;</b>
 </center>
 
index d733529319587d1b1e3404125af1f55607a38e87..95b640e82ca6cf4b7033d8d76bce7f3a06daae64 100644 (file)
@@ -1227,7 +1227,7 @@ int main() {
 all:
         make micaz sim
         g++ -g -c -o Driver.o Driver.c -I../../tos/lib/tossim/
-        g++ -o Driver Driver.o build/micaz/tossim.o build/micaz/sim.o
+        g++ -o Driver Driver.o build/micaz/tossim.o build/micaz/sim.o build/micaz/c-support.o
       </pre>
         
 
@@ -1351,12 +1351,12 @@ This lesson introduced the basics of the TOSSIM simulator. It showed
 you how to configure a network, how to run a simulation, how to
 inspect variables, how to inject packets, and how to compile with C++.
 
-
-<p><b><a href="lesson5.html">&lt; Previous Lesson</a></b> 
-&nbsp;|&nbsp; 
-<b><a href="lesson13.html">Next Lesson </a>&nbsp;&gt;</b>
-<b><a
- href="index.html">Top</a></b>
+<center>
+<p>&lt;&nbsp;<b><a href="lesson10.html">Previous Lesson</a></b> |&nbsp; <b><a
+ href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson12.html">Next
+Lesson </a>&nbsp;&gt;</b>
+</p>
+</center>
 
 </body>
 </html>
index 719e3dce7ea458170ce460fc177b58057033f2cc..dfdc721a4f182be2c77e8aad2ab5faaf7ae911bd 100644 (file)
@@ -197,8 +197,8 @@ into a single application.<br>
 </p>
 <hr><br>
 <center>
-<p>&lt;&nbsp;<b><a href="lesson1.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson3.html">Next
+<p>&lt;&nbsp;<b><a href="lesson11.html">Previous Lesson</a></b> |&nbsp; <b><a
+ href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson13.html">Next
 Lesson </a>&nbsp;&gt;</b>
 </p>
 </center>
index 7d838a78f43140cea2f373fad7e23b7cdbc1d71e..3af80d7b51fe5d7915cb60d76c0884322a351cbc 100644 (file)
@@ -254,7 +254,7 @@ From <a href="../../pdf/tinyos-programming.pdf">
 <hr>
 <center>
 <p>&lt;&nbsp;<b><a href="lesson5.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson11.html">Next Lesson </a>&nbsp;&gt;</b>
+ href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson7.html">Next Lesson </a>&nbsp;&gt;</b>
 </center>
 
 </body>
index ee7f9f3db4bf2f2201d89ded486179dd8ff1c5b7..232133d5b5044f7678c5d55b64b9b266400964d9 100644 (file)
 <body>\r
 \r
 <div class="title">Lesson 8: Resource Arbitration and Power Management </div>\r
-<div class="subtitle">Last updated 30 October 2006</div>
-
-<h1>Introduction</h1>
-
-<p>
-TinyOS distinguishes between three kinds of resource abstractions: <b>dedicated</b>, <b>virtualized</b>, and <b>shared</b>. Two fundamental questions must be asked about each type of abstraction.
-<ol>
-<li>How can a client gain access to the resource provided through this abstraction?</li>
-<li>How can the power state of that resource be controlled?</li>
-</ol>
-Components offer resource sharing mechanisms and power mangement capabilites according to the goals and level of abstraction required by their clients.
-</p>
-
-<hr>
-
-<p>
-An abstraction is dedicated if it represents a resource which a subsystem needs exclusive access to at all times. In this class of resources, no sharing policy is needed since only a single component ever requires use of the resource.  Resource clients simply call commands from the interfaces provided by the resource just as they would with any other TinyOS component.  Resources of this type provide either an <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interface for controlling their power states.  The definition of each of these interfaces can be found in <tt>tinyos-2.x/tos/interfaces</tt>.
-</p>
-
-<pre>
-interface AsyncStdControl {
-  async command error_t start();
-  async command error_t stop();
-}
-</pre>
-
-<pre>
-interface StdControl {
-  command error_t start();
-  command error_t stop();
-}
-</pre>
-
-<pre>
-interface SplitControl {
-  async command error_t start();
-  async command void startDone(error_t error);
-  async command error_t stop();
-  async command void stopDone(error_t error);
-}
-</pre>
-
-<p>
-Currently, the power states of all dedicated resources are controlled by one of these three interfaces.  They are only allowed to enter one of two logical power states (on/off), regardless of the number of physical power states provided by the hardware on top of which their resource abstraction has been built. Which of these interfaces is provided by a particular resource depends on the timing requirements for physically powering it on or off.
-<p>
-
-<hr>
-
-<p>
-Virtual abstractions hide multiple clients from each other through software virtualization. Every client of a virtualized resource interacts with it as if it were a dedicated resource, with all virtualized instances being multiplexed on top of a single underlying resource. Because the virtualization is done in software, there is no upper bound on the number of clients using the abstraction, barring memory or efficiency constraints.  The power states of a virtualized resource are handled automatically, and no interface is provided to the user for explicity controlling its power state.  As they are built on top of shared resources, the reason their power states can be automatically controlled will become clearer after reading the following section.
-</p>
-
-<hr>
-
-<p>
-Dedicated abstractions are useful when a resource is always controlled by a single component. Virtualized abstractions are
-useful when clients are willing to pay a bit of overhead and sacrifice control in order to share a resource in a simple way. There are situations, however, when many clients need precise control of a resource. Clearly, they can't all have such control at the same time:  some degree of multiplexing is needed.
-</p>
-
-<p>
-A motivating example of a shared resource is a bus. The bus may have multiple peripherals on it, corresponding to 
-different subsystems. For example, on the Telos platform the flash chip (storage) and the radio (network) share a bus. The storage and network stacks need exclusive access to the bus when using it, but they also need to share it with the other subsystem. In this case, virtualization is problematic, as the radio stack needs to be able to perform a series of operations in quick succession without having to reacquire the bus in each case. Having the bus be a shared resource allows the radio stack to send a series of operations to the radio atomically, without having to buffer them all up 
-in memory beforehand (introducing memory pressure in the process).
-</p>
-
-<p>
-In TinyOS, a resource <b>arbiter</b> is responsible for multiplexing between the different clients of a shared resource. It determines which client has access to the resource at which time. While a client holds a resource, it has complete and unfettered control. Arbiters assume that clients are cooperative, only acquiring the resource when needed 
-and holding on to it no longer than necessary. Clients explicitly release resources: there is no way for an arbiter to forcibly reclaim it.
-</p>
-
-<p>
-Shared resources are essentially built on top of dedicated resources, with access to them being controlled by an arbiter component.  In this way, <b>power managers</b> can be used to automatically control the power state of these resources through their <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interfaces.  They communicate with the arbiter (through the use of a <tt>ResourceController</tt> interface), monitoring whether the resource is being used by any of its clients and powering it on/off accordingly.  The figure below shows how an arbiter component and a power manager can be wired together to provide arbitration and automatic power management for a shared resource.
-</p>
-
-<center>
-<img src="img/arbiter_pm_graph.png",
-     alt="This is a picture of how an arbiter and power manager work together", 
-     height=225
-     center
-></img><br>
-Figure 1: Arbiters and Power Managers
-</center>
-
-<p>
-The arbiter component provides the <tt>Resource</tt>, <tt>ArbiterInfo</tt>, <tt>ResourceRequested</tt>, and <tt>ResourceController</tt> interfaces and uses the <tt>ResourceConfigure</tt> interface.  The power manager doesn't provide any interfaces, but uses one of either the <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interfaces from the underlying resource, as well as the <tt>ResourceController</tt> interface provided by the arbiter.  The figure below shows how these interface are then wired together with the implementation of a shared resource.  Please refer to TEP 108 for more information on arbiters and TEP 115 for more information on Power Managers.
-</p>
-
-<center>
-<img src="img/shared_resource_graph.png",
-     alt="This is a picture of how a shared resource works together with an arbiter and a power manager", 
-     height=450
-     center
-></img><br>
-Figure 2: Shared Resource Configuration
-</center>
-
-<p>
-From this figure, we see that the only interfaces exposed to a client through the shared resource abstraction are the <tt>Resource</tt> and <tt>ResourceRequested</tt> interfaces provided by the arbiter as well as any resource specific interfaces provided by the resource itself.  It also uses a <tt>ResourceConfigure</tt> interface, expecting it to be  implemented on a client by client basis depending on their requirements. A client requests access to a shared resource through the <tt>Resource</tt> interface and runs operations on it using whatever resource specific interfaces are provided.  A client may choose to wire itself to the <tt>ResourceRequested</tt> interface if it wishes to hold onto a resource indefinitely and be informed whenever other clients request its use.
-</p>  
-
-<p>
-The rest of this tutorial is dedicated to teaching users how to use shared resources and show them how wiring is done between all components that make them up.</p>
-<p>
-Specifically, this tutorial will teach users how to:
-<ol> 
-<li> Wire in a shared resource for use by a client.
-<li> Use the <tt>Resource</tt> interface to gain access to a shared resource.</li>
-<li> Change the arbitration policy used by a particular shared resource.</li>
-<li> Wire up a power manager for use by a shared resource.</li>
-</ol>
-</p>
-
-<h1>Working with Shared Resources</h1>
-<p>This section shows you how to gain access to and use shared resources in TinyOS.  It walks through the process of making a request through the <code>Resource</code> interface and handling the <tt>granted</tt> event that is signaled back.  We will connect multiple clients to a single shared resources and see how access to each of them gets arbitrated.  We also show how to hold onto a resource until another client has requested it by implementing the <tt>ResourceRequested</tt> interface.
-</p>
-
-<p>To begin, go to the <tt>tinyos-2.x/apps/tests/TestSharedResource</tt> directory and install this application on a mote.  After installing the application you should see three leds flashing in sequence.</p> 
-
-<p>Let's take a look at the different components contained in this directory to see whats going on.  Start with the top level application component: <code>TestSharedResourceAppC</code></p>
-
-<pre>
-configuration TestSharedResourceAppC{
-}
-implementation {
-  components MainC,LedsC, TestSharedResourceC as App,
-  new TimerMilliC() as Timer0,
-  new TimerMilliC() as Timer1,
-  new TimerMilliC() as Timer2;
-  App -> MainC.Boot;
-  App.Leds -> LedsC;
-  App.Timer0 -> Timer0;
-  App.Timer1 -> Timer1;
-  App.Timer2 -> Timer2;
-  
-  components
-  new SharedResourceC() as SharedResource0,
-  new SharedResourceC() as SharedResource1, 
-  new SharedResourceC() as SharedResource2;
-  App.Resource0 -> SharedResource0;
-  App.Resource1 -> SharedResource1;
-  App.Resource2 -> SharedResource2;
-  App.ResourceOperations0 -> SharedResource0;
-  App.ResourceOperations1 -> SharedResource1;
-  App.ResourceOperations2 -> SharedResource2;
-}
-</pre>
-
-<p>Other than the instantiation and wiring of the interfaces provided by the <code>SharedResourceC</code> component, this configuration is identical to the one presented in Lesson 1 for the Blink Application.</p>  
-
-<p>All shared resources in TinyOS are provided through a generic component similar to the <code>SharedResourceC</code> component.  A resource client simply instantiates a new instance of this component and wires to the interfaces it provides.  In this application, three instances of the <code>SharedResourceC</code> component are instantiated and wired to three different clients from the <code>TestSharedResourceC</code> component.  Each instantiation provides a <tt>Resource</tt>, <tt>ResourceOperations</tt>, and <tt>ResourceRequested</tt> interface, and uses a <tt>ResourceConfgigure</tt> interface. In this example, no wiring is done to the <tt>ResourceConfigure</tt> or <tt>ResourceRequested</tt> interface as wiring to to these interfaces is optional.  The <tt>ResourceOperations</tt> interface is an <b>EXAMPLE</B> of a resource specific interface that a resource may provide to perform operations on it.  Calls to commands through this interface will only succeed if the client calling them happens to have access to the resource when they are called.
-</p>
-
-<p>Let's take a look at the <code>TestSharedResourceC</code> to see how access is actually granted to a Resource.
-</p>
-
-<pre>
-module TestSharedResourceC {
-  uses {
-    interface Boot;  
-    interface Leds;
-    interface Timer<TMilli> as Timer0;
-    interface Timer<TMilli> as Timer1;
-    interface Timer<TMilli> as Timer2;
-    
-    interface Resource as Resource0;
-    interface ResourceOperations as ResourceOperations0;
-    
-    interface Resource as Resource1;
-    interface ResourceOperations as ResourceOperations1;
-    
-    interface Resource as Resource2;
-    interface ResourceOperations as ResourceOperations2;
-  }
-}
-</pre>
-
-<p>Each pair of <code>Resource/ResourceOperations</code> interfaces reperesents a different client of the shared resource used by this application.  At boot time, we put in a request for the shared resource through each of these clients in the order (0,2,1).</p>
-
-<pre>
-event void Boot.booted() {
-  call Resource0.request();
-  call Resource2.request();
-  call Resource1.request();
-}
-</pre>
-
-<p>Each of these requests is serviced in the order of the arbitration policy used by the shared resource.  In the case of <code>SharedResourceC</code>, a Round-Robin policy is used, so these requests are serviced in the order (0,1,2).  If a first-come-first-serve policy were in use, they would we be serviced in the order the were put in, i.e. (0,2,1).</p>
-
-<p>Whenever a client's request for a resource has been granted, the <code>Resource.granted()</code> event for that client gets signaled.  In this application, the body of the granted event for each client simply performs an operation on the resource as provided through the <code>ResourceOperations</code> interface.</p>
-
-<pre>
-event void Resource0.granted() {
-  call ResourceOperations0.operation();   
-}  
-event void Resource1.granted() {
-  call ResourceOperations1.operation();
-}  
-event void Resource2.granted() {
-  call ResourceOperations2.operation();
-} 
-</pre>
-
-<p>Whenever one of these operations completes, a <code>ResourceOperations.operationDone()</code> event is signaled.  Once this event is received by each client, a timer is started to hold onto the resource for 250 (binary) ms and an LED corresponding to that client is toggled.</p>
-
-<pre>
-#define HOLD_PERIOD 250
-
-event void ResourceOperations0.operationDone(error_t error) {
-  call Timer0.startOneShot(HOLD_PERIOD);  
-  call Leds.led0Toggle();
-}
-event void ResourceOperations1.operationDone(error_t error) {
-  call Timer1.startOneShot(HOLD_PERIOD);  
-  call Leds.led1Toggle();
-}
-event void ResourceOperations2.operationDone(error_t error) {
-  call Timer2.startOneShot(HOLD_PERIOD);  
-  call Leds.led2Toggle();
-}
-</pre> 
-
-<p>Whenever one of these timers goes off, the client that started it releases the resource and immediately puts in a request for it again.</p>
-
-<pre>
-event void Timer0.fired() {
-  call Resource0.release();
-  call Resource0.request();
-}
-event void Timer1.fired() {
-  call Resource1.release();
-  call Resource1.request();
-}
-event void Timer2.fired() {
-  call Resource2.release();
-  call Resource2.request();
-}
-</pre>
-
-<p>In this way, requests are continuously put in by each client, allowing the application to continuously flash the LEDs in the order in which requests are being serviced.  As stated before, the <code>SharedResourceC</code> component services these requests in a round-robin fashion.  If you would like to see the requests serviced in the order they are received (and see the LEDs flash accordingly), you can open up the <code>SharedResourceP</code> component in the <tt>apps/tests/TestSharedResource</tt> directory and replace the <code>RoundRobinArbiter</code> component with the <code>FcfsArbiter</code> component.</p>
-
-<table>
- <tr><td><b>RoundRobinArbiter</b></td><td width=10></td><td><b>FcfsArbiter</b></td></tr>
- <tr><td>
-<pre>
-configuration SharedResourceP {
-       provides interface Resource[uint8_t id];
-       provides interface ResourceRequested[uint8_t id];
-       provides interface ResourceOperations[uint8_t id];
-       uses interface ResourceConfigure[uint8_t id];
-}
-implementation {
-  components new RoundRobinArbiterC(TEST_SHARED_RESOURCE) as Arbiter;
-  ...
-  ...
-}
-</pre>
-</td>
-<td></td>
-<td>
-<pre>
-configuration SharedResourceP {
-       provides interface Resource[uint8_t id];
-       provides interface ResourceRequested[uint8_t id];
-       provides interface ResourceOperations[uint8_t id];
-       uses interface ResourceConfigure[uint8_t id];
-}
-implementation {
-  components new FcfsArbiterC(TEST_SHARED_RESOURCE) as Arbiter;
-  ...
-  ...
-}
-</pre>
-</td>
-</tr>
-</table>
-</center>
-</table>
-
-<p>Looking through the rest of this component, you can see how its wiring matches the connections shown in Figure 2.</p>
-
-<pre>
-#define TEST_SHARED_RESOURCE   "Test.Shared.Resource"
-configuration SharedResourceP {
-       provides interface Resource[uint8_t id];
-       provides interface ResourceRequested[uint8_t id];
-       provides interface ResourceOperations[uint8_t id];
-       uses interface ResourceConfigure[uint8_t id];
-}
-implementation {
-  components new RoundRobinArbiterC(TEST_SHARED_RESOURCE) as Arbiter;
-  components new SplitControlPowerManagerC() as PowerManager;
-  components ResourceP;
-  components SharedResourceImplP;
-
-  ResourceOperations = SharedResourceImplP;
-  Resource = Arbiter;
-  ResourceRequested = Arbiter;
-  ResourceConfigure = Arbiter;
-  SharedResourceImplP.ArbiterInfo -> Arbiter;
-  PowerManager.ResourceController -> Arbiter;
-  
-  PowerManager.SplitControl -> ResourceP;
-  SharedResourceImplP.ResourceOperations -> ResourceP;
-}
-</pre>
-
-<p>
-Four different components are instantiated by this configuration:
-</p>
-
-<pre>
-components new RoundRobinArbiterC(TEST_SHARED_RESOURCE) as Arbiter;
-components new SplitControlPowerManagerC() as PowerManager;
-components ResourceP;
-components SharedResourceImplP;
-</pre>
-
-<p>
-As we've already seen, the <tt>RoundRobinArbiterC</tt> component is used to provide arbitration between clients using <tt>SharedResourceC</tt>.  The <tt>SplitControlPowerManagerC</tt> component is used to perform automatic power management of the resource to turn it on whenever a new client requests its use and shut it down whenever it goes idle.  The <tt>ResourceP</tt> component is the implementation of a dedicated resource which provides a <tt>SplitControl</tt> interface and a <tt>ResourceOperations</tt> interface.  This dedicated resource is wrapped by the <tt>SharedResourceImplP</tt> component in order to provide protected shared access to it.  <tt>SharedResourceImplP</tt> wraps all the commands provided by the dedicated resource, and uses the <tt>ArbiterInfo</tt> interface to keep clients from calling them without first being granted access to the resource.
-</p>
-
-<p>
-If you would like to see more examples of how to use the different arbiters and power managers provided in the default TinyOS distribution, please refer to the test applications located in <tt>tinyos-2.x/apps/tests/TestArbiter</tt> and <tt>tinyos-2.x/apps/tests/TestPowerManager</tt>.  This tutorial has provided enough background information on how to use these components in order for you to sift through these applications on your own. 
-</p>
-
-<h1>Conclusion</h1>
-<p>
-This tutorial has given an overview of how resource arbitration and mechanisms for performing power management on those resources is provided in TinyOS.  It walked us through the steps necessary for:
-<ol> 
-<li> Wiring in a shared resource for use by a client.
-<li> Using the <tt>Resource</tt> interface to gain access to a shared resource.</li>
-<li> Changing the arbitration policy used by a particular shared resource.</li>
-<li> Wrapping a dedicated resource and wiring in a power manager in order to create a shared resource.</li>
-</ol>
-</p>
-
-<p>
-While the power managers presented in this tutorial are powerful components for providing power management of shared reosurces, they are not the only power management mechanisms provided by TinyOS.  Microcontroller power management is also preformed as outlined in TEP115.  Whenever the task queue empties, the lowest power state that the microcontroller is capapble of dropping to is automatically calculated and then switched to.  In this way, the user is not burdened with explicity controlling these power states.  The cc1000 and cc2420 radio implementations also provide "Low Power Listening" (LPL) interfaces for controlling their duty cycles.  Although the LPL interface used by each radio stack differs somewhat, they are both able to provide energy savings not achieveable through other means.  Ultimately we would like to see the components providing this LPL interface implemented as power manager components for the "radio resource" and be wired to the radio in the same way as the other power managers described in this tutorial.  The LPL implementation for the cc2420 can be found under <tt>tinyos-2.x/tos/chips/cc2420_lpl</tt> and the LPL implementation for the cc1000 can be found under <tt>tinyos-2.x/tos/chips/cc1000</tt>.  As these interfaces begin to mature and merge into one, this tutorial will be updated appropriately to accomodate the change.
-</p>
-
-<!-- Related Docs -->
-<p>
-<a name=#related_docs>
-<h1>Related Documentation</h1>
-</a>
-<ul>
-<li> <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide                   
-       <i>Sections 6.2 and 7.4</i></a>
-<li> <a href="../tep108.html">TEP 108: Resource Arbitration</a>
-<li> <a href="../tep112.html">TEP 112: Microcontroller Power Management</a>
-<li> <a href="../tep115.html">TEP 115: Power Management of Non-Virtualized Devices</a>
-</ul>
-
-<p>
-<hr>
-
-<!-- Begin footer -->
-<br>
-<hr>
-<center>
-<p>&lt;&nbsp;<b><a href="lesson7.html">Previous Lesson</a></b> |&nbsp; <b><a
- href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson9.html">Next Lesson </a>&nbsp;&gt;</b>
-</center>
-
-</body>
-</html>
+<div class="subtitle">Last updated 30 October 2006</div>\r
+\r
+<h1>Introduction</h1>\r
+\r
+<p>\r
+TinyOS distinguishes between three kinds of resource abstractions: <b>dedicated</b>, <b>virtualized</b>, and <b>shared</b>. Two fundamental questions must be asked about each type of abstraction.\r
+<ol>\r
+<li>How can a client gain access to the resource provided through this abstraction?</li>\r
+<li>How can the power state of that resource be controlled?</li>\r
+</ol>\r
+Components offer resource sharing mechanisms and power mangement capabilites according to the goals and level of abstraction required by their clients.\r
+</p>\r
+\r
+<hr>\r
+\r
+<p>\r
+An abstraction is dedicated if it represents a resource which a subsystem needs exclusive access to at all times. In this class of resources, no sharing policy is needed since only a single component ever requires use of the resource.  Resource clients simply call commands from the interfaces provided by the resource just as they would with any other TinyOS component.  Resources of this type provide either an <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interface for controlling their power states.  The definition of each of these interfaces can be found in <tt>tinyos-2.x/tos/interfaces</tt>.\r
+</p>\r
+\r
+<pre>\r
+interface AsyncStdControl {\r
+  async command error_t start();\r
+  async command error_t stop();\r
+}\r
+</pre>\r
+\r
+<pre>\r
+interface StdControl {\r
+  command error_t start();\r
+  command error_t stop();\r
+}\r
+</pre>\r
+\r
+<pre>\r
+interface SplitControl {\r
+  async command error_t start();\r
+  async command void startDone(error_t error);\r
+  async command error_t stop();\r
+  async command void stopDone(error_t error);\r
+}\r
+</pre>\r
+\r
+<p>\r
+Currently, the power states of all dedicated resources are controlled by one of these three interfaces.  They are only allowed to enter one of two logical power states (on/off), regardless of the number of physical power states provided by the hardware on top of which their resource abstraction has been built. Which of these interfaces is provided by a particular resource depends on the timing requirements for physically powering it on or off.\r
+<p>\r
+\r
+<hr>\r
+\r
+<p>\r
+Virtual abstractions hide multiple clients from each other through software virtualization. Every client of a virtualized resource interacts with it as if it were a dedicated resource, with all virtualized instances being multiplexed on top of a single underlying resource. Because the virtualization is done in software, there is no upper bound on the number of clients using the abstraction, barring memory or efficiency constraints.  The power states of a virtualized resource are handled automatically, and no interface is provided to the user for explicity controlling its power state.  As they are built on top of shared resources, the reason their power states can be automatically controlled will become clearer after reading the following section.\r
+</p>\r
+\r
+<hr>\r
+\r
+<p>\r
+Dedicated abstractions are useful when a resource is always controlled by a single component. Virtualized abstractions are\r
+useful when clients are willing to pay a bit of overhead and sacrifice control in order to share a resource in a simple way. There are situations, however, when many clients need precise control of a resource. Clearly, they can't all have such control at the same time:  some degree of multiplexing is needed.\r
+</p>\r
+\r
+<p>\r
+A motivating example of a shared resource is a bus. The bus may have multiple peripherals on it, corresponding to \r
+different subsystems. For example, on the Telos platform the flash chip (storage) and the radio (network) share a bus. The storage and network stacks need exclusive access to the bus when using it, but they also need to share it with the other subsystem. In this case, virtualization is problematic, as the radio stack needs to be able to perform a series of operations in quick succession without having to reacquire the bus in each case. Having the bus be a shared resource allows the radio stack to send a series of operations to the radio atomically, without having to buffer them all up \r
+in memory beforehand (introducing memory pressure in the process).\r
+</p>\r
+\r
+<p>\r
+In TinyOS, a resource <b>arbiter</b> is responsible for multiplexing between the different clients of a shared resource. It determines which client has access to the resource at which time. While a client holds a resource, it has complete and unfettered control. Arbiters assume that clients are cooperative, only acquiring the resource when needed \r
+and holding on to it no longer than necessary. Clients explicitly release resources: there is no way for an arbiter to forcibly reclaim it.\r
+</p>\r
+\r
+<p>\r
+Shared resources are essentially built on top of dedicated resources, with access to them being controlled by an arbiter component.  In this way, <b>power managers</b> can be used to automatically control the power state of these resources through their <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interfaces.  They communicate with the arbiter (through the use of a <tt>ResourceController</tt> interface), monitoring whether the resource is being used by any of its clients and powering it on/off accordingly.  The figure below shows how an arbiter component and a power manager can be wired together to provide arbitration and automatic power management for a shared resource.\r
+</p>\r
+\r
+<center>\r
+<img src="img/arbiter_pm_graph.png",\r
+     alt="This is a picture of how an arbiter and power manager work together", \r
+     height=225\r
+     center\r
+></img><br>\r
+Figure 1: Arbiters and Power Managers\r
+</center>\r
+\r
+<p>\r
+The arbiter component provides the <tt>Resource</tt>, <tt>ArbiterInfo</tt>, <tt>ResourceRequested</tt>, and <tt>ResourceController</tt> interfaces and uses the <tt>ResourceConfigure</tt> interface.  The power manager doesn't provide any interfaces, but uses one of either the <tt>AsyncStdControl</tt>, <tt>StdControl</tt>, or <tt>SplitControl</tt> interfaces from the underlying resource, as well as the <tt>ResourceController</tt> interface provided by the arbiter.  The figure below shows how these interface are then wired together with the implementation of a shared resource.  Please refer to TEP 108 for more information on arbiters and TEP 115 for more information on Power Managers.\r
+</p>\r
+\r
+<center>\r
+<img src="img/shared_resource_graph.png",\r
+     alt="This is a picture of how a shared resource works together with an arbiter and a power manager", \r
+     height=450\r
+     center\r
+></img><br>\r
+Figure 2: Shared Resource Configuration\r
+</center>\r
+\r
+<p>\r
+From this figure, we see that the only interfaces exposed to a client through the shared resource abstraction are the <tt>Resource</tt> and <tt>ResourceRequested</tt> interfaces provided by the arbiter as well as any resource specific interfaces provided by the resource itself.  It also uses a <tt>ResourceConfigure</tt> interface, expecting it to be  implemented on a client by client basis depending on their requirements. A client requests access to a shared resource through the <tt>Resource</tt> interface and runs operations on it using whatever resource specific interfaces are provided.  A client may choose to wire itself to the <tt>ResourceRequested</tt> interface if it wishes to hold onto a resource indefinitely and be informed whenever other clients request its use.\r
+</p>  \r
+\r
+<p>\r
+The rest of this tutorial is dedicated to teaching users how to use shared resources and show them how wiring is done between all components that make them up.</p>\r
+<p>\r
+Specifically, this tutorial will teach users how to:\r
+<ol> \r
+<li> Wire in a shared resource for use by a client.\r
+<li> Use the <tt>Resource</tt> interface to gain access to a shared resource.</li>\r
+<li> Change the arbitration policy used by a particular shared resource.</li>\r
+<li> Wire up a power manager for use by a shared resource.</li>\r
+</ol>\r
+</p>\r
+\r
+<h1>Working with Shared Resources</h1>\r
+<p>This section shows you how to gain access to and use shared resources in TinyOS.  It walks through the process of making a request through the <code>Resource</code> interface and handling the <tt>granted</tt> event that is signaled back.  We will connect multiple clients to a single shared resources and see how access to each of them gets arbitrated.  We also show how to hold onto a resource until another client has requested it by implementing the <tt>ResourceRequested</tt> interface.\r
+</p>\r
+\r
+<p>To begin, go to the <tt>tinyos-2.x/apps/tests/TestSharedResource</tt> directory and install this application on a mote.  After installing the application you should see three leds flashing in sequence.</p> \r
+\r
+<p>Let's take a look at the different components contained in this directory to see whats going on.  Start with the top level application component: <code>TestSharedResourceAppC</code></p>\r
+\r
+<pre>\r
+configuration TestSharedResourceAppC{\r
+}\r
+implementation {\r
+  components MainC,LedsC, TestSharedResourceC as App,\r
+  new TimerMilliC() as Timer0,\r
+  new TimerMilliC() as Timer1,\r
+  new TimerMilliC() as Timer2;\r
+  App -> MainC.Boot;\r
+  App.Leds -> LedsC;\r
+  App.Timer0 -> Timer0;\r
+  App.Timer1 -> Timer1;\r
+  App.Timer2 -> Timer2;\r
+  \r
+  components\r
+  new SharedResourceC() as SharedResource0,\r
+  new SharedResourceC() as SharedResource1, \r
+  new SharedResourceC() as SharedResource2;\r
+  App.Resource0 -> SharedResource0;\r
+  App.Resource1 -> SharedResource1;\r
+  App.Resource2 -> SharedResource2;\r
+  App.ResourceOperations0 -> SharedResource0;\r
+  App.ResourceOperations1 -> SharedResource1;\r
+  App.ResourceOperations2 -> SharedResource2;\r
+}\r
+</pre>\r
+\r
+<p>Other than the instantiation and wiring of the interfaces provided by the <code>SharedResourceC</code> component, this configuration is identical to the one presented in Lesson 1 for the Blink Application.</p>  \r
+\r
+<p>All shared resources in TinyOS are provided through a generic component similar to the <code>SharedResourceC</code> component.  A resource client simply instantiates a new instance of this component and wires to the interfaces it provides.  In this application, three instances of the <code>SharedResourceC</code> component are instantiated and wired to three different clients from the <code>TestSharedResourceC</code> component.  Each instantiation provides a <tt>Resource</tt>, <tt>ResourceOperations</tt>, and <tt>ResourceRequested</tt> interface, and uses a <tt>ResourceConfgigure</tt> interface. In this example, no wiring is done to the <tt>ResourceConfigure</tt> or <tt>ResourceRequested</tt> interface as wiring to to these interfaces is optional.  The <tt>ResourceOperations</tt> interface is an <b>EXAMPLE</B> of a resource specific interface that a resource may provide to perform operations on it.  Calls to commands through this interface will only succeed if the client calling them happens to have access to the resource when they are called.\r
+</p>\r
+\r
+<p>Let's take a look at the <code>TestSharedResourceC</code> to see how access is actually granted to a Resource.\r
+</p>\r
+\r
+<pre>\r
+module TestSharedResourceC {\r
+  uses {\r
+    interface Boot;  \r
+    interface Leds;\r
+    interface Timer<TMilli> as Timer0;\r
+    interface Timer<TMilli> as Timer1;\r
+    interface Timer<TMilli> as Timer2;\r
+    \r
+    interface Resource as Resource0;\r
+    interface ResourceOperations as ResourceOperations0;\r
+    \r
+    interface Resource as Resource1;\r
+    interface ResourceOperations as ResourceOperations1;\r
+    \r
+    interface Resource as Resource2;\r
+    interface ResourceOperations as ResourceOperations2;\r
+  }\r
+}\r
+</pre>\r
+\r
+<p>Each pair of <code>Resource/ResourceOperations</code> interfaces reperesents a different client of the shared resource used by this application.  At boot time, we put in a request for the shared resource through each of these clients in the order (0,2,1).</p>\r
+\r
+<pre>\r
+event void Boot.booted() {\r
+  call Resource0.request();\r
+  call Resource2.request();\r
+  call Resource1.request();\r
+}\r
+</pre>\r
+\r
+<p>Each of these requests is serviced in the order of the arbitration policy used by the shared resource.  In the case of <code>SharedResourceC</code>, a Round-Robin policy is used, so these requests are serviced in the order (0,1,2).  If a first-come-first-serve policy were in use, they would we be serviced in the order the were put in, i.e. (0,2,1).</p>\r
+\r
+<p>Whenever a client's request for a resource has been granted, the <code>Resource.granted()</code> event for that client gets signaled.  In this application, the body of the granted event for each client simply performs an operation on the resource as provided through the <code>ResourceOperations</code> interface.</p>\r
+\r
+<pre>\r
+event void Resource0.granted() {\r
+  call ResourceOperations0.operation();   \r
+}  \r
+event void Resource1.granted() {\r
+  call ResourceOperations1.operation();\r
+}  \r
+event void Resource2.granted() {\r
+  call ResourceOperations2.operation();\r
+} \r
+</pre>\r
+\r
+<p>Whenever one of these operations completes, a <code>ResourceOperations.operationDone()</code> event is signaled.  Once this event is received by each client, a timer is started to hold onto the resource for 250 (binary) ms and an LED corresponding to that client is toggled.</p>\r
+\r
+<pre>\r
+#define HOLD_PERIOD 250\r
+\r
+event void ResourceOperations0.operationDone(error_t error) {\r
+  call Timer0.startOneShot(HOLD_PERIOD);  \r
+  call Leds.led0Toggle();\r
+}\r
+event void ResourceOperations1.operationDone(error_t error) {\r
+  call Timer1.startOneShot(HOLD_PERIOD);  \r
+  call Leds.led1Toggle();\r
+}\r
+event void ResourceOperations2.operationDone(error_t error) {\r
+  call Timer2.startOneShot(HOLD_PERIOD);  \r
+  call Leds.led2Toggle();\r
+}\r
+</pre> \r
+\r
+<p>Whenever one of these timers goes off, the client that started it releases the resource and immediately puts in a request for it again.</p>\r
+\r
+<pre>\r
+event void Timer0.fired() {\r
+  call Resource0.release();\r
+  call Resource0.request();\r
+}\r
+event void Timer1.fired() {\r
+  call Resource1.release();\r
+  call Resource1.request();\r
+}\r
+event void Timer2.fired() {\r
+  call Resource2.release();\r
+  call Resource2.request();\r
+}\r
+</pre>\r
+\r
+<p>In this way, requests are continuously put in by each client, allowing the application to continuously flash the LEDs in the order in which requests are being serviced.  As stated before, the <code>SharedResourceC</code> component services these requests in a round-robin fashion.  If you would like to see the requests serviced in the order they are received (and see the LEDs flash accordingly), you can open up the <code>SharedResourceP</code> component in the <tt>apps/tests/TestSharedResource</tt> directory and replace the <code>RoundRobinArbiter</code> component with the <code>FcfsArbiter</code> component.</p>\r
+\r
+<table>\r
+ <tr><td><b>RoundRobinArbiter</b></td><td width=10></td><td><b>FcfsArbiter</b></td></tr>\r
+ <tr><td>\r
+<pre>\r
+configuration SharedResourceP {\r
+       provides interface Resource[uint8_t id];\r
+       provides interface ResourceRequested[uint8_t id];\r
+       provides interface ResourceOperations[uint8_t id];\r
+       uses interface ResourceConfigure[uint8_t id];\r
+}\r
+implementation {\r
+  components new RoundRobinArbiterC(TEST_SHARED_RESOURCE) as Arbiter;\r
+  ...\r
+  ...\r
+}\r
+</pre>\r
+</td>\r
+<td></td>\r
+<td>\r
+<pre>\r
+configuration SharedResourceP {\r
+       provides interface Resource[uint8_t id];\r
+       provides interface ResourceRequested[uint8_t id];\r
+       provides interface ResourceOperations[uint8_t id];\r
+       uses interface ResourceConfigure[uint8_t id];\r
+}\r
+implementation {\r
+  components new FcfsArbiterC(TEST_SHARED_RESOURCE) as Arbiter;\r
+  ...\r
+  ...\r
+}\r
+</pre>\r
+</td>\r
+</tr>\r
+</table>\r
+</center>\r
+</table>\r
+\r
+<p>Looking through the rest of this component, you can see how its wiring matches the connections shown in Figure 2.</p>\r
+\r
+<pre>\r
+#define TEST_SHARED_RESOURCE   "Test.Shared.Resource"\r
+configuration SharedResourceP {\r
+       provides interface Resource[uint8_t id];\r
+       provides interface ResourceRequested[uint8_t id];\r
+       provides interface ResourceOperations[uint8_t id];\r
+       uses interface ResourceConfigure[uint8_t id];\r
+}\r
+implementation {\r
+  components new RoundRobinArbiterC(TEST_SHARED_RESOURCE) as Arbiter;\r
+  components new SplitControlPowerManagerC() as PowerManager;\r
+  components ResourceP;\r
+  components SharedResourceImplP;\r
+\r
+  ResourceOperations = SharedResourceImplP;\r
+  Resource = Arbiter;\r
+  ResourceRequested = Arbiter;\r
+  ResourceConfigure = Arbiter;\r
+  SharedResourceImplP.ArbiterInfo -> Arbiter;\r
+  PowerManager.ResourceController -> Arbiter;\r
+  \r
+  PowerManager.SplitControl -> ResourceP;\r
+  SharedResourceImplP.ResourceOperations -> ResourceP;\r
+}\r
+</pre>\r
+\r
+<p>\r
+Four different components are instantiated by this configuration:\r
+</p>\r
+\r
+<pre>\r
+components new RoundRobinArbiterC(TEST_SHARED_RESOURCE) as Arbiter;\r
+components new SplitControlPowerManagerC() as PowerManager;\r
+components ResourceP;\r
+components SharedResourceImplP;\r
+</pre>\r
+\r
+<p>\r
+As we've already seen, the <tt>RoundRobinArbiterC</tt> component is used to provide arbitration between clients using <tt>SharedResourceC</tt>.  The <tt>SplitControlPowerManagerC</tt> component is used to perform automatic power management of the resource to turn it on whenever a new client requests its use and shut it down whenever it goes idle.  The <tt>ResourceP</tt> component is the implementation of a dedicated resource which provides a <tt>SplitControl</tt> interface and a <tt>ResourceOperations</tt> interface.  This dedicated resource is wrapped by the <tt>SharedResourceImplP</tt> component in order to provide protected shared access to it.  <tt>SharedResourceImplP</tt> wraps all the commands provided by the dedicated resource, and uses the <tt>ArbiterInfo</tt> interface to keep clients from calling them without first being granted access to the resource.\r
+</p>\r
+\r
+<p>\r
+If you would like to see more examples of how to use the different arbiters and power managers provided in the default TinyOS distribution, please refer to the test applications located in <tt>tinyos-2.x/apps/tests/TestArbiter</tt> and <tt>tinyos-2.x/apps/tests/TestPowerManager</tt>.  This tutorial has provided enough background information on how to use these components in order for you to sift through these applications on your own. \r
+</p>\r
+\r
+<h1>Conclusion</h1>\r
+<p>\r
+This tutorial has given an overview of how resource arbitration and mechanisms for performing power management on those resources is provided in TinyOS.  It walked us through the steps necessary for:\r
+<ol> \r
+<li> Wiring in a shared resource for use by a client.\r
+<li> Using the <tt>Resource</tt> interface to gain access to a shared resource.</li>\r
+<li> Changing the arbitration policy used by a particular shared resource.</li>\r
+<li> Wrapping a dedicated resource and wiring in a power manager in order to create a shared resource.</li>\r
+</ol>\r
+</p>\r
+\r
+<p>\r
+While the power managers presented in this tutorial are powerful components for providing power management of shared reosurces, they are not the only power management mechanisms provided by TinyOS.  Microcontroller power management is also preformed as outlined in TEP115.  Whenever the task queue empties, the lowest power state that the microcontroller is capapble of dropping to is automatically calculated and then switched to.  In this way, the user is not burdened with explicity controlling these power states.  The cc1000 and cc2420 radio implementations also provide "Low Power Listening" (LPL) interfaces for controlling their duty cycles.  Although the LPL interface used by each radio stack differs somewhat, they are both able to provide energy savings not achieveable through other means.  Ultimately we would like to see the components providing this LPL interface implemented as power manager components for the "radio resource" and be wired to the radio in the same way as the other power managers described in this tutorial.  The LPL implementation for the cc2420 can be found under <tt>tinyos-2.x/tos/chips/cc2420_lpl</tt> and the LPL implementation for the cc1000 can be found under <tt>tinyos-2.x/tos/chips/cc1000</tt>.  As these interfaces begin to mature and merge into one, this tutorial will be updated appropriately to accomodate the change.\r
+</p>\r
+\r
+<!-- Related Docs -->\r
+<p>\r
+<a name=#related_docs>\r
+<h1>Related Documentation</h1>\r
+</a>\r
+<ul>\r
+<li> <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide                   \r
+       <i>Sections 6.2 and 7.4</i></a>\r
+<li> <a href="../tep108.html">TEP 108: Resource Arbitration</a>\r
+<li> <a href="../tep112.html">TEP 112: Microcontroller Power Management</a>\r
+<li> <a href="../tep115.html">TEP 115: Power Management of Non-Virtualized Devices</a>\r
+</ul>\r
+\r
+<p>\r
+<hr>\r
+\r
+<!-- Begin footer -->\r
+<br>\r
+<hr>\r
+<center>\r
+<p>&lt;&nbsp;<b><a href="lesson7.html">Previous Lesson</a></b> |&nbsp; <b><a\r
+ href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson10.html">Next Lesson </a>&nbsp;&gt;</b>\r
+</center>\r
+\r
+</body>\r
+</html>\r
index f84f0c4fa0bb80a291f15e134be96dcc312b4647..4c9d1e5deb61d3e50df58ec4319aebb6b7ae79da 100644 (file)
@@ -351,16 +351,21 @@ For a module to have an earliest deadline first task, it uses the
 TaskEdf interface. Its configuration SHOULD wire it to TinySchedulerC.
 The key used for task unique identifiers MUST be "TinySchedulerC.TaskInterface",
 where *TaskInterface* is the name of the new task interface as presented
-by the scheduler.  For example, the module SomethingP requires two EDF
-tasks::
+by the scheduler.  A common way to make sure a consistent string is used
+is to #define it. For example, TaskEdf.nc might include::
+
+#define UQ_TASK_EDF "TinySchedulerC.TaskEdf"
 
+In this example, the module SomethingP requires two EDF
+tasks::
+  
   configuration SomethingC {  
     ...  
   }  
   implementation {  
     components SomethingP, TinySchedulerC;  
-    SomethingP.SendTask -> TinySchedulerC.TaskEdf["TinySchedulerC.TaskEdf"];  
-    SomethingP.SenseTask -> TinySchedulerC.TaskEdf["TinySchedulerC.TaskEdf"];  
+    SomethingP.SendTask -> TinySchedulerC.TaskEdf[unique(UQ_TASK_EDF)];  
+    SomethingP.SenseTask -> TinySchedulerC.TaskEdf[unique(UQ_TASK_EDF)];  
   }  
 
 The module SomethingP also has a basic task. The nesC compiler
index 12894aaba16d804cfa50e62a7a3304430ca167d4..08a451e525f082eb285f5c997a0c321119309dfc 100644 (file)
@@ -33,7 +33,7 @@ that provide access to sensors.
 This section describes the basic organization principles for sensor
 drivers in TinyOS.
 
-For background, a sensor may be attached to the microcontroller on a
+For background, a sensor can be attached to the microcontroller on a
 TinyOS platform through a few different types of connections:
 
  * Included within the microcontroller itself
@@ -42,49 +42,50 @@ TinyOS platform through a few different types of connections:
  * Connected to general-purpose IO pins for digital communication
  * Connected through a standard digital bus protocol (1-Wire, I2C, SPI)
 
-Physically, these connections may also be decoupled by attaching the
+Physically, these connections can also be decoupled by attaching the
 sensors to a `sensor board`, which can be removed from the TinyOS
-platform, and may fit multiple different TinyOS platforms.
+platform, and could attach to multiple different TinyOS platforms.
 
 The capabilities of a physical sensor are made available to a TinyOS
 application through a `sensor driver`. 
 
-According to the HAA [TEP2]_, TinyOS devices should provide both
+According to the HAA [TEP2]_, 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.
+drivers SHOULD follow this spirit as well.
 
 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.
 
-Sensors, being physical devices that may be shared, can benefit from
+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.
 
-The same physical sensor may be attached to multiple different TinyOS
+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.
 
 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.
+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.
 
 This document takes no position on the meaning of the values returned
-by sensor drivers. They may be raw uninterpreted values or they may
+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 interpret the value properly.
+the driver MAY provide additional interfaces that would allow
+higher-level clients to obtain information needed to properly
+interpret the value.
 
 2. Sensor HIL Components
 ====================================================================
@@ -102,17 +103,20 @@ A sensor device driver SHOULD be a generic component that virtualizes
 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.
+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.
 
 For example::
 
   generic configuration SensirionSht11C() {
     provides interface Read<uint16_t> as Temperature;
     provides interface ReadStream<uint16_t> as TemperatureStream;
+    provides interface DeviceMetadata as TemperatureDeviceMetadata;
+
     provides interface Read<uint16_t> as Humidity;
     provides interface ReadStream<uint16_t> as HumidityStream;
+    provides interface DeviceMetadata as HumidityDeviceMetadata;
   }
   implementation {
     // connect to the ADC HIL, GPIO HAL, or sensor's HAL
@@ -128,32 +132,24 @@ automatically. For sensors without a constant power draw, the sensor
 MAY be started once at boot time by wiring to the `MainC.Boot`
 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 [TEP115]_ may be useful for this purpose.
+some time after that call completes. Using one of the power-management
+components described in [TEP115]_ can make this implementation easier.
 
 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::
+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::
 
   interface DeviceMetadata {
     command uint8_t getSignificantBits();
   }
 
-The name of the instance of DeviceMetadata SHOULD clearly indicate
-which interface it corresponds to.
-
-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::
-
-  component DemoSensorC {
-    provides interface Read<uint16_t>;
-  }
+The name of the instance of DeviceMetadata MUST clearly indicate which
+interface it corresponds to.
 
-then the driver MAY shift the 12-bit value left so that its range is
-0x0000 - 0xfff0, rather than 0x0000 - 0x0fff. 
+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 "12". 
 
 Sensor driver components SHOULD be named according to the make and
 model of the sensing device being presented. Using specific names
@@ -164,26 +160,30 @@ 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.
 
-A "common" naming layer atop a HIL may look like this::
+A "common" naming layer atop a HIL might look like this::
 
   generic configuration TemperatureC() {
     provides interface Read<uint16_t>;
     provides interface ReadStream<uint16_t>;
+    provides interface DeviceMetadata;
   }
   implementation {
     components new SensirionSht11C();
     Read = SensirionSht11C.Temperature;
     ReadStream = SensirionSht11C.TemperatureStream;
+    DeviceMetadata = SensirionSht11C.TemperatureDeviceMetadata;
   }
 
   generic configuration HumidityC() {
     provides interface Read<uint16_t>;
     provides interface ReadStream<uint16_t>;
+    provides interface DeviceMetadata;
   }
   implementation {
     components new SensirionSht11C();
     Read = SensirionSht11C.Humidity;
     ReadStream = SensirionSht11C.HumidityStream;
+    DeviceMetadata = SensirionSht11C.HumidityDeviceMetadata;
   }
 
 3. Sensor HAL Components
@@ -222,8 +222,8 @@ For example::
 4. Directory Organization Guidelines
 ====================================================================
 
-Because the same physical sensor may be attached to TinyOS platforms
-in many different ways, the organization of sensor drivers should
+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.
 
 Sensor components commonly exist at three levels:
@@ -267,7 +267,7 @@ perl variables, and MUST NOT modify any others:
   subdirectories.
 
 - @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.
 
 If the sensor board wishes to define any C types or constants, it
@@ -278,14 +278,14 @@ A sensor board directory MAY contain a "chips" directory, with
 subdirectories for each of the sensors connected to the sensor board.
 If a "chips" 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
 "<sensorboard>/chips/<sensor>".
 
 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
 "tos/<platform>/chips/<sensor>". 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.
 
 Sensors that exist as part of a larger chip, like a MCU internal
@@ -298,7 +298,7 @@ the sensors on a platform and/or sensorboard.
 
 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 `-I` directives to locate all of the necessary pieces.
 
 5. Authors' Addresses
@@ -375,6 +375,7 @@ the arbitration and access to the ADC.
   generic configuration HamamatsuS1087ParC() {
     provides interface Read<uint16_t>;
     provides interface ReadStream<uint16_t>;
+    provides interface DeviceMetadata;
   }
   implementation {
     components new AdcReadClientC();
@@ -384,35 +385,39 @@ the arbitration and access to the ADC.
     ReadStream = AdcReadStreamClientC;
 
     components HamamatsuS1087ParP;
-    AdcReadClientC.Msp430Adc12Config -> HamamatsuS1087ParP;
-    AdcReadStreamClientC.Msp430Adc12Config -> HamamatsuS1087ParP;
+    DeviceMetadata = HamamatsuS1087ParP;
+    AdcReadClientC.AdcConfigure -> HamamatsuS1087ParP;
+    AdcReadStreamClientC.AdcConfigure -> HamamatsuS1087ParP;
   }
   
 ::
 
   tos/platforms/telosa/chips/s1087/HamamatsuS1087ParP.nc
 
+  #include "Msp430Adc12.h"
+
   module HamamatsuS1087ParP {
-    provides interface Msp430Adc12Config;
+    provides interface AdcConfigure<const msp430adc12_channel_config_t*>;
+    provides interface DeviceMetadata;
   }
   implementation {
 
-    async command msp430adc12_channel_config_t 
-      Msp430Adc12Config.getChannelSettings() {
+    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
+    };
  
-      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
-      };
-      
-      return config;
+    async command const msp430adc12_channel_config_t* AdcConfigure.getConfiguration() {
+      return &config;
     }
+
+    command uint8_t DeviceMetadata.getSignificantBits() { return 12; }
   }
 
 2. Binary Pin-Connected Sensor
@@ -438,17 +443,18 @@ none of the operations are split-phase.
   configuration UserButtonC {
     provides interface Get<bool>;
     provides interface Notify<bool>;
+    provides interface DeviceMetadata;
   }
   implementation {
 
     components UserButtonLogicP;
+    Get = UserButtonLogicP;
+    Notify = UserButtonLogicP;
+    DeviceMetadata = UserButtonLogicP;
 
     components HplUserButtonC;
     UserButtonLogicP.GpioInterrupt -> HplUserButtonC.GpioInterrupt;
     UserButtonLogicP.GeneralIO -> HplUserButtonC.GeneralIO;
-
-    Get = UserButtonLogicP;
-    Notify = UserButtonLogicP;
   }
 
 ::
@@ -458,6 +464,7 @@ none of the operations are split-phase.
   module UserButtonLogicP {
     provides interface Get<bool>;
     provides interface Notify<bool>;
+    provides interface DeviceMetadata;
 
     uses interface GeneralIO;
     uses interface GpioInterrupt; 
@@ -505,6 +512,8 @@ none of the operations are split-phase.
         call GpioInterrupt.enableRisingEdge();
       }
     }
+
+    command uint8_t DeviceMetadata.getSignificantBits() { return 1; }
   }
 
 ::
@@ -564,14 +573,18 @@ on top of the I2C or SPI bus would likely require fewer components.
   
   generic configuration SensirionSht11C() {  
     provides interface Read<uint16_t> as Temperature;
+    provides interface DeviceMetadata as TemperatureDeviceMetadata;
     provides interface Read<uint16_t> 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("Sht11.Resource") };
@@ -589,7 +602,9 @@ on top of the I2C or SPI bus would likely require fewer components.
   
   generic module SensirionSht11ReaderP() {
     provides interface Read<uint16_t> as Temperature;
+    provides interface DeviceMetadata as TemperatureDeviceMetadata;
     provides interface Read<uint16_t> as Humidity;
+    provides interface DeviceMetadata as HumidityDeviceMetadata;
     
     uses interface Resource as TempResource;
     uses interface Resource as HumResource;
@@ -614,7 +629,9 @@ on top of the I2C or SPI bus would likely require fewer components.
       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;
@@ -633,6 +650,8 @@ on top of the I2C or SPI bus would likely require fewer components.
       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 ) { }
index 56e975914c8255cb33e7a1fb750c492c167e37fb..2d4b2bd83f6bbed3a951f8999c3ef2b8d326bb86 100644 (file)
@@ -137,6 +137,13 @@ If the ``result`` parameter of the ``Read.readDone`` and
 ``ReadWrite.readDone`` events is not SUCCESS, then the memory of the
 ``val`` parameter MUST be filled with zeroes.
 
+If the call to ``Read.read`` has returned SUCCESS, but the
+``Read.readDone`` event has not yet been signalled, then a subsequent
+call to ``Read.read`` MUST not return SUCCESS. This simple locking
+technique, as opposed to a more complex system in which multiple
+read/readDone pairs may be outstanding, is intended to reduce the
+complexity of code that is a client of a SID interface.
+
 Examples of sensors that would be suited to this class of interface
 include many basic sensors, such as photo, temp, voltage, and ADC
 readings.
index 8f0e9c3bbe25da328e21cc5e2429d148fec7723b..e1b48d18ee6f493b3ca44b2a336d305e3ccc1d0a 100644 (file)
@@ -24,7 +24,11 @@ Abstract
 
 The memo documents the interfaces, components, and semantics used by
 collection protocol in TinyOS 2.x. Collection provides a best-effort,
-multihop delivery of packets to the root of a tree.
+multihop delivery of packets to the root of *a* tree. There may be
+multiple roots in a network, and in this case the semantics implemented
+are of *anycast* delivery to at least one of the roots. A node sending
+a packet does not specify which root the packet is destined to.
 
 1. Introduction
 ====================================================================
@@ -44,7 +48,11 @@ rather than one tree, it has a *forest* of trees. By picking a
 parent node, a collection protocol implicitly joins one of these
 trees. Collection provides a best-effort,
 multihop delivery of packets to one of a network's tree roots:
-it is an *anycast* protocol.
+it is an *anycast* protocol. The semantics is that the protocol
+will make a reasonable effort to deliver the message to at least
+one of the roots in the network. There are however no guarantees of 
+delivery, and there can be duplicates delivered to one or more
+roots. There is also no ordering guarantees.
 
 Given the limited state that nodes can store and a general need
 for distributed tree building algorithms, simple collection protocols
@@ -75,34 +83,21 @@ for a collection service outlined above.
 A node can perform four different roles in collection: producer,
 consumer, snooper, and in-network processor. Depending on their role,
 the nodes use different interfaces to interact with the collection
-component.
-
-The nodes that generate data to be sent to the root are
-*producers*. The producers use the Send interface [1_] to send
-data to the root of the collection tree. The collection tree
-identifier is be specified as a parameter to Send during
-instantiation.
-
-Root nodes that receive data from the network are *consumers*. The
-consumers use the Receive interface [1_] to receive a message
-delivered by collection. The collection tree identifier is be
-specified as a parameter to Receive during instantiation.
+component. 
 
-The nodes that overhear messages in transit are *snoopers*. The snoopers
-use the Receive interface [1_] to receive a snooped message. The
-collection tree identifier is be specified as a parameter to Receive
-during instantiation.
-
-The nodes can process a packet that are in transit. These in-network
-*processors* use the Intercept interface [1_] to receive and
-update a packet. The collection tree identifier is be specified as a
-parameter to Intercept during instantiation.
+A consumer is a root of a tree. The set of all roots and the paths that
+lead to them form the collection routing infrastructure in the network.
+For any connected set of nodes implementing the collection protocol 
+there is only one collection infrastructure, *i.e.*, all roots in this 
+set active at the same time are part of the same infrastructure.
 
 A node is configured to become a root by using the RootControl
 interface. RootControl.setRoot() MUST make the current node a root of
-the tree specified during instantiation. RootControl.unsetRoot() MUST
-make the current root no longer a root in the tree specified during
-instantiation. RootControl.unsetRoot() MAY be called on a node that is
+the the collection infrastructure. RootControl.unsetRoot() MUST
+make the current root no longer a root in the collection infrastructure.
+Both calls are idempotent.
+RootControl.setRoot() MAY be called on a node that is already a root, to
+no effect. RootControl.unsetRoot() MAY be called on a node that is
 not a root::
 
   interface RootControl {
@@ -111,14 +106,38 @@ not a root::
     command bool isRoot();
   }
 
+The collection infrastructure can be multiplexed among independent
+applications, by means of a *collection identifier*. It is important
+to note that the *data* traffic in the protocol is multiplexed,
+while the *control* traffic is not.
+
+The nodes that generate data to be sent to the root are *producers*.
+The producers use the Send interface [1_] to send data to the root
+of the collection tree.  The collection identifier is specified as a
+parameter to Send during instantiation.
+
+Root nodes that receive data from the network are *consumers*. The
+consumers use the Receive interface [1_] to receive a message
+delivered by collection. The collection identifier is specified
+as a parameter to Receive during instantiation.
+
+The nodes that overhear messages in transit are *snoopers*. The
+snoopers use the Receive interface [1_] to receive a snooped
+message. The collection identifier is specified as a parameter
+to Receive during instantiation.
+
+The nodes can process a packet that are in transit. These in-network
+*processors* use the Intercept interface [1_] to receive and update
+a packet. The collection identifier is specified as a parameter
+to Intercept during instantiation.
 
 3 Collection Services
 ====================================================================
 
-A collection service MUST provide one component, TreeCollectionC,
+A collection service MUST provide one component, CollectionC,
 which has the following signature::
 
-  configuration TreeCollectionC {
+  configuration CollectionC {
     provides {
       interface StdControl;
       interface Send[uint8_t client];
@@ -128,7 +147,6 @@ which has the following signature::
       interface RootControl;
       interface Packet;
       interface CollectionPacket;
-      interface TreeRoutingInspect;
     }
     uses {
       interface CollectionId[uint8_t client];
@@ -136,12 +154,12 @@ which has the following signature::
   }
 
 
-TreeCollectionC MAY have additional interfaces, but they MUST have
+CollectionC MAY have additional interfaces, but they MUST have
 default functions on all outgoing invocations (commands for uses,
 events for provides) of those interfaces so that it can operate
 properly if they are not wired.
 
-Components SHOULD NOT wire to TreeCollectionC.Send. The generic
+Components SHOULD NOT wire to CollectionC.Send. The generic
 component CollectionSenderC (described in section 3.1) provides
 a virtualized sending interface.
 
@@ -154,53 +172,39 @@ collection_id_t generally have the same payload format, so that
 snoopers, intercepters, and receivers can parse it properly.
 
 Receive.receive MUST NOT be signaled on non-root
-nodes. TreeCollectionC MAY signal Receive.receive on a root node when
+nodes. CollectionC MAY signal Receive.receive on a root node when
 a data packet successfully arrives at that node. If a root node calls
-Send, TreeCollectionC MUST treat it as it if were a received packet.
+Send, CollectionC MUST treat it as it if were a received packet.
 Note that the buffer swapping semantics of Receive.receive, when
-combined with the pass semantics of Send, require that TreeCollectionC
+combined with the pass semantics of Send, require that CollectionC
 make a copy of the buffer if it signals Receive.receive.
 
-If TreeCollectionC receives a data packet to forward and it is not a
+If CollectionC receives a data packet to forward and it is not a
 root node, it MAY signal Intercept.forward.
 
-If TreeCollectionC receives a data packet that a different node
+If CollectionC receives a data packet that a different node
 is supposed to forward, it MAY signal Snoop.receive.
 
 RootControl allows a node to be made a collection tree root.
-TreeCollectionC SHOULD NOT configure a node as a root by default.
+CollectionC SHOULD NOT configure a node as a root by default.
 
 Packet and CollectionPacket allow components to access collection
 data packet fields [1_].
 
-TreeRoutingInspect provides information on the current position of
-the node in a routing tree::
-
-  interface TreeRoutingInspect {
-    command error_t getParent(am_addr_t* parent);
-    command error_t getHopcount(uint8_t* hopcount);
-    command error_t getMetric(uint16_t* metric);
-  }
-
-In each of these commands, if the return value is not SUCCESS, the
-value stored in the pointer argument is undefined. The getMetric
-command provides a measure of the quality of a node's route to the
-base station. This routing metric MUST be monotonically increasing
-across hops. In a collection tree, if node A is the parent of node B,
-then node B's metric value MUST be greater than node A's.
-
 3.1 CollectionSenderC
 --------------------------------------------------------------------
 
 Collection has a virtualized sending abstraction, the generic
 component CollectionSenderC::
 
-generic configuration CollectionSenderC(collection_id_t collectid) {
-  provides {
-    interface Send;
-    interface Packet;
+  generic configuration CollectionSenderC(collection_id_t collectid) {
+    provides {
+      interface Send;
+      interface Packet;
+    }
   }
-}
+
+
 
 This abstraction follows a similar virtualization approach to
 AMSenderC [1_], except that it is parameterized by a collection_id_t
@@ -212,40 +216,49 @@ based on its collection ID and contents.
 ====================================================================
 
 An implementation of this TEP can be found in
-``tinyos-2.x/tos/lib/net/collection``. The implementation consists of
-three major components, which are wired together to form a
-CollectionC: LinkEstimatorP, TreeRoutingEngineP, and ForwardingEngineP.
-
-This decomposition tries to encourage evolution of components and ease
-of use through modularization. Neighbor management and link estimation
-are are decoupled from the routing protocol. Furthermore, the routing
-protocol and route selection are decoupled from the forwarding policies,
-such as queueing and timing.
+``tinyos-2.x/tos/lib/net/ctp`` and ``tinyos-2.x/tos/lib/net/le``, in
+the CTP protocol. It is beyond the scope of this document to fully
+describe CTP, but we outline its main components. CTP will be
+described in an upcoming TEP [2_].  This implementation is a
+reference implementation, and is not the only possibility.  It
+consists of three major components, which are wired together to form
+a CollectionC: LinkEstimatorP, CtpTreeRoutingEngineP, and
+CtpForwardingEngineP. 
+
+This decomposition tries to encourage evolution of components and
+ease of use through modularization. Neighbor management and link
+estimation are decoupled from the routing protocol. Furthermore, the
+routing protocol and route selection are decoupled from the
+forwarding policies, such as queueing and timing.
 
 4.1 LinkEstimatorP
 --------------------------------------------------------------------
 
 LinkEstimatorP estimates the quality of link to or from each
-neighbor. Link estimation can be done in a variety of ways, and we do
-not impose one here. It is decoupled from the establishment of
-routes. There is a narrow interface (LinkEstimator and
-NeighborTableEviction) between the link estimator and the routing
-engine. The one requirement is that the quality returned is
-standardized. A smaller return value from LinkEstimator.getQuality(),
-LinkEstimator.getforwardQuality(), LinkEstimator.getreserveQuality()
-MUST imply that the link to the neighbor is estimated to be of a
-higher quality than the one that results in a smaller return
-value. The range of value SHOULD be [0,255] and the variation in link
-quality in that range SHOULD be linear. Radio provided values such as
-LQI or RSI, beacon based link estimation to compute ETX, or their
-combination are some possible approaches to estimating link
-qualities. LinkEstimatorP MAY have its own control messages to compute
-bi-directional link qualities. LinkEstimatorP provides calls (txAck(),
-txNoAck(), and clearDLQ()) to update the link estimates based on
-successful or unsuccessful data transmission to the neighbors. The
-user of LinkEstimatorP can call insertNeighbor() to manually insert a
-node in the neighbor table, pinNeighbor() to prevent a neighbor from
-being evicted, and unpinNeighbor() to restore eviction policy::
+neighbor. Link estimation can be done in a variety of ways, and we
+do not impose one here. It is decoupled from the establishment of
+routes. There is a narrow interface -- LinkEstimator -- between the
+link estimator and the routing engine. The one requirement is that
+the quality returned is standardized. A smaller return value from
+LinkEstimator.getQuality(), LinkEstimator.getforwardQuality(),
+LinkEstimator.getReverseQuality() MUST imply that the link to the
+neighbor is estimated to be of a higher quality than the one that
+results in a larger return value. The range of value SHOULD be
+[0,255] and the variation in link quality in that range SHOULD be
+linear. Radio provided values such as LQI or RSI, beacon based link
+estimation to compute ETX, or their combination are some possible
+approaches to estimating link qualities. 
+
+LinkEstimatorP MAY have its own control messages to compute
+bi-directional link qualities. LinkEstimatorP provides calls
+(txAck(), txNoAck(), and clearDLQ()) to update the link estimates
+based on successful or unsuccessful data transmission to the
+neighbors. 
+
+The user of LinkEstimatorP can call insertNeighbor() to manually
+insert a node in the neighbor table, pinNeighbor() to prevent a
+neighbor from being evicted, and unpinNeighbor() to restore eviction
+policy::
 
   typedef uint16_t neighbor_table_entry_t
 
@@ -274,52 +287,74 @@ being evicted, and unpinNeighbor() to restore eviction policy::
     event void evicted(am_addr_t neighbor);
   }
 
-  interface NeighborTableEviction {
-    event void evicted(uint16_t neighbor)
-  }
 
 
-4.2 TreeRoutingEngineP
+4.2 CtpRoutingEngineP
 --------------------------------------------------------------------
 
-TreeRoutingEngineP is responsible for computing routes to the roots of a
-tree. It uses NeighborTable and LinkEstimator interfaces to learn
+CtpRoutingEngineP is responsible for computing routes to the roots of a
+tree. In traditional networking terminology, this is part of the
+control plane of the network, and is does not directly forward any
+data packets, which is the responsibility of CtpForwardingEngine. 
+The main interface between the two is UnicastNameFreeRouting.
+
+CtpRoutingEngineP uses the LinkEstimator interface to learn
 about the nodes in the neighbor table maintained by LinkEstimatorP and
 the quality of links to and from the neighbors. The routing protocol
 on which collection is implemented MUST be a tree-based routing
-protocol with a single or multiple roots. TreeRoutingEngineP 
+protocol with a single or multiple roots. CtpRoutingEngineP 
 allows a node to be configured as a root or a non-root node
-dynamically. TreeRoutingEngineP maintains multiple candidate next hops::
-
-  generic module TreeRoutingEngineP(uint8_t routingTableSize) {
-    provides {
-        interface UnicastNameFreeRouting as Routing;
-        interface RootControl;
-        interface TreeRoutingInspect;
-        interface StdControl;
-        interface Init;
-    } 
-    uses {
-        interface AMSend as BeaconSend;
-        interface Receive as BeaconReceive;
-        interface LinkEstimator;
-        interface AMPacket;
-        interface LinkSrcPacket;
-        interface SplitControl as RadioControl;
-        interface Timer<TMilli> as BeaconTimer;
-        interface Random;
-        interface CollectionDebug;
-    }
+dynamically. CtpRoutingEngineP maintains multiple candidate next hops::
+
+  generic module CtpRoutingEngineP(uint8_t routingTableSize, 
+                                   uint16_t minInterval, 
+                                   uint16_t maxInterval) {
+      provides {
+          interface UnicastNameFreeRouting as Routing;
+          interface RootControl;
+          interface CtpInfo;
+          interface StdControl;
+          interface CtpRoutingPacket;
+          interface Init;
+      } 
+      uses {
+          interface AMSend as BeaconSend;
+          interface Receive as BeaconReceive;
+          interface LinkEstimator;
+          interface AMPacket;
+          interface LinkSrcPacket;
+          interface SplitControl as RadioControl;
+          interface Timer<TMilli> as BeaconTimer;
+          interface Timer<TMilli> as RouteTimer;
+          interface Random;
+          interface CollectionDebug;
+          interface CtpCongestion;
+      }
   }
 
-4.3 ForwardingEngineP
+
+::
+
+ interface UnicastNameFreeRouting {
+   command am_addr_t nextHop();
+
+   command bool hasRoute();
+   event void routeFound();
+   event void noRoute();
+ }
+
+
+
+4.3 CtpForwardingEngineP
 --------------------------------------------------------------------
 
-The ForwardingEngineP component provides all the top level interfaces
-(except RootControl) which TreeCollectionC provides and an application 
-uses:: 
+The CtpForwardingEngineP component provides all the top level interfaces
+(except RootControl) which CollectionC provides and an application 
+uses. It deals with retransmissions, duplicate suppression, packet
+timing, loop detection, and also informs the LinkEstimator of the
+outcome of attempted transmissions.::
 
-  generic module ForwardingEngineP() {
+  generic module CtpForwardingEngineP() {
     provides {
       interface Init;
       interface StdControl;
@@ -329,20 +364,24 @@ uses::
       interface Intercept[collection_id_t id];
       interface Packet;
       interface CollectionPacket;
+      interface CtpPacket;
+      interface CtpCongestion;
     }
     uses {
+      interface SplitControl as RadioControl;
       interface AMSend as SubSend;
       interface Receive as SubReceive;
       interface Receive as SubSnoop;
       interface Packet as SubPacket;
       interface UnicastNameFreeRouting;
-      interface SplitControl as RadioControl;
       interface Queue<fe_queue_entry_t*> as SendQueue;
       interface Pool<fe_queue_entry_t> as QEntryPool;
       interface Pool<message_t> as MessagePool;
       interface Timer<TMilli> as RetxmitTimer;
-      interface Cache<uint32_t> as SentCache;
-      interface TreeRoutingInspect;
+      interface LinkEstimator;
+      interface Timer<TMilli> as CongestionTimer;
+      interface Cache<message_t*> as SentCache;
+      interface CtpInfo;
       interface PacketAcknowledgements;
       interface Random;
       interface RootControl;
@@ -352,13 +391,14 @@ uses::
     }
   }
 
-ForwardingEngineP uses a large number of interfaces, which can be
+
+CtpForwardingEngineP uses a large number of interfaces, which can be
 broken up into a few groups of functionality:
 
   * Single hop communication: SubSend, SubReceive, SubSnoop,
     SubPacket, PacketAcknowledgments, AMPacket
-  * Routing: UnicastNameFreeRouting, TreeRoutingInspect, 
-    RootControl, CollectionId, SentCache
+  * Routing: UnicastNameFreeRouting, RootControl, CtpInfo,
+    CollectionId, SentCache
   * Queue and buffer management: SendQueue, MessagePool,
     QEntryPool
   * Packet timing: Random, RetxmitTimer
@@ -406,4 +446,5 @@ broken up into a few groups of functionality:
 ====================================================================
 
 .. [1] TEP 116: Packet Protocols
+.. [2] TEP 124: The Collection Tree Protocol (CTP) - (upcoming)
  
diff --git a/support/sdk/java/net/tinyos/comm/package.html b/support/sdk/java/net/tinyos/comm/package.html
new file mode 100644 (file)
index 0000000..c1f867f
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides the Java half of JNI interfaces to serial ports.
+
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+For how to this package is used to communicate with motes, please see:
+<ul>
+  <li><a href="http://www.tinyos.net/tinyos-2.x/doc/html/tutorial/lesson4.html">Lesson 4 of the TinyOS tutorials.</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
diff --git a/support/sdk/java/net/tinyos/message/package.html b/support/sdk/java/net/tinyos/message/package.html
new file mode 100644 (file)
index 0000000..2d1e351
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides abstractions for reading and writing data messages to different communication sources. 
+
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
diff --git a/support/sdk/java/net/tinyos/mviz/package.html b/support/sdk/java/net/tinyos/mviz/package.html
new file mode 100644 (file)
index 0000000..2444d1b
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides a GUI interface to a TinyOS network.
+
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+For how to use the classes in this package, please see the man page of the <tt>tos-mviz</tt> tool.
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
diff --git a/support/sdk/java/net/tinyos/packet/package.html b/support/sdk/java/net/tinyos/packet/package.html
new file mode 100644 (file)
index 0000000..d025fa4
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides for transforming byte arrays into TinyOS packet abstractions.
+
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+The <tt>mig</tt> tool generates packets from arbitrary packet format
+delcarations.
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
diff --git a/support/sdk/java/net/tinyos/sf/package.html b/support/sdk/java/net/tinyos/sf/package.html
new file mode 100644 (file)
index 0000000..36d6453
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides a communication source mux/demux (SerialForwarder) that allows multiple
+clients to share a single packet source.
+
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+Lesson 4 of the TinyOS tutorials describes how to use SerialForwarder.
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
diff --git a/support/sdk/java/net/tinyos/sim/package.html b/support/sdk/java/net/tinyos/sim/package.html
new file mode 100644 (file)
index 0000000..9f69c2b
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides tools to generate communication topologies for TOSSIM.
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+Lesson 11 of the TinyOS tutorials describe how to use these tools.
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
diff --git a/support/sdk/java/net/tinyos/tools/package.html b/support/sdk/java/net/tinyos/tools/package.html
new file mode 100644 (file)
index 0000000..287b7f3
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides low-level tools for interacting with TinyOS nodes. 
+
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
diff --git a/support/sdk/java/net/tinyos/util/package.html b/support/sdk/java/net/tinyos/util/package.html
new file mode 100644 (file)
index 0000000..d2789ba
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+  @(#)package.html     1.60 98/01/27
+
+  Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, 
+  Palo Alto, California, 94303, U.S.A.  All Rights Reserved.
+
+  This software is the confidential and proprietary information of Sun
+  Microsystems, Inc. ("Confidential Information").  You shall not
+  disclose such Confidential Information and shall use it only in
+  accordance with the terms of the license agreement you entered into
+  with Sun.
+
+  CopyrightVersion 1.2
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides low-level utilities used by many packages.
+
+
+<h2>Package Specification</h2>
+
+<h2>Related Documentation</h2>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
+
index a56b904dd925b4201dba5a4bfd9efaf14ccda21d..81c0f3c76bd52424a62a1c9071006ce4b5e432fd 100644 (file)
@@ -120,6 +120,8 @@ implementation
     call CC.write(CC1K_PA_POW, 0);
 
     calibrateNow();
+    
+    call CC1000Control.rxMode();
   }
 
   /*
index cff7a950313a84e0e486034d05ebcac6f8ff2e3d..81c0f3c76bd52424a62a1c9071006ce4b5e432fd 100644 (file)
-/* $Id$\r
- * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
- * All rights reserved.\r
- *\r
- * Permission to use, copy, modify, and distribute this software and its\r
- * documentation for any purpose, without fee, and without written agreement is\r
- * hereby granted, provided that the above copyright notice, the following\r
- * two paragraphs and the author appear in all copies of this software.\r
- * \r
- * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
- * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
- * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
- *\r
- * Copyright (c) 2002-2005 Intel Corporation\r
- * All rights reserved.\r
- *\r
- * This file is distributed under the terms in the attached INTEL-LICENSE     \r
- * file. If you do not find these files, copies can be found by writing to\r
- * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
- * 94704.  Attention:  Intel License Inquiry.\r
- */\r
-#include "CC1000Const.h"\r
-#include "Timer.h"\r
-\r
-/**\r
- * This module provides the CONTROL functionality for the Chipcon1000\r
- * series radio.  It exports a custom interface to control CC1000\r
- * operation.\r
- *\r
- * @author Philip Buonadonna\r
- * @author Jaein Jeong\r
- * @author David Gay\r
- */\r
-module CC1000ControlP {\r
-  provides {\r
-    interface CC1000Control;\r
-  }\r
-  uses {\r
-    interface HplCC1000 as CC;\r
-    interface BusyWait<TMicro, uint16_t>;\r
-  }\r
-}\r
-implementation\r
-{\r
-  uint8_t txCurrent, rxCurrent, power;\r
-\r
-  enum {\r
-    IF = 150000,\r
-    FREQ_MIN = 4194304,\r
-    FREQ_MAX = 16751615\r
-  };\r
-\r
-  const_uint32_t fRefTbl[9] = {2457600,\r
-                              2106514,\r
-                              1843200,\r
-                              1638400,\r
-                              1474560,\r
-                              1340509,\r
-                              1228800,\r
-                              1134277,\r
-                              1053257};\r
-  \r
-  const_uint16_t corTbl[9] = {1213,\r
-                             1416,\r
-                             1618,\r
-                             1820,\r
-                             2022,\r
-                             2224,\r
-                             2427,\r
-                             2629,\r
-                             2831};\r
-  \r
-  const_uint16_t fSepTbl[9] = {0x1AA,\r
-                              0x1F1,\r
-                              0x238,\r
-                              0x280,\r
-                              0x2C7,\r
-                              0x30E,\r
-                              0x355,\r
-                              0x39C,\r
-                              0x3E3};\r
-  \r
-  void calibrateNow() {\r
-    // start cal\r
-    call CC.write(CC1K_CAL,\r
-                 1 << CC1K_CAL_START |\r
-                 1 << CC1K_CAL_WAIT |\r
-                 6 << CC1K_CAL_ITERATE);\r
-    while ((call CC.read(CC1K_CAL) & 1 << CC1K_CAL_COMPLETE) == 0)\r
-      ;\r
-\r
-    //exit cal mode\r
-    call CC.write(CC1K_CAL, 1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE);\r
-  }\r
-\r
-  void calibrate() {\r
-    call CC.write(CC1K_PA_POW, 0x00);  // turn off rf amp\r
-    call CC.write(CC1K_TEST4, 0x3f);   // chip rate >= 38.4kb\r
-\r
-    // RX - configure main freq A\r
-    call CC.write(CC1K_MAIN, 1 << CC1K_TX_PD | 1 << CC1K_RESET_N);\r
-\r
-    calibrateNow();\r
-\r
-    // TX - configure main freq B\r
-    call CC.write(CC1K_MAIN,\r
-                 1 << CC1K_RXTX |\r
-                 1 << CC1K_F_REG |\r
-                 1 << CC1K_RX_PD | \r
-                 1 << CC1K_RESET_N);\r
-    // Set TX current\r
-    call CC.write(CC1K_CURRENT, txCurrent);\r
-    call CC.write(CC1K_PA_POW, 0);\r
-\r
-    calibrateNow();\r
-  }\r
-\r
-  /*\r
-   * cc1000ComputeFreq(uint32_t desiredFreq);\r
-   *\r
-   * Compute an achievable frequency and the necessary CC1K parameters from\r
-   * a given desired frequency (Hz). The function returns the actual achieved\r
-   * channel frequency in Hz.\r
-   *\r
-   * This routine assumes the following:\r
-   *  - Crystal Freq: 14.7456 MHz\r
-   *  - LO Injection: High\r
-   *  - Separation: 64 KHz\r
-   *  - IF: 150 KHz\r
-   * \r
-   * Approximate costs for this function:\r
-   *  - ~870 bytes FLASH\r
-   *  - ~32 bytes RAM\r
-   *  - 9400 cycles\r
-   */\r
-  uint32_t cc1000SetFrequency(uint32_t desiredFreq) {\r
-    uint32_t ActualChannel = 0;\r
-    uint32_t RXFreq = 0, TXFreq = 0;\r
-    int32_t Offset = 0x7fffffff;\r
-    uint16_t FSep = 0;\r
-    uint8_t RefDiv = 0;\r
-    uint8_t i, match, frontend;\r
-\r
-    for (i = 0; i < 9; i++)\r
-      {\r
-       uint32_t NRef = desiredFreq + IF;\r
-       uint32_t FRef = read_uint32_t(&fRefTbl[i]);\r
-       uint32_t Channel = 0;\r
-       uint32_t RXCalc = 0, TXCalc = 0;\r
-       int32_t  diff;\r
-\r
-       NRef = ((desiredFreq + IF)  <<  2) / FRef;\r
-       if (NRef & 0x1)\r
-         NRef++;\r
-\r
-       if (NRef & 0x2)\r
-         {\r
-           RXCalc = 16384 >> 1;\r
-           Channel = FRef >> 1;\r
-         }\r
-\r
-       NRef >>= 2;\r
-\r
-       RXCalc += (NRef * 16384) - 8192;\r
-       if ((RXCalc < FREQ_MIN) || (RXCalc > FREQ_MAX)) \r
-         continue;\r
-    \r
-       TXCalc = RXCalc - read_uint16_t(&corTbl[i]);\r
-       if (TXCalc < FREQ_MIN || TXCalc > FREQ_MAX)\r
-         continue;\r
-\r
-       Channel += NRef * FRef;\r
-       Channel -= IF;\r
-\r
-       diff = Channel - desiredFreq;\r
-       if (diff < 0)\r
-         diff = -diff;\r
-\r
-       if (diff < Offset)\r
-         {\r
-           RXFreq = RXCalc;\r
-           TXFreq = TXCalc;\r
-           ActualChannel = Channel;\r
-           FSep = read_uint16_t(&fSepTbl[i]);\r
-           RefDiv = i + 6;\r
-           Offset = diff;\r
-         }\r
-      }\r
-\r
-    if (RefDiv != 0)\r
-      {\r
-       call CC.write(CC1K_FREQ_0A, RXFreq);\r
-       call CC.write(CC1K_FREQ_1A, RXFreq >> 8);\r
-       call CC.write(CC1K_FREQ_2A, RXFreq >> 16);\r
-\r
-       call CC.write(CC1K_FREQ_0B, TXFreq);\r
-       call CC.write(CC1K_FREQ_1B, TXFreq >> 8);\r
-       call CC.write(CC1K_FREQ_2B, TXFreq >> 16);\r
-\r
-       call CC.write(CC1K_FSEP0, FSep);\r
-       call CC.write(CC1K_FSEP1, FSep >> 8);\r
-\r
-       if (ActualChannel < 500000000)\r
-         {\r
-           if (ActualChannel < 400000000)\r
-             {\r
-               rxCurrent = 8 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE;\r
-               txCurrent = 9 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE;\r
-             }\r
-           else\r
-             {\r
-               rxCurrent = 4 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE;\r
-               txCurrent = 8 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE;\r
-             }\r
-           frontend = 1 << CC1K_IF_RSSI;\r
-           match = 7 << CC1K_RX_MATCH;\r
-         }\r
-       else\r
-         {\r
-           rxCurrent = 8 << CC1K_VCO_CURRENT | 3 << CC1K_LO_DRIVE;\r
-           txCurrent = 15 << CC1K_VCO_CURRENT | 3 << CC1K_PA_DRIVE;\r
-\r
-           frontend =\r
-             1 << CC1K_BUF_CURRENT | 2 << CC1K_LNA_CURRENT | \r
-             1 << CC1K_IF_RSSI;\r
-           match = 2 << CC1K_RX_MATCH; // datasheet says to use 1...\r
-         }\r
-       call CC.write(CC1K_CURRENT, rxCurrent);\r
-       call CC.write(CC1K_MATCH, match);\r
-       call CC.write(CC1K_FRONT_END, frontend);\r
-       call CC.write(CC1K_PLL, RefDiv << CC1K_REFDIV);\r
-      }\r
-\r
-    return ActualChannel;\r
-  }\r
-\r
-  command void CC1000Control.init() {\r
-    call CC.init();\r
-\r
-    // wake up xtal and reset unit\r
-    call CC.write(CC1K_MAIN,\r
-                 1 << CC1K_RX_PD | 1 << CC1K_TX_PD | \r
-                 1 << CC1K_FS_PD | 1 << CC1K_BIAS_PD); \r
-    // clear reset.\r
-    call CC1000Control.coreOn();\r
-    call BusyWait.wait(2000);\r
-\r
-    // Set default parameter values\r
-    // POWER: 0dbm (~900MHz), 6dbm (~430MHz)\r
-    power = 8 << CC1K_PA_HIGHPOWER | 0 << CC1K_PA_LOWPOWER;\r
-    call CC.write(CC1K_PA_POW, power);\r
-\r
-    // select Manchester Violation for CHP_OUT\r
-    call CC.write(CC1K_LOCK_SELECT, 9 << CC1K_LOCK_SELECT);\r
-\r
-    // Default modem values = 19.2 Kbps (38.4 kBaud), Manchester encoded\r
-    call CC.write(CC1K_MODEM2, 0);\r
-    call CC.write(CC1K_MODEM1, \r
-                 3 << CC1K_MLIMIT |\r
-                 1 << CC1K_LOCK_AVG_MODE | \r
-                 3 << CC1K_SETTLING |\r
-                 1 << CC1K_MODEM_RESET_N);\r
-    call CC.write(CC1K_MODEM0, \r
-                 5 << CC1K_BAUDRATE |\r
-                 1 << CC1K_DATA_FORMAT | \r
-                 1 << CC1K_XOSC_FREQ);\r
-\r
-    call CC.write(CC1K_FSCTRL, 1 << CC1K_FS_RESET_N);\r
-\r
-#ifdef CC1K_DEF_FREQ\r
-    call CC1000Control.tuneManual(CC1K_DEF_FREQ);\r
-#else\r
-    call CC1000Control.tunePreset(CC1K_DEF_PRESET);\r
-#endif\r
-    call CC1000Control.off();\r
-  }\r
-\r
-  command void CC1000Control.tunePreset(uint8_t freq) {\r
-    int i;\r
-\r
-    // FREQA, FREQB, FSEP, CURRENT(RX), FRONT_END, POWER, PLL\r
-    for (i = CC1K_FREQ_2A; i <= CC1K_PLL; i++)\r
-      call CC.write(i, read_uint8_t(&CC1K_Params[freq][i]));\r
-    call CC.write(CC1K_MATCH, read_uint8_t(&CC1K_Params[freq][CC1K_MATCH]));\r
-    rxCurrent = read_uint8_t(&CC1K_Params[freq][CC1K_CURRENT]);\r
-    txCurrent = read_uint8_t(&CC1K_Params[freq][CC1K_MATCH + 1]);\r
-    power = read_uint8_t(&CC1K_Params[freq][CC1K_PA_POW]);\r
-\r
-    calibrate();\r
-  }\r
-\r
-  command uint32_t CC1000Control.tuneManual(uint32_t DesiredFreq) {\r
-    uint32_t actualFreq;\r
-\r
-    actualFreq = cc1000SetFrequency(DesiredFreq);\r
-\r
-    calibrate();\r
-\r
-    return actualFreq;\r
-  }\r
-\r
-  async command void CC1000Control.txMode() {\r
-    // MAIN register to TX mode\r
-    call CC.write(CC1K_MAIN,\r
-                 1 << CC1K_RXTX |\r
-                 1 << CC1K_F_REG |\r
-                 1 << CC1K_RX_PD | \r
-                 1 << CC1K_RESET_N);\r
-    // Set the TX mode VCO Current\r
-    call CC.write(CC1K_CURRENT, txCurrent);\r
-    call BusyWait.wait(250);\r
-    call CC.write(CC1K_PA_POW, power);\r
-    call BusyWait.wait(20);\r
-  }\r
-\r
-  async command void CC1000Control.rxMode() {\r
-    // MAIN register to RX mode\r
-    // Powerup Freqency Synthesizer and Receiver\r
-    call CC.write(CC1K_CURRENT, rxCurrent);\r
-    call CC.write(CC1K_PA_POW, 0); // turn off power amp\r
-    call CC.write(CC1K_MAIN, 1 << CC1K_TX_PD | 1 << CC1K_RESET_N);\r
-    call BusyWait.wait(125);\r
-  }\r
-\r
-  async command void CC1000Control.coreOn() {\r
-    // MAIN register to SLEEP mode\r
-    call CC.write(CC1K_MAIN,\r
-                 1 << CC1K_RX_PD |\r
-                 1 << CC1K_TX_PD | \r
-                 1 << CC1K_FS_PD |\r
-                 1 << CC1K_BIAS_PD |\r
-                 1 << CC1K_RESET_N);\r
-  }\r
-\r
-  async command void CC1000Control.biasOn() {\r
-    call CC.write(CC1K_MAIN,\r
-                 1 << CC1K_RX_PD |\r
-                 1 << CC1K_TX_PD | \r
-                 1 << CC1K_FS_PD | \r
-                 1 << CC1K_RESET_N);\r
-  }\r
-\r
-\r
-  async command void CC1000Control.off() {\r
-    // MAIN register to power down mode. Shut everything off\r
-    call CC.write(CC1K_MAIN,\r
-                 1 << CC1K_RX_PD |\r
-                 1 << CC1K_TX_PD | \r
-                 1 << CC1K_FS_PD |\r
-                 1 << CC1K_CORE_PD |\r
-                 1 << CC1K_BIAS_PD |\r
-                 1 << CC1K_RESET_N);\r
-    call CC.write(CC1K_PA_POW, 0);  // turn off rf amp\r
-  }\r
-\r
-  command void CC1000Control.setRFPower(uint8_t newPower) {\r
-    power = newPower;\r
-  }\r
-\r
-  command uint8_t CC1000Control.getRFPower() {\r
-    return power;\r
-  }\r
-\r
-  command void CC1000Control.selectLock(uint8_t fn) {\r
-    // Select function of CHP_OUT pin (readable via getLock)\r
-    call CC.write(CC1K_LOCK, fn << CC1K_LOCK_SELECT);\r
-  }\r
-\r
-  command uint8_t CC1000Control.getLock() {\r
-    return call CC.getLOCK(); \r
-  }\r
-\r
-  command bool CC1000Control.getLOStatus() {\r
-    // We use a high-side LO (local oscillator) frequency -> data will be\r
-    // inverted. See cc1000ComputeFreq and CC1000 datasheet p.23.\r
-    return TRUE;\r
-  }\r
-}\r
+/* $Id$
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2005 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+#include "CC1000Const.h"
+#include "Timer.h"
+
+/**
+ * This module provides the CONTROL functionality for the Chipcon1000
+ * series radio.  It exports a custom interface to control CC1000
+ * operation.
+ *
+ * @author Philip Buonadonna
+ * @author Jaein Jeong
+ * @author David Gay
+ */
+module CC1000ControlP {
+  provides {
+    interface CC1000Control;
+  }
+  uses {
+    interface HplCC1000 as CC;
+    interface BusyWait<TMicro, uint16_t>;
+  }
+}
+implementation
+{
+  uint8_t txCurrent, rxCurrent, power;
+
+  enum {
+    IF = 150000,
+    FREQ_MIN = 4194304,
+    FREQ_MAX = 16751615
+  };
+
+  const_uint32_t fRefTbl[9] = {2457600,
+                              2106514,
+                              1843200,
+                              1638400,
+                              1474560,
+                              1340509,
+                              1228800,
+                              1134277,
+                              1053257};
+  
+  const_uint16_t corTbl[9] = {1213,
+                             1416,
+                             1618,
+                             1820,
+                             2022,
+                             2224,
+                             2427,
+                             2629,
+                             2831};
+  
+  const_uint16_t fSepTbl[9] = {0x1AA,
+                              0x1F1,
+                              0x238,
+                              0x280,
+                              0x2C7,
+                              0x30E,
+                              0x355,
+                              0x39C,
+                              0x3E3};
+  
+  void calibrateNow() {
+    // start cal
+    call CC.write(CC1K_CAL,
+                 1 << CC1K_CAL_START |
+                 1 << CC1K_CAL_WAIT |
+                 6 << CC1K_CAL_ITERATE);
+    while ((call CC.read(CC1K_CAL) & 1 << CC1K_CAL_COMPLETE) == 0)
+      ;
+
+    //exit cal mode
+    call CC.write(CC1K_CAL, 1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE);
+  }
+
+  void calibrate() {
+    call CC.write(CC1K_PA_POW, 0x00);  // turn off rf amp
+    call CC.write(CC1K_TEST4, 0x3f);   // chip rate >= 38.4kb
+
+    // RX - configure main freq A
+    call CC.write(CC1K_MAIN, 1 << CC1K_TX_PD | 1 << CC1K_RESET_N);
+
+    calibrateNow();
+
+    // TX - configure main freq B
+    call CC.write(CC1K_MAIN,
+                 1 << CC1K_RXTX |
+                 1 << CC1K_F_REG |
+                 1 << CC1K_RX_PD | 
+                 1 << CC1K_RESET_N);
+    // Set TX current
+    call CC.write(CC1K_CURRENT, txCurrent);
+    call CC.write(CC1K_PA_POW, 0);
+
+    calibrateNow();
+    
+    call CC1000Control.rxMode();
+  }
+
+  /*
+   * cc1000ComputeFreq(uint32_t desiredFreq);
+   *
+   * Compute an achievable frequency and the necessary CC1K parameters from
+   * a given desired frequency (Hz). The function returns the actual achieved
+   * channel frequency in Hz.
+   *
+   * This routine assumes the following:
+   *  - Crystal Freq: 14.7456 MHz
+   *  - LO Injection: High
+   *  - Separation: 64 KHz
+   *  - IF: 150 KHz
+   * 
+   * Approximate costs for this function:
+   *  - ~870 bytes FLASH
+   *  - ~32 bytes RAM
+   *  - 9400 cycles
+   */
+  uint32_t cc1000SetFrequency(uint32_t desiredFreq) {
+    uint32_t ActualChannel = 0;
+    uint32_t RXFreq = 0, TXFreq = 0;
+    int32_t Offset = 0x7fffffff;
+    uint16_t FSep = 0;
+    uint8_t RefDiv = 0;
+    uint8_t i, match, frontend;
+
+    for (i = 0; i < 9; i++)
+      {
+       uint32_t NRef = desiredFreq + IF;
+       uint32_t FRef = read_uint32_t(&fRefTbl[i]);
+       uint32_t Channel = 0;
+       uint32_t RXCalc = 0, TXCalc = 0;
+       int32_t  diff;
+
+       NRef = ((desiredFreq + IF)  <<  2) / FRef;
+       if (NRef & 0x1)
+         NRef++;
+
+       if (NRef & 0x2)
+         {
+           RXCalc = 16384 >> 1;
+           Channel = FRef >> 1;
+         }
+
+       NRef >>= 2;
+
+       RXCalc += (NRef * 16384) - 8192;
+       if ((RXCalc < FREQ_MIN) || (RXCalc > FREQ_MAX)) 
+         continue;
+    
+       TXCalc = RXCalc - read_uint16_t(&corTbl[i]);
+       if (TXCalc < FREQ_MIN || TXCalc > FREQ_MAX)
+         continue;
+
+       Channel += NRef * FRef;
+       Channel -= IF;
+
+       diff = Channel - desiredFreq;
+       if (diff < 0)
+         diff = -diff;
+
+       if (diff < Offset)
+         {
+           RXFreq = RXCalc;
+           TXFreq = TXCalc;
+           ActualChannel = Channel;
+           FSep = read_uint16_t(&fSepTbl[i]);
+           RefDiv = i + 6;
+           Offset = diff;
+         }
+      }
+
+    if (RefDiv != 0)
+      {
+       call CC.write(CC1K_FREQ_0A, RXFreq);
+       call CC.write(CC1K_FREQ_1A, RXFreq >> 8);
+       call CC.write(CC1K_FREQ_2A, RXFreq >> 16);
+
+       call CC.write(CC1K_FREQ_0B, TXFreq);
+       call CC.write(CC1K_FREQ_1B, TXFreq >> 8);
+       call CC.write(CC1K_FREQ_2B, TXFreq >> 16);
+
+       call CC.write(CC1K_FSEP0, FSep);
+       call CC.write(CC1K_FSEP1, FSep >> 8);
+
+       if (ActualChannel < 500000000)
+         {
+           if (ActualChannel < 400000000)
+             {
+               rxCurrent = 8 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE;
+               txCurrent = 9 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE;
+             }
+           else
+             {
+               rxCurrent = 4 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE;
+               txCurrent = 8 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE;
+             }
+           frontend = 1 << CC1K_IF_RSSI;
+           match = 7 << CC1K_RX_MATCH;
+         }
+       else
+         {
+           rxCurrent = 8 << CC1K_VCO_CURRENT | 3 << CC1K_LO_DRIVE;
+           txCurrent = 15 << CC1K_VCO_CURRENT | 3 << CC1K_PA_DRIVE;
+
+           frontend =
+             1 << CC1K_BUF_CURRENT | 2 << CC1K_LNA_CURRENT | 
+             1 << CC1K_IF_RSSI;
+           match = 2 << CC1K_RX_MATCH; // datasheet says to use 1...
+         }
+       call CC.write(CC1K_CURRENT, rxCurrent);
+       call CC.write(CC1K_MATCH, match);
+       call CC.write(CC1K_FRONT_END, frontend);
+       call CC.write(CC1K_PLL, RefDiv << CC1K_REFDIV);
+      }
+
+    return ActualChannel;
+  }
+
+  command void CC1000Control.init() {
+    call CC.init();
+
+    // wake up xtal and reset unit
+    call CC.write(CC1K_MAIN,
+                 1 << CC1K_RX_PD | 1 << CC1K_TX_PD | 
+                 1 << CC1K_FS_PD | 1 << CC1K_BIAS_PD); 
+    // clear reset.
+    call CC1000Control.coreOn();
+    call BusyWait.wait(2000);
+
+    // Set default parameter values
+    // POWER: 0dbm (~900MHz), 6dbm (~430MHz)
+    power = 8 << CC1K_PA_HIGHPOWER | 0 << CC1K_PA_LOWPOWER;
+    call CC.write(CC1K_PA_POW, power);
+
+    // select Manchester Violation for CHP_OUT
+    call CC.write(CC1K_LOCK_SELECT, 9 << CC1K_LOCK_SELECT);
+
+    // Default modem values = 19.2 Kbps (38.4 kBaud), Manchester encoded
+    call CC.write(CC1K_MODEM2, 0);
+    call CC.write(CC1K_MODEM1, 
+                 3 << CC1K_MLIMIT |
+                 1 << CC1K_LOCK_AVG_MODE | 
+                 3 << CC1K_SETTLING |
+                 1 << CC1K_MODEM_RESET_N);
+    call CC.write(CC1K_MODEM0, 
+                 5 << CC1K_BAUDRATE |
+                 1 << CC1K_DATA_FORMAT | 
+                 1 << CC1K_XOSC_FREQ);
+
+    call CC.write(CC1K_FSCTRL, 1 << CC1K_FS_RESET_N);
+
+#ifdef CC1K_DEF_FREQ
+    call CC1000Control.tuneManual(CC1K_DEF_FREQ);
+#else
+    call CC1000Control.tunePreset(CC1K_DEF_PRESET);
+#endif
+    call CC1000Control.off();
+  }
+
+  command void CC1000Control.tunePreset(uint8_t freq) {
+    int i;
+
+    // FREQA, FREQB, FSEP, CURRENT(RX), FRONT_END, POWER, PLL
+    for (i = CC1K_FREQ_2A; i <= CC1K_PLL; i++)
+      call CC.write(i, read_uint8_t(&CC1K_Params[freq][i]));
+    call CC.write(CC1K_MATCH, read_uint8_t(&CC1K_Params[freq][CC1K_MATCH]));
+    rxCurrent = read_uint8_t(&CC1K_Params[freq][CC1K_CURRENT]);
+    txCurrent = read_uint8_t(&CC1K_Params[freq][CC1K_MATCH + 1]);
+    power = read_uint8_t(&CC1K_Params[freq][CC1K_PA_POW]);
+
+    calibrate();
+  }
+
+  command uint32_t CC1000Control.tuneManual(uint32_t DesiredFreq) {
+    uint32_t actualFreq;
+
+    actualFreq = cc1000SetFrequency(DesiredFreq);
+
+    calibrate();
+
+    return actualFreq;
+  }
+
+  async command void CC1000Control.txMode() {
+    // MAIN register to TX mode
+    call CC.write(CC1K_MAIN,
+                 1 << CC1K_RXTX |
+                 1 << CC1K_F_REG |
+                 1 << CC1K_RX_PD | 
+                 1 << CC1K_RESET_N);
+    // Set the TX mode VCO Current
+    call CC.write(CC1K_CURRENT, txCurrent);
+    call BusyWait.wait(250);
+    call CC.write(CC1K_PA_POW, power);
+    call BusyWait.wait(20);
+  }
+
+  async command void CC1000Control.rxMode() {
+    // MAIN register to RX mode
+    // Powerup Freqency Synthesizer and Receiver
+    call CC.write(CC1K_CURRENT, rxCurrent);
+    call CC.write(CC1K_PA_POW, 0); // turn off power amp
+    call CC.write(CC1K_MAIN, 1 << CC1K_TX_PD | 1 << CC1K_RESET_N);
+    call BusyWait.wait(125);
+  }
+
+  async command void CC1000Control.coreOn() {
+    // MAIN register to SLEEP mode
+    call CC.write(CC1K_MAIN,
+                 1 << CC1K_RX_PD |
+                 1 << CC1K_TX_PD | 
+                 1 << CC1K_FS_PD |
+                 1 << CC1K_BIAS_PD |
+                 1 << CC1K_RESET_N);
+  }
+
+  async command void CC1000Control.biasOn() {
+    call CC.write(CC1K_MAIN,
+                 1 << CC1K_RX_PD |
+                 1 << CC1K_TX_PD | 
+                 1 << CC1K_FS_PD | 
+                 1 << CC1K_RESET_N);
+  }
+
+
+  async command void CC1000Control.off() {
+    // MAIN register to power down mode. Shut everything off
+    call CC.write(CC1K_MAIN,
+                 1 << CC1K_RX_PD |
+                 1 << CC1K_TX_PD | 
+                 1 << CC1K_FS_PD |
+                 1 << CC1K_CORE_PD |
+                 1 << CC1K_BIAS_PD |
+                 1 << CC1K_RESET_N);
+    call CC.write(CC1K_PA_POW, 0);  // turn off rf amp
+  }
+
+  command void CC1000Control.setRFPower(uint8_t newPower) {
+    power = newPower;
+  }
+
+  command uint8_t CC1000Control.getRFPower() {
+    return power;
+  }
+
+  command void CC1000Control.selectLock(uint8_t fn) {
+    // Select function of CHP_OUT pin (readable via getLock)
+    call CC.write(CC1K_LOCK, fn << CC1K_LOCK_SELECT);
+  }
+
+  command uint8_t CC1000Control.getLock() {
+    return call CC.getLOCK(); 
+  }
+
+  command bool CC1000Control.getLOStatus() {
+    // We use a high-side LO (local oscillator) frequency -> data will be
+    // inverted. See cc1000ComputeFreq and CC1000 datasheet p.23.
+    return TRUE;
+  }
+}
index 5bd67abc28faa3b770ed7bcb819a277b5c5d4261..46c26c3cc359335ec9405d0889b47b2d1bd03d32 100644 (file)
@@ -119,10 +119,8 @@ implementation {
       return status;
     state = S_SETSCANMODE;
 
-    configByteShadow &= ~MAX136X_CONFIG_SCAN(3);
-    configByteShadow |= MAX136X_CONFIG_SCAN(mode);
-
-    configByteShadow &= ~MAX136X_CONFIG_CS(3);
+    configByteShadow &= ~(MAX136X_CONFIG_SCAN(0x3) | MAX136X_CONFIG_CS(0xF));
+    configByteShadow |= MAX136X_CONFIG_SCAN(0x0);
     configByteShadow |= MAX136X_CONFIG_CS(chanhigh);
 
     mI2CBuffer[0] = configByteShadow;
@@ -142,7 +140,8 @@ implementation {
       return status;
     state = S_SETMONMODE;
 
-    configByteShadow &= ~MAX136X_CONFIG_CS(3);
+    configByteShadow &= ~(MAX136X_CONFIG_SCAN(0x3) | MAX136X_CONFIG_CS(0xF));
+    configByteShadow |= MAX136X_CONFIG_SCAN(0x2);
     configByteShadow |= MAX136X_CONFIG_CS(chanhigh);
 
     monitorByteShadow &= ~MAX136X_MONITOR_DELAY(7);
@@ -236,7 +235,6 @@ implementation {
   }
 
   command error_t HalMAX136xAdvanced.enableAlert(bool bEnable) {
-    uint8_t i;
     error_t status;
     if(state != S_IDLE)
       return FAIL;
@@ -250,8 +248,8 @@ implementation {
     else
       monitorByteShadow &= ~MAX136X_MONITOR_INTEN;
 
-    mI2CBuffer[1] = setupByteShadow;
-    mI2CBuffer[2] = monitorByteShadow;
+    mI2CBuffer[0] = setupByteShadow;
+    mI2CBuffer[1] = (0xF0 | monitorByteShadow);
     
     call HplMAX136x.setConfig(mI2CBuffer, 2);
     return SUCCESS;
index a4fc0d8a18490a810e7380d9abacfe0ce1c577af..d17091d57724661cba7f9b4fb395a5adbcf5d770 100644 (file)
@@ -48,6 +48,7 @@ generic module HplMAX136xLogicP(uint16_t devAddr)
 
   uses interface I2CPacket<TI2CBasicAddr>;
   uses interface GpioInterrupt as InterruptAlert;
+  uses interface GeneralIO as InterruptPin;
 }
 
 implementation {
@@ -124,6 +125,8 @@ implementation {
   }
 
   command error_t Init.init() {
+    call InterruptPin.makeInput();
+    call InterruptAlert.enableFallingEdge();
     atomic {
       mStopRequested = FALSE;
       mState = STATE_STOPPED;
@@ -177,7 +180,6 @@ implementation {
   }
 
   async event void I2CPacket.readDone(error_t i2c_error, uint16_t chipAddr, uint8_t len, uint8_t *buf) {
-    uint16_t tempVal;
     error_t error = i2c_error;
 
     switch (mState) {
index dd9f5e1767e8ddda4a1388942761d97b27bf5705..64c87a7e2ec226cb4133dcb704dac82257c08b35 100644 (file)
@@ -52,9 +52,7 @@ implementation {
   mcu_power_t powerState = MSP430_POWER_ACTIVE;
 
   /* Note that the power values are maintained in an order
-   * based on their active components, NOT on their values.
-   * Look at atm128hardware.h and page 42 of the ATmeg128
-   * manual (figure 17).*/
+   * based on their active components, NOT on their values.*/
   // NOTE: This table should be in progmem.
   const uint16_t msp430PowerBits[MSP430_POWER_LPM4 + 1] = {
     0,                                       // ACTIVE
@@ -81,20 +79,25 @@ implementation {
 #endif
        )
       pState = MSP430_POWER_LPM1;
-    // ADC12 check
-    if (ADC12CTL1 & ADC12BUSY){
-      if (!(ADC12CTL0 & MSC) && ((TACTL & TASSEL_3) == TASSEL_2))
-       pState = MSP430_POWER_LPM1;
-      else
-        switch (ADC12CTL1 & ADC12SSEL_3) {
-       case ADC12SSEL_2:
-         pState = MSP430_POWER_ACTIVE;
-         break;
-       case ADC12SSEL_3:
-         pState = MSP430_POWER_LPM1;
-         break;
-        }
+    
+#ifdef __msp430_have_adc12
+    // ADC12 check, pre-condition: pState != MSP430_POWER_ACTIVE
+    if (ADC12CTL0 & ADC12ON){
+      if (ADC12CTL1 & ADC12SSEL_2){
+        // sample or conversion operation with MCLK or SMCLK
+        if (ADC12CTL1 & ADC12SSEL_1)
+          pState = MSP430_POWER_LPM1;
+        else
+          pState = MSP430_POWER_ACTIVE;
+      } else if ((ADC12CTL1 & SHS0) && ((TACTL & TASSEL_3) == TASSEL_2)){
+        // Timer A is used as sample-and-hold source and SMCLK sources Timer A
+        // (Timer A interrupts are always disabled when it is used by the 
+        // ADC subsystem, that's why the Timer check above is not enough)
+             pState = MSP430_POWER_LPM1;
+      }
     }
+#endif
+    
     return pState;
   }
   
index 0eb04afc4b3ff2be0c2187ba33ec9731b12516db..2f6d406700278e0f8220f8a7298aaf650b51964e 100644 (file)
@@ -105,16 +105,6 @@ interface HplAdc12
    */
   async command void resetIFGs(); 
 
-  /** 
-   * Signals an ADC12MEMx overflow.
-   */ 
-  async event void memOverflow();
-
-  /** 
-   * Signals a Conversion time overflow.
-   */ 
-  async event void conversionTimeOverflow();
-
   /** 
    * Signals a conversion result. 
    * @param iv ADC12 interrupt vector value 0x6, 0x8, ... , 0x24
@@ -137,5 +127,10 @@ interface HplAdc12
    */
   async command void startConversion();
 
+  /**
+   * Enables conversion (sets the ENC bit).
+   */
+  async command void enableConversion();
+
 }
 
index 7240e7668edc1a011c6ad9d85ca09632294677aa..2423dba00de14cc0044a31307aacf100a307906f 100644 (file)
@@ -113,16 +113,14 @@ implementation
     ADC12CTL0 &= ~(ADC12ON); 
   }
   
+  async command void HplAdc12.enableConversion(){ 
+    ADC12CTL0 |= ENC; 
+  }
+    
   async command bool HplAdc12.isBusy(){ return ADC12CTL1 & ADC12BUSY; }
 
   TOSH_SIGNAL(ADC_VECTOR) {
-    uint16_t iv = ADC12IV;
-    switch(iv)
-    {
-      case  2: signal HplAdc12.memOverflow(); return;
-      case  4: signal HplAdc12.conversionTimeOverflow(); return;
-    }
-    signal HplAdc12.conversionDone(iv);
+    signal HplAdc12.conversionDone(ADC12IV);
   }
 }
 
index 90952a0c2594b0ed06190466660e11d2b8299e98..d8ce94ea1d0df7d935350dad9938cdb5f4258137 100644 (file)
 #define P6PIN_AUTO_CONFIGURE
 #define REF_VOLT_AUTO_CONFIGURE
 #define CHECK_ARGS
-
-/*
- * The msp430adc12_channel_config_t includes all relevant flags to configure
- * the ADC12 for single channel conversions. They are contained in the following
- * MSP430 registers: ADC12CTL0, ADC12CTL1, ADC12MCTLx and TACTL of TimerA (if
- * applicable) and named according to section "17.3 ADC12 Registers" of the
- * "MSP430x1xx Family User's Guide".
- * 
- *                   **********************************
- *                    
- * .inch: ADC12 input channel (ADC12MCTLx register). An (external) input
- * channel maps to one of msp430's A0-A7 pins (see device specific data sheet).
- *
- * .sref: reference voltage (ADC12MCTLx register). If REFERENCE_VREFplus_AVss
- * or REFERENCE_VREFplus_VREFnegterm is chosen AND the client wires to the
- * Msp430Adc12ClientAutoRVGC or Msp430Adc12ClientAutoDMA_RVGC component then
- * the reference voltage generator has automatically been enabled to the
- * voltage level defined by the "ref2_5v" flag (see below) when the
- * Resource.granted() event is signalled to the client. Otherwise this flag is
- * ignored.
- * 
- * .ref2_5v: Reference generator voltage level (ADC12CTL0 register). See "sref"
- * flag.
- * 
- * .adc12ssel: ADC12 clock source select for the sample-hold-time (ADC12CTL1
- * register). In combination the "adc12ssel", "adc12div" and "sht" define the
- * sample-hold-time: "adc12ssel" defines the clock source, "adc12div" defines
- * the ADC12 clock divider and "sht" define the time expressed in jiffies.
- * (the sample-hold-time depends on the resistence of the attached sensor, and
- * is calculated using to the formula in section 17.2.4 of the user guide)
- *
- * .adc12div: ADC12 clock divider (ADC12CTL1 register). See "adc12ssel".
- *
- * .sht: Sample-and-hold time (ADC12CTL1 register). See "adc12ssel".
- * 
- * .sampcon_ssel: Clock source for the sampling period (TASSEL for TimerA).
- * When an ADC client specifies a non-zero "jiffies" parameter (passed in the
- * relevant Msp430Adc12SingleChannel interface commands), the ADC
- * implementation will automatically configure TimerA to be sourced from
- * "sampcon_ssel" with an input divider of "sampcon_id". During the sampling
- * process TimerA will then be used to trigger a conversion every "jiffies"
- * clock ticks.
- * 
- * .sampcon_id: Input divider for "sampcon_ssel"  (IDx in TACTL register,
- * TimerA). See "sampcon_ssel".
- *
- * 
- *                   **********************************
- *                    
- * EXAMPLE: Assuming that SMCLK runs at 1 MHz the following code snippet
- * performs 2000 ADC conversions on channel A2 with a sampling period of 4000 Hz.
- * The sampling period is defined by the combination of SAMPCON_SOURCE_SMCLK,
- * SAMPCON_CLOCK_DIV_1 and a "jiffies" parameter of (1000000 / 4000) = 250. 
-   #define NUM_SAMPLES 2000
-   uint16_t buffer[NUM_SAMPLES];
-   
-   msp430adc12_channel_config_t config = {
-    INPUT_CHANNEL_A2, REFERENCE_VREFplus_AVss, REFVOLT_LEVEL_NONE,
-    SHT_SOURCE_SMCLK, SHT_CLOCK_DIV_1, SAMPLE_HOLD_64_CYCLES,
-    SAMPCON_SOURCE_SMCLK, SAMPCON_CLOCK_DIV_1 
-   };
-  
-  event void Boot.booted()
-  {
-    call Resource.request();
-  }
-  
-  event void Resource.granted()
-  {
-    error_t result;
-    result = call SingleChannel.configureMultiple(&config, buffer, BUFFER_SIZE, 250);
-    if (result == SUCCESS)
-      call SingleChannel.getData();
-  }
-
-  async event uint16_t* SingleChannel.multipleDataReady(uint16_t *buf, uint16_t length)
-  {
-    // buffer contains conversion results
-  }
- */
-
  
 typedef struct { 
+  // see README.txt for a more detailed explanation
   unsigned int inch: 4;            // input channel 
   unsigned int sref: 3;            // reference voltage 
   unsigned int ref2_5v: 1;         // reference voltage level 
@@ -135,6 +54,15 @@ typedef struct {
   unsigned int : 0;                // align to a word boundary 
 } msp430adc12_channel_config_t;
 
+typedef struct 
+{
+  // see README.txt for a more detailed explanation
+  volatile unsigned
+  inch: 4,                                     // input channel
+  sref: 3,                                     // reference voltage
+  eos: 1;                                      // end of sequence flag
+} __attribute__ ((packed)) adc12memctl_t;
+
 enum inch_enum
 {  
    // see device specific data sheet which pin Ax is mapped to
@@ -232,16 +160,8 @@ enum sampcon_id_enum
 // The unique string for accessing HAL2 via ReadStream
 #define ADCC_READ_STREAM_SERVICE "AdcC.ReadStream.Client"
 
-typedef struct 
-{
-  volatile unsigned
-  inch: 4,                                     // input channel
-  sref: 3,                                     // reference voltage
-  eos: 1;                                      // end of sequence flag
-} __attribute__ ((packed)) adc12memctl_t;
-
 /* Test for GCC bug (bitfield access) - only version 3.2.3 is known to be stable */
-// check: is this relevant anymore ?
+// TODO: check whether this is still relevant...
 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION == 332
 #error "The msp430-gcc version (3.3.2) contains a bug which results in false accessing \
@@ -251,4 +171,8 @@ of bitfields in structs and makes MSP430ADC12M.nc fail ! Use version 3.2.3 inste
 of bitfields in structs (MSP430ADC12M.nc would fail). Use version 3.2.3 instead."
 #endif  
 
+#ifndef __msp430_have_adc12
+#error MSP430ADC12C: Target msp430 device does not have ADC12 module
+#endif
+
 #endif
index 23f06fab3c423a47d9e8dfa7ed4f676fd71c79a3..4d40621b42eac725b5ee7bc22e229477cc46169f 100644 (file)
@@ -47,6 +47,8 @@ generic configuration Msp430Adc12ClientC()
   provides {\r
     interface Resource;\r
     interface Msp430Adc12SingleChannel;\r
+    interface Msp430Adc12MultiChannel;\r
+    interface Msp430Adc12Overflow;\r
   }\r
 } implementation {\r
   components Msp430Adc12P;\r
@@ -56,4 +58,6 @@ generic configuration Msp430Adc12ClientC()
   };\r
   Resource = Msp430Adc12P.Resource[ID];\r
   Msp430Adc12SingleChannel = Msp430Adc12P.SingleChannel[ID];\r
+  Msp430Adc12MultiChannel = Msp430Adc12P.MultiChannel[ID];\r
+  Msp430Adc12Overflow = Msp430Adc12P.Overflow[ID];\r
 }\r
index 4b5c3ff8ccae1fae06053f497ee40225b528755b..0c7e8f0f5dc3722f8c8c35209d77c4005b0679d4 100644 (file)
@@ -39,6 +39,8 @@ module Msp430Adc12ImplP
   provides {
     interface Init;
     interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
+    interface Msp430Adc12MultiChannel as MultiChannel[uint8_t id];
+    interface Msp430Adc12Overflow as Overflow[uint8_t id];
     interface AsyncStdControl as DMAExtension[uint8_t id];
        }
        uses {
@@ -66,17 +68,20 @@ implementation
     SINGLE_DATA_REPEAT = 2,
     MULTIPLE_DATA = 4,
     MULTIPLE_DATA_REPEAT = 8,
-    CONVERSION_MODE_MASK = 0x0F,
+    MULTI_CHANNEL = 16,
+    CONVERSION_MODE_MASK = 0x1F,
 
-    ADC_BUSY = 16,                /* request pending */
-    USE_TIMERA = 32,              /* TimerA used for SAMPCON signal */
+    ADC_BUSY = 32,                /* request pending */
+    USE_TIMERA = 64,              /* TimerA used for SAMPCON signal */
+    ADC_OVERFLOW = 128,
   };
 
   uint8_t state;                  /* see enum above */
   
-  uint16_t *resultBuffer;  /* conversion results */
+  uint16_t *resultBuffer;         /* conversion results */
   uint16_t resultBufferLength;    /* length of buffer */
   uint16_t resultBufferIndex;     /* offset into buffer */
+  uint8_t numChannels;            /* number of channels (multi-channel conversion) */
   uint8_t clientID;               /* ID of client that called getData() */
 
   command error_t Init.init()
@@ -378,12 +383,102 @@ implementation
     return FAIL;
   }
 
+  async command error_t MultiChannel.configure[uint8_t id](
+      const msp430adc12_channel_config_t *config,
+      adc12memctl_t *memctl, uint8_t numMemctl, uint16_t *buf, 
+      uint16_t numSamples, uint16_t jiffies)
+  {
+    error_t result = ERESERVE;
+#ifdef CHECK_ARGS
+    if (!config || !memctl || !numMemctl || numMemctl > 15 || !numSamples || 
+        !buf || jiffies == 1 || jiffies == 2 || numSamples % (numMemctl+1) != 0)
+      return EINVAL;
+#endif
+    atomic {
+      if (state & ADC_BUSY)
+        return EBUSY;
+      if (call ADCArbiterInfo.userId() == id){
+        adc12ctl1_t ctl1 = {
+          adc12busy: 0,
+          // use seq. of channels (rep.seq. channel does not work with TimerA + MSC ?)
+          conseq: (jiffies == 0) ? 3 : 1, 
+          adc12ssel: config->adc12ssel,
+          adc12div: config->adc12div,
+          issh: 0,
+          shp: 1,
+          shs: (jiffies == 0) ? 0 : 1,
+          cstartadd: 0
+        };
+        adc12memctl_t firstMemctl = {
+          inch: config->inch,
+          sref: config->sref,
+          eos: 0
+        };     
+        uint16_t i, mask = 1;
+        adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
+        ctl0.msc = 1;
+        ctl0.sht0 = config->sht;
+        ctl0.sht1 = config->sht;
+
+        state = MULTI_CHANNEL;
+        resultBuffer = buf;
+        resultBufferLength = numSamples;
+        resultBufferIndex = 0;
+        numChannels = numMemctl+1;
+        call HplAdc12.setCtl0(ctl0);
+        call HplAdc12.setCtl1(ctl1);
+        call HplAdc12.setMCtl(0, firstMemctl);
+        for (i=0; i<(numMemctl-1) && i < 14; i++){
+          memctl[i].eos = 0;
+          call HplAdc12.setMCtl(i+1, memctl[i]);
+        }
+        memctl[i].eos = 1;
+        call HplAdc12.setMCtl(i+1, memctl[i]);
+        call HplAdc12.setIEFlags(mask << (i+1));        
+        
+        if (jiffies){
+          state |= USE_TIMERA;
+          prepareTimerA(jiffies, config->sampcon_ssel, config->sampcon_id);
+        }
+        result = SUCCESS;
+      }      
+    }
+    return result;
+  }
+
+  async command error_t MultiChannel.getData[uint8_t id]()
+  {
+    uint8_t i;
+    atomic {
+      if (call ADCArbiterInfo.userId() == id){
+        if (!resultBuffer)
+          return EINVAL;
+        if (state & ADC_BUSY)
+          return EBUSY;
+        state |= ADC_BUSY;
+        clientID = id;
+        for (i=0; i<numChannels; i++)
+          configureAdcPin((call HplAdc12.getMCtl(i)).inch);
+        call HplAdc12.startConversion();
+        if (state & USE_TIMERA)
+          startTimerA(); 
+        return SUCCESS;
+      }
+    }
+    return FAIL;
+  }
+  
   void stopConversion()
   {
-    adc12memctl_t memctl = call HplAdc12.getMCtl(0);
+    uint8_t i;
     if (state & USE_TIMERA)
       call TimerA.setMode(MSP430TIMER_STOP_MODE);
-    resetAdcPin( memctl.inch );
+    resetAdcPin( (call HplAdc12.getMCtl(0)).inch );
+    if (state & MULTI_CHANNEL){
+      ADC12IV = 0; // clear any pending overflow
+      for (i=1; i<numChannels; i++)
+        resetAdcPin( (call HplAdc12.getMCtl(i)).inch );
+    }
     call HplAdc12.stopConversion();
     call HplAdc12.resetIFGs(); 
     state &= ~ADC_BUSY;
@@ -418,6 +513,13 @@ implementation
 
   async event void HplAdc12.conversionDone(uint16_t iv)
   {
+    if (iv <= 4){ // check for overflow
+      if (iv == 2)
+        signal Overflow.memOverflow[clientID]();
+      else
+        signal Overflow.conversionTimeOverflow[clientID]();
+    }
+#ifndef MSP430ADC12_ONLY_DMA
     switch (state & CONVERSION_MODE_MASK) 
     { 
       case SINGLE_DATA:
@@ -433,6 +535,21 @@ implementation
             stopConversion();
           break;
         }
+      case MULTI_CHANNEL:
+        {
+          uint16_t i = 0;
+          do {
+            *resultBuffer++ = call HplAdc12.getMem(i);
+          } while (++i < numChannels);
+          resultBufferIndex += numChannels;
+          if (resultBufferLength == resultBufferIndex){
+            stopConversion();
+            resultBuffer -= resultBufferLength;
+            resultBufferIndex = 0;
+            signal MultiChannel.dataReady[clientID](resultBuffer, resultBufferLength);
+          } else call HplAdc12.enableConversion();
+        }
+        break;
       case MULTIPLE_DATA:
         {
           uint16_t i = 0, length;
@@ -474,6 +591,7 @@ implementation
           break;
         }
       } // switch
+#endif
   }
 
   default async event error_t SingleChannel.singleDataReady[uint8_t id](uint16_t data)
@@ -486,9 +604,11 @@ implementation
   {
     return 0;
   }
+   
+  default async event void MultiChannel.dataReady[uint8_t id](uint16_t *buffer, uint16_t numSamples) {};
   
-  async event void HplAdc12.memOverflow(){}
-  async event void HplAdc12.conversionTimeOverflow(){}
+  default async event void Overflow.memOverflow[uint8_t id](){}
+  default async event void Overflow.conversionTimeOverflow[uint8_t id](){}
 
 }
 
diff --git a/tos/chips/msp430/adc12/Msp430Adc12MultiChannel.nc b/tos/chips/msp430/adc12/Msp430Adc12MultiChannel.nc
new file mode 100644 (file)
index 0000000..0ded55e
--- /dev/null
@@ -0,0 +1,113 @@
+/* 
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+/** 
+ * This interface provides access to the ADC12 on the level of HAL. It can be
+ * used to sample up to 16 (different) ADC channels. It separates between
+ * configuration and data collection: every time a client has been granted
+ * access to the ADC subsystem (via the Resource interface), it first has to
+ * configure the ADC.  Afterwards the client may call getData() more than once
+ * without reconfiguring the ADC in between (if the client has not released the
+ * ADC via the Resource interface), i.e.<p>
+ * 
+ *    configure() -> ( getData() -> dataReady() )*
+ *
+ * @author Jan Hauer 
+ */
+
+#include "Msp430Adc12.h" 
+interface Msp430Adc12MultiChannel 
+{   
+
+  /** 
+   * Configures the ADC to perform conversion(s) on multiple channels.  Any
+   * previous configuration will be overwritten.  If SUCCESS is returned
+   * calling <code>getData()</code> will start the conversion immediately and a
+   * <code>dataReady()</code> event will be signalled with the conversion
+   * result when the conversion has finished.
+   *
+   * @param config Main ADC12 configuration and configuration of the first
+   * channel 
+   *
+   * @param memctl List of additional channels and respective reference
+   * voltages
+   *
+   * @param numMemctl Number of entries in the list
+   * 
+   * @param buffer Buffer to store the conversion results, it must have
+   * numSamples entries. Results will be stored in the order the channels where
+   * specified.
+   *
+   * @param numSamples Total number of samples. Note: numSamples %
+   * (numMemctl+1) must be zero. For example, to sample every channel twice use
+   * numSamples = (numMemctl+1) * 2
+   *
+   * @param jiffies Sampling period per sequence in terms of clock ticks of
+   * "sampcon_ssel" and input divider "sampcon_id". A sequence of (numMemctl+1)
+   * is always sampled as fast as possible and <code>jiffies</code> specifies
+   * the time between those sequences. For example, if numSamples =
+   * (numMemctl+1) * 5, then dataReady() will be signalled after (approx.)
+   * 5*jiffies clock ticks after the call to getData() and each set of
+   * numMemctl+1 channels was sampled at (almost) the same time.
+   *
+   * @return SUCCESS means that the ADC was configured successfully and
+   * <code>getData()</code> can be called to start the conversion.
+   */
+
+  async command error_t configure(const msp430adc12_channel_config_t *config,
+      adc12memctl_t *memctl, uint8_t numMemctl, uint16_t *buffer, 
+      uint16_t numSamples, uint16_t jiffies);
+
+  /** 
+   * Starts sampling the adc channels using the configuration as specified by
+   * the last call to <code>configure()</code>.
+   *
+   * @return SUCCESS means that the conversion was started successfully and an
+   * event dataReady() will be signalled. Otherwise no event will be signalled.
+   */ 
+  async command error_t getData();
+  
+  /** 
+   * Conversion results are ready. Results are stored in the buffer in the
+   * order the channels where specified in the <code>configure()</code>
+   * command, i.e. every (numMemctl+1)-th entry maps to the same channel. 
+   * 
+   * @param buffer Conversion results (lower 12 bit are valid, respectively).
+   * @param numSamples Number of results stored in <code>buffer</code> 
+   */    
+  async event void dataReady(uint16_t *buffer, uint16_t numSamples); 
+
+}
+
diff --git a/tos/chips/msp430/adc12/Msp430Adc12Overflow.nc b/tos/chips/msp430/adc12/Msp430Adc12Overflow.nc
new file mode 100644 (file)
index 0000000..466e83f
--- /dev/null
@@ -0,0 +1,56 @@
+/* 
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+/** 
+ * Signals an ADC12MEMx overflow or conversion time overflow condition to the
+ * client.
+ *
+ * @author Jan Hauer 
+ */
+
+#include "Msp430Adc12.h" 
+interface Msp430Adc12Overflow 
+{   
+  /** 
+   * An ADC12MEMx overflow condition has occured.
+   */ 
+  async event void memOverflow();
+
+  /** 
+   * A conversion time overflow condition has occured.
+   */ 
+  async event void conversionTimeOverflow();
+}
+
index 834e586f4a0e1c80cfe64cbfe9f4c158ba5645f4..bb1afb6d9e2c174773412f9e62de7c535b7b219d 100644 (file)
@@ -39,6 +39,8 @@ configuration Msp430Adc12P
   provides {
     interface Resource[uint8_t id]; 
     interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id]; 
+    interface Msp430Adc12MultiChannel as MultiChannel[uint8_t id]; 
+    interface Msp430Adc12Overflow as Overflow[uint8_t id]; 
     interface AsyncStdControl as DMAExtension[uint8_t id];
   }
 } implementation { 
@@ -47,6 +49,8 @@ configuration Msp430Adc12P
 
   Resource = Arbiter;
   SingleChannel = Msp430Adc12ImplP.SingleChannel;
+  MultiChannel= Msp430Adc12ImplP.MultiChannel;
+  Overflow = Msp430Adc12ImplP.Overflow;
   DMAExtension = Msp430Adc12ImplP.DMAExtension;
   
   Msp430Adc12ImplP.Init <- MainC;
index 8a9d0cb22a2ce2194af059017483b4a7d2a626a7..630f2b907491903203754e5165f4def52c31a55f 100644 (file)
 /** 
  * 
  * This interface provides access to the ADC12 on the level of HAL. It can be
- * used to sample an adc channel once or repeatedly (one event is signalled per
- * conversion result) or perform multiple conversions for a channel once or
- * repeatedly (one event is signalled per multiple conversion results). It
- * cannot be used to sample different adc channels with a single command.
+ * used to sample a single adc channel once or repeatedly (one event is
+ * signalled per conversion result) or perform multiple conversions for a
+ * single channel once or repeatedly (one event is signalled per multiple
+ * conversion results). It cannot be used to sample different adc channels with
+ * a single command (use the Msp430Adc12MultiChannel interface instead).
  * Sampling a channel requires calling a sequence of two commands, configureX()
  * and getData(), where X is either 'Single', 'SingleRepeat', 'Multiple' or
  * 'MultipleRepeat'. Conversion results will be signalled by the
  * dataReadySingle() or dataReadyMultiple() event, depending on the previous
  * configuration, i.e. there are four possible sequences:
  * 
- *    configureSingle()          -> [ getData() -> singleDataReady() ]*
- * or configureSingleRepeat()    -> [ getData() -> singleDataReady() ]*
- * or configureMultiple()        -> [ getData() -> multipleDataReady() ]*
- * or configureMultipleRepeat()  -> getData() -> multipleDataReady()
+ * <p> configureSingle()          -> ( getData() -> singleDataReady() )*
+ * <p> configureSingleRepeat()    -> ( getData() -> singleDataReady() )*
+ * <p> configureMultiple()        -> ( getData() -> multipleDataReady() )*
+ * <p> configureMultipleRepeat()  -> getData() -> multipleDataReady()
  *
- * where configureX() and getData() are commands called by the client and
+ * <p> where configureX() and getData() are commands called by the client and
  * singleDataReady() and multipleDataReady() are events signalled back to the
- * client by the adc subsystem. Note that a configuration is valid until
- * the client reconfigures or releases the ADC (using the Resource 
- * interface), except for configureMultipleRepeat(), which is only valid 
- * for a single call to getData(). This means that after a successful 
- * configuration with, for example, configureSingle() the client may call 
- * getData() more than once without reconfiguring the ADC in between 
- * (if the client has not released the ADC via the Resource interface).
+ * client by the adc subsystem. Note that a configuration is valid until the
+ * client reconfigures or releases the ADC (using the Resource interface),
+ * except for configureMultipleRepeat(), which is only valid for a single call
+ * to getData(). This means that after a successful configuration with, for
+ * example, configureSingle() the client may call getData() more than once
+ * without reconfiguring the ADC in between (if the client has not released the
+ * ADC via the Resource interface).
  *
  * @author Jan Hauer 
  */
@@ -193,9 +194,7 @@ interface Msp430Adc12SingleChannel
    * ignored. If the ADC was configured with the
    * <code>configureSingleRepeat()</code> command then the return value tells
    * whether another conversion should be performed (<code>SUCCESS()</code>) or
-   * not (<code>FAIL</code>). If <code>SUCCESS()</code> is returned then the
-   * sampling period will be as specified in the
-   * <code>configureSingleRepeat()</code> command.
+   * not (<code>FAIL</code>).
    * 
    * @param data Conversion result (lower 12 bit).  
    *
@@ -222,7 +221,7 @@ interface Msp430Adc12SingleChannel
    * @return
    * A null pointer stops a repeated conversion mode. Any non-zero value is
    * interpreted as the next buffer, which must have at least
-   * <code>numSamples</code> entries. The return value us ignored if the ADC
+   * <code>numSamples</code> entries. The return value is ignored if the ADC
    * was configured with <code>configureMultiple()</code>.
    */    
   async event uint16_t* multipleDataReady(uint16_t buffer[], uint16_t numSamples); 
index 326751b28e78f3795fe5b76725bb7515388244cc..e1df33a4311051fd523730b90e1dff25c85025ff 100644 (file)
@@ -271,8 +271,6 @@ module Msp430RefVoltGeneratorP
     }
   }
 
-  async event void HplAdc12.memOverflow(){}
-  async event void HplAdc12.conversionTimeOverflow(){}
   async event void HplAdc12.conversionDone(uint16_t iv){}
 
   default event void RefVolt_1_5V.startDone(error_t error){}
index 377a7e68b6c8181f214eecb881d572e459e5dbdf..7acc1c116bb6a49b618db08d61401072c26aa6b1 100644 (file)
@@ -1,6 +1,6 @@
-The implementation of the 12-bit ADC stack on the MSP430 is in compliance with
-TEP 101 (tinyos-2.x/doc/txt/tep101.txt) and provides virtualized access to the
-ADC12 by seven different components: AdcReadClientC, AdcReadNowClientC,
+The implementation of the 12-bit ADC stack on the MSP430 is in compliance
+with TEP 101 (tinyos-2.x/doc/txt/tep101.txt) and provides virtualized access
+to the ADC12 by seven different components: AdcReadClientC, AdcReadNowClientC,
 AdcReadStreamClientC, Msp430Adc12ClientC, Msp430Adc12ClientAutoDMAC,
 Msp430Adc12ClientAutoRVGC and Msp430Adc12ClientAutoDMA_RVGC. A client
 component may wire to any of these components and it SHOULD NOT wire to any
@@ -8,6 +8,10 @@ other components in 'tinyos-2.x/tos/chips/msp430/adc12'. This document
 explains the difference between the seven components.
 
 
+1. HIL
+====================================================================
+
+
 A platform-independent application (an application like 'Oscilloscope' that is
 supposed to run on, for example, the 'telosb' and 'micaz' platform at the same
 time) cannot wire to an MSP430-specific interface like Msp430Adc12SingleChannel
@@ -24,6 +28,9 @@ values. Thus, if a client component does not care so much about efficiency but
 rather about portability it should wire to any of these components.
 
 
+2. HAL
+====================================================================
+
 An application that is written for an MSP430-based platform like 'eyesIFX' or
 'telosb' can access the ADC12 in a more efficient way to, for example, do
 high-frequency sampling through the Msp430Adc12SingleChannel interface. On the
@@ -52,6 +59,10 @@ application may wire to:
   * Msp430Adc12ClientAutoDMAC: DMA, but no automatic reference voltage
   * Msp430Adc12ClientAutoDMA_RVGC: DMA and automatic reference voltage
 
+
+PINs
+--------------------------------------------------------------------
+
 During a conversion the respective ADC port pin (ports 6.0 - 6.7) must be
 configured such that the peripheral module function is selected and the port
 pin is switched to input direction. By default, for every client this is done
@@ -61,6 +72,87 @@ and input direction and immediately after the conversion has finished it is
 switched to I/O function mode. To disable this feature please comment out the
 "P6PIN_AUTO_CONFIGURE" macro in Msp430Adc12.h.
 
+
+Configuration for single channel conversions
+--------------------------------------------------------------------
+
+The msp430adc12_channel_config_t struct holds all information needed to
+configure the ADC12 for single channel conversions. The flags come from the
+following MSP430 registers: ADC12CTL0, ADC12CTL1, ADC12MCTLx and TACTL and are
+named according to the "MSP430x1xx Family User's Guide". Their meaning is as
+follows:
+
+  .inch: ADC12 input channel (ADC12MCTLx register). An (external) input
+  channel maps to one of msp430's A0-A7 pins (see device specific data sheet).
+
+  .sref: reference voltage (ADC12MCTLx register). If REFERENCE_VREFplus_AVss
+  or REFERENCE_VREFplus_VREFnegterm is chosen AND the client wires to the
+  Msp430Adc12ClientAutoRVGC or Msp430Adc12ClientAutoDMA_RVGC component then
+  the reference voltage generator has automatically been enabled to the
+  voltage level defined by the "ref2_5v" flag (see below) when the
+  Resource.granted() event is signalled to the client. Otherwise this flag is
+  ignored.
+  
+  .ref2_5v: Reference generator voltage level (ADC12CTL0 register). See
+  "sref".
+  
+  .adc12ssel: ADC12 clock source select for the sample-hold-time (ADC12CTL1
+  register). In combination the "adc12ssel", "adc12div" and "sht" define the
+  sample-hold-time: "adc12ssel" defines the clock source, "adc12div" defines
+  the ADC12 clock divider and "sht" define the time expressed in jiffies.
+  (the sample-hold-time depends on the resistence of the attached sensor, and
+  is calculated using to the formula in section 17.2.4 of the user guide)
+  
+  .adc12div: ADC12 clock divider (ADC12CTL1 register). See "adc12ssel".
+  
+  .sht: Sample-and-hold time (ADC12CTL1 register). See "adc12ssel".
+  
+  .sampcon_ssel: Clock source for the sampling period (TASSEL for TimerA).
+  When an ADC client specifies a non-zero "jiffies" parameter (using the
+  Msp430Adc12SingleChannel.configureX commands), the ADC
+  implementation will automatically configure TimerA to be sourced from
+  "sampcon_ssel" with an input divider of "sampcon_id". During the sampling
+  process TimerA will be used to trigger a single
+  (Msp430Adc12SingleChannel interface) or a sequence of (Msp430Adc12MultiChannel 
+  interface) conversions every "jiffies" clock ticks.
+  
+  .sampcon_id: Input divider for "sampcon_ssel"  (IDx in TACTL register,
+  TimerA). See "sampcon_ssel".
+
+
+Example: Assuming that SMCLK runs at 1 MHz the following code snippet
+performs 2000 ADC conversions on channel A2 with a sampling period of 4000 Hz.
+The sampling period is defined by the combination of SAMPCON_SOURCE_SMCLK,
+SAMPCON_CLOCK_DIV_1 and a "jiffies" parameter of (1000000 / 4000) = 250. 
+
+   #define NUM_SAMPLES 2000
+   uint16_t buffer[NUM_SAMPLES];
+   
+   const msp430adc12_channel_config_t config = {
+    INPUT_CHANNEL_A2, REFERENCE_VREFplus_AVss, REFVOLT_LEVEL_NONE,
+    SHT_SOURCE_SMCLK, SHT_CLOCK_DIV_1, SAMPLE_HOLD_64_CYCLES,
+    SAMPCON_SOURCE_SMCLK, SAMPCON_CLOCK_DIV_1 
+   };
+  
+  event void Boot.booted()
+  {
+    call Resource.request();
+  }
+  
+  event void Resource.granted()
+  {
+    error_t result;
+    result = call SingleChannel.configureMultiple(&config, buffer, BUFFER_SIZE, 250);
+    if (result == SUCCESS)
+      call SingleChannel.getData();
+  }
+
+  async event uint16_t* SingleChannel.multipleDataReady(uint16_t *buf, uint16_t length)
+  {
+    // buffer contains conversion results
+  }
+
 -----
 
 $Date$
index cf1b18e5146649100f5e1158349304555d801939..9d0cedd87662664b5af6f38f5019666ef1f72d4b 100644 (file)
@@ -123,6 +123,17 @@ to_type func_name(from_type x) { union {from_type f; to_type t;} c = {f:x}; retu
 #undef signal
 #endif
 
+// define platform constants that can be changed for different compilers
+// these are all msp430-gcc specific (add as necessary)
+
+#ifdef __msp430_headers_adc10_h
+#define __msp430_have_adc10
+#endif
+
+#ifdef __msp430_headers_adc12_h
+#define __msp430_have_adc12
+#endif
+
 // I2CBusy flag is not defined by current MSP430-GCC
 #ifdef __msp430_have_usart0_with_i2c
 #ifndef I2CBUSY
index 8f2f8e940c11ccfe3f4a97647618c62c207e2681..ebf91d341c280e3ca23d0d3e909aa420a11a177c 100644 (file)
@@ -5,7 +5,7 @@ interface HplMsp430I2C {
   
   async command bool isI2C();
   async command void clearModeI2C();
-  async command void setModeI2C( msp430_i2c_config_t* config );
+  async command void setModeI2C( msp430_i2c_union_config_t* config );
   
   // U0CTL
   async command void setMasterMode();
index 68398d21e6d5f1aa490a1bf32469a3761ec6915d..3279016ce3c36b166bed5ee09ac6fa080b852df9 100644 (file)
@@ -63,8 +63,9 @@ implementation {
     }
   }
   
-  async command void HplI2C.setModeI2C( msp430_i2c_config_t* config ) {
+  async command void HplI2C.setModeI2C( msp430_i2c_union_config_t* config ) {
     
+    call HplUsart.resetUsart(TRUE);
     call HplUsart.disableUart();
     call HplUsart.disableSpi();
     call SIMO.makeInput();
@@ -79,18 +80,13 @@ implementation {
       U0CTL |= SYNC | I2C;
       U0CTL &= ~I2CEN;
       
-      U0CTL |= ( ( config->rxdmaen << 7 ) |
-                 ( config->txdmaen << 6 ) |
-                 ( config->xa << 4 ) |
-                 ( config->listen << 3 ) );
-      I2CTCTL = 0;
-      I2CTCTL = ( ( config->i2cword << 7 ) |
-                 ( config->i2crm << 6 ) |
-                 ( config->i2cssel << 4 ) );
-      I2CPSC = config->i2cpsc;
-      I2CSCLH = config->i2csclh;
-      I2CSCLL = config->i2cscll;
-      I2COA = config->i2coa;
+      U0CTL = (config->i2cRegisters.uctl | (I2C | SYNC)) & ~I2CEN;
+      I2CTCTL = config->i2cRegisters.i2ctctl;
+            
+      I2CPSC = config->i2cRegisters.i2cpsc;
+      I2CSCLH = config->i2cRegisters.i2csclh;
+      I2CSCLL = config->i2cRegisters.i2cscll;
+      I2COA = config->i2cRegisters.i2coa;
       U0CTL |= I2CEN;
       
     }
index fb937871d964a3126fc33e387fb34c49195713f5..835b536957dae61b642a6172bf991fe1a2a7112f 100644 (file)
@@ -165,25 +165,13 @@ interface HplMsp430Usart {
   /**
    * Switches USART to Spi mode.
    */
-  async command void setModeSpi(msp430_spi_config_t* config);
-  
-  /**
-   * Switches USART to Uart TX mode (RX pins disabled).
-   * Interrupts disabled by default.
-   */
-  async command void setModeUartTx(msp430_uart_config_t* config);
-  
-  /**
-   * Switches USART to Uart RX mode (TX pins disabled)..
-   * Interrupts disabled by default.
-   */
-  async command void setModeUartRx(msp430_uart_config_t* config);
+  async command void setModeSpi(msp430_spi_union_config_t* config);
   
   /**
    * Switches USART to Uart mode (RX and TX enabled)
    * Interrupts disabled by default.
    */
-  async command void setModeUart(msp430_uart_config_t* config);
+  async command void setModeUart(msp430_uart_union_config_t* config);
   
   /* Dis/enabling of UTXIFG / URXIFG */
   async command void disableRxIntr();
index 5fdeb41b010b797f0bdabb4780086ea4e19a8f82..cf618bfbbdba8cc75855497c1102b256380c6293 100644 (file)
@@ -67,6 +67,7 @@
  * @author: Jonathan Hui <jhui@archedrock.com>
  * @author: Vlado Handziski <handzisk@tkn.tu-berlin.de>
  * @author: Joe Polastre
+ * @author: Philipp Huppertz <huppertz@tkn.tu-berlin.de>
  * @version $Revision$ $Date$
  */
 
@@ -206,7 +207,6 @@ implementation
   async command void Usart.disableUart() {
     atomic {
       ME1 &= ~(UTXE0 | URXE0);   // USART0 UART module enable
-      call Usart.resetUsart(TRUE);
       call UTXD.selectIOFunc();
       call URXD.selectIOFunc();
     }
@@ -247,113 +247,64 @@ implementation
   async command void Usart.disableSpi() {
     atomic {
       ME1 &= ~USPIE0;   // USART0 SPI module disable
-      call Usart.resetUsart(TRUE);
       call SIMO.selectIOFunc();
       call SOMI.selectIOFunc();
       call UCLK.selectIOFunc();
     }
   }
+  
+  void configSpi(msp430_spi_union_config_t* config) {
+    // U0CTL = (config->spiRegisters.uctl & ~I2C) | SYNC | SWRST;
+    U0CTL = (config->spiRegisters.uctl) | SYNC | SWRST;  
+    U0TCTL = config->spiRegisters.utctl;
 
-  void configSpi(msp430_spi_config_t* config) {
-    msp430_uctl_t uctl = call Usart.getUctl();
-    msp430_utctl_t utctl = call Usart.getUtctl();
-
-    uctl.clen = config->clen;
-    uctl.listen = config->listen;
-    uctl.mm = config->mm;
-    uctl.sync = 1;
-
-    utctl.ckph = config->ckph;
-    utctl.ckpl = config->ckpl;
-    utctl.ssel = config->ssel;
-    utctl.stc = config->stc;
-    
-    call Usart.setUctl(uctl);
-    call Usart.setUtctl(utctl);
-    call Usart.setUbr(config->ubr);
+    call Usart.setUbr(config->spiRegisters.ubr);
     call Usart.setUmctl(0x00);
   }
 
-
-  async command void Usart.setModeSpi(msp430_spi_config_t* config) {
+  async command void Usart.setModeSpi(msp430_spi_union_config_t* config) {
+    
     atomic {
+       call Usart.resetUsart(TRUE);
+       call HplI2C.clearModeI2C();
+       call Usart.disableUart();
       configSpi(config);
       call Usart.enableSpi();
       call Usart.resetUsart(FALSE);
       call Usart.clrIntr();
       call Usart.disableIntr();
-    }
-    return;
-  }
-
-
-  void configUart(msp430_uart_config_t* config) {
-    msp430_uctl_t uctl = call Usart.getUctl();
-    msp430_utctl_t utctl = call Usart.getUtctl();
-    msp430_urctl_t urctl = call Usart.getUrctl();
-
-    uctl.pena = config->pena;
-    uctl.pev = config->pev;
-    uctl.spb = config->spb;
-    uctl.clen = config->clen;
-    uctl.listen = config->listen;
-    uctl.sync = 0;
-    uctl.mm = config->mm;
-
-    utctl.ckpl = config->ckpl;
-    utctl.ssel = config->ssel;
-    utctl.urxse = config->urxse;
-
-    urctl.urxeie = config->urxeie;
-    urctl.urxwie = config->urxwie;
-
-    call Usart.setUctl(uctl);
-    call Usart.setUtctl(utctl);
-    call Usart.setUrctl(urctl);
-    call Usart.setUbr(config->ubr);
-    call Usart.setUmctl(config->umctl);
-  }
-
-  async command void Usart.setModeUartTx(msp430_uart_config_t* config) {
-
-    atomic {
-      call UTXD.selectModuleFunc();
-      call URXD.selectIOFunc();
-      call Usart.resetUsart(TRUE);
-      configUart(config);
-      call Usart.enableUartTx();
-      call Usart.resetUsart(FALSE);
-      call Usart.clrIntr();
-      call Usart.disableIntr();
-    }
-
+    }    
     return;
   }
 
-  async command void Usart.setModeUartRx(msp430_uart_config_t* config) {
+  void configUart(msp430_uart_union_config_t* config) {
 
-    atomic {
-      call UTXD.selectIOFunc();
-      call URXD.selectModuleFunc();
-      call Usart.resetUsart(TRUE);
-      configUart(config);
-      call Usart.enableUartRx();
-      call Usart.resetUsart(FALSE);
-      call Usart.clrIntr();
-      call Usart.disableIntr();
-    }
+    U0CTL = (config->uartRegisters.uctl & ~SYNC) | SWRST;
+    U0TCTL = config->uartRegisters.utctl;
+    U0RCTL = config->uartRegisters.urctl;        
     
-    return;
+    call Usart.setUbr(config->uartRegisters.ubr);
+    call Usart.setUmctl(config->uartRegisters.umctl);
   }
 
-  async command void Usart.setModeUart(msp430_uart_config_t* config) {
+  async command void Usart.setModeUart(msp430_uart_union_config_t* config) {
 
-    atomic {
-      call UTXD.selectModuleFunc();
-      call URXD.selectModuleFunc();
+    atomic { 
       call Usart.resetUsart(TRUE);
+       call HplI2C.clearModeI2C();
+       call Usart.disableSpi();
       configUart(config);
-      call Usart.enableUart();
+      if ((config->uartConfig.utxe == 1) && (config->uartConfig.urxe == 1)) {
+       call Usart.enableUart();
+      } else if ((config->uartConfig.utxe == 0) && (config->uartConfig.urxe == 1)) {
+        call Usart.disableUartTx();
+        call Usart.enableUartRx();
+      } else if ((config->uartConfig.utxe == 1) && (config->uartConfig.urxe == 0)){
+        call Usart.disableUartRx();
+        call Usart.enableUartTx();
+      } else {
+        call Usart.disableUart();
+      }
       call Usart.resetUsart(FALSE);
       call Usart.clrIntr();
       call Usart.disableIntr();
@@ -364,7 +315,6 @@ implementation
 
   async command bool Usart.isTxIntrPending(){
     if (IFG1 & UTXIFG0){
-      IFG1 &= ~UTXIFG0;
       return TRUE;
     }
     return FALSE;
@@ -441,5 +391,6 @@ implementation
 
   default async event void I2CInterrupts.fired() {}
   default async command bool HplI2C.isI2C() { return FALSE; }
+  default async command void HplI2C.clearModeI2C() {};
   
 }
index 629ef00e37eff400d8bf81cf1d97d088298742c4..d5a8a268b54080e3a95b2a97463a84d77c51ee26 100644 (file)
@@ -158,7 +158,7 @@ implementation
 
   async command void Usart.resetUsart(bool reset) {
     if (reset)
-      SET_FLAG(U1CTL, SWRST);
+      U1CTL = SWRST;
     else
       CLR_FLAG(U1CTL, SWRST);
   }
@@ -209,8 +209,8 @@ implementation
   }
 
   async command void Usart.disableUart() {
-    ME2 &= ~(UTXE1 | URXE1);   // USART1 UART module enable
     atomic {
+      ME2 &= ~(UTXE1 | URXE1);   // USART1 UART module enable
       call UTXD.selectIOFunc();
       call URXD.selectIOFunc();
     }
@@ -249,133 +249,74 @@ implementation
   }
 
   async command void Usart.disableSpi() {
-    ME2 &= ~USPIE1;   // USART1 SPI module disable
     atomic {
+      ME2 &= ~USPIE1;   // USART1 SPI module disable
       call SIMO.selectIOFunc();
       call SOMI.selectIOFunc();
       call UCLK.selectIOFunc();
     }
   }
 
-  void configSpi(msp430_spi_config_t* config) {
-    msp430_uctl_t uctl = call Usart.getUctl();
-    msp430_utctl_t utctl = call Usart.getUtctl();
+  void configSpi(msp430_spi_union_config_t* config) {
+    U1CTL = (config->spiRegisters.uctl) | SYNC | SWRST;  
+    U1TCTL = config->spiRegisters.utctl;
 
-    uctl.clen = config->clen;
-    uctl.listen = config->listen;
-    uctl.mm = config->mm;
-    uctl.sync = 1;
-
-    utctl.ckph = config->ckph;
-    utctl.ckpl = config->ckpl;
-    utctl.ssel = config->ssel;
-    utctl.stc = config->stc;
-
-    call Usart.setUctl(uctl);
-    call Usart.setUtctl(utctl);
-    call Usart.setUbr(config->ubr);
+    call Usart.setUbr(config->spiRegisters.ubr);
     call Usart.setUmctl(0x00);
   }
 
 
-  async command void Usart.setModeSpi(msp430_spi_config_t* config) {
-    call Usart.disableUart();
+  async command void Usart.setModeSpi(msp430_spi_union_config_t* config) {    
     atomic {
       call Usart.resetUsart(TRUE);
+      call Usart.disableUart();
       configSpi(config);
       call Usart.enableSpi();
       call Usart.resetUsart(FALSE);
       call Usart.clrIntr();
       call Usart.disableIntr();
-    }
+    }    
     return;
   }
 
 
-  void configUart(msp430_uart_config_t* config) {
-    msp430_uctl_t uctl = call Usart.getUctl();
-    msp430_utctl_t utctl = call Usart.getUtctl();
-    msp430_urctl_t urctl = call Usart.getUrctl();
-
-    uctl.pena = config->pena;
-    uctl.pev = config->pev;
-    uctl.spb = config->spb;
-    uctl.clen = config->clen;
-    uctl.listen = config->listen;
-    uctl.sync = 0;
-    uctl.mm = config->mm;
-
-    utctl.ckpl = config->ckpl;
-    utctl.ssel = config->ssel;
-    utctl.urxse = config->urxse;
-
-    urctl.urxeie = config->urxeie;
-    urctl.urxwie = config->urxwie;
-
-    call Usart.setUctl(uctl);
-    call Usart.setUtctl(utctl);
-    call Usart.setUrctl(urctl);
-    call Usart.setUbr(config->ubr);
-    call Usart.setUmctl(config->umctl);
-  }
-
-  async command void Usart.setModeUartTx(msp430_uart_config_t* config) {
-
-    call Usart.disableSpi();
-    call Usart.disableUart();
-
-    atomic {
-      call UTXD.selectModuleFunc();
-      call URXD.selectIOFunc();
-      call Usart.resetUsart(TRUE);
-      configUart(config);
-      call Usart.enableUartTx();
-      call Usart.resetUsart(FALSE);
-      call Usart.clrIntr();
-      call Usart.disableIntr();
-    }
-    return;
-  }
-
-  async command void Usart.setModeUartRx(msp430_uart_config_t* config) {
+  void configUart(msp430_uart_union_config_t* config) {
 
-    call Usart.disableSpi();
-    call Usart.disableUart();
+    U1CTL = (config->uartRegisters.uctl & ~SYNC) | SWRST;
+    U1TCTL = config->uartRegisters.utctl;
+    U1RCTL = config->uartRegisters.urctl;        
     
-    atomic {
-      call UTXD.selectIOFunc();
-      call URXD.selectModuleFunc();
-      call Usart.resetUsart(TRUE);
-      configUart(config);
-      call Usart.enableUartRx();
-      call Usart.resetUsart(FALSE);
-      call Usart.clrIntr();
-      call Usart.disableIntr();
-    }
-    return;
+    call Usart.setUbr(config->uartRegisters.ubr);
+    call Usart.setUmctl(config->uartRegisters.umctl);
   }
 
-  async command void Usart.setModeUart(msp430_uart_config_t* config) {
-
-    call Usart.disableSpi();
-    call Usart.disableUart();
+  async command void Usart.setModeUart(msp430_uart_union_config_t* config) {
 
-    atomic {
-      call UTXD.selectModuleFunc();
-      call URXD.selectModuleFunc();
+    atomic { 
       call Usart.resetUsart(TRUE);
+      call Usart.disableSpi();
       configUart(config);
-      call Usart.enableUart();
+      if ((config->uartConfig.utxe == 1) && (config->uartConfig.urxe == 1)) {
+       call Usart.enableUart();
+      } else if ((config->uartConfig.utxe == 0) && (config->uartConfig.urxe == 1)) {
+        call Usart.disableUartTx();
+        call Usart.enableUartRx();
+      } else if ((config->uartConfig.utxe == 1) && (config->uartConfig.urxe == 0)){
+        call Usart.disableUartRx();
+        call Usart.enableUartTx();
+      } else {
+        call Usart.disableUart();
+      }
       call Usart.resetUsart(FALSE);
       call Usart.clrIntr();
       call Usart.disableIntr();
     }
+    
     return;
   }
 
   async command bool Usart.isTxIntrPending(){
     if (IFG2 & UTXIFG1){
-      IFG2 &= ~UTXIFG1;
       return TRUE;
     }
     return FALSE;
index c01e4a081cc9e004e44093dd5138d3afccb35cb0..00832bd708b9ed8280908b0050cabf0d85f031a4 100644 (file)
@@ -36,5 +36,5 @@
 #include "msp430usart.h"
 
 interface Msp430I2CConfigure {
-  async command msp430_i2c_config_t* getConfig();
+  async command msp430_i2c_union_config_t* getConfig();
 }
index ff1635085cb019b880a0aff4b6088f802875921d..a3c59539bf81966a275d36620da1011387c74822 100644 (file)
@@ -99,7 +99,7 @@ implementation {
   default async command error_t UsartResource.immediateRequest[ uint8_t id ]() { return FAIL; }
   default async command error_t UsartResource.release[ uint8_t id ]() {return FAIL;}
   default event void Resource.granted[ uint8_t id ]() {}
-  default async command msp430_i2c_config_t* Msp430I2CConfigure.getConfig[uint8_t id]() {
+  default async command msp430_i2c_union_config_t* Msp430I2CConfigure.getConfig[uint8_t id]() {
     return &msp430_i2c_default_config;
   }
   
index f6fd05db14b0f2e813aeb23caa36b8cac691fc4b..293333fc0ab474f3f919b09476b9962e72cf766c 100644 (file)
@@ -36,5 +36,5 @@
 #include "msp430usart.h"
 
 interface Msp430SpiConfigure {
-  async command msp430_spi_config_t* getConfig();
+  async command msp430_spi_union_config_t* getConfig();
 }
index a1025dc877f740dae598b62a1b5176905acd504d..c72a054487e03a4b215969c7e9cffd09891cf8ed 100644 (file)
@@ -96,7 +96,7 @@ implementation {
   default async command error_t UsartResource.request[ uint8_t id ]() { return FAIL; }
   default async command error_t UsartResource.immediateRequest[ uint8_t id ]() { return FAIL; }
   default async command error_t UsartResource.release[ uint8_t id ]() { return FAIL; }
-  default async command msp430_spi_config_t* Msp430SpiConfigure.getConfig[uint8_t id]() {
+  default async command msp430_spi_union_config_t* Msp430SpiConfigure.getConfig[uint8_t id]() {
     return &msp430_spi_default_config;
   }
 
@@ -106,6 +106,7 @@ implementation {
 
     call Usart.tx( tx );
     while( !call Usart.isRxIntrPending() );
+    call Usart.clrRxIntr();
     return call Usart.rx();
 
   }
index fcb277700ec6876d098ac050b75b1750e03bcd16..57102aaf7d0dccd839aa3ea623c0ff2aefca9152 100644 (file)
@@ -86,7 +86,9 @@ implementation {
   }
 
   async command void ResourceConfigure.unconfigure[ uint8_t id ]() {
+    call Usart.resetUsart(TRUE);
     call Usart.disableSpi();
+    call Usart.resetUsart(FALSE);
   }
 
   event void UsartResource.granted[ uint8_t id ]() {
@@ -95,11 +97,13 @@ implementation {
 
   async command uint8_t SpiByte.write( uint8_t tx ) {
     uint8_t byte;
-    call Usart.disableRxIntr();
+    // we are in spi mode which is configured to have turned off interrupts
+    //call Usart.disableRxIntr();
     call Usart.tx( tx );
     while( !call Usart.isRxIntrPending() );
+    call Usart.clrRxIntr();
     byte = call Usart.rx();
-    call Usart.enableRxIntr();
+    //call Usart.enableRxIntr();
     return byte;
   }
 
@@ -107,7 +111,7 @@ implementation {
   default async command error_t UsartResource.request[ uint8_t id ]() { return FAIL; }
   default async command error_t UsartResource.immediateRequest[ uint8_t id ]() { return FAIL; }
   default async command error_t UsartResource.release[ uint8_t id ]() { return FAIL; }
-  default async command msp430_spi_config_t* Msp430SpiConfigure.getConfig[uint8_t id]() {
+  default async command msp430_spi_union_config_t* Msp430SpiConfigure.getConfig[uint8_t id]() {
     return &msp430_spi_default_config;
   }
 
@@ -127,8 +131,10 @@ implementation {
 
       while ( ++m_pos < end ) {
         while( !call Usart.isTxIntrPending() );
+        call Usart.clrTxIntr();
         call Usart.tx( m_tx_buf ? m_tx_buf[ m_pos ] : 0 );
         while( !call Usart.isRxIntrPending() );
+        call Usart.clrRxIntr();
         tmp = call Usart.rx();
         if ( m_rx_buf )
           m_rx_buf[ m_pos - 1 ] = tmp;
index f910998c4e16588ed62615d1aa80d3856d9a9a09..b61f800426253763e9dd09ede913193f241540a6 100644 (file)
@@ -39,7 +39,6 @@ configuration Msp430Uart0P {
 
   provides interface Resource[ uint8_t id ];
   provides interface ResourceConfigure[uint8_t id ];
-  provides interface Msp430UartControl as UartControl[ uint8_t id ];
   provides interface UartStream;
   provides interface UartByte;
 
@@ -55,7 +54,6 @@ implementation {
   Resource = UartP.Resource;
   ResourceConfigure = UartP.ResourceConfigure;
   Msp430UartConfigure = UartP.Msp430UartConfigure;
-  UartControl = UartP.UartControl;
   UartStream = UartP.UartStream;
   UartByte = UartP.UartByte;
   UsartResource = UartP.UsartResource;
index 4e1700821eab5882518d963f336453f9f8c3f641..4829a4c58a0e6376a49a6278f14e1495397a5063 100644 (file)
@@ -43,7 +43,6 @@ generic configuration Msp430Uart1C() {
   provides interface Resource;
   provides interface UartStream;
   provides interface UartByte;
-  provides interface Msp430UartControl as UartControl;
 
   uses interface Msp430UartConfigure;
 }
@@ -58,7 +57,6 @@ implementation {
   Resource = UartP.Resource[ CLIENT_ID ];
   UartStream = UartP.UartStream;
   UartByte = UartP.UartByte;
-  UartControl = UartP.UartControl[ CLIENT_ID ];
   Msp430UartConfigure = UartP.Msp430UartConfigure[ CLIENT_ID ];
 
   components new Msp430Usart1C() as UsartC;
index 4c57206cc9440b99d7195c280ea850a67690e0ab..834feea7a1b225483e4ff11aa667c0113f638e87 100644 (file)
@@ -39,7 +39,6 @@ configuration Msp430Uart1P {
 
   provides interface Resource[ uint8_t id ];
   provides interface ResourceConfigure[uint8_t id ];
-  provides interface Msp430UartControl as UartControl[ uint8_t id ];
   provides interface UartStream;
   provides interface UartByte;
   
@@ -55,7 +54,6 @@ implementation {
   Resource = UartP.Resource;
   ResourceConfigure = UartP.ResourceConfigure;
   Msp430UartConfigure = UartP.Msp430UartConfigure;
-  UartControl = UartP.UartControl;
   UartStream = UartP.UartStream;
   UartByte = UartP.UartByte;
   UsartResource = UartP.UsartResource;
index 92af98730666351778aa258dbffa79049b09045e..1522348a2fbb13bf8df9d345e0d4946a1b41d7a9 100644 (file)
@@ -36,5 +36,5 @@
 #include "msp430usart.h"
 
 interface Msp430UartConfigure {
-  async command msp430_uart_config_t* getConfig();
+  async command msp430_uart_union_config_t* getConfig();
 }
diff --git a/tos/chips/msp430/usart/Msp430UartControl.nc b/tos/chips/msp430/usart/Msp430UartControl.nc
deleted file mode 100644 (file)
index 49f8352..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2004-2006, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- *   of its contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Interface used by Msp430Uart clients to control/configure the Uart.
- *
- * @author Philipp Huppertz (huppertz@tkn.tu-berlin.de)
- */
-interface Msp430UartControl {
-
-  /**
-  * Sets the Uart to Rx mode.
-  */
-  async command void setModeRx();
-  
-  /**
-  * Sets the Uart to Tx mode.
-  */
-  async command void setModeTx();
-  
-  /**
-  * Sets the Uart to duplex mode.
-  */
-  async command void setModeDuplex();
-  
-}
index c08d3fc00960babf62133af1a9897b4e0db26b5f..290fb60605a81a9435306999298bbe0f8b959d2a 100644 (file)
@@ -41,7 +41,7 @@ generic module Msp430UartP() {
 
   provides interface Resource[ uint8_t id ];
   provides interface ResourceConfigure[ uint8_t id ];
-  provides interface Msp430UartControl as UartControl[ uint8_t id ];
+  //provides interface Msp430UartControl as UartControl[ uint8_t id ];
   provides interface UartStream;
   provides interface UartByte;
   
@@ -80,39 +80,22 @@ implementation {
   }
 
   async command void ResourceConfigure.configure[ uint8_t id ]() {
-    call UartControl.setModeDuplex[id]();
+    msp430_uart_union_config_t* config = call Msp430UartConfigure.getConfig[id]();
+    m_byte_time = config->uartConfig.ubr / 2;
+    call Usart.setModeUart(config);
+    call Usart.enableIntr();
   }
 
   async command void ResourceConfigure.unconfigure[ uint8_t id ]() {
+    call Usart.resetUsart(TRUE);
     call Usart.disableIntr();
     call Usart.disableUart();
+    call Usart.resetUsart(FALSE);
   }
 
   event void UsartResource.granted[ uint8_t id ]() {
     signal Resource.granted[ id ]();
   }
-
-  async command void UartControl.setModeRx[ uint8_t id ]() {
-    msp430_uart_config_t* config = call Msp430UartConfigure.getConfig[id]();
-    m_byte_time = config->ubr / 2;
-    call Usart.setModeUartRx(config);
-    call Usart.clrIntr();
-    call Usart.enableRxIntr();
-  }
-  
-  async command void UartControl.setModeTx[ uint8_t id ]() {
-    call Usart.setModeUartTx(call Msp430UartConfigure.getConfig[id]());
-    call Usart.clrIntr();
-    call Usart.enableTxIntr();
-  }
-  
-  async command void UartControl.setModeDuplex[ uint8_t id ]() {
-    msp430_uart_config_t* config = call Msp430UartConfigure.getConfig[id]();
-    m_byte_time = config->ubr / 2;
-    call Usart.setModeUart(config);
-    call Usart.clrIntr();
-    call Usart.enableIntr();
-  }
   
   async command error_t UartStream.enableReceiveInterrupt() {
     call Usart.enableRxIntr();
@@ -177,6 +160,7 @@ implementation {
   async command error_t UartByte.send( uint8_t data ) {
     call Usart.tx( data );
     while( !call Usart.isTxIntrPending() );
+    call Usart.clrTxIntr();
     return SUCCESS;
   }
   
@@ -188,7 +172,7 @@ implementation {
     start = call Counter.get();
     while( !call Usart.isRxIntrPending() ) {
       if ( ( call Counter.get() - start ) >= timeout_micro )
-       return FAIL;
+                               return FAIL;
     }
     *byte = call Usart.rx();
     
@@ -202,7 +186,7 @@ implementation {
   default async command error_t UsartResource.request[ uint8_t id ]() { return FAIL; }
   default async command error_t UsartResource.immediateRequest[ uint8_t id ]() { return FAIL; }
   default async command error_t UsartResource.release[ uint8_t id ]() { return FAIL; }
-  default async command msp430_uart_config_t* Msp430UartConfigure.getConfig[uint8_t id]() {
+  default async command msp430_uart_union_config_t* Msp430UartConfigure.getConfig[uint8_t id]() {
     return &msp430_uart_default_config;
   }
 
index db998fcd648834e97881ac3067044a1bc43d8599..7939cedbc634c0904dbb4b3ba818181a5c1bd153 100644 (file)
@@ -30,7 +30,7 @@
 
 /**
  * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
- * $Revision$ $Date$
+ * @author Philipp Huppertz <huppertz@tkn.tu-berlin.de>
  */
 
 #ifndef _H_Msp430Usart_h
@@ -97,51 +97,64 @@ DEFINE_UNION_CAST(urctl2int,uint8_t,msp430_urctl_t)
 DEFINE_UNION_CAST(int2urctl,msp430_urctl_t,uint8_t)
 
 typedef struct {
-  unsigned int ubr: 16;        //Clock division factor (>=0x0002)
-  unsigned int ssel: 2;     //Clock source (00=external UCLK [slave]; 01=ACLK [master]; 10=SMCLK [master]; 11=SMCLK [master])
-  unsigned int clen: 1;     //Character length (0=7-bit data; 1=8-bit data)
-  unsigned int listen: 1;   //Listen enable (0=disabled; 1=enabled, feed tx back to receiver)
+  unsigned int ubr: 16;     //Clock division factor (>=0x0002)
+  
+  unsigned int :1;
   unsigned int mm: 1;       //Master mode (0=slave; 1=master)
-  unsigned int ckph: 1;     //Clock phase (0=normal; 1=half-cycle delayed)
-  unsigned int ckpl: 1;     //Clock polarity (0=inactive is low && data at rising edge; 1=inverted)
+  unsigned int :1;
+  unsigned int listen: 1;   //Listen enable (0=disabled; 1=enabled, feed tx back to receiver)
+  unsigned int clen: 1;     //Character length (0=7-bit data; 1=8-bit data)
+  unsigned int: 3;
+  
+  unsigned int:1;
   unsigned int stc: 1;      //Slave transmit (0=4-pin SPI && STE enabled; 1=3-pin SPI && STE disabled)
+  unsigned int:2;
+  unsigned int ssel: 2;     //Clock source (00=external UCLK [slave]; 01=ACLK [master]; 10=SMCLK [master] 11=SMCLK [master]); 
+  unsigned int ckpl: 1;     //Clock polarity (0=inactive is low && data at rising edge; 1=inverted)
+  unsigned int ckph: 1;     //Clock phase (0=normal; 1=half-cycle delayed)
   unsigned int :0;
 } msp430_spi_config_t;
 
-msp430_spi_config_t msp430_spi_default_config = {ubr: 0x0002, ssel: 0x02, clen: 1, listen: 0, mm: 1, ckph: 1, ckpl: 0, stc:1};
-
 typedef struct {
-  unsigned int ubr:16;      //Baud rate (use enum msp430_uart_rate_t for predefined rates)
-  unsigned int umctl: 8;    //Modulation (use enum msp430_uart_rate_t for predefined rates)
-  unsigned int ssel: 2;     //Clock source (00=UCLKI; 01=ACLK; 10=SMCLK; 11=SMCLK)
-  unsigned int pena: 1;     //Parity enable (0=disabled; 1=enabled)
-  unsigned int pev: 1;      //Parity select (0=odd; 1=even)
-  unsigned int spb: 1;      //Stop bits (0=one stop bit; 1=two stop bits)
-  unsigned int clen: 1;     //Character length (0=7-bit data; 1=8-bit data)
-  unsigned int listen: 1;   //Listen enable (0=disabled; 1=enabled, feed tx back to receiver)
-  unsigned int mm: 1;       //Multiprocessor mode (0=idle-line protocol; 1=address-bit protocol)
-  unsigned int :0;
-  unsigned int ckpl: 1;     //Clock polarity (0=normal; 1=inverted)
-  unsigned int urxse: 1;    //Receive start-edge detection (0=disabled; 1=enabled)
-  unsigned int urxeie: 1;   //Erroneous-character receive (0=rejected; 1=recieved and URXIFGx set)
-  unsigned int urxwie: 1;   //Wake-up interrupt-enable (0=all characters set URXIFGx; 1=only address sets URXIFGx)
-} msp430_uart_config_t;
+  uint16_t ubr;
+  uint8_t uctl;
+  uint8_t utctl;
+} msp430_spi_registers_t;
+
+typedef union {
+  msp430_spi_config_t spiConfig;
+  msp430_spi_registers_t spiRegisters;
+} msp430_spi_union_config_t;
 
+msp430_spi_union_config_t msp430_spi_default_config = { 
+  {
+    ubr : 0x0002, 
+    ssel : 0x02, 
+    clen : 1, 
+    listen : 0, 
+    mm : 1, 
+    ckph : 1, 
+    ckpl : 0, 
+    stc : 1
+  } 
+};
+    
+    
+    
+/**
+  The calculations were performed using the msp-uart.pl script:
+  msp-uart.pl -- calculates the uart registers for MSP430
+
+  Copyright (C) 2002 - Pedro Zorzenon Neto - pzn dot debian dot org
+ **/
 typedef enum {
-  /**
-     The calculations were performed using the msp-uart.pl script:
-     # msp-uart.pl -- calculates the uart registers for MSP430
-     #
-     # Copyright (C) 2002 - Pedro Zorzenon Neto - pzn dot debian dot org
-  **/
-  
   //32KHZ = 32,768 Hz, 1MHZ = 1,048,576 Hz
   UBR_32KHZ_1200=0x001B,    UMCTL_32KHZ_1200=0x94,
   UBR_32KHZ_1800=0x0012,    UMCTL_32KHZ_1800=0x84,
   UBR_32KHZ_2400=0x000D,    UMCTL_32KHZ_2400=0x6D,
   UBR_32KHZ_4800=0x0006,    UMCTL_32KHZ_4800=0x77,
   UBR_32KHZ_9600=0x0003,    UMCTL_32KHZ_9600=0x29,  // (Warning: triggers MSP430 errata US14)
-  
+
   UBR_1MHZ_1200=0x0369,   UMCTL_1MHZ_1200=0x7B,
   UBR_1MHZ_1800=0x0246,   UMCTL_1MHZ_1800=0x55,
   UBR_1MHZ_2400=0x01B4,   UMCTL_1MHZ_2400=0xDF,
@@ -155,34 +168,142 @@ typedef enum {
   UBR_1MHZ_230400=0x0004, UMCTL_1MHZ_230400=0x55,
 } msp430_uart_rate_t;
 
-msp430_uart_config_t msp430_uart_default_config = {ubr: UBR_1MHZ_57600, umctl: UMCTL_1MHZ_57600, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0};
+typedef struct {
+  unsigned int ubr:16;      //Baud rate (use enum msp430_uart_rate_t for predefined rates)
+  
+  unsigned int umctl: 8;    //Modulation (use enum msp430_uart_rate_t for predefined rates)
+  
+  unsigned int :1;
+  unsigned int mm: 1;       //Multiprocessor mode (0=idle-line protocol; 1=address-bit protocol)
+  unsigned int :1;
+  unsigned int listen: 1;   //Listen enable (0=disabled; 1=enabled, feed tx back to receiver)
+  unsigned int clen: 1;     //Character length (0=7-bit data; 1=8-bit data)
+  unsigned int spb: 1;      //Stop bits (0=one stop bit; 1=two stop bits)
+  unsigned int pev: 1;      //Parity select (0=odd; 1=even)
+  unsigned int pena: 1;     //Parity enable (0=disabled; 1=enabled)
+  unsigned int :0;
+  
+  unsigned int :3;
+  unsigned int urxse: 1;    //Receive start-edge detection (0=disabled; 1=enabled)
+  unsigned int ssel: 2;     //Clock source (00=UCLKI; 01=ACLK; 10=SMCLK; 11=SMCLK)
+  unsigned int ckpl: 1;     //Clock polarity (0=normal; 1=inverted)
+  unsigned int :1;
+  
+  unsigned int :2;
+  unsigned int urxwie: 1;   //Wake-up interrupt-enable (0=all characters set URXIFGx; 1=only address sets URXIFGx)
+  unsigned int urxeie: 1;   //Erroneous-character receive (0=rejected; 1=recieved and URXIFGx set)
+  unsigned int :4;
+  unsigned int :0;
+  
+  unsigned int utxe:1;                 // 1:enable tx module
+  unsigned int urxe:1;                 // 1:enable rx module
+} msp430_uart_config_t;
 
 typedef struct {
-  unsigned int rxdmaen: 1;  // Receive DMA enable. 0 = disabled.
-  unsigned int txdmaen: 1;  // Transmit DMA enable. 0 = disabled.
-  unsigned int xa: 1;       // Extended addressing. 0 = 7-bit addressing.
-  unsigned int listen: 1;   // Listen. 0 = disabled.
-  unsigned int i2cword : 1; // Word mode. 0 = byte mode.
-  unsigned int i2crm : 1;   // Repeat mode. 0 = I2CNDAT.
-  unsigned int i2cssel : 2; // Clock source select. 0=None, 1=ACLK, 2=SMCLK
-  unsigned int i2cpsc : 8;  // Clock prescaler.
-  unsigned int i2csclh : 8; // Shift clock high register.
-  unsigned int i2cscll : 8; // Shift clock low register.
+  uint16_t ubr;
+  uint8_t umctl;
+  uint8_t uctl;
+  uint8_t utctl;
+  uint8_t urctl;
+  uint8_t ume;
+} msp430_uart_registers_t;
+
+typedef union {
+  msp430_uart_config_t uartConfig;
+  msp430_uart_registers_t uartRegisters;
+} msp430_uart_union_config_t;
+    
+msp430_uart_union_config_t msp430_uart_default_config = { 
+  {
+    utxe : 1, 
+    urxe : 1, 
+    ubr : UBR_1MHZ_57600, 
+    umctl : UMCTL_1MHZ_57600, 
+    ssel : 0x02, 
+    pena : 0, 
+    pev : 0, 
+    spb : 0, 
+    clen : 1, 
+    listen : 0, 
+    mm : 0, 
+    ckpl : 0, 
+    urxse : 0, 
+    urxeie : 1, 
+    urxwie : 0,
+    utxe : 1,
+    urxe : 1
+  } 
+};
+
+
+
+typedef struct {
+  unsigned int i2cstt: 1; // I2CSTT Bit 0 START bit. (0=No action; 1=Send START condition)
+  unsigned int i2cstp: 1; // I2CSTP Bit 1 STOP bit. (0=No action; 1=Send STOP condition)
+  unsigned int i2cstb: 1; // I2CSTB Bit 2 Start byte. (0=No action; 1=Send START condition and start byte (01h))
+  unsigned int i2cctrx: 1; //I2CTRX Bit 3 I2C transmit. (0=Receive mode; 1=Transmit mode) pin.
+  unsigned int i2cssel: 2; // I2C clock source select. (00=No clock; 01=ACLK; 10=SMCLK; 11=SMCLK)
+  unsigned int i2ccrm: 1;  // I2C repeat mode 
+  unsigned int i2cword: 1; // I2C word mode. Selects byte(=0) or word(=1) mode for the I2C data register.
+} __attribute__ ((packed)) msp430_i2ctctl_t;
+
+DEFINE_UNION_CAST(i2ctctl2int,uint8_t,msp430_i2ctctl_t)
+DEFINE_UNION_CAST(int2i2ctctl,msp430_i2ctctl_t,uint8_t)
+
+typedef struct {
+  unsigned int :1;
+  unsigned int mst: 1;      //Master mode (0=slave; 1=master)
+  unsigned int :1;
+  unsigned int listen: 1;   //Listen enable (0=disabled; 1=enabled, feed tx back to receiver)
+  unsigned int xa: 1;       //Extended addressing (0=7-bit addressing; 1=8-bit addressing)
+  unsigned int :1;
+  unsigned int txdmaen: 1;  //DMA to TX (0=disabled; 1=enabled)
+  unsigned int rxdmaen: 1;  //RX to DMA (0=disabled; 1=enabled)
+    
+  unsigned int :4;
+  unsigned int i2cssel: 2;  //Clock source (00=disabled; 01=ACLK; 10=SMCLK; 11=SMCLK)
+  unsigned int i2crm: 1;    //Repeat mode (0=use I2CNDAT; 1=count in software)
+  unsigned int i2cword: 1;  //Word mode (0=byte mode; 1=word mode)
+  
+  unsigned int i2cpsc: 8;   //Clock prescaler (values >0x04 not recomended)
+  
+  unsigned int i2csclh: 8;  //High period (high period=[value+2]*i2cpsc; can not be lower than 5*i2cpsc)
+  
+  unsigned int i2cscll: 8;  //Low period (low period=[value+2]*i2cpsc; can not be lower than 5*i2cpsc)
+  
   unsigned int i2coa : 10;  // Own address register.
+  unsigned int :6;
 } msp430_i2c_config_t;
+    
+typedef struct {
+  uint8_t uctl;
+  uint8_t i2ctctl;
+  uint8_t i2cpsc;
+  uint8_t i2csclh;
+  uint8_t i2cscll;
+  uint16_t i2coa;
+} msp430_i2c_registers_t;
+
+typedef union {
+  msp430_i2c_config_t i2cConfig;
+  msp430_i2c_registers_t i2cRegisters;
+} msp430_i2c_union_config_t;
 
-msp430_i2c_config_t msp430_i2c_default_config = { 
-  rxdmaen : 0,
-  txdmaen : 0,
-  xa : 0,
-  listen : 0,
-  i2cword : 0,
-  i2crm : 1,
-  i2cssel : 2,
-  i2cpsc : 0,
-  i2csclh : 3,
-  i2cscll : 3,
-  i2coa : 0,
+msp430_i2c_union_config_t msp430_i2c_default_config = { 
+  {
+    rxdmaen : 0, 
+    txdmaen : 0, 
+    xa : 0, 
+    listen : 0, 
+    mst : 1,
+    i2cword : 0, 
+    i2crm : 0, 
+    i2cssel : 0x2, 
+    i2cpsc : 0, 
+    i2csclh : 0x3, 
+    i2cscll : 0x3,
+    i2coa : 0,
+  } 
 };
 
 
index 614b12717caebcec785bb3802d6b1a06f6a9a93c..1681e81de5ad55efae4e6cb09b3b083cfe4a64ae 100644 (file)
 
 interface HalPXA27xSleep {
   /**
-   * Sleep for a given number of milliseconds. This function supports
-   * sleep times up to 65534ms.  Larger sleep durations must
-   * use one of the other methods.
+   * Sleep for a given number of milliseconds. Only standard 
+   * sleep mode is used. This function supports
+   * sleep times up to 65534ms. Larger sleep durations must
+   * use one of the other methods. 
    *
    * @param time Sleep duration in milliseconds up to 65534.
    * 
@@ -50,7 +51,9 @@ interface HalPXA27xSleep {
   /**
    * Sleep for a given number of seconds up to 62859 sec.
    * If the function is passed a value greater than 62859, it
-   * will default to the maximum.
+   * will default to the maximum. For sleep durations greater
+   * than 30 secs, the processor will be placed into deep sleep
+   * mode. Otherwise standard sleep mode is used.
    *
    * @param time Sleep duration in seconds.
    *
@@ -58,18 +61,18 @@ interface HalPXA27xSleep {
   async command void sleepSeconds(uint32_t time);
 
   /**
-   * Sleep for a given number of minutes up to 1439 min.
-   * If the function is passed a value greater than 1439, it
-   * will default to the maximum.
+   * Sleep for a given number of minutes up to 1439 min. Deep
+   * sleep mode is used. If the function is passed a value 
+   * greater than 1439, it will default to the maximum. 
    *
    * @param time Sleep duration in minutes.
    */
   async command void sleepMinutes(uint32_t time);
 
   /**
-   * Sleep for a given number of hours up to 23 hours
-   * If the function is passed a value greater than 23, it
-   * will default to the maximum.
+   * Sleep for a given number of hours up to 23 hours. Deep
+   * sleep mode is used. If the function is passed a value 
+   * greater than 23, it will default to the maximum. 
    *
    * @param time Sleep duration in hours
    */
index f65e8d7901b9fcf647ccb8bbd99238e2bf1dbc1b..fa07c0ea05e3137e86d5c43cd8971decc5996980 100644 (file)
@@ -43,7 +43,7 @@ module HalPXA27xSleepM {
 
 implementation {
 
-  void doSleep(uint32_t swRegVal) {
+  void doSleep(uint32_t swRegVal, bool useDeepSleep) {
     int i;
     call HplPXA27xPower.setPWER(PWER_WERTC);
     // let it wrap around itself if necessary
@@ -54,8 +54,14 @@ implementation {
     call HplPXA27xRTC.setRTSR(RTSR_SWCE);
     for(i = 0; i < 5000; i++); // spin for a bit
 
-    call HplPXA27xPower.setPWRMode(PWRMODE_M_SLEEP);
+    if (useDeepSleep) {
+      call HplPXA27xPower.setPWRMode(PWRMODE_M_DEEPSLEEP);
+      // this call never returns
+    }
+    else {
+      call HplPXA27xPower.setPWRMode(PWRMODE_M_SLEEP);
     // this call never returns
+    }
   }
 
    
index 1429f7bd0be10e1a3d625cca291ce0766d55d03e..192b01b3eefc7a622e9cceb60dae7859d7b3b029 100644 (file)
@@ -326,8 +326,7 @@ implementation {
            log_info->write_addr = m_addr;
        }
        // move on to next log block
-       if ( (uint16_t)m_addr == 0 &&
-            ++block < (call Sector.getNumSectors[ id ]()*BLOCKS_PER_SECTOR)) {
+       if (++block < (call Sector.getNumSectors[ id ]()*BLOCKS_PER_SECTOR)) {
          addr += BLOCK_SIZE;
          call Sector.read[ id ]( addr, (uint8_t*)&m_addr, sizeof( m_addr ) );
        }
index cb6616434a857a142230936a84159640a1786584..de8f61a15e06cd3f1afe99cf4367cb0ca8cf34c0 100644 (file)
@@ -488,14 +488,9 @@ implementation {
   
   /* << tested >> */
   async command void HplTda5250Config.SetSleepMode() {
-    currentConfig = CONFIG_ALL_PD_POWER_DOWN(currentConfig);
-    if (currentConfig & MASK_CONFIG_CONTROL_TXRX_REGISTER) {
-      call CONFIG.set(currentConfig);
-    }
-    else {
-      call PWDDD.makeOutput();
-      call PWDDD.set();
-    }
+        currentConfig = CONFIG_ALL_PD_POWER_DOWN(currentConfig);
+       call PWDDD.makeOutput();
+        call PWDDD.set();
   }
   
   async command bool HplTda5250Config.IsTxRxPinControlled() {
index 160f05ed4506c3d8dd0ee4e2a431269c40c7df73..df881560650162cb7f87ee97d477fde4a4e8972f 100644 (file)
@@ -123,18 +123,12 @@ implementation {
   async event void Uart.receiveDone( uint8_t* buf, uint16_t len, error_t error ) {}
   
   async command error_t HplTda5250DataControl.setToTx() {
-    if(call UartResource.isOwner() == FALSE)
-      return FAIL;
     call UartDataControl.setToTx();
-    call Uart.disableReceiveInterrupt();
     return SUCCESS;
   }
 
   async command error_t HplTda5250DataControl.setToRx() {
-    if(call UartResource.isOwner() == FALSE)
-      return FAIL;
     call UartDataControl.setToRx();
-    call Uart.enableReceiveInterrupt();
     return SUCCESS;
   }
        
index 22282c5e196e37019cfe058a71ecafb2a1818bce..4e2b46e47a73f02c66388142798c7d3e1f65f6d2 100644 (file)
@@ -72,6 +72,6 @@ implementation {
   
   Tda5250RadioP.HplTda5250Config -> HplTda5250ConfigC;
   Tda5250RadioP.HplTda5250Data -> HplTda5250DataC;
-       Tda5250RadioP.HplTda5250DataControl -> HplTda5250DataC;
+  Tda5250RadioP.HplTda5250DataControl -> HplTda5250DataC;
 
 }
index 0ae7224c88a589ecb8d1c06c848fb25db127861a..20d39dcf9e563cbb0650354613aac7349a2b89f3 100644 (file)
@@ -1,37 +1,37 @@
-/*
-* Copyright (c) 2004-2006, Technische Universitaet Berlin
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* - Redistributions of source code must retain the above copyright notice,
-*   this list of conditions and the following disclaimer.
-* - Redistributions in binary form must reproduce the above copyright
-*   notice, this list of conditions and the following disclaimer in the
-*   documentation and/or other materials provided with the distribution.
-* - Neither the name of the Technische Universitaet Berlin nor the names
-*   of its contributors may be used to endorse or promote products derived
-*   from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* - Revision -------------------------------------------------------------
-* $Revision$
-* $Date$
-* @author: Kevin Klues (klues@tkn.tu-berlin.de)
-* ========================================================================
-*/
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2004-2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Kevin Klues (klues@tkn.tu-berlin.de)
+ * ========================================================================
+ */
 
 #include "tda5250Const.h"
 
  *
  * @author Kevin Klues
  * @author Philipp Huppertz
+ * @author Andreas Koepke
  */
+#include "Timer.h"
+
 module Tda5250RadioP {
-  provides {
-    interface Init;
-    interface SplitControl;
-    interface Tda5250Control;
-    interface RadioByteComm;
-    interface ResourceRequested;
-  }
-  uses {
-    interface HplTda5250Config;
-    interface HplTda5250Data;
-               interface HplTda5250DataControl;
-    interface Resource as ConfigResource;
-    interface Resource as DataResource;
-    interface ResourceRequested as DataResourceRequested;
-    
-    interface Alarm<T32khz, uint16_t> as DelayTimer;
-  }
+    provides {
+        interface Init;
+        interface SplitControl;
+        interface Tda5250Control;
+        interface RadioByteComm;
+        interface ResourceRequested;
+    }
+    uses {
+        interface HplTda5250Config;
+        interface HplTda5250Data;
+        interface HplTda5250DataControl;
+        interface Resource as ConfigResource;
+        interface Resource as DataResource;
+        interface ResourceRequested as DataResourceRequested;
+        interface Alarm<T32khz, uint16_t> as DelayTimer;
+    }
 }
 
 implementation {
   
-  typedef enum {
-    TRANSMITTER_DELAY,
-    RECEIVER_DELAY,
-    RSSISTABLE_DELAY
-  } delayTimer_t;
+    typedef enum {
+        TRANSMITTER_DELAY,
+        RECEIVER_DELAY,
+        RSSISTABLE_DELAY
+    } delayTimer_t;
   
-  delayTimer_t delayTimer;  // current Mode of the Timer (RssiStable, TxSetupTime, RxSetupTime)
-  radioMode_t radioMode;    // Current Mode of the Radio
-  float onTime, offTime;
+    delayTimer_t delayTimer;  // current Mode of the Timer (RssiStable, TxSetupTime, RxSetupTime)
+    radioMode_t radioMode;    // Current Mode of the Radio
+    float onTime, offTime;
 
-      /**************** Radio Init *****************/
-      command error_t Init.init() {
+    /**************** Radio Init *****************/
+    command error_t Init.init() {
         radioMode = RADIO_MODE_OFF;
         return SUCCESS;
-      }
+    }
 
-      /**************** Radio Start  *****************/
-      task void startDoneTask() {
+    /**************** Radio Start  *****************/
+    task void startDoneTask() {
         signal SplitControl.startDone(SUCCESS);
-      }
+    }
       
-      command error_t SplitControl.start() {
+    command error_t SplitControl.start() {
         radioMode_t mode;
         atomic mode = radioMode;
         if(mode == RADIO_MODE_OFF) {
-          atomic radioMode = RADIO_MODE_ON_TRANSITION;
-          return call ConfigResource.request();
+            atomic radioMode = RADIO_MODE_ON_TRANSITION;
+            return call ConfigResource.request();
         }
         return FAIL;
-      }
+    }
 
-      /**************** Radio Stop  *****************/
-      task void stopDoneTask() {
+    /**************** Radio Stop  *****************/
+    task void stopDoneTask() {
         signal SplitControl.stopDone(SUCCESS); 
-      }
+    }
       
-      command error_t SplitControl.stop(){
+    command error_t SplitControl.stop(){
         atomic radioMode = RADIO_MODE_OFF_TRANSITION;
         return call ConfigResource.request();
-      }
+    }
 
-  /* radioBusy
-      * This function checks whether the radio is busy
-      * so as to decide whether it can perform some operation or not.
-  */
-      bool radioBusy() {
+    /* radioBusy
+     * This function checks whether the radio is busy
+     * so as to decide whether it can perform some operation or not.
+     */
+    bool radioBusy() {
         switch(radioMode) {
-          case RADIO_MODE_OFF:
-          case RADIO_MODE_ON_TRANSITION:
-          case RADIO_MODE_OFF_TRANSITION:
-          case RADIO_MODE_TX_TRANSITION:
-          case RADIO_MODE_RX_TRANSITION:
-          case RADIO_MODE_TIMER_TRANSITION:
-          case RADIO_MODE_SELF_POLLING_TRANSITION:
-          case RADIO_MODE_SLEEP_TRANSITION:
-            return TRUE;
-          default:
-            return FALSE;
+            case RADIO_MODE_OFF:
+            case RADIO_MODE_ON_TRANSITION:
+            case RADIO_MODE_OFF_TRANSITION:
+            case RADIO_MODE_TX_TRANSITION:
+            case RADIO_MODE_RX_TRANSITION:
+            case RADIO_MODE_TIMER_TRANSITION:
+            case RADIO_MODE_SELF_POLLING_TRANSITION:
+            case RADIO_MODE_SLEEP_TRANSITION:
+                return TRUE;
+            default:
+                return FALSE;
         }
-      }
+    }
 
-      void switchConfigResource() {
+    void switchConfigResource() {
         radioMode_t mode;
         atomic mode = radioMode;
         switch(mode) {
-          case RADIO_MODE_ON_TRANSITION:
-            call HplTda5250Config.reset();
-            call HplTda5250Config.SetRFPower(255);
-            call ConfigResource.release();
-            atomic radioMode = RADIO_MODE_ON;
-            post startDoneTask();
-            break;
-          case RADIO_MODE_OFF_TRANSITION:
-            call HplTda5250Config.SetClockOffDuringPowerDown();
-            call HplTda5250Config.SetSleepMode();
-            call ConfigResource.release();
-            atomic radioMode = RADIO_MODE_OFF;
-            post stopDoneTask();
-            break;
-          case RADIO_MODE_SLEEP_TRANSITION:
-            call HplTda5250Config.SetSlaveMode();
-            call HplTda5250Config.SetSleepMode();
-            if (!(call HplTda5250Config.IsTxRxPinControlled()))
-              call ConfigResource.release();
-            atomic radioMode = RADIO_MODE_SLEEP;
-            signal Tda5250Control.SleepModeDone();
-            break;
-          case RADIO_MODE_TX_TRANSITION:
-            call HplTda5250Config.SetSlaveMode();
-            call HplTda5250Config.SetTxMode();
-            if (!(call HplTda5250Config.IsTxRxPinControlled()))
-              call ConfigResource.release();
-            atomic delayTimer = TRANSMITTER_DELAY;
-            call DelayTimer.start(TDA5250_TRANSMITTER_SETUP_TIME);
-            break;
-          case RADIO_MODE_RX_TRANSITION:
-            call HplTda5250Config.SetSlaveMode();
-            call HplTda5250Config.SetRxMode();
-            if (!(call HplTda5250Config.IsTxRxPinControlled()))
-              call ConfigResource.release();
-            atomic delayTimer = RECEIVER_DELAY;
-            call DelayTimer.start(TDA5250_RECEIVER_SETUP_TIME);
-            break;
-          case RADIO_MODE_TIMER_TRANSITION:
-            call HplTda5250Config.SetTimerMode(onTime, offTime);
-            call ConfigResource.release();
-            atomic radioMode = RADIO_MODE_TIMER;
-            signal Tda5250Control.TimerModeDone();
-            break;
-          case RADIO_MODE_SELF_POLLING_TRANSITION:
-            call HplTda5250Config.SetSelfPollingMode(onTime, offTime);
-            call ConfigResource.release();
-            atomic radioMode = RADIO_MODE_SELF_POLLING;
-            signal Tda5250Control.SelfPollingModeDone();
-            break;
-          default:
-            break;
+            case RADIO_MODE_ON_TRANSITION:
+                call HplTda5250Config.reset();
+                call HplTda5250Config.SetRFPower(255);
+                call ConfigResource.release();
+                atomic radioMode = RADIO_MODE_ON;
+                post startDoneTask();
+                break;
+            case RADIO_MODE_OFF_TRANSITION:
+                call HplTda5250Config.SetSleepMode();
+                call ConfigResource.release();
+                atomic radioMode = RADIO_MODE_OFF;
+                post stopDoneTask();
+                break;
+            case RADIO_MODE_SLEEP_TRANSITION:
+                call HplTda5250Config.SetSlaveMode();
+                call HplTda5250Config.SetSleepMode();
+                atomic radioMode = RADIO_MODE_SLEEP;
+                signal Tda5250Control.SleepModeDone();
+                break;
+            case RADIO_MODE_TX_TRANSITION:
+                call HplTda5250Config.SetSlaveMode();
+                call HplTda5250Config.SetTxMode();
+                if (!(call HplTda5250Config.IsTxRxPinControlled()))
+                    call ConfigResource.release();
+                atomic delayTimer = TRANSMITTER_DELAY;
+                call DelayTimer.start(TDA5250_TRANSMITTER_SETUP_TIME);
+                break;
+            case RADIO_MODE_RX_TRANSITION:
+                call HplTda5250Config.SetSlaveMode();
+                call HplTda5250Config.SetRxMode();
+                if (!(call HplTda5250Config.IsTxRxPinControlled()))
+                    call ConfigResource.release();
+                atomic delayTimer = RECEIVER_DELAY;
+                call DelayTimer.start(TDA5250_RECEIVER_SETUP_TIME);
+                break;
+            case RADIO_MODE_TIMER_TRANSITION:
+                call HplTda5250Config.SetTimerMode(onTime, offTime);
+                call ConfigResource.release();
+                atomic radioMode = RADIO_MODE_TIMER;
+                signal Tda5250Control.TimerModeDone();
+                break;
+            case RADIO_MODE_SELF_POLLING_TRANSITION:
+                call HplTda5250Config.SetSelfPollingMode(onTime, offTime);
+                call ConfigResource.release();
+                atomic radioMode = RADIO_MODE_SELF_POLLING;
+                signal Tda5250Control.SelfPollingModeDone();
+                break;
+            default:
+                break;
         }
-      }
+    }
 
-      event void ConfigResource.granted() {
+    event void ConfigResource.granted() {
         switchConfigResource();
-      }
+    }
 
-      void switchDataResource() {
+    void switchDataResource() {
         radioMode_t mode;
         atomic mode = radioMode;
         switch(mode) {
           case RADIO_MODE_TX_TRANSITION:
-            call HplTda5250DataControl.setToTx();
             atomic radioMode = RADIO_MODE_TX;
             signal Tda5250Control.TxModeDone();
             break;
           case RADIO_MODE_RX_TRANSITION:
-            call HplTda5250DataControl.setToRx();
             atomic radioMode = RADIO_MODE_RX;
             signal Tda5250Control.RxModeDone();
             break;
           default:
             break;
         }
-      }
+    }
       
-      event void DataResource.granted() {
+    event void DataResource.granted() {
         switchDataResource();
-      }
+    }
       
-      // information for higher layers that the DataResource has been requested
-      async event void DataResourceRequested.requested() {
+    // information for higher layers that the DataResource has been requested
+    async event void DataResourceRequested.requested() {
         signal ResourceRequested.requested();
-      }
+    }
 
-      async event void DataResourceRequested.immediateRequested() {
+    async event void DataResourceRequested.immediateRequested() {
         signal ResourceRequested.immediateRequested();
-      }
+    }
 
-  /**
-      Set the mode of the radio
-      The choices are TIMER_MODE, SELF_POLLING_MODE
-  */
-      async command error_t Tda5250Control.TimerMode(float on_time, float off_time) {
+    /**
+       Set the mode of the radio
+       The choices are TIMER_MODE, SELF_POLLING_MODE
+    */
+    async command error_t Tda5250Control.TimerMode(float on_time, float off_time) {
         radioMode_t mode;
         atomic {
-          if(radioBusy() == FALSE) {
-            radioMode = RADIO_MODE_TIMER_TRANSITION;
-            onTime = on_time;
-            offTime = off_time;
-          }
-          mode = radioMode;
+            if(radioBusy() == FALSE) {
+                radioMode = RADIO_MODE_TIMER_TRANSITION;
+                onTime = on_time;
+                offTime = off_time;
+            }
+            mode = radioMode;
         }
         if(radioMode == RADIO_MODE_TIMER_TRANSITION) {
-          call DataResource.release();
-         if (call ConfigResource.immediateRequest() == SUCCESS) {
-           switchConfigResource();
-         } else {
-            call ConfigResource.request();
-         }
-          return SUCCESS;
+            call DataResource.release();
+            if (call ConfigResource.immediateRequest() == SUCCESS) {
+                switchConfigResource();
+            } else {
+                call ConfigResource.request();
+            }
+            return SUCCESS;
         }
         return FAIL;
-      }
+    }
 
-      async command error_t Tda5250Control.ResetTimerMode() {
+    async command error_t Tda5250Control.ResetTimerMode() {
         radioMode_t mode;
         atomic {
-          if(radioBusy() == FALSE) {
-            radioMode = RADIO_MODE_TIMER_TRANSITION;
-          }
-          mode = radioMode;
+            if(radioBusy() == FALSE) {
+                radioMode = RADIO_MODE_TIMER_TRANSITION;
+            }
+            mode = radioMode;
         }
         if(radioMode == RADIO_MODE_TIMER_TRANSITION) {
-          call DataResource.release();
-          if (call ConfigResource.immediateRequest() == SUCCESS) {
-            switchConfigResource();
-          } else {
-            call ConfigResource.request();
-          }
-          return SUCCESS;
+            call DataResource.release();
+            if (call ConfigResource.immediateRequest() == SUCCESS) {
+                switchConfigResource();
+            } else {
+                call ConfigResource.request();
+            }
+            return SUCCESS;
         }
         return FAIL;
-      }
+    }
 
-      async command error_t Tda5250Control.SelfPollingMode(float on_time, float off_time) {
+    async command error_t Tda5250Control.SelfPollingMode(float on_time, float off_time) {
         radioMode_t mode;
         atomic {
-          if(radioBusy() == FALSE) {
-            radioMode = RADIO_MODE_SELF_POLLING_TRANSITION;
-            onTime = on_time;
-            offTime = off_time;
-          }
-          mode = radioMode;
+            if(radioBusy() == FALSE) {
+                radioMode = RADIO_MODE_SELF_POLLING_TRANSITION;
+                onTime = on_time;
+                offTime = off_time;
+            }
+            mode = radioMode;
         }
         if(radioMode == RADIO_MODE_SELF_POLLING_TRANSITION) {
-          call DataResource.release();
-          if (call ConfigResource.immediateRequest() == SUCCESS) {
-            switchConfigResource();
-          } else {
-            call ConfigResource.request();
-          }
-          return SUCCESS;
+            call DataResource.release();
+            if (call ConfigResource.immediateRequest() == SUCCESS) {
+                switchConfigResource();
+            } else {
+                call ConfigResource.request();
+            }
+            return SUCCESS;
         }
         return FAIL;
-      }
+    }
 
-      async command error_t Tda5250Control.ResetSelfPollingMode() {
+    async command error_t Tda5250Control.ResetSelfPollingMode() {
         radioMode_t mode;
         atomic {
-          if(radioBusy() == FALSE) {
-            radioMode = RADIO_MODE_SELF_POLLING_TRANSITION;
-          }
-          mode = radioMode;
+            if(radioBusy() == FALSE) {
+                radioMode = RADIO_MODE_SELF_POLLING_TRANSITION;
+            }
+            mode = radioMode;
         }
         if(radioMode == RADIO_MODE_SELF_POLLING_TRANSITION) {
-          call DataResource.release();
-          if (call ConfigResource.immediateRequest() == SUCCESS) {
-            switchConfigResource();
-          } else {
-            call ConfigResource.request();
-          }
-          return SUCCESS;
+            call DataResource.release();
+            if (call ConfigResource.immediateRequest() == SUCCESS) {
+                switchConfigResource();
+            } else {
+                call ConfigResource.request();
+            }
+            return SUCCESS;
         }
         return FAIL;
-      }
+    }
 
-      async command error_t Tda5250Control.SleepMode() {
+    async command error_t Tda5250Control.SleepMode() {
         radioMode_t mode;
         atomic{
-          if(radioBusy() == FALSE) {
-            radioMode = RADIO_MODE_SLEEP_TRANSITION;
-          }
-          mode = radioMode;
+            if(radioBusy() == FALSE) {
+                radioMode = RADIO_MODE_SLEEP_TRANSITION;
+            }
+            mode = radioMode;
         }
         if(mode == RADIO_MODE_SLEEP_TRANSITION) {
-          call DataResource.release();
-          if (call HplTda5250Config.IsTxRxPinControlled()) {
+            call DataResource.release();
             switchConfigResource();
-          } else {
-            if (call ConfigResource.immediateRequest() == SUCCESS) {
-              switchConfigResource();
-            } else {
-              call ConfigResource.request();
-            }
-          }
-          return SUCCESS;
+            return SUCCESS;
         }
         return FAIL;
-      }
-
-      async command error_t Tda5250Control.TxMode() {
+    }
+    
+    async command error_t Tda5250Control.TxMode() {
         radioMode_t mode;
         atomic {
-          if(radioBusy() == FALSE) {
-            radioMode = RADIO_MODE_TX_TRANSITION;
-          }
-          mode = radioMode;
+            if(radioBusy() == FALSE) {
+                radioMode = RADIO_MODE_TX_TRANSITION;
+            }
+            mode = radioMode;
         }
         if(mode == RADIO_MODE_TX_TRANSITION) {
           call DataResource.release();
+          call HplTda5250DataControl.setToTx();
           if (call HplTda5250Config.IsTxRxPinControlled()) {
             switchConfigResource();
           } else {
@@ -356,57 +346,58 @@ implementation {
           return SUCCESS;
         }
         return FAIL;
-      }
+    }
 
-      async command error_t Tda5250Control.RxMode() {
+    async command error_t Tda5250Control.RxMode() {
         radioMode_t mode;
         atomic {
-          if(radioBusy() == FALSE) {
-            radioMode = RADIO_MODE_RX_TRANSITION;
-          }
-          mode = radioMode;
+            if(radioBusy() == FALSE) {
+                radioMode = RADIO_MODE_RX_TRANSITION;
+            }
+            mode = radioMode;
         }
         if(mode == RADIO_MODE_RX_TRANSITION) {
           call DataResource.release();
+          call HplTda5250DataControl.setToRx();
           if (call HplTda5250Config.IsTxRxPinControlled()) {
             switchConfigResource();
           } else {
-            if (call ConfigResource.immediateRequest() == SUCCESS) {
-              switchConfigResource();
-            } else {
-              call ConfigResource.request();
-            }
+              if (call ConfigResource.immediateRequest() == SUCCESS) {
+                  switchConfigResource();
+              } else {
+                  call ConfigResource.request();
+              }
           }
           return SUCCESS;
         }
         return FAIL;
-      }
+    }
 
-      async event void HplTda5250Data.txReady() {
+    async event void HplTda5250Data.txReady() {
         signal RadioByteComm.txByteReady(SUCCESS);
-      }
-      async event void HplTda5250Data.rxDone(uint8_t data) {
+    }
+    async event void HplTda5250Data.rxDone(uint8_t data) {
         signal RadioByteComm.rxByteReady(data);
-      }
+    }
 
-      async event void HplTda5250Config.PWDDDInterrupt() {
+    async event void HplTda5250Config.PWDDDInterrupt() {
         signal Tda5250Control.PWDDDInterrupt();
-      }
+    }
 
-      async command void RadioByteComm.txByte(uint8_t data) {
+    async command void RadioByteComm.txByte(uint8_t data) {
         error_t error = call HplTda5250Data.tx(data);
         if(error != SUCCESS) {
-          signal RadioByteComm.txByteReady(error);
+            signal RadioByteComm.txByteReady(error);
         }
-      }
+    }
 
-      async command bool RadioByteComm.isTxDone() {
+    async command bool RadioByteComm.isTxDone() {
         //return call HplTda5250Data.isTxDone();
         return TRUE;
-      }
+    }
       
-      /* Generate events (these are no interrupts */
-      async event void DelayTimer.fired() {
+/* Generate events (these are no interrupts */
+    async event void DelayTimer.fired() {
         delayTimer_t delay;
         atomic { delay = delayTimer; }
         switch (delay) {
@@ -423,7 +414,7 @@ implementation {
             }
             break;
           case TRANSMITTER_DELAY :
-           if (call DataResource.immediateRequest() == SUCCESS) {
+            if (call DataResource.immediateRequest() == SUCCESS) {
               switchDataResource();
             } else {
               call DataResource.request();
diff --git a/tos/chips/tda5250/mac/ChannelCongestion.nc b/tos/chips/tda5250/mac/ChannelCongestion.nc
new file mode 100644 (file)
index 0000000..a65338d
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * Interface of MAC to inform any interested party on current congestion state
+ * in radio neighborhood.
+ * @author Andreas Koepke (koepke at tkn.tu-berlin.de)
+ */ 
+interface ChannelCongestion {
+    /**
+     * signal current congestion level. There are 5 levels, 0 means no
+     * congestion, 5 means high congestion
+     */
+    async event void congestionEvent(uint8_t level);
+}
index 6750ae756b1361edd799b9cd9ea57915ef20a948..7445c712217981a03d136a66eec9607758e34e7e 100644 (file)
@@ -58,6 +58,8 @@ implementation {
       CsmaMacP,
       RssiFixedThresholdCMC as Cca,
       new Alarm32khz16C() as Timer,
+      new TimerMilliC() as ReRxTimer,
+      McuSleepC,
       RandomLfsrC
 #ifdef MAC_DEBUG
       ,PlatformLedsC
@@ -65,7 +67,9 @@ implementation {
       ;
               
     MainC.SoftwareInit -> CsmaMacP;
-              
+
+    McuSleepC.McuPowerOverride -> CsmaMacP;
+    
     SplitControl = CsmaMacP;
     
     MacSend = CsmaMacP;
@@ -93,6 +97,9 @@ implementation {
     CsmaMacP.RadioResourceRequested -> Tda5250RadioC.ResourceRequested;
 
     CsmaMacP.Timer -> Timer;
+
+    CsmaMacP.ReRxTimer -> ReRxTimer;
+    
 #ifdef MAC_DEBUG
     CsmaMacP.Led0 -> PlatformLedsC.Led0;
     CsmaMacP.Led1 -> PlatformLedsC.Led1;
index e221db75eaf0d707a075139b0dfec113189ca5b6..28de91414a2145e3e98d880136962514a85b774c 100644 (file)
@@ -50,6 +50,7 @@ module CsmaMacP {
         interface MacSend;
         interface MacReceive;
         interface Packet;
+        interface McuPowerOverride;
     }
     uses {
         interface StdControl as CcaStdControl;
@@ -69,6 +70,8 @@ module CsmaMacP {
         interface Resource as RssiAdcResource;
 
         interface Random;
+
+        interface Timer<TMilli> as ReRxTimer;
         
         interface Alarm<T32khz, uint16_t> as Timer;
         async command am_addr_t amAddress();
@@ -87,7 +90,7 @@ implementation
     enum {
         BYTE_TIME=13,                // byte at 38400 kBit/s, 4b6b encoded
         PREAMBLE_BYTE_TIME=9,        // byte at 38400 kBit/s, no coding
-        PHY_HEADER_TIME=35,          // 4 Phy Preamble at 38400
+        PHY_HEADER_TIME=51,          // 6 Phy Preamble at 38400
         SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME,
         SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 38400 kBit/s with 4b6b encoding
         MAXTIMERVALUE=0xFFFF,        // helps to compute backoff
@@ -95,16 +98,16 @@ implementation
         RX_SETUP_TIME=111,    // time to set up receiver
         TX_SETUP_TIME=69,     // time to set up transmitter
         ADDED_DELAY = 30,
-        RX_ACK_TIMEOUT=RX_SETUP_TIME + PHY_HEADER_TIME + 4 + 3*ADDED_DELAY,
+        RX_ACK_TIMEOUT=RX_SETUP_TIME + PHY_HEADER_TIME + 19 + 2*ADDED_DELAY,
         TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11,
-        MIN_BACKOFF_MASK=0x3F,   // about txrx_turnaround time
         MAX_SHORT_RETRY=7,
         MAX_LONG_RETRY=4,
+        BACKOFF_MASK=0xFFF,  // minimum time around one packet time
         MIN_PREAMBLE_BYTES=2,
         TOKEN_ACK_FLAG = 64,
         TOKEN_ACK_MASK = 0x3f,
         INVALID_SNR = 0xffff,
-        MSG_TABLE_ENTRIES=5,
+        MSG_TABLE_ENTRIES=20,
         MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY,
     };
     
@@ -149,7 +152,6 @@ implementation
     uint8_t flags;
     uint8_t seqNo;
     
-    uint16_t slotMask;
     uint16_t restLaufzeit;
 
     /* duplicate suppression */
@@ -306,12 +308,13 @@ implementation
     }
 
     /**************** Helper functions ********/
+
+    task void postponeReRx() {
+        call ReRxTimer.startOneShot(5000);
+    }
+    
     uint16_t backoff(uint8_t counter) {
-        uint16_t mask = MIN_BACKOFF_MASK;
-        unsigned i;
-        for(i = 0; i < counter; i++) {
-            mask = (mask << 1) + 1;
-        }
+        uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter);
         return (call Random.rand16() & mask);
     }
 
@@ -327,6 +330,9 @@ implementation
             else {
                 restLaufzeit +=  MAXTIMERVALUE - now;
             }
+            if(restLaufzeit > BACKOFF_MASK) {
+                restLaufzeit = backoff(0);
+            }
             setFlag(&flags, RESUME_BACKOFF);
         }
     }
@@ -485,7 +491,6 @@ implementation
             shortRetryCounter = 0;
             longRetryCounter = 0;
             flags = 0;
-            slotMask = MIN_BACKOFF_MASK;
             for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
                 knownMsgTable[i].age = MAX_AGE;
             }
@@ -578,6 +583,7 @@ implementation
     }
 
     async event void RadioModes.RxModeDone() {
+        post postponeReRx();
         atomic {
             if(macState == SW_RX) {
                 storeOldState(21);
@@ -606,6 +612,7 @@ implementation
     }
 
     async event void RadioModes.TxModeDone() {
+        post postponeReRx();
         atomic {
             if(macState == SW_TX) {
                 storeOldState(30);
@@ -680,7 +687,7 @@ implementation
     
     /****** PacketSerializer events **********************/
     async event void PacketReceive.receiveDetected() {
-      if(macState <= RX_ACK) {
+        if(macState <= RX_ACK) {
             storeOldState(60);
             interruptBackoffTimer();
             if(macState == CCA) computeBackoff();
@@ -950,15 +957,29 @@ implementation
     
     async event void ChannelMonitorData.getSnrDone(int16_t data) {
     }
-
     
     /***** unused Radio Modes events **************************/
     
     async event void RadioModes.TimerModeDone() {}
-    async event void RadioModes.SleepModeDone() {}
+
+    async event void RadioModes.SleepModeDone() {
+        atomic setRxMode();
+    }
+    
     async event void RadioModes.SelfPollingModeDone() {}
     async event void RadioModes.PWDDDInterrupt() {}
 
+    event void ReRxTimer.fired() {
+        atomic {
+            if((macState == RX) && (call RadioModes.SleepMode() == SUCCESS)) {
+                // ok 
+            }
+            else {
+                post postponeReRx();
+            }
+        }
+    }
+    
     /***** abused TimeStamping events **************************/
     async event void RadioTimeStamping.receivedSFD( uint16_t time ) {
         if(macState == RX_P) call ChannelMonitor.rxSuccess();
@@ -991,6 +1012,11 @@ implementation
     
     // we don't care about urgent Resource requestes
     async event void RadioResourceRequested.immediateRequested() {}
+
+    /** prevent MCU from going into a too low power mode */
+    async command mcu_power_t McuPowerOverride.lowestState() {
+        return MSP430_POWER_LPM1;
+    }
 }
 
 
diff --git a/tos/chips/tda5250/mac/RedMac.h b/tos/chips/tda5250/mac/RedMac.h
new file mode 100644 (file)
index 0000000..84497b4
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES {} LOSS OF USE, DATA,
+ * OR PROFITS {} OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Description ---------------------------------------------------------
+ * packet headers for RedMac primitive messages
+ * - Author --------------------------------------------------------------
+ * @author: Andreas Koepke (koepke@tkn.tu-berlin.de)
+ * ========================================================================
+ */
+
+#ifndef RED_MAC_H
+#define RED_MAC_H
+
+/*
+ * highest bit of token set: this message is ACK and not intended for the
+ * upper layers. Token is used for alternating bit like duplicate detection,
+ * and set by the sender in [0,127] intervall. The receiver reflects the
+ * token in the Ack, with the highest bit set. 
+ */
+
+typedef nx_struct red_mac_header_t {
+    nx_uint8_t    repetitionCounter;
+    nx_uint32_t   time; // processing delay of message
+} red_mac_header_t;
+
+#define RELIABLE_MCAST_MIN_ADDR 0xE000
+
+#endif
diff --git a/tos/chips/tda5250/mac/RedMacC.nc b/tos/chips/tda5250/mac/RedMacC.nc
new file mode 100644 (file)
index 0000000..f3beede
--- /dev/null
@@ -0,0 +1,107 @@
+/* -*- mode:c++; indent-tabs-mode:nil -*- 
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names 
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Description ---------------------------------------------------------
+ * low power nonpersistent CSMA MAC, rendez-vous via redundantly sent packets
+ * - Author --------------------------------------------------------------
+ * @author: Andreas Koepke (koepke@tkn.tu-berlin.de)
+ * ========================================================================
+ */
+
+
+configuration RedMacC {
+  provides {
+    interface SplitControl;
+    interface MacSend;
+    interface MacReceive;
+    interface Packet;
+    interface LocalTime<T32khz> as LocalTime;
+    interface SleepTime;
+    interface ChannelCongestion;
+  }
+  uses {
+    interface PhySend as PacketSend;
+    interface PhyReceive as PacketReceive;
+    interface Packet as SubPacket;
+    interface Tda5250Control;  
+    interface UartPhyControl;
+    interface RadioTimeStamping;
+  }
+}
+implementation {
+    components  MainC,
+        RedMacP,
+        RssiFixedThresholdCMC as Cca,
+        new Alarm32khzC() as Timer,
+        new Alarm32khzC() as SampleTimer,
+        RandomLfsrC,
+        McuSleepC,
+        Counter32khzC;
+    
+    components ActiveMessageAddressC;
+    RedMacP.amAddress -> ActiveMessageAddressC;
+
+    MainC.SoftwareInit -> RedMacP;
+              
+    SplitControl = RedMacP;
+    McuSleepC.McuPowerOverride -> RedMacP;
+    MacSend = RedMacP;
+    MacReceive = RedMacP;
+    Tda5250Control = RedMacP;
+    UartPhyControl = RedMacP;
+    RadioTimeStamping = RedMacP;
+    LocalTime = RedMacP;
+    ChannelCongestion = RedMacP;
+    
+    RedMacP = PacketSend;
+    RedMacP = PacketReceive;
+    RedMacP = SubPacket;
+    RedMacP = Packet;
+    RedMacP = SleepTime;
+    
+    RedMacP.CcaStdControl -> Cca.StdControl;
+    RedMacP.ChannelMonitor -> Cca.ChannelMonitor;
+    RedMacP.ChannelMonitorData -> Cca.ChannelMonitorData;
+    RedMacP.ChannelMonitorControl -> Cca.ChannelMonitorControl;
+    RedMacP.RssiAdcResource -> Cca.RssiAdcResource;
+    
+    MainC.SoftwareInit -> RandomLfsrC;
+    RedMacP.Random -> RandomLfsrC;
+
+    RedMacP.Timer -> Timer;
+    RedMacP.SampleTimer -> SampleTimer;
+    RedMacP.Counter32khz16 -> Counter32khzC.Counter32khz16;
+/*    
+    components PlatformLedsC;
+    RedMacP.Led0 -> PlatformLedsC.Led0;
+    RedMacP.Led1 -> PlatformLedsC.Led1;
+    RedMacP.Led2 -> PlatformLedsC.Led2;
+    RedMacP.Led3 -> PlatformLedsC.Led3;
+*/
+}
+
diff --git a/tos/chips/tda5250/mac/RedMacP.nc b/tos/chips/tda5250/mac/RedMacP.nc
new file mode 100644 (file)
index 0000000..1a8600f
--- /dev/null
@@ -0,0 +1,1329 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Description ---------------------------------------------------------
+ * low power nonpersistent CSMA MAC, rendez-vous via redundantly sent packets
+ * - Author --------------------------------------------------------------
+ * @author: Andreas Koepke (koepke@tkn.tu-berlin.de)
+ * ========================================================================
+ */
+
+
+#include "radiopacketfunctions.h"
+#include "flagfunctions.h"
+#include "PacketAck.h"
+#include "RedMac.h"
+
+// #define MACM_DEBUG                    // debug...
+module RedMacP {
+    provides {
+        interface Init;
+        interface SplitControl;
+        interface MacSend;
+        interface MacReceive;
+        interface Packet;
+        interface LocalTime<T32khz> as LocalTime32khz;
+        interface SleepTime;
+        interface Teamgeist;
+        interface ChannelCongestion;
+        interface McuPowerOverride;
+    }
+    uses {
+        interface StdControl as CcaStdControl;
+        interface PhySend as PacketSend;
+        interface PhyReceive as PacketReceive;
+        interface RadioTimeStamping;
+        
+        interface Tda5250Control as RadioModes;  
+
+        interface UartPhyControl;
+      
+        interface ChannelMonitor;
+        interface ChannelMonitorControl;  
+        interface ChannelMonitorData;
+        interface Resource as RssiAdcResource;
+
+        interface Random;
+
+        interface Packet as SubPacket;
+        
+        interface Alarm<T32khz, uint16_t> as Timer;
+        interface Alarm<T32khz, uint16_t> as SampleTimer;
+        interface Counter<T32khz,uint16_t> as Counter32khz16;
+        async command am_addr_t amAddress();
+#ifdef MACM_DEBUG
+        interface GeneralIO as Led0;
+        interface GeneralIO as Led1;
+        interface GeneralIO as Led2;
+        interface GeneralIO as Led3;
+#endif
+    }
+}
+implementation
+{
+    /****** MAC State machine *********************************/
+    typedef enum {
+        RX,
+        RX_ACK,
+        CCA,
+        CCA_ACK,
+        RX_P,
+        RX_ACK_P,
+        SLEEP,
+        TX,
+        TX_ACK,
+        INIT,
+        STOP
+    } macState_t;
+
+    macState_t macState;
+
+    /****** debug vars & defs & functions  ***********************/
+#ifdef MACM_DEBUG
+#define HISTORY_ENTRIES 60
+    typedef struct {
+        int index;
+        macState_t state;
+        int        place;
+    } history_t;
+    
+    history_t history[HISTORY_ENTRIES];
+    unsigned histIndex;
+    void storeOldState(int p) {
+        atomic {
+            history[histIndex].index = histIndex;
+            history[histIndex].state = macState;
+            history[histIndex].place = p;
+            histIndex++;
+            if(histIndex >= HISTORY_ENTRIES) histIndex = 0;
+        }
+    }
+#else
+    void storeOldState(int p) {};
+#endif
+
+    void signalFailure(uint8_t place) {
+#ifdef MACM_DEBUG
+        unsigned long i,j;
+        atomic {
+            for(;;) {
+                call Led0.clr();
+                call Led1.clr();
+                call Led2.clr();
+                call Led3.clr();
+                
+                for(i = 0; i < 100; i++) {
+                    for(j=0; j < 200; j++) {
+                        (i & 1) ? call Led0.set() : call Led0.clr();
+                    }
+                    for(j=0; j < 200; j++) {
+                        (i & 2) ? call Led1.set() : call Led1.clr();
+                    }
+                    for(j=0; j < 200; j++) {
+                        (i & 4) ? call Led2.set() : call Led2.clr();
+                    }
+                    for(j=0; j < 200; j++) {
+                        (i & 8) ? call Led3.set() : call Led3.clr();
+                    }
+                }
+
+                (place & 1) ? call Led0.set() : call Led0.clr();
+                (place & 2) ? call Led1.set() : call Led1.clr();
+                (place & 4) ? call Led2.set() : call Led2.clr();
+                (place & 8) ? call Led3.set() : call Led3.clr();
+
+                for(i = 0; i < 1000000; i++) {
+                    ;
+                }
+
+                (macState & 1) ? call Led0.set() : call Led0.clr();
+                (macState & 2) ? call Led1.set() : call Led1.clr();
+                (macState & 4) ? call Led2.set() : call Led2.clr();
+                (macState & 8) ? call Led3.set() : call Led3.clr();
+
+                for(i = 0; i < 1000000; i++) {
+                    ;
+                }
+            }
+        }
+#endif
+    }
+
+    void signalMacState() {
+#ifdef MACM_DEBUG
+/*         (macState & 1) ? call Led0.set() : call Led0.clr();
+         (macState & 2) ? call Led1.set() : call Led1.clr();
+         (macState & 4) ? call Led2.set() : call Led2.clr();
+         (macState & 8) ? call Led3.set() : call Led3.clr();
+*/
+#endif
+    }
+
+
+    /**************** Module Global Constants  *****************/
+    enum {
+        BYTE_TIME=13,                // byte at 38400 kBit/s, 4b6b encoded
+        PREAMBLE_BYTE_TIME=9,        // byte at 38400 kBit/s, no coding
+        PHY_HEADER_TIME=51,          // 6 Phy Preamble at 38400
+        SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME,
+        SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 38400 kBit/s with 4b6b encoding
+        MAX_TIME_VALUE=0xFFFFFFFF,
+        MAXTIMERVALUE=0xFFFF,        // helps to compute backoff
+        //DEFAULT_SLEEP_TIME=3250,
+        DEFAULT_SLEEP_TIME=6500,
+        // DEFAULT_SLEEP_TIME=9750,
+        DATA_DETECT_TIME=17,
+        RX_SETUP_TIME=111,    // time to set up receiver
+        TX_SETUP_TIME=69,     // time to set up transmitter
+        ADDED_DELAY = 40,
+        RX_ACK_TIMEOUT = RX_SETUP_TIME + PHY_HEADER_TIME + 29 + 2*ADDED_DELAY,
+        TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11,
+        // the duration of a send ACK
+        ACK_DURATION = SUB_HEADER_TIME + SUB_FOOTER_TIME,
+        MAX_SHORT_RETRY=7,
+        MAX_LONG_RETRY=2,
+        MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY,
+        MSG_TABLE_ENTRIES=20,
+        TOKEN_ACK_FLAG = 64,
+        TOKEN_ACK_MASK = 0x3f,
+        /* correct the difference between the transmittedSFD and the receivedSFD
+           that appears due to buffering, measured value on an osci is 320us, so this
+           value is actually 10.48576
+        */
+        TIME_CORRECTION = 10,
+        INVALID_SNR = 0xffff,
+        PREAMBLE_LONG = 6,
+        PREAMBLE_SHORT = 2,
+    };
+    
+
+    /**************** Module Global Variables  *****************/
+    typedef union 
+    {
+        uint32_t op;
+        struct {
+            uint16_t lo;
+            uint16_t hi;
+        };
+    } ui32parts_t;
+    
+    /* flags */
+    typedef enum {
+        SWITCHING = 1,
+        RSSI_STABLE = 2,
+        UNHANDLED_PACKET = 4,
+        MESSAGE_PREPARED = 8,
+        RESUME_BACKOFF = 16,
+        CANCEL_SEND = 32,
+        ACTION_DETECTED = 64,
+        TEAMGEIST_ACTIVE=128
+    } flags_t;
+
+        /* duplicate suppression */
+    typedef struct knownMessage_t {
+        am_addr_t src;
+        uint8_t token;
+        uint8_t age;
+    } knownMessage_t;
+    
+    knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES];
+    uint8_t flags;
+    uint8_t checkCounter;
+    uint8_t shortRetryCounter;
+    uint8_t longRetryCounter;
+    uint16_t sleepTime;
+    uint16_t rssiValue;
+    uint32_t restLaufzeit;
+    
+    message_t *txBufPtr;
+    uint16_t txLen;
+    red_mac_header_t *txMacHdr;
+
+    uint16_t seqNo;
+    message_t ackMsg;
+
+    uint16_t counter2sec;
+    uint32_t rxTime;
+
+    am_id_t teamgeistType;
+
+    uint8_t congestionLevel;
+    uint16_t MIN_BACKOFF_MASK;
+    
+    /****** Secure switching of radio modes ***/
+    void interruptBackoffTimer();
+    
+    task void SetRxModeTask();
+    task void SetTxModeTask();
+    task void SetSleepModeTask();
+
+    task void ReleaseAdcTask() {
+        bool release = FALSE;
+        atomic {
+            if((macState >= SLEEP) &&  call RssiAdcResource.isOwner())  {
+                release = TRUE;
+            }
+        }
+        if(release) call RssiAdcResource.release(); 
+    }
+
+    void requestAdc() {
+        if(!call RssiAdcResource.isOwner()) {
+            call RssiAdcResource.immediateRequest();
+        }
+    }
+
+    void setRxMode() {
+        setFlag(&flags, SWITCHING);
+        clearFlag(&flags, RSSI_STABLE);
+        storeOldState(0);
+        checkCounter = 0;
+        rssiValue = INVALID_SNR;
+        if(call RadioModes.RxMode() == FAIL) {
+            post SetRxModeTask();
+        }
+        requestAdc();
+    }
+    
+    task void SetRxModeTask() {
+        atomic {
+            if(isFlagSet(&flags, SWITCHING) && ((macState <= CCA) || (macState == INIT))) setRxMode();
+        }
+    }
+
+    void setSleepMode() {
+        storeOldState(161);
+        clearFlag(&flags, RSSI_STABLE);
+        post ReleaseAdcTask();
+        setFlag(&flags, SWITCHING);
+        if(call RadioModes.SleepMode() == FAIL) {
+            post SetSleepModeTask();
+        }
+    }
+    
+    task void SetSleepModeTask() {
+        atomic if(isFlagSet(&flags, SWITCHING) && ((macState == SLEEP) || (macState == STOP))) setSleepMode();
+    }
+
+
+    void setTxMode() {
+        post ReleaseAdcTask();
+        storeOldState(2);
+        clearFlag(&flags, RSSI_STABLE);
+        setFlag(&flags, SWITCHING);
+        if(call RadioModes.TxMode() == FAIL) {
+            post SetTxModeTask();
+        }
+    }
+
+    task void SetTxModeTask() {
+        atomic {
+            if(isFlagSet(&flags, SWITCHING) && ((macState == TX) || (macState == TX_ACK))) setTxMode();
+        }
+    }
+
+    /**************** Helper functions ************************/
+    void checkSend() {
+        storeOldState(10);
+        if((shortRetryCounter) && (txBufPtr != NULL) && (isFlagSet(&flags, MESSAGE_PREPARED)) && 
+           (macState == SLEEP) && (!isFlagSet(&flags, RESUME_BACKOFF)) && (!call Timer.isRunning())) {
+            storeOldState(11);
+            macState = CCA;
+            checkCounter = 0;
+            setRxMode();
+        }
+    }
+
+    uint32_t backoff(uint8_t counter) {
+        uint32_t rVal = call Random.rand16() &  MIN_BACKOFF_MASK;
+        return rVal << counter;
+    }
+    
+    bool needsAckTx(message_t* msg) {
+        bool rVal = FALSE;
+        if(getHeader(msg)->dest < AM_BROADCAST_ADDR) {
+            if(getMetadata(msg)->ack != NO_ACK_REQUESTED) {
+                rVal = TRUE;
+            }
+        }
+        return rVal;
+    }
+    
+    bool needsAckRx(message_t* msg, uint8_t *level) {
+        bool rVal = FALSE;
+        am_addr_t dest = getHeader(msg)->dest;
+        uint8_t token;
+        uint16_t snr = 1;
+        if(dest < AM_BROADCAST_ADDR) {
+            if(dest < RELIABLE_MCAST_MIN_ADDR) {
+                token = getHeader(msg)->token;
+                if(isFlagSet(&token, ACK_REQUESTED)) {
+                    rVal = TRUE;
+                }
+            }
+            else {
+                if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
+                   (getHeader(msg)->type == teamgeistType)) {
+                    if(rssiValue != INVALID_SNR) snr = rssiValue;
+                    rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr);
+                    *level = 1;
+                }
+            }
+        }
+        return rVal;
+    }
+
+    task void PrepareMsgTask() {
+        message_t *msg;
+        uint8_t length;
+        red_mac_header_t *macHdr;
+        uint16_t sT;
+        atomic {
+            msg = txBufPtr;
+            length = txLen;
+            sT = sleepTime;
+        }
+        if(msg == NULL) return;
+        macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, NULL);
+        macHdr->repetitionCounter = sT/(length * BYTE_TIME + SUB_HEADER_TIME + SUB_FOOTER_TIME + 
+                                        TX_GAP_TIME) + 1;
+        atomic {
+            if((longRetryCounter > 1) &&
+               isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
+               (getHeader(msg)->type == teamgeistType)) {
+                getHeader(msg)->dest = signal Teamgeist.getDestination(msg, longRetryCounter - 1);
+            }
+            getHeader(msg)->token = seqNo;
+            if(needsAckTx(msg)) getHeader(msg)->token |= ACK_REQUESTED;
+            txMacHdr = macHdr;
+            setFlag(&flags, MESSAGE_PREPARED);
+            if((macState == SLEEP) && (!call Timer.isRunning()) && (!isFlagSet(&flags, RESUME_BACKOFF))) {
+                call Timer.start(backoff(longRetryCounter));
+            }
+        }
+    }
+
+    bool prepareRepetition() {
+        bool repeat;
+        atomic {
+            if(isFlagSet(&flags, CANCEL_SEND)) txMacHdr->repetitionCounter = 0;
+            repeat = (txMacHdr->repetitionCounter >= 1);
+            txMacHdr->repetitionCounter--;
+        }
+        return repeat;
+    }
+
+    void signalSendDone(error_t error) {
+        message_t *m;
+        error_t e = error;
+        storeOldState(12);
+        atomic {
+            m = txBufPtr;
+            txBufPtr = NULL;
+            txLen  = 0;
+            longRetryCounter = 0;
+            shortRetryCounter = 0;
+            if(rssiValue != INVALID_SNR) {
+                (getMetadata(m))->strength = rssiValue;
+            }
+            else {
+                (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
+            }
+            if(isFlagSet(&flags, CANCEL_SEND)) {
+                e = ECANCEL;
+            }
+            clearFlag(&flags, CANCEL_SEND);
+        }
+        signal MacSend.sendDone(m, e);
+    }
+    
+    void updateRetryCounters() {
+        shortRetryCounter++;
+        if(shortRetryCounter > MAX_SHORT_RETRY) {
+            longRetryCounter++;
+            shortRetryCounter = 1;
+            if(longRetryCounter > MAX_LONG_RETRY) {
+                storeOldState(13);
+                signalSendDone(FAIL);
+            }
+        }
+    }
+
+    void updateLongRetryCounters() {
+        atomic {
+            clearFlag(&flags, MESSAGE_PREPARED);
+            longRetryCounter++;
+            shortRetryCounter = 1;
+            if(longRetryCounter > MAX_LONG_RETRY) {
+                storeOldState(13);
+                signalSendDone(FAIL);
+            } else {
+                post PrepareMsgTask();
+            }
+        }
+    }
+
+    bool ackIsForMe(message_t* msg) {
+        uint8_t localToken = seqNo;
+        setFlag(&localToken, TOKEN_ACK_FLAG);
+        if((getHeader(msg)->dest == call amAddress()) && (localToken == getHeader(msg)->token)) return TRUE;
+        return FALSE;
+    }
+
+    void interruptBackoffTimer() {
+        uint16_t now;
+        if(call Timer.isRunning()) {
+            restLaufzeit = call Timer.getAlarm();
+            call Timer.stop();
+            now = call Timer.getNow();
+            if(restLaufzeit >= now) {
+                restLaufzeit = restLaufzeit - now;
+            }
+            else {
+                restLaufzeit +=  MAXTIMERVALUE - now;
+            }
+            if(restLaufzeit > MIN_BACKOFF_MASK << MAX_LONG_RETRY) {
+                restLaufzeit = backoff(0);
+            }
+            setFlag(&flags, RESUME_BACKOFF);
+        }
+    }
+
+    void computeBackoff() {
+        if(!isFlagSet(&flags, RESUME_BACKOFF)) {
+            setFlag(&flags, RESUME_BACKOFF);
+            restLaufzeit = backoff(longRetryCounter);
+            updateRetryCounters();
+            storeOldState(92);
+        }
+    }
+
+    bool msgIsForMe(message_t* msg) {
+        if(getHeader(msg)->dest == AM_BROADCAST_ADDR) return TRUE;
+        if(getHeader(msg)->dest == call amAddress()) return TRUE;
+        if(getHeader(msg)->dest >= RELIABLE_MCAST_MIN_ADDR) return TRUE;
+        return FALSE;
+    }
+
+    bool isControl(message_t* m) {
+        uint8_t token = getHeader(m)->token;
+        return isFlagSet(&token, TOKEN_ACK_FLAG);
+    }
+    
+    bool isNewMsg(message_t* msg) {
+        bool rVal = TRUE;
+        uint8_t i;
+        for(i=0; i < MSG_TABLE_ENTRIES; i++) {
+            if((getHeader(msg)->src == knownMsgTable[i].src) &&
+               (((getHeader(msg)->token) & TOKEN_ACK_MASK) == knownMsgTable[i].token) &&
+               (knownMsgTable[i].age < MAX_AGE)) {
+                knownMsgTable[i].age = 0;
+                rVal = FALSE;
+                break;
+            }
+        }
+        return rVal;
+    }
+
+    unsigned findOldest() {
+        unsigned i;
+        unsigned oldIndex = 0;
+        unsigned age = knownMsgTable[oldIndex].age;
+        for(i = 1; i < MSG_TABLE_ENTRIES; i++) {
+            if(age < knownMsgTable[i].age) {
+                oldIndex = i;
+                age = knownMsgTable[i].age;
+            }
+        }
+        return oldIndex;
+    }
+
+    void rememberMsg(message_t* msg) {
+        unsigned oldest = findOldest();
+        knownMsgTable[oldest].src = getHeader(msg)->src;
+        knownMsgTable[oldest].token = (getHeader(msg)->token) & TOKEN_ACK_MASK;
+        knownMsgTable[oldest].age = 0;
+    }
+
+    void prepareAck(message_t* msg) {
+        uint8_t rToken = getHeader(msg)->token & TOKEN_ACK_MASK;
+        setFlag(&rToken, TOKEN_ACK_FLAG);
+        getHeader(&ackMsg)->token = rToken;
+        getHeader(&ackMsg)->src = call amAddress();
+        getHeader(&ackMsg)->dest = getHeader(msg)->src;
+        getHeader(&ackMsg)->type = getHeader(msg)->type;
+    }
+    
+    uint32_t calcGeneratedTime(red_mac_header_t *m) {
+        return rxTime - m->time - TIME_CORRECTION;
+    }
+    
+    /**************** Init ************************/
+    
+    command error_t Init.init(){
+        uint8_t i;
+        atomic {
+            macState = INIT;
+            flags = 0;
+            checkCounter = 0;
+            rssiValue = 0;
+            restLaufzeit = 0;
+            seqNo = call Random.rand16() % TOKEN_ACK_FLAG;
+            txBufPtr = NULL;
+            txLen = 0;
+            txMacHdr = NULL;
+            sleepTime = DEFAULT_SLEEP_TIME;
+            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
+                knownMsgTable[i].age = MAX_AGE;
+            }
+            for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sleepTime; ) {
+                MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
+            }
+            MIN_BACKOFF_MASK >>= 2;
+            storeOldState(20);
+            shortRetryCounter = 0;
+            longRetryCounter = 0;
+            counter2sec = 127;
+            rxTime = 0;
+            teamgeistType = 0;
+        }
+        return SUCCESS;
+    }
+
+    /****************  SplitControl  *****************/
+
+    task void StartDoneTask() {
+        storeOldState(14);
+        atomic  {
+            call SampleTimer.start(sleepTime);
+            macState = SLEEP;
+            setFlag(&flags, TEAMGEIST_ACTIVE);
+            teamgeistType = signal Teamgeist.observedAMType();
+        }
+        signal SplitControl.startDone(SUCCESS);        
+    }
+    
+    command error_t SplitControl.start() {
+        call CcaStdControl.start();
+        atomic {
+            macState = INIT;
+            // signalMacState();
+            setRxMode();
+            storeOldState(15);
+        }
+        return SUCCESS;
+    }
+    
+    task void StopDoneTask() {
+        call Init.init();
+        storeOldState(16);
+        signal SplitControl.stopDone(SUCCESS);        
+    }
+    
+    command error_t SplitControl.stop() {
+        call CcaStdControl.stop();
+        call Timer.stop();
+        call SampleTimer.stop();
+        atomic {
+            if((macState == SLEEP) && isFlagSet(&flags, SWITCHING)) {
+                macState = STOP;
+                storeOldState(17);
+            }
+            else {
+                macState = STOP;
+                setSleepMode();
+                storeOldState(18);
+            }
+        }
+        return SUCCESS;
+    }
+
+    /****** Packet interface ********************/
+    command void Packet.clear(message_t* msg) {
+        call SubPacket.clear(msg);
+    }
+    
+    command uint8_t Packet.payloadLength(message_t* msg) {
+        return call SubPacket.payloadLength(msg) - sizeof(red_mac_header_t);
+    }
+    
+    command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+        call SubPacket.setPayloadLength(msg,len + sizeof(red_mac_header_t));
+    }
+    
+    command uint8_t Packet.maxPayloadLength() {
+        return call SubPacket.maxPayloadLength() - sizeof(red_mac_header_t);
+    }
+    
+    command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+        nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len);
+        if (len != NULL) {
+            *len -= sizeof(red_mac_header_t);
+        }
+        return (void*)(payload + sizeof(red_mac_header_t));
+    }
+    
+    /****** Radio(Mode) events *************************/
+    async event void RadioModes.RssiStable() {
+        if(isFlagSet(&flags, RSSI_STABLE)) signalFailure(0);
+        setFlag(&flags, RSSI_STABLE);
+        if((macState == RX) || (macState == CCA)) {
+            call Timer.start(DATA_DETECT_TIME);
+            storeOldState(30);
+        }
+        else if(macState == RX_P) {
+            storeOldState(31);
+            if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
+        }
+        else if(macState == RX_ACK) {
+            // if(call RssiAdcResource.isOwner()) call ChannelMonitor.start();
+            storeOldState(32);
+        }
+        else if(macState == RX_ACK_P) {
+        }
+        else if(macState == INIT) {
+            storeOldState(33);
+            if(call RssiAdcResource.isOwner()) {
+                call ChannelMonitorControl.updateNoiseFloor();
+            } else {
+                call RssiAdcResource.request();
+            }
+        }
+        else if(macState == STOP) {
+            storeOldState(34);
+        }
+        else {
+            storeOldState(35);
+            signalFailure(1);
+        }
+    }
+    
+    async event void RadioModes.RxModeDone() {
+        storeOldState(40);
+        if(!isFlagSet(&flags, SWITCHING)) signalFailure(2);
+        atomic {
+            clearFlag(&flags, SWITCHING);
+            if((macState == RX) || (macState == RX_ACK) || (macState == CCA) ||
+               (macState == INIT) || (macState == STOP)) {
+                storeOldState(41);
+                if(macState != RX_ACK) requestAdc();
+            }
+            else {
+                storeOldState(42);
+                signalFailure(3);
+            }
+        }
+    }
+    
+    async event void RadioModes.TxModeDone() {
+        storeOldState(50);
+        if(!isFlagSet(&flags, SWITCHING)) signalFailure(4);
+        atomic {
+            clearFlag(&flags, SWITCHING);
+            if(macState == TX) {
+                call UartPhyControl.setNumPreambles(PREAMBLE_SHORT);
+                setFlag(&flags, ACTION_DETECTED);
+                if(txBufPtr == NULL) signalFailure(5);
+                if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
+                    storeOldState(51);
+                } else {
+                    storeOldState(52);
+                    signalFailure(6);
+                }
+            }
+            else if(macState == TX_ACK) {
+                if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
+                    storeOldState(53);
+                } else {
+                    storeOldState(54);
+                    signalFailure(6);
+                }
+            }
+            else {
+                storeOldState(55);
+                signalFailure(7);
+            }
+        }
+    }
+
+    async event void RadioModes.SleepModeDone() {
+        storeOldState(60);
+        if(!isFlagSet(&flags, SWITCHING)) signalFailure(8);
+        atomic {
+            clearFlag(&flags, SWITCHING);
+            if(isFlagSet(&flags, ACTION_DETECTED)) {
+                if(congestionLevel < 5) congestionLevel++;
+            } else {
+                if(congestionLevel > 0) congestionLevel--;
+            }
+            if((macState == SLEEP) && (!call Timer.isRunning())) {
+                if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                    storeOldState(61);
+                    clearFlag(&flags, RESUME_BACKOFF);
+                    call Timer.start(restLaufzeit);
+                    restLaufzeit = 0;
+                }
+                else {
+                    storeOldState(62);
+                    checkSend();
+                }
+            }
+            else if(macState == INIT) {
+                storeOldState(63);
+                post StartDoneTask();
+            }
+            else if(macState == STOP) {
+                storeOldState(64);
+                post StopDoneTask();
+            }
+            signal ChannelCongestion.congestionEvent(congestionLevel);
+        }
+    }
+    
+    /****** MacSend events *************************/    
+    async command error_t MacSend.send(message_t* msg, uint8_t len) {
+        error_t err = SUCCESS;
+        atomic {
+            if((shortRetryCounter == 0) && (txBufPtr == NULL)) {
+                clearFlag(&flags, MESSAGE_PREPARED);
+                storeOldState(65);
+                shortRetryCounter = 1;
+                longRetryCounter = 1;
+                txBufPtr = msg;
+                txLen = len + sizeof(red_mac_header_t);
+                seqNo++;
+                if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
+            }
+            else {
+                storeOldState(66);
+                err = EBUSY;
+            }
+        }
+        if(err == SUCCESS) {
+            post PrepareMsgTask();
+        }
+        return err;
+    }
+
+    async command error_t MacSend.cancel(message_t* msg) {
+        error_t err = FAIL;
+        atomic {
+            if(msg == txBufPtr) {
+                setFlag(&flags, CANCEL_SEND);
+                shortRetryCounter = MAX_SHORT_RETRY + 2;
+                longRetryCounter  = MAX_LONG_RETRY + 2;
+                if(macState == SLEEP) signalSendDone(ECANCEL);
+                err = SUCCESS;
+            }
+        }
+        return err;
+    }
+    
+    /****** PacketSerializer events **********************/
+    
+    async event void PacketReceive.receiveDetected() {
+        rssiValue = INVALID_SNR;
+        setFlag(&flags, ACTION_DETECTED);
+        if(macState <= CCA_ACK) {
+            if(macState == CCA) computeBackoff();
+            if(macState != RX_ACK) {
+                macState = RX_P;
+            } else {
+                macState = RX_ACK_P;
+            }
+        }
+        else if(macState == INIT) {
+            storeOldState(72);
+            if(isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(9);
+            setFlag(&flags, UNHANDLED_PACKET);
+        }
+    }
+    
+    async event message_t* PacketReceive.receiveDone(message_t* msg, void* payload, uint8_t len, error_t error) {
+        message_t *m = msg;
+        macState_t action = STOP;
+        uint32_t nav = 0;
+        uint8_t level = 0;
+        bool isCnt;
+        
+        storeOldState(80);
+        if(macState == RX_P) {
+            storeOldState(81);
+            if(error == SUCCESS) {
+                storeOldState(82);
+                isCnt = isControl(msg);
+                if(msgIsForMe(msg)) {
+                    if(!isCnt) {
+                        storeOldState(83);
+                        if(isNewMsg(msg)) {
+                            storeOldState(84);
+                            if(rssiValue != INVALID_SNR) {
+                                (getMetadata(m))->strength = rssiValue;
+                            }
+                            else {
+                                if(call RssiAdcResource.isOwner()) {
+                                    (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
+                                }
+                                else {
+                                    (getMetadata(m))->strength = 1;
+                                }
+                            }
+                            (getMetadata(msg))->time = calcGeneratedTime((red_mac_header_t*) payload);
+                            m = signal MacReceive.receiveDone(msg);
+                            // assume a buffer swap -- if buffer is not swapped, assume that the
+                            // message was not successfully delivered to upper layers
+                            if(m != msg) {
+                                storeOldState(85);
+                                rememberMsg(msg);
+                            } else {
+                                storeOldState(86);
+                                action = RX;
+                            }
+                        }
+                        if(needsAckRx(msg, &level) && (action != RX)) {
+                            storeOldState(87);
+                            action = CCA_ACK;
+                        }
+                        else {
+                            storeOldState(88);
+                            if(action != RX) {
+                                nav = ((red_mac_header_t*)payload)->repetitionCounter *
+                                    (SUB_HEADER_TIME + getHeader(msg)->length*BYTE_TIME +
+                                     SUB_FOOTER_TIME + RX_ACK_TIMEOUT + TX_SETUP_TIME) + ACK_DURATION;
+                                action = SLEEP;
+                            }
+                        }
+                    }
+                    else {
+                        storeOldState(89);
+                        action = RX;
+                    }
+                }
+                else {
+                    storeOldState(90);
+                    action = SLEEP;
+                    if(!isCnt) {
+                        nav = ((red_mac_header_t*)payload)->repetitionCounter *
+                            (SUB_HEADER_TIME + getHeader(msg)->length*BYTE_TIME +
+                             SUB_FOOTER_TIME + RX_ACK_TIMEOUT + TX_SETUP_TIME) +
+                            ACK_DURATION;
+                    }
+                }
+            }
+            else {
+                storeOldState(91);
+                action = RX;
+            }
+        }
+        else if(macState == RX_ACK_P) {
+            if(error == SUCCESS) {
+                if(ackIsForMe(msg)) {
+                    storeOldState(92);
+                    if(rssiValue != INVALID_SNR) {
+                        (getMetadata(txBufPtr))->strength = rssiValue;
+                    }
+                    else {
+                        if(call RssiAdcResource.isOwner()) {
+                            (getMetadata(txBufPtr))->strength = call ChannelMonitorData.readSnr();
+                        }
+                        else {
+                            (getMetadata(txBufPtr))->strength = 1;
+                        }
+                    }
+                    (getMetadata(txBufPtr))->ack = WAS_ACKED;
+                    if(isFlagSet(&flags, TEAMGEIST_ACTIVE) && (getHeader(txBufPtr)->type == teamgeistType)) {
+                        signal Teamgeist.gotAck(txBufPtr, getHeader(msg)->src,
+                                                getMetadata(txBufPtr)->strength);
+                    }
+                    signalSendDone(SUCCESS);
+                    action = SLEEP;
+                }
+                else {
+                    updateLongRetryCounters();
+                    action = RX;
+                }
+            }
+            else {
+                if(call Timer.isRunning()) {
+                    storeOldState(94);
+                    action = RX_ACK;
+                }
+                else {
+                    updateLongRetryCounters();
+                    action = RX;
+                }
+            }
+        }
+        else {
+            storeOldState(96);
+            action = INIT;
+        }
+        if(action == CCA_ACK) {
+            prepareAck(msg);
+            macState = CCA_ACK;
+            if(call Random.rand16() & 4) {
+                call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + (ADDED_DELAY>>level));
+                call UartPhyControl.setNumPreambles(PREAMBLE_SHORT);
+            }
+            else {
+                call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME);
+                call UartPhyControl.setNumPreambles(PREAMBLE_LONG);
+            }
+        }
+        else if(action == RX_ACK) {
+            macState = RX_ACK;
+        }
+        else if(action == RX) {
+            macState = RX;
+            checkCounter = 0;
+            call Timer.start(DATA_DETECT_TIME);
+        }
+        else if(action == SLEEP) {
+            macState = SLEEP;
+            setSleepMode();
+            if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                if(nav > restLaufzeit) restLaufzeit += nav;
+            }
+            else {
+                setFlag(&flags, RESUME_BACKOFF);
+                restLaufzeit = nav + backoff(longRetryCounter);
+            }
+        }
+        else if(action == INIT) {
+            if(!isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(11);
+            clearFlag(&flags, UNHANDLED_PACKET);
+        }
+        else {
+            storeOldState(94);
+            signalFailure(11);
+        }
+        return m;
+    }
+
+    async event void PacketSend.sendDone(message_t* msg, error_t error) {
+        if(macState == TX) {
+            storeOldState(97);
+            if(msg != txBufPtr) signalFailure(12);
+            storeOldState(99);
+            macState = RX_ACK;
+            setRxMode();
+            call Timer.start(RX_ACK_TIMEOUT);
+            checkCounter = 0;
+        }
+        else if(macState == TX_ACK) {
+            checkCounter = 0;
+            macState = RX;
+            setRxMode();
+        }
+        else {
+            signalFailure(13);
+        }
+    }
+    
+    /***** TimeStamping stuff **************************/
+    async event void RadioTimeStamping.receivedSFD( uint16_t time ) {
+        if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
+        if(macState == RX_P) {
+            rxTime = call LocalTime32khz.get();
+            call ChannelMonitor.rxSuccess();
+        }
+    }
+    
+    async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) {
+        uint32_t now;
+        uint32_t mTime;
+        if((macState == TX) && (p_msg == txBufPtr)) {
+            now = call LocalTime32khz.get();
+            mTime = getMetadata(p_msg)->time;
+            if(now >= mTime) {
+                txMacHdr->time = now - mTime;
+            }
+            else {
+                // assume a clock wrap here
+                txMacHdr->time = MAX_TIME_VALUE - mTime + now;
+            }
+        }
+    }
+    
+    async command uint32_t LocalTime32khz.get() {
+        ui32parts_t time;
+        atomic {
+            time.lo = call Counter32khz16.get();
+            time.hi = counter2sec;
+        }
+        return time.op;
+    }
+    
+    async event void Counter32khz16.overflow() {
+        counter2sec++;
+    }
+
+    
+    
+    /****** Timer ******************************/
+
+    void checkOnBusy() {
+        setFlag(&flags, ACTION_DETECTED);
+        if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
+            if(macState == CCA) {
+                computeBackoff();
+            }
+            requestAdc();
+            storeOldState(150);
+            macState = RX;
+            checkCounter = 0;
+            call Timer.start(TX_GAP_TIME>>1);
+        }
+    }
+
+    void checkOnIdle()  {
+        if(macState == RX) {
+            checkCounter++;
+            if(checkCounter >= 3) {
+                storeOldState(153);
+                macState = SLEEP;
+                setSleepMode();
+            }
+            else {
+                storeOldState(154);
+                call Timer.start(TX_GAP_TIME>>1);
+                requestAdc();
+            }
+        }
+        else if(macState == CCA) {
+            checkCounter++;
+            if(checkCounter < 3) {
+                storeOldState(158);                
+                call Timer.start((TX_GAP_TIME + backoff(0))>>1);
+                requestAdc();
+            }
+            else {
+                storeOldState(159);
+                macState = TX;
+                setTxMode();
+            }
+        }
+        else if(macState == CCA_ACK) {
+            storeOldState(160);
+            macState = TX_ACK;
+            setTxMode();
+        }
+    }
+    
+    async event void Timer.fired() {
+        storeOldState(100);
+        if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
+            if(isFlagSet(&flags, SWITCHING)) signalFailure(14);
+            if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) {
+                if(call UartPhyControl.isBusy()) {
+                    storeOldState(101);
+                    checkOnBusy();
+                }
+                else {
+                    storeOldState(102);
+                    checkOnIdle();
+                }
+            }
+        }
+        else if(macState == RX_ACK) {
+            if(prepareRepetition()) {
+                storeOldState(156);
+                macState = TX;
+                setTxMode();
+            }
+            else {
+                if(needsAckTx(txBufPtr)) {
+                    storeOldState(157);
+                    updateLongRetryCounters();
+                }
+                else {
+                    storeOldState(158);
+                    signalSendDone(SUCCESS);
+                }
+                macState = SLEEP;
+                setSleepMode();
+            }
+        }
+        else if(macState == SLEEP) {
+             if(isFlagSet(&flags, SWITCHING)) {
+                 storeOldState(106);
+                 call Timer.start(backoff(0));
+             }
+             else {
+                 storeOldState(107);
+                 checkSend();
+             }
+        }
+        else if((macState == RX_ACK_P) || (macState == RX_P)) {
+            storeOldState(108);
+        }
+        else if(macState == INIT) {
+            storeOldState(109);
+            post StartDoneTask();
+        }
+        else {
+            storeOldState(110);
+            signalFailure(15);
+        }
+    }
+
+    /****** SampleTimer ******************************/
+
+    task void ageMsgsTask() {
+        unsigned i;
+        atomic {
+            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
+                if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age;
+            }
+        }
+    }
+    
+    async event void SampleTimer.fired() {
+        call SampleTimer.start(sleepTime);
+        storeOldState(111);
+        if((macState == SLEEP) && (!isFlagSet(&flags, SWITCHING))) {
+            clearFlag(&flags, ACTION_DETECTED);
+            interruptBackoffTimer();
+            macState = RX;
+            storeOldState(112);
+            setRxMode();
+            call Timer.stop();
+        }
+        post ageMsgsTask();
+    }
+
+    /***** SleepTime **********************************/
+    async command void SleepTime.setSleepTime(uint16_t sT) {
+        atomic {
+            sleepTime = sT;
+            for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sT; ) {
+                MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
+            }
+            MIN_BACKOFF_MASK >>= 3;
+        }
+    }
+    
+    async command uint16_t SleepTime.getSleepTime() {
+        uint16_t st;
+        atomic st = sleepTime;
+        return st;
+    }
+
+    /****** ChannelMonitor events *********************/
+
+    async event void ChannelMonitor.channelBusy() {
+        storeOldState(120);
+        checkOnBusy();
+    }
+
+    async event void ChannelMonitor.channelIdle() {
+        storeOldState(121);
+        checkOnIdle();
+    }
+
+    /****** ChannelMonitorControl events **************/
+    
+    event void ChannelMonitorControl.updateNoiseFloorDone() {
+        if(macState == INIT) {
+            storeOldState(130);
+            call Timer.start(call Random.rand16() % DEFAULT_SLEEP_TIME);
+            setSleepMode();
+        } else {
+            storeOldState(131);
+            signalFailure(16);
+        }
+    }
+
+    /***** ChannelMonitorData events ******************/
+    
+    async event void ChannelMonitorData.getSnrDone(int16_t data) {
+        storeOldState(140);
+        atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data;
+    }
+    
+    /***** Rssi Resource events ******************/
+    event void RssiAdcResource.granted() {
+        macState_t ms;
+        atomic ms = macState;
+        if(ms < SLEEP) {
+            storeOldState(144);
+        }
+        else if(ms == INIT) {
+            storeOldState(145);
+            call ChannelMonitorControl.updateNoiseFloor();            
+        }
+        else {
+            storeOldState(146);
+            post ReleaseAdcTask();
+        }
+    }
+    
+    /***** default Teamgeist events **************************/
+
+    default event am_id_t Teamgeist.observedAMType() {
+        clearFlag(&flags, TEAMGEIST_ACTIVE);
+        return teamgeistType;
+    }
+
+    default async event bool Teamgeist.needsAck(message_t *msg, am_addr_t src, am_addr_t dest, uint16_t snr) {
+        clearFlag(&flags, TEAMGEIST_ACTIVE);
+        return TRUE;
+    }
+
+    default async event uint8_t Teamgeist.estimateForwarders(message_t *msg) {
+        return 1;
+    }
+
+    default async event am_addr_t Teamgeist.getDestination(message_t *msg, uint8_t retryCounter) {
+        return getHeader(msg)->dest;
+    }
+    
+    default async event void Teamgeist.gotAck(message_t *msg, am_addr_t ackSender, uint16_t snr) {
+    }
+    
+    default async event void ChannelCongestion.congestionEvent(uint8_t level) {}
+    
+    /***** unused Radio Modes events **************************/
+    
+    async event void RadioModes.TimerModeDone() {}
+    async event void RadioModes.SelfPollingModeDone() {}
+    async event void RadioModes.PWDDDInterrupt() {}
+
+    /** prevent MCU from going into a too low power mode */
+    async command mcu_power_t McuPowerOverride.lowestState() {
+        mcu_power_t mp;
+        if(macState != SLEEP) {
+            mp = MSP430_POWER_LPM1;
+        }
+        else {
+            mp = MSP430_POWER_LPM3;
+        }
+        return mp;
+    }
+}
+
diff --git a/tos/chips/tda5250/mac/SleepTime.nc b/tos/chips/tda5250/mac/SleepTime.nc
new file mode 100644 (file)
index 0000000..e745d34
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * Interface to control the duty cycle of the MAC
+ * @author Andreas Koepke (koepke at tkn.tu-berlin.de)
+ */ 
+interface SleepTime {
+  /**
+   * set the sleep time of the MAC in units of a 32kHz clock, the setting
+   * takes effect on the next wakeup. To avoid synchroninization of the wake
+   * up times, some additional randomization can be necessary, esp. when
+   * switching from shorter to longer sleep times.
+   */
+  async command void setSleepTime(uint16_t sT);
+  
+  /**
+   * which sleep time is in effect?
+   */
+  async command uint16_t getSleepTime();
+}
diff --git a/tos/chips/tda5250/mac/Teamgeist.nc b/tos/chips/tda5250/mac/Teamgeist.nc
new file mode 100644 (file)
index 0000000..f7bf6ac
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * Interface that helps the MAC to cooperate with the routing
+ * @author Andreas Koepke (koepke at tkn.tu-berlin.de)
+ */ 
+interface Teamgeist {
+    /**
+     * Get the AM type of the messages that are jointly routed by the MAC and
+     * the routing layer. Only for these messages the MAC tries to access the
+     * routing layer. 
+     */
+    event am_id_t observedAMType();
+
+    /**
+     * The MAC layer uses this function to ask the routing protocol whether it
+     * should acknowledge and thus propose himself as a forwarder. 
+     */
+    async event bool needsAck(message_t *msg, am_addr_t src, am_addr_t dest, uint16_t snr);
+
+    /**
+     * Sending the message to the original destination did not work.
+     * Ask for a different one.
+     */
+    async event am_addr_t getDestination(message_t *msg, uint8_t retryCounter);
+    
+    /**
+     * Information on the ACK.
+     */
+    async event void gotAck(message_t *msg, am_addr_t ackSender, uint16_t snr);
+
+    /**
+     * The MAC layer uses this function to ask the routing protocol how many
+     * potential forwarders there are. This may not give a precise number, but
+     * a rough estimate.
+     */
+    async event uint8_t estimateForwarders(message_t *msg);
+}
index 3b37613db22686561fa6b540b9d809800867f683..46e9a3b34d6804c29cf4732123da19f97027961e 100644 (file)
@@ -92,7 +92,7 @@ interface Leds {
   /**
    * Get the current LED settings as a bitmask. Each bit corresponds to
    * whether an LED is on; bit 0 is LED 0, bit 1 is LED 1, etc. You can
-   * also use the enums LED_LED0, LED_LED1. For example, this expression
+   * also use the enums LEDS_LED0, LEDS_LED1. For example, this expression
    * will determine whether LED 2 is on:
    *
    * <pre> (call Leds.get() & LEDS_LED2) </pre>
diff --git a/tos/interfaces/State.nc b/tos/interfaces/State.nc
new file mode 100644 (file)
index 0000000..0b5507f
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+\r
+/**\r
+ * State machine interface\r
+ * @author David Moss - dmm@rincon.com\r
+ */\r
\r
+interface State {\r
+\r
+  /**\r
+   * This will allow a state change so long as the current\r
+   * state is S_IDLE.\r
+   * @return SUCCESS if the state is change, FAIL if it isn't\r
+   */\r
+  async command error_t requestState(uint8_t reqState);\r
+  \r
+  /**\r
+   * Force the state machine to go into a certain state,\r
+   * regardless of the current state it's in.\r
+   */\r
+  async command void forceState(uint8_t reqState);\r
+  \r
+  /**\r
+   * Set the current state back to S_IDLE\r
+   */\r
+  async command void toIdle();\r
+  \r
+  /**\r
+   * @return TRUE if the state machine is in S_IDLE\r
+   */\r
+  async command bool isIdle();\r
+  \r
+  /**\r
+   * Get the current state\r
+   */\r
+  async command uint8_t getState();\r
+\r
+}\r
index 0f1b4a2fce5eef742b094406124d855ca4d9088a..297c186004ce4f091f6a4ce57a4c5046eaa750d1 100644 (file)
@@ -41,7 +41,7 @@ module HilTimerMilliC {
 implementation {
 
   enum {
-    TIMER_COUNT = uniqueCount("UQ_TIMER_MILLI")
+    TIMER_COUNT = uniqueCount(UQ_TIMER_MILLI)
   };
 
   typedef struct tossim_timer {
index 9e671841e9379d9b8a5558b60563a324344c181e..641f9fe68f587c1bdb63d8fbea1761664021afc8 100644 (file)
@@ -6,14 +6,17 @@ typedef struct sim_gain_noise {
 } sim_gain_noise_t;
 
 
-gain_entry_t* connectivity[TOSSIM_MAX_NODES];
-sim_gain_noise_t noise[TOSSIM_MAX_NODES];
+gain_entry_t* connectivity[TOSSIM_MAX_NODES + 1];
+sim_gain_noise_t noise[TOSSIM_MAX_NODES + 1];
 double sensitivity = 4.0;
 
 gain_entry_t* sim_gain_allocate_link(int mote);
 void sim_gain_deallocate_link(gain_entry_t* link);
 
 gain_entry_t* sim_gain_first(int src) __attribute__ ((C, spontaneous)) {
+  if (src > TOSSIM_MAX_NODES) {
+    return connectivity[TOSSIM_MAX_NODES];
+  } 
   return connectivity[src];
 }
 
@@ -24,9 +27,12 @@ gain_entry_t* sim_gain_next(gain_entry_t* link) __attribute__ ((C, spontaneous))
 void sim_gain_add(int src, int dest, double gain) __attribute__ ((C, spontaneous))  {
   gain_entry_t* current;
   int temp = sim_node();
+  if (src > TOSSIM_MAX_NODES) {
+    src = TOSSIM_MAX_NODES;
+  }
   sim_set_node(src);
 
-  current = connectivity[src];
+  current = sim_gain_first(src);
   while (current != NULL) {
     if (current->mote == dest) {
       sim_set_node(temp);
@@ -50,7 +56,7 @@ double sim_gain_value(int src, int dest) __attribute__ ((C, spontaneous))  {
   gain_entry_t* current;
   int temp = sim_node();
   sim_set_node(src);
-  current = connectivity[src];
+  current = sim_gain_first(src);
   while (current != NULL) {
     if (current->mote == dest) {
       sim_set_node(temp);
@@ -66,7 +72,7 @@ bool sim_gain_connected(int src, int dest) __attribute__ ((C, spontaneous)) {
   gain_entry_t* current;
   int temp = sim_node();
   sim_set_node(src);
-  current = connectivity[src];
+  current = sim_gain_first(src);
   while (current != NULL) {
     if (current->mote == dest) {
       sim_set_node(temp);
@@ -82,9 +88,14 @@ void sim_gain_remove(int src, int dest) __attribute__ ((C, spontaneous))  {
   gain_entry_t* current;
   gain_entry_t* prevLink;
   int temp = sim_node();
+  
+  if (src > TOSSIM_MAX_NODES) {
+    src = TOSSIM_MAX_NODES;
+  }
+
   sim_set_node(src);
     
-  current = connectivity[src];
+  current = sim_gain_first(src);
   prevLink = NULL;
     
   while (current != NULL) {
@@ -107,23 +118,36 @@ void sim_gain_remove(int src, int dest) __attribute__ ((C, spontaneous))  {
 }
 
 void sim_gain_set_noise_floor(int node, double mean, double range) __attribute__ ((C, spontaneous))  {
+  if (node > TOSSIM_MAX_NODES) {
+    node = TOSSIM_MAX_NODES;
+  }
   noise[node].mean = mean;
   noise[node].range = range;
 }
 
 double sim_gain_noise_mean(int node) {
+  if (node > TOSSIM_MAX_NODES) {
+    node = TOSSIM_MAX_NODES;
+  }
   return noise[node].mean;
 }
 
 double sim_gain_noise_range(int node) {
+  if (node > TOSSIM_MAX_NODES) {
+    node = TOSSIM_MAX_NODES;
+  }
   return noise[node].range;
 }
 
 // Pick a number a number from the uniform distribution of
 // [mean-range, mean+range].
 double sim_gain_sample_noise(int node)  __attribute__ ((C, spontaneous)) {
-  double val = noise[node].mean;
-  double adjust = (sim_random() % 2000000);
+  double val, adjust;
+  if (node > TOSSIM_MAX_NODES) {
+    node = TOSSIM_MAX_NODES;
+  } 
+  val = noise[node].mean;
+  adjust = (sim_random() % 2000000);
   adjust /= 1000000.0;
   adjust -= 1.0;
   adjust *= noise[node].range;
diff --git a/tos/platforms/eyesIFX/Msp430Timer32khzMapC.nc b/tos/platforms/eyesIFX/Msp430Timer32khzMapC.nc
deleted file mode 100644 (file)
index 0702d8f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-//$Id$
-
-/* "Copyright (c) 2000-2003 The Regents of the University of California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement
- * is hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
- * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
- */
-
-//@author Cory Sharp <cssharp@eecs.berkeley.edu>
-
-/*
-  Msp430Timer32khzMapC presents as paramaterized interfaces all of the 32khz
-  hardware timers on the MSP430 that are available for compile time allocation
-  by "new Alarm32khzC()", "new AlarmMilliC()", and so on.
-
-  Platforms based on the Msp430 are encouraged to copy in and override this
-  file, presenting only the hardware timers that are available for allocation
-  on that platform.
-*/
-
-configuration Msp430Timer32khzMapC
-{
-  provides interface Msp430Timer[ uint8_t id ];
-  provides interface Msp430TimerControl[ uint8_t id ];
-  provides interface Msp430Compare[ uint8_t id ];
-}
-implementation
-{
-  components Msp430TimerC;
-
-  Msp430Timer[0] = Msp430TimerC.TimerB;
-  Msp430TimerControl[0] = Msp430TimerC.ControlB0;
-  Msp430Compare[0] = Msp430TimerC.CompareB0;
-
-  Msp430Timer[1] = Msp430TimerC.TimerB;
-  Msp430TimerControl[1] = Msp430TimerC.ControlB1;
-  Msp430Compare[1] = Msp430TimerC.CompareB1;
-
-  Msp430Timer[2] = Msp430TimerC.TimerB;
-  Msp430TimerControl[2] = Msp430TimerC.ControlB2;
-  Msp430Compare[2] = Msp430TimerC.CompareB2;
-
-  Msp430Timer[3] = Msp430TimerC.TimerB;
-  Msp430TimerControl[3] = Msp430TimerC.ControlB3;
-  Msp430Compare[3] = Msp430TimerC.CompareB3;
-
-  Msp430Timer[4] = Msp430TimerC.TimerB;
-  Msp430TimerControl[4] = Msp430TimerC.ControlB4;
-  Msp430Compare[4] = Msp430TimerC.CompareB4;
-
-  Msp430Timer[5] = Msp430TimerC.TimerB;
-  Msp430TimerControl[5] = Msp430TimerC.ControlB5;
-  Msp430Compare[5] = Msp430TimerC.CompareB5;
-
-  Msp430Timer[6] = Msp430TimerC.TimerB;
-  Msp430TimerControl[6] = Msp430TimerC.ControlB6;
-  Msp430Compare[6] = Msp430TimerC.CompareB6;
-}
-
index 379a0fa05165334bf2a5c13eb79c5113cf083672..ae0a096b1ff76927a4be542ec6e740e83c904ece 100644 (file)
@@ -51,8 +51,10 @@ implementation
         Tda5250RadioC as Radio,                  //The actual Tda5250 radio over which data is receives/transmitted
         Uart4b6bPhyC as UartPhy,                 //The UartPhy turns Bits into Bytes
         PacketSerializerP  as PacketSerializer,  //The PacketSerializer turns Bytes into Packets
+        // RedMacC as Mac,                         //The MAC protocol to use
         CsmaMacC as Mac,                         //The MAC protocol to use
-        LinkLayerC as Llc;                       //The Link Layer Control module to use
+        
+            LinkLayerC as Llc;                       //The Link Layer Control module to use
     
     //Don't change wirings below this point, just change which components
     //They are compposed of in the list above             
index 60f7c4ce79740c1406d0eff84880d7b79540f724..5b2384d4fd7c778c0cc62fe9f097b99e291d211b 100644 (file)
@@ -48,8 +48,7 @@ configuration RssiFixedThresholdCMC
 implementation
 {
     components RssiFixedThresholdCMP,
-               //  RssiSensorVccC as Rssi, FIXME: has no arbitration!?
-        new RssiSensorC() as Rssi,
+        new RssiSensorVccC() as Rssi,
         new BatteryLevelSensorC() as Voltage,
         new TimerMilliC() as Timer,
         MainC;
index c91e73f26a383e7d08873addd2beaa30c622d064..febe95c1dd05414698215a7b70d25125226ba7b9 100644 (file)
@@ -47,7 +47,6 @@ module Uart4b6bPhyP {
     uses {
         interface RadioByteComm;
         interface Alarm<T32khz, uint16_t> as RxByteTimer;
-        // interface GeneralIO as Led3;
     }
 }
 implementation
@@ -76,7 +75,8 @@ implementation
         BYTE_TIME=11,
         PREAMBLE_BYTE=0x55,
         SYNC_BYTE=0xFF,
-        SFD_BYTE=0x83
+        SFD_BYTE=0x83,
+        SFD_BYTE2=0x7c
     };
     
     /** Module Global Variables  */
@@ -121,18 +121,12 @@ implementation
     
     void resetState() {
         call RxByteTimer.stop();
-        switch(phyState) {
-                       case STATE_PREAMBLE:
-            case STATE_PREAMBLE_CODE:
-             case STATE_SFD2:
-                break;
-            default:
-                signal PhyPacketRx.recvFooterDone(FAIL);
-                break;
+        if(phyState >= STATE_DATA_HIGH) {
+            signal PhyPacketRx.recvFooterDone(FAIL);
         }
         phyState = STATE_PREAMBLE; 
     }
-    
+
     async event void RxByteTimer.fired() {
         // no bytes have arrived, so...
         resetState();
@@ -219,10 +213,10 @@ implementation
                 phyState = STATE_SFD2;
                 call RadioByteComm.txByte(SFD_BYTE);
                 break;
-               case STATE_SFD2:
-               phyState = STATE_SFD3;
-               call RadioByteComm.txByte(SFD_BYTE);
-               break;
+            case STATE_SFD2:
+                phyState = STATE_SFD3;
+                call RadioByteComm.txByte(SFD_BYTE);
+                break;
             case STATE_SFD3:
                 phyState = STATE_HEADER_DONE;
                 call RadioByteComm.txByte(SFD_BYTE);
@@ -267,113 +261,119 @@ implementation
 
     /* Rx Done */
     async event void RadioByteComm.rxByteReady(uint8_t data) {
-      call RxByteTimer.start(byteTime);
-        ReceiveNextByte(data);
-    }
-
-    /* Receive the next Byte from the USART */
-    void ReceiveNextByte(uint8_t data) {
         uint8_t decodedByte;
         uint8_t low;
         uint8_t high;
         if((data == SFD_BYTE) && (phyState != STATE_SFD2) && (phyState != STATE_DATA_HIGH_OR_SFD)) {
             resetState();
-            phyState = STATE_SFD1;
+            phyState = STATE_SFD2;
             call RxByteTimer.start(byteTime<<1);
         }
-        switch(phyState) {
-            case STATE_PREAMBLE:
-                low = data & 0xf;
-                high = data >> 4;
-                if((low > 0) && (low < 0xf) && (high > 0) && (high < 0xf))
-                    phyState = STATE_PREAMBLE_CODE;
-                break;
-            case STATE_PREAMBLE_CODE:
-                low = data & 0xf;
-                high = data >> 4;
-                if((low == 0) || (low == 0xf) || (high == 0) || (high == 0xf))
-                    phyState = STATE_PREAMBLE;
-                break;
-               case STATE_SFD1:
-               phyState = STATE_SFD2;
-            break;
-            case STATE_SFD2:
-              if(data == SFD_BYTE) {
-                       call RxByteTimer.start(byteTime<<1);
-                       signal PhyPacketRx.recvHeaderDone(SUCCESS);
-                  phyState = STATE_DATA_HIGH_OR_SFD;
-              }
-              else {
-                resetState();
-              }
-            break;
-            case STATE_DATA_HIGH_OR_SFD:
-                if(data != SFD_BYTE) {
+        else {
+            switch(phyState) {
+                case STATE_SFD2:
+                    if(data == SFD_BYTE) {
+                        phyState = STATE_DATA_HIGH_OR_SFD;
+                        call RxByteTimer.start(byteTime << 1);
+                    }
+                    else {
+                        resetState();
+                    }
+                    break;
+                case STATE_DATA_HIGH_OR_SFD:    
+                    if(data != SFD_BYTE) {
+                        decodedByte = sixBitToNibble[data >> 2];
+                        if(decodedByte != ILLEGAL_CODE) {
+                            bufByte = decodedByte << 2;
+                            bufByte |= data & 0x03;
+                            bufByte <<= 2;
+                            phyState = STATE_DATA_MIDDLE;
+                            signal PhyPacketRx.recvHeaderDone(SUCCESS);
+                            call RxByteTimer.start(byteTime);
+                        }
+                        else {
+                            resetState();
+                        }
+                    }
+                    else {
+                        phyState = STATE_DATA_HIGH;
+                        signal PhyPacketRx.recvHeaderDone(SUCCESS);
+                        call RxByteTimer.start(byteTime);
+                    }
+                    break;
+                case STATE_DATA_HIGH:
                     decodedByte = sixBitToNibble[data >> 2];
                     if(decodedByte != ILLEGAL_CODE) {
                         bufByte = decodedByte << 2;
                         bufByte |= data & 0x03;
                         bufByte <<= 2;
                         phyState = STATE_DATA_MIDDLE;
+                        call RxByteTimer.start(byteTime);
                     }
                     else {
                         resetState();
                     }
-                }
-                else {
-                    phyState = STATE_DATA_HIGH;
-                }
-                break;
-            case STATE_DATA_HIGH:
-                decodedByte = sixBitToNibble[data >> 2];
-                if(decodedByte != ILLEGAL_CODE) {
-                    bufByte = decodedByte << 2;
-                    bufByte |= data & 0x03;
-                    bufByte <<= 2;
-                    phyState = STATE_DATA_MIDDLE;
-                }
-                else {
-                    resetState();
-                }
-                break;
-            case STATE_DATA_MIDDLE:
-                decodedByte = sixBitToNibble[((bufByte & 0x0f)<<2) | (data >> 4)];
-                if(decodedByte != ILLEGAL_CODE) {
-                    phyState = STATE_DATA_LOW;
-                    signal SerializerRadioByteComm.rxByteReady((bufByte & 0xf0) | decodedByte);
-                    bufByte = (data & 0x0f) << 2;
-                }
-                else {
-                    resetState();
-                }
-                break;
-            case STATE_DATA_LOW:
-                decodedByte = sixBitToNibble[bufByte | (data >> 6)];
-                if(decodedByte != ILLEGAL_CODE) {
-                    bufByte = (decodedByte << 4);
-                    decodedByte = sixBitToNibble[data & 0x3f];
+                    break;
+                case STATE_DATA_MIDDLE:
+                    decodedByte = sixBitToNibble[((bufByte & 0x0f)<<2) | (data >> 4)];
                     if(decodedByte != ILLEGAL_CODE) {
-                        phyState = STATE_DATA_HIGH;
-                        signal SerializerRadioByteComm.rxByteReady(bufByte | decodedByte);
+                        phyState = STATE_DATA_LOW;
+                        signal SerializerRadioByteComm.rxByteReady((bufByte & 0xf0) | decodedByte);
+                        bufByte = (data & 0x0f) << 2;
+                        call RxByteTimer.start(byteTime);
                     }
                     else {
                         resetState();
                     }
-                }
-                else {
-                    resetState();
-                }
-                break;
-                // maybe there will be a time.... we will need this. but for now there is no footer
-                //case STATE_FOOTER_START:
-                //phyState = STATE_FOOTER_DONE;
-                //break;
-                //case STATE_FOOTER_DONE:
-                //phyState = STATE_NULL;
-                //signal PhyPacketRx.recvFooterDone(TRUE);
-                //break;
-            default:
-                break;
+                    break;
+                case STATE_DATA_LOW:
+                    decodedByte = sixBitToNibble[bufByte | (data >> 6)];
+                    if(decodedByte != ILLEGAL_CODE) {
+                        bufByte = (decodedByte << 4);
+                        decodedByte = sixBitToNibble[data & 0x3f];
+                        if(decodedByte != ILLEGAL_CODE) {
+                            phyState = STATE_DATA_HIGH;
+                            signal SerializerRadioByteComm.rxByteReady(bufByte | decodedByte);
+                            call RxByteTimer.start(byteTime);
+                        }
+                        else {
+                            resetState();
+                        }
+                    }
+                    else {
+                        resetState();
+                    }
+                    break;
+                case STATE_PREAMBLE:
+                    low = data & 0xf;
+                    high = data >> 4;
+                    if((low > 0) && (low < 0xf) && (high > 0) && (high < 0xf)) {
+                        phyState = STATE_PREAMBLE_CODE;
+                        call RxByteTimer.start(byteTime);
+                    }
+                    break;
+                case STATE_PREAMBLE_CODE:
+                    low = data & 0xf;
+                    high = data >> 4;
+                    if((low == 0) || (low == 0xf) || (high == 0) || (high == 0xf)) {
+                        phyState = STATE_PREAMBLE;
+                    }
+                    else {
+                        call RxByteTimer.start(byteTime);
+                    }
+                    break;
+                    // maybe there will be a time.... we will need this. but for now there is no footer
+                    //case STATE_FOOTER_START:
+                    //phyState = STATE_FOOTER_DONE;
+                    //break;
+                    //case STATE_FOOTER_DONE:
+                    //phyState = STATE_NULL;
+                    //signal PhyPacketRx.recvFooterDone(TRUE);
+                    //break;
+                default:
+                    break;
+            }
         }
+        
     }
 }
diff --git a/tos/platforms/eyesIFX/byte_radio/UartPhyC.nc b/tos/platforms/eyesIFX/byte_radio/UartPhyC.nc
deleted file mode 100644 (file)
index e3dad86..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-* Copyright (c) 2006, Technische Universitaet Berlin
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* - Redistributions of source code must retain the above copyright notice,
-*   this list of conditions and the following disclaimer.
-* - Redistributions in binary form must reproduce the above copyright
-*   notice, this list of conditions and the following disclaimer in the
-*   documentation and/or other materials provided with the distribution.
-* - Neither the name of the Technische Universitaet Berlin nor the names
-*   of its contributors may be used to endorse or promote products derived
-*   from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* - Description ---------------------------------------------------------
-*
-* - Revision -------------------------------------------------------------
-* $Revision$
-* $Date$
-* @author: Philipp Huppertz <huppertz@tkn.tu-berlin.de>
-* ========================================================================
-*/
-
-/**
- * Configuration for the byte radio physical layer. Together with the
- * PacketSerializerP the UartPhyP module turns byte streams into packets.
- *
- * @see PacketSerializerP
- *
- * @author Philipp Huppertz <huppertz@tkn.tu-berlin.de>
- */
-configuration UartPhyC
-{
-  provides{
-    interface PhyPacketTx;
-    interface RadioByteComm as SerializerRadioByteComm;
-    interface PhyPacketRx;
-    interface UartPhyControl;
-  }
-  uses {
-    interface RadioByteComm;
-  }
-}
-implementation
-{
-    components 
-        new Alarm32khzC() as RxByteTimer,
-        UartPhyP,
-//         PlatformLedsC,
-        MainC;
-    
-    MainC.SoftwareInit -> UartPhyP;
-    PhyPacketRx = UartPhyP;
-    SerializerRadioByteComm = UartPhyP;
-    RadioByteComm = UartPhyP;
-    PhyPacketTx = UartPhyP;
-    UartPhyControl = UartPhyP;
-    
-    UartPhyP.RxByteTimer -> RxByteTimer;
-//     PlatformLedsC.Led0 <- UartPhyP.Led0;
-//     PlatformLedsC.Led1 <- UartPhyP.Led1;
-}
diff --git a/tos/platforms/eyesIFX/byte_radio/UartPhyP.nc b/tos/platforms/eyesIFX/byte_radio/UartPhyP.nc
deleted file mode 100644 (file)
index 9601314..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/* -*- mode:c++; indent-tabs-mode: nil -*-
- * Copyright (c) 2004, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- *   of its contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Description ---------------------------------------------------------
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author: Kevin Klues (klues@tkn.tu-berlin.de)
- * @author: Philipp Huppertz <huppertz@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-#include "manchester.h"
-
-/**
- * Implementation of the physical layer for the eyesIFX byte radio.
- * Together with the PacketSerializerP this module turns byte streams 
- * into packets.
- *
- * @author Kevin Klues <klues@tkn.tu-berlin.de>
- * @author Philipp Huppertz <huppertz@tkn.tu-berlin.de>
- */
-module UartPhyP {
-    provides {
-        interface Init;
-        interface PhyPacketTx;
-        interface RadioByteComm as SerializerRadioByteComm;
-        interface PhyPacketRx;
-        interface UartPhyControl;
-    }
-    uses {
-        interface RadioByteComm;
-        interface Alarm<T32khz, uint16_t> as RxByteTimer;
-    }
-}
-implementation
-{
-    /* Module Definitions  */
-    typedef enum {
-        STATE_PREAMBLE,
-        STATE_SYNC,
-        STATE_SFD,
-        STATE_HEADER_DONE,
-        STATE_DATA_HIGH,
-        STATE_DATA_LOW,
-        STATE_FOOTER_START,
-        STATE_FOOTER_DONE
-    } phyState_t;
-
-
-
-
-#define PREAMBLE_LENGTH   4
-#define BYTE_TIME         22
-#define PREAMBLE_BYTE     0x55
-#define SYNC_BYTE         0xFF
-#define SFD_BYTE          0x05
-
-    /** Module Global Variables  */
-    phyState_t phyState;    // Current Phy state State
-    uint16_t preambleCount;
-    uint16_t numPreambles;  // Number of preambles to send before the packet
-    uint8_t byteTime;       // max. time between two bytes
-    uint8_t bufByte;
-    
-    /* Local Function Declarations */
-    void TransmitNextByte();
-    void ReceiveNextByte(uint8_t data);
-
-    /* Radio Init */
-    command error_t Init.init(){
-        atomic {
-            phyState = STATE_PREAMBLE;
-            numPreambles = PREAMBLE_LENGTH;
-            byteTime = BYTE_TIME;
-        }
-        return SUCCESS;
-    }
-    
-    command error_t UartPhyControl.setNumPreambles(uint16_t numPreambleBytes) {
-        atomic {
-            numPreambles = numPreambleBytes;
-        }
-        return SUCCESS;
-    }
-    
-    command error_t UartPhyControl.setByteTimeout(uint8_t byteTimeout) {
-        if (call RxByteTimer.isRunning() == TRUE) {
-            return FAIL;
-        } else {
-            atomic byteTime = byteTimeout * 33;
-            return SUCCESS;
-        }
-    }
-    
-    async command bool UartPhyControl.isBusy() {
-        return phyState != STATE_PREAMBLE;
-    }
-    
-    void resetState() {
-        atomic {
-            call RxByteTimer.stop();
-            switch(phyState) {
-                case STATE_SYNC:
-                case STATE_SFD:
-                    signal PhyPacketRx.recvHeaderDone(FAIL);
-                    break;
-                case STATE_DATA_HIGH:
-                case STATE_DATA_LOW:
-                case STATE_FOOTER_START:
-                    signal PhyPacketRx.recvFooterDone(FAIL);
-                    break;
-                default:
-                    break;
-            }
-            phyState = STATE_PREAMBLE; 
-        }
-    }
-    
-    async event void RxByteTimer.fired() {
-        // no bytes have arrived, so...
-        resetState();
-    }
-
-    async command void PhyPacketTx.sendHeader() {
-        atomic {
-            phyState = STATE_PREAMBLE;
-            preambleCount = numPreambles;
-        }
-        TransmitNextByte();
-    }
-
-    async command void SerializerRadioByteComm.txByte(uint8_t data) {
-        bufByte = data;
-        call RadioByteComm.txByte(manchesterEncodeNibble((bufByte & 0xf0) >> 4));
-        phyState = STATE_DATA_LOW;
-    }
-
-    async command bool SerializerRadioByteComm.isTxDone() {
-        return call RadioByteComm.isTxDone();
-    }
-
-    async command void PhyPacketTx.sendFooter() {
-        atomic phyState = STATE_FOOTER_START;
-        TransmitNextByte();
-    }
-
-
-    /* Radio Recv */
-    async command void PhyPacketRx.recvFooter() {
-        // currently there is no footer
-        // atomic phyState = STATE_FOOTER_START;
-        atomic {
-            phyState = STATE_PREAMBLE;
-        }
-        call RxByteTimer.stop();
-        signal PhyPacketRx.recvFooterDone(SUCCESS);
-    }
-
-    
-    /* Tx Done */
-    async event void RadioByteComm.txByteReady(error_t error) {
-        if(error == SUCCESS) {
-            TransmitNextByte();
-        } else {
-            atomic {
-                signal SerializerRadioByteComm.txByteReady(error);
-                phyState = STATE_PREAMBLE;
-            }
-        }
-    }
-
-    void TransmitNextByte() {
-        atomic {
-            switch(phyState) {
-                case STATE_PREAMBLE:
-                    if(preambleCount > 0) {
-                        preambleCount--;
-                    } else {
-                        phyState = STATE_SYNC;
-                    }
-                    call RadioByteComm.txByte(PREAMBLE_BYTE);
-                    break;
-                case STATE_SYNC:
-                    phyState = STATE_SFD;
-                    call RadioByteComm.txByte(SYNC_BYTE);
-                    break;
-                case STATE_SFD:
-                    phyState = STATE_HEADER_DONE;
-                    call RadioByteComm.txByte(SFD_BYTE);
-                    break;
-                case STATE_HEADER_DONE:
-                    phyState = STATE_DATA_HIGH;
-                    signal PhyPacketTx.sendHeaderDone();
-                    break;
-                case STATE_DATA_HIGH:
-                    signal SerializerRadioByteComm.txByteReady(SUCCESS);
-                    break;
-                case STATE_DATA_LOW:
-                    call RadioByteComm.txByte(manchesterEncodeNibble(bufByte & 0x0f));
-                    phyState = STATE_DATA_HIGH;                    
-                    break;
-                case STATE_FOOTER_START:
-                    /* Pseudo-Footer: the MSP430 has two buffers: one for
-                     * transmit, one to store the next byte to be transmitted,
-                     * this footer fills the next-to-transmit buffer, to make
-                     * sure that the last real byte is actually
-                     * transmitted. The byte stored by this call may not be
-                     * transmitted fully or not at all. 
-                     */
-                    phyState = STATE_FOOTER_DONE;
-                    call RadioByteComm.txByte(manchesterEncodeNibble(bufByte & 0x0f));
-                    break;
-                case STATE_FOOTER_DONE:
-                    phyState = STATE_PREAMBLE;
-                    signal PhyPacketTx.sendFooterDone();
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    /* Rx Done */
-    async event void RadioByteComm.rxByteReady(uint8_t data) {
-        call RxByteTimer.start(byteTime);
-        ReceiveNextByte(data);
-    }
-
-    /* Receive the next Byte from the USART */
-    void ReceiveNextByte(uint8_t data) {
-        uint8_t decodedByte;
-        atomic {
-            switch(phyState) {
-                case STATE_SYNC:
-                    if(data != PREAMBLE_BYTE) {
-                        if (data == SFD_BYTE) {
-                            signal PhyPacketRx.recvHeaderDone(SUCCESS);
-                            phyState = STATE_DATA_HIGH;
-                        } else {
-                            phyState = STATE_SFD;
-                        } 
-                    }
-                    break;
-                case STATE_SFD:
-                    if (data == SFD_BYTE) {
-                        signal PhyPacketRx.recvHeaderDone(SUCCESS);
-                        phyState = STATE_DATA_HIGH;
-                    } else {
-                        phyState = STATE_PREAMBLE; 
-                    }
-                    break;
-                case STATE_PREAMBLE:
-                    if(data == PREAMBLE_BYTE) {
-                        phyState = STATE_SYNC;
-                    } 
-                    break;
-                case STATE_DATA_HIGH:
-                    decodedByte = manchesterDecodeByte(data);
-                    if(decodedByte != 0xff) {
-                        bufByte = decodedByte << 4;
-                        phyState = STATE_DATA_LOW;
-                    }
-                    else {
-                        resetState();
-                    }
-                    break;
-                case STATE_DATA_LOW:
-                    decodedByte = manchesterDecodeByte(data);
-                    if(decodedByte != 0xff) {
-                        bufByte |= decodedByte;
-                        phyState = STATE_DATA_HIGH;
-                        signal SerializerRadioByteComm.rxByteReady(bufByte);
-                    }
-                    else {
-                        resetState();
-                    }
-                    break;
-                    // maybe there will be a time.... we will need this. but for now there is no footer
-                    //case STATE_FOOTER_START:
-                    //phyState = STATE_FOOTER_DONE;
-                    //break;
-                    //case STATE_FOOTER_DONE:
-                    //phyState = STATE_NULL;
-                    //signal PhyPacketRx.recvFooterDone(TRUE);
-                    //break;
-                default:
-                    break;
-            }
-        }
-    }
-
-}
index 0cf129ccf2e1b1b9a5c4de4039cb3a0df9e75e1d..4b496f1cd235284fcb70e869ecaea9fe093b215f 100644 (file)
 
 generic configuration Msp430Uart0C() {
 
-  provides interface Resource;   provides interface ResourceRequested;
+  provides interface Resource;   
+  provides interface ResourceRequested;
   provides interface UartStream;
   provides interface UartByte;
-  provides interface Msp430UartControl as UartControl;
 
   uses interface Msp430UartConfigure;
 }
@@ -58,7 +58,6 @@ implementation {
   Resource = UartP.Resource[ CLIENT_ID ];
   UartStream = UartP.UartStream;
   UartByte = UartP.UartByte;
-  UartControl = UartP.UartControl[ CLIENT_ID ];
   Msp430UartConfigure = UartP.Msp430UartConfigure[ CLIENT_ID ];
 
   components new Msp430Usart0C() as UsartC;
diff --git a/tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataC.nc b/tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataC.nc
deleted file mode 100644 (file)
index 0bab5bd..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Copyright (c) 2004, Technische Universitat Berlin
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* - Redistributions of source code must retain the above copyright notice,
-*   this list of conditions and the following disclaimer.
-* - Redistributions in binary form must reproduce the above copyright
-*   notice, this list of conditions and the following disclaimer in the
-*   documentation and/or other materials provided with the distribution.
-* - Neither the name of the Technische Universitat Berlin nor the names
-*   of its contributors may be used to endorse or promote products derived
-*   from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-* - Revision -------------------------------------------------------------
-* $Revision$
-* $Date$
-* ========================================================================
-*/
-
-#include "msp430baudrates.h"
-#include "tda5250BusResourceId.h"
-
-/**
- * Controlling the TDA5250 at the HPL layer.
- *
- * @author Kevin Klues (klues@tkn.tu-berlin.de)
- */
-configuration HplTda5250DataC {
-  provides {
-    interface Init;
-    interface HplTda5250Data;
-    interface Resource as Resource;
-  }
-}
-implementation {
-
-
-  components HplTda5250DataP
-      , new Msp430Usart0C()
-      , Tda5250RadioIOC
-      ;
-
-  Init = HplTda5250DataP;
-  Resource = HplTda5250DataP.Resource;
-  HplTda5250Data = HplTda5250DataP;
-
-  HplTda5250DataP.DATA -> Tda5250RadioIOC.Tda5250RadioDATA;
-  HplTda5250DataP.Usart -> Msp430Usart0C;
-  HplTda5250DataP.UsartInterrupts -> Msp430Usart0C;
-  HplTda5250DataP.UartResource -> Msp430Usart0C.Resource;
-}
index d5b6ce3e21d7e1b4d2fe1101bdbb4a5609c3b547..ef3659e509711a5b9e0aa70fcc5a6cbc9016dad2 100644 (file)
@@ -56,6 +56,5 @@ implementation {
   UartStream = Msp430Uart0C.UartStream;
   UartDataControl = HplTda5250DataIOP.UartDataControl;
   
-  HplTda5250DataIOP.Msp430UartControl -> Msp430Uart0C.UartControl;
        HplTda5250DataIOP.UartResourceConfigure <- Msp430Uart0C.Msp430UartConfigure;  
 }
index 97860d47833c1ffcc4b7f0b2e60ac010ed5fbf0d..2e1ed40af8ef9ba22be917802537926d1f2727e1 100644 (file)
@@ -44,24 +44,27 @@ module HplTda5250DataIOP {
     interface HplTda5250DataControl as UartDataControl;
                interface Msp430UartConfigure as UartResourceConfigure;
   } 
-  uses {
-    interface  Msp430UartControl;
-  }
 }
 
 implementation {
   
   async command error_t UartDataControl.setToTx() {
-    call Msp430UartControl.setModeTx();
+        atomic {
+      tda5250_uart_config.uartConfig.utxe = 1;
+      tda5250_uart_config.uartConfig.urxe = 0;
+    }
     return SUCCESS;
   }
 
   async command error_t UartDataControl.setToRx() {
-    call Msp430UartControl.setModeRx();
+    atomic {
+      tda5250_uart_config.uartConfig.utxe = 0;
+      tda5250_uart_config.uartConfig.urxe = 1;
+    }
     return SUCCESS;
   }
        
-       async command msp430_uart_config_t* UartResourceConfigure.getConfig() {
+       async command msp430_uart_union_config_t* UartResourceConfigure.getConfig() {
                return &tda5250_uart_config;
        }
 
diff --git a/tos/platforms/eyesIFX/chips/tda5250/tda5250BusResourceId.h b/tos/platforms/eyesIFX/chips/tda5250/tda5250BusResourceId.h
deleted file mode 100644 (file)
index 12b8e24..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2006, Technische Universitat Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitat Berlin nor the names
- *   of its contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * ========================================================================
- */
-
-#include "msp430UsartResource.h"
-
-#ifndef TDA5250BUSRESOURCEID_H
-#define TDA5250BUSRESOURCEID_H
-
-enum {
-    TDA5250_UART_BUS_ID = unique(MSP430_UARTO_BUS)
-};
-
-#endif
index 382618614024fd1bfede7502ca009dca9869f158..b04824cb70b5f364690fed7f88e1ffb8ffd1f014 100644 (file)
@@ -40,7 +40,7 @@ enum {
     TDA5250_UART_BUS_ID = unique(MSP430_UARTO_BUS)
 };
 
-msp430_uart_config_t tda5250_uart_config = {ubr: UBR_1MHZ_38400, umctl: UMCTL_1MHZ_38400, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0};
+msp430_uart_union_config_t tda5250_uart_config = { {ubr: UBR_1MHZ_38400, umctl: UMCTL_1MHZ_38400, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0, urxe: 1, utxe: 0} };
 
 
 #endif
index 55ff4ac5ccc591a41261251bbef49c01a390c12f..dc93e52a54526cb06da6cbd924cd0c9b496a49e7 100644 (file)
@@ -4,11 +4,7 @@ module eyesIFXSerialP {
  uses interface Resource;
 }
 implementation {
-  //msp430_uart_config_t msp430_uart_eyes_config = {ubr: UBR_1MHZ_115200, umctl: UMCTL_1MHZ_115200, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0};
-  
-  // when the tda5250 is in receive mode we get problems with 115200 baud 
-  // on the serial line ...
-  msp430_uart_config_t msp430_uart_eyes_config = {ubr: UBR_1MHZ_57600, umctl: UMCTL_1MHZ_57600, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0};
+  msp430_uart_union_config_t msp430_uart_eyes_config = { {ubr: UBR_1MHZ_57600, umctl: UMCTL_1MHZ_57600, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0, urxe: 1, utxe: 1} };
 
   command error_t StdControl.start(){
     return call Resource.immediateRequest();
@@ -19,7 +15,7 @@ implementation {
   }
   event void Resource.granted(){}
 
-  async command msp430_uart_config_t* Msp430UartConfigure.getConfig() {
+  async command msp430_uart_union_config_t* Msp430UartConfigure.getConfig() {
     return &msp430_uart_eyes_config;
   }
 }
index 084b0d02a0de25fc644bfff883e97f759772500c..2f187dced352210795e6c66a185acef38686741b 100644 (file)
 #include "Serial.h"
 #include "tda5250_message.h"
 
+#ifdef TOSH_DATA_LENGTH
+#undef TOSH_DATA_LENGTH
+#endif
+
+#define TOSH_DATA_LENGTH 48
+
 typedef union message_header_t {
   tda5250_header_t radio;
   serial_header_t serial;
index 0a576cba2ff170b2d631483fb8ee794ef68d0564..304386eb0ba127002472569e1fc780147f23833d 100644 (file)
@@ -54,11 +54,9 @@ generic configuration RssiSensorVccC()
 implementation
 {
     components SensorSettingsC as Settings;
-    components RssiSensorVccP as RssiSensor;
-    components new Msp430Adc12ClientC() as AdcClient;
+    components new AdcReadNowClientC() as AdcReadNowClient;
     
-    ReadNow = RssiSensor;
-    ReadNowResource = RssiSensor;
-    RssiSensor.SubResource -> AdcClient;
-    RssiSensor.SingleChannel -> AdcClient;
+    ReadNow = AdcReadNowClient;
+    ReadNowResource = AdcReadNowClient;
+    AdcReadNowClient.AdcConfigure -> Settings.AdcConfigure[RSSI_SENSOR_VCC];
 }
diff --git a/tos/platforms/eyesIFX/sensors/RssiSensorVccP.nc b/tos/platforms/eyesIFX/sensors/RssiSensorVccP.nc
deleted file mode 100644 (file)
index 6045941..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- mode:c++ -*-
- * Copyright (c) 2004, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright 
- *   notice, this list of conditions and the following disclaimer in the 
- *   documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names 
- *   of its contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-/** 
- *
- * Please refer to TEP 109 for more information about this component and its
- * intended use. This component provides platform-independent access to the
- * RSSI sensor exported by the TDA5250 radio on the eyesIFXv{1,2} platform.
- * Note: The radio must be configured to output the RSSI on the pin!
- *
- * @author Jan Hauer
- */
-
-#include <sensors.h>
-
-module RssiSensorVccP
-{
-    provides {
-        interface ReadNow<uint16_t> as ReadNow;
-        interface Resource as ReadNowResource;
-    }
-    uses {
-        interface Resource as SubResource;
-        interface Msp430Adc12SingleChannel as SingleChannel;
-    }
-}
-implementation
-{
-    async command error_t ReadNow.read() {
-        return call SingleChannel.getData();
-    }
-    
-    async event error_t SingleChannel.singleDataReady(uint16_t data) {
-      signal ReadNow.readDone(SUCCESS, data);
-      return FAIL;  
-    }
-
-    async event uint16_t* SingleChannel.multipleDataReady(uint16_t buffer[], uint16_t numSamples){
-      return 0;
-    }
-    
-    async command error_t ReadNowResource.request() {
-        return call SubResource.request();
-    }
-    
-    async command error_t ReadNowResource.immediateRequest() {
-        error_t res = call SubResource.immediateRequest();
-        if(res == SUCCESS) {
-            res = call SingleChannel.configureSingle(&sensorconfigurations[RSSI_SENSOR_VCC]);
-            if(res != SUCCESS) call SubResource.release();
-        }
-        return res;
-    }
-
-    event void SubResource.granted() {
-        call SingleChannel.configureSingle(&sensorconfigurations[RSSI_SENSOR_VCC]);
-        signal ReadNowResource.granted();
-    }
-
-    async command error_t ReadNowResource.release() {
-        return call SubResource.release();
-    }
-    
-    async command bool ReadNowResource.isOwner() {
-        return call SubResource.isOwner();
-    }
-}
index 4774732176976dd99b73f59971be540b0b5b48ed..261dbf8bd4a6e3356f6d6c5deb58bab6afdbba8a 100644 (file)
@@ -7,15 +7,21 @@ push( @includes, qw(
 
   %T/platforms/telosa
   %T/platforms/telosa/chips/cc2420
+  %T/platforms/telosa/chips/s1087
+  %T/platforms/telosa/chips/s10871
+  %T/platforms/telosa/chips/sht11
   %T/chips/cc2420
   %T/chips/msp430
   %T/chips/msp430/adc12
-  %T/chips/msp430/bus
   %T/chips/msp430/pins
   %T/chips/msp430/timer
+  %T/chips/msp430/usart
+  %T/chips/msp430/sensors
+  %T/chips/sht11  
   %T/lib/timer
   %T/lib/serial
   %T/lib/adc
+  %T/lib/power
 
 ) );
 
index 9d4f36082f261f9f44df61ee6ac2156c423323e9..cf5eee2d18c02cbd357d69f5d6fb3d7cd6f95271 100644 (file)
@@ -5,7 +5,7 @@ module TelosSerialP {
 }
 implementation {
   
-  msp430_uart_config_t msp430_uart_telos_config = {ubr: UBR_1MHZ_115200, umctl: UMCTL_1MHZ_115200, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0};
+  msp430_uart_union_config_t msp430_uart_telos_config = { {ubr: UBR_1MHZ_115200, umctl: UMCTL_1MHZ_115200, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0, utxe : 1, urxe : 1} };
 
   command error_t StdControl.start(){
     return call Resource.immediateRequest();
@@ -16,7 +16,7 @@ implementation {
   }
   event void Resource.granted(){}
 
-  async command msp430_uart_config_t* Msp430UartConfigure.getConfig() {
+  async command msp430_uart_union_config_t* Msp430UartConfigure.getConfig() {
     return &msp430_uart_telos_config;
   }
   
index 94709258659523ca9d8e910308c2c1827fe9e0a9..0222530cf1ed89d870d5f421eccf08a6f3771741 100644 (file)
@@ -5,7 +5,7 @@ module TinyNodeSerialP {
 }
 implementation {
 
-  msp430_uart_config_t msp430_uart_tinynode_config = {ubr: UBR_1MHZ_115200, umctl: UMCTL_1MHZ_115200, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0};
+  msp430_uart_union_config_t msp430_uart_tinynode_config = {{ubr: UBR_1MHZ_115200, umctl: UMCTL_1MHZ_115200, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0, utxe : 1, urxe : 1}};
   
   
   command error_t StdControl.start(){
@@ -19,7 +19,7 @@ implementation {
 
   event void Resource.granted(){}
   
-  async command msp430_uart_config_t* Msp430UartConfigure.getConfig() {
+  async command msp430_uart_union_config_t* Msp430UartConfigure.getConfig() {
     return &msp430_uart_tinynode_config;
   }
 
index 01b773416ca7ca825b4c1ccf698a6cc7bd779bcd..34edc15b247fc65c017d2436bbceb532a755b3e3 100644 (file)
@@ -42,6 +42,7 @@
  */
 
 configuration HalSensirionSht11C {
+  provides interface SplitControl;
   provides interface Resource[ uint8_t client ];
   provides interface SensirionSht11[ uint8_t client ];
 }
@@ -50,10 +51,12 @@ implementation {
   SensirionSht11 = SensirionSht11LogicP;
 
   components HplSensirionSht11C;
+  SplitControl = HplSensirionSht11C;
   Resource = HplSensirionSht11C.Resource;
   SensirionSht11LogicP.DATA -> HplSensirionSht11C.DATA;
   SensirionSht11LogicP.CLOCK -> HplSensirionSht11C.SCK;
   SensirionSht11LogicP.InterruptDATA -> HplSensirionSht11C.InterruptDATA;
+
   
   components new TimerMilliC();
   SensirionSht11LogicP.Timer -> TimerMilliC;
index 4cc85246ce7cee9bcf00bb7a3c873fa76b52a291..b32e5f6329d60a737371684142ac01d503a17cca 100644 (file)
@@ -43,6 +43,7 @@
 #include <im2sb.h>
 
 configuration HplSensirionSht11C {
+  provides interface SplitControl;
   provides interface Resource[ uint8_t id ];
   provides interface GeneralIO as DATA;
   provides interface GeneralIO as SCK;
@@ -55,6 +56,15 @@ implementation {
   SCK = GeneralIOC.GeneralIO[GPIO_SHT11_CLK];
   InterruptDATA = GeneralIOC.GpioInterrupt[GPIO_SHT11_DATA];
 
+  components HplSensirionSht11P;
+  SplitControl = HplSensirionSht11P;
+  
+  components new TimerMilliC();
+  components HplPXA27xGPIOC;
+  HplSensirionSht11P.Timer -> TimerMilliC;
+  HplSensirionSht11P.DATA -> HplPXA27xGPIOC.HplPXA27xGPIOPin[GPIO_SHT11_DATA];
+  HplSensirionSht11P.SCK -> HplPXA27xGPIOC.HplPXA27xGPIOPin[GPIO_SHT11_CLK];
+  
   components new SimpleFcfsArbiterC( "Sht11.Resource" ) as Arbiter;
   Resource = Arbiter;
 }
index 075d68686a2955729e6de507f358fb0b1dc5e94c..ef6faa7123a1b9dae7b6746d8c2896d6aa30455b 100644 (file)
@@ -42,8 +42,8 @@
 module HplSensirionSht11P {
   provides interface SplitControl;
   uses interface Timer<TMilli>;
-  uses interface HPlPXA27xGPIOPin as DATA;
-  uses interface HPLPXA27xGPIOPin as SCK;
+  uses interface HplPXA27xGPIOPin as DATA;
+  uses interface HplPXA27xGPIOPin as SCK;
 }
 implementation {
   task void stopTask();
@@ -71,5 +71,8 @@ implementation {
   task void stopTask() {
     signal SplitControl.stopDone( SUCCESS );
   }
+
+  async event void DATA.interruptGPIOPin() { return; }
+  async event void SCK.interruptGPIOPin() { return; }
 }
 
index f03d2c69c645d6608a46dca31f9c3031e802f6cb..7f7bdbd4140c0f9962b6162c980b3b8d5afa3e1f 100644 (file)
@@ -47,7 +47,11 @@ implementation {
   Resource = Arbiter;
 
   components new HplMAX136xLogicP(MAX136_SLAVE_ADDR) as Logic;
-  MainC.SoftwareInit -> Logic;
+  //MainC.SoftwareInit -> Logic;
+
+ components GeneralIOC;
+  Logic.InterruptAlert -> GeneralIOC.GpioInterrupt[GPIO_MAX1363_ANALOG_INT];
+  Logic.InterruptPin -> GeneralIOC.GeneralIO[GPIO_MAX1363_ANALOG_INT];
 
   components new HalPXA27xI2CMasterC(TRUE) as I2CC;
   Logic.I2CPacket -> I2CC;
@@ -55,9 +59,12 @@ implementation {
   components MAX136xInternalP as Internal;
   HplMAX136x = Internal.HplMAX136x;
   Internal.ToHPLC -> Logic.HplMAX136x;
-
+  Internal.SubInit -> Logic.Init;
+  Internal.InterruptAlert -> GeneralIOC.GpioInterrupt[GPIO_MAX1363_ANALOG_INT];
+  MainC.SoftwareInit -> Internal.Init;
   SplitControl = Logic;
 
   components HplPXA27xGPIOC;
   I2CC.I2CSCL -> HplPXA27xGPIOC.HplPXA27xGPIOPin[I2C_SCL];
   I2CC.I2CSDA -> HplPXA27xGPIOC.HplPXA27xGPIOPin[I2C_SDA];
index 7c5e182cd12f3e204fe1fb9d26e27826b977b655..ce873891c2d9e44256dd940fdfaa11daff314a91 100644 (file)
  * @author Phil Buonadonna
  */
 module MAX136xInternalP {
+  provides interface Init;
   provides interface HplMAX136x[uint8_t id];
+  uses interface Init as SubInit;
   uses interface HplMAX136x as ToHPLC;
+  uses interface GpioInterrupt as InterruptAlert;
 }
 
 implementation {
   uint8_t currentId;
 
+  command error_t Init.init() {
+    call SubInit.init();
+    // The Intel Mote 2 Sensorboard multiplexes the MAX136 interrupt through a NAND
+    // gate.  Need to override the edge trigger from the driver default
+    call InterruptAlert.enableRisingEdge();
+    return SUCCESS;
+  }
+
   command error_t HplMAX136x.measureChannels[uint8_t id](uint8_t *buf, uint8_t len) {
     currentId = id;
     return call ToHPLC.measureChannels(buf, len);
@@ -66,6 +77,8 @@ implementation {
     signal HplMAX136x.readStatusDone[currentId](error, buf);
   }
 
+  async event void InterruptAlert.fired() {}
+
   default async event void HplMAX136x.measureChannelsDone[uint8_t id]( error_t error, uint8_t *buf, uint8_t len ) {}
   default async event void HplMAX136x.setConfigDone[uint8_t id]( error_t error , uint8_t *cfgbuf, uint8_t len) {}
   default async event void HplMAX136x.alertThreshold[uint8_t id]() {}
diff --git a/tos/sensorboards/im2sb/README.txt b/tos/sensorboards/im2sb/README.txt
new file mode 100644 (file)
index 0000000..1d9ed60
--- /dev/null
@@ -0,0 +1,15 @@
+Intel Mote 2 Demo Sensorboard Release Notes
+
+* The configuration provided assumes the following I2C addresses:
+
+  TSL2561 - 0x49
+  TMP175  - 0X4A
+  MAX136  - 0x34
+
+These address assignments are compatible with the DS2745 on the optional battery board.  Modify the address assignments as needed.
+
+* The TMP175 anbd TSL2561 interrupts will work ONLY IF the board has been modified to include a pullup resistor on their associated interrupt lines. Some boards do not include these resistors.
+
+
+
+
index d5e25a391c49a1d8f6e061696a46128a17d11232..9fa48fcb076918f6c7389a49ed19da2892574504 100644 (file)
  */
 
 generic configuration SensirionSht11C() {
+  provides interface SplitControl;
   provides interface Read<uint16_t> as Temperature;
   provides interface Read<uint16_t> as Humidity;
-  //provides interface HalSht11Advanced;
+  provides interface HalSht11Advanced;
 }
 implementation {
   components new SensirionSht11ReaderP();
@@ -59,14 +60,15 @@ implementation {
   enum { TEMP_KEY = unique("Sht11.Resource") };
   enum { HUM_KEY = unique("Sht11.Resource") };
 
+  SplitControl = HalSensirionSht11C;
   SensirionSht11ReaderP.TempResource -> HalSensirionSht11C.Resource[ TEMP_KEY ];
   SensirionSht11ReaderP.Sht11Temp -> HalSensirionSht11C.SensirionSht11[ TEMP_KEY ];
   SensirionSht11ReaderP.HumResource -> HalSensirionSht11C.Resource[ HUM_KEY ];
   SensirionSht11ReaderP.Sht11Hum -> HalSensirionSht11C.SensirionSht11[ HUM_KEY ];
 
-  //enum { ADV_KEY = unique("Sht11.Resource") };
-  //components HalSht11ControlP;
-  //HalSht11Advanced = HalSht11ControlP;
-  //HalSht11ControlP.Resource -> HalSensirionSht11C.Resource[ ADV_KEY ];
-  //HalSht11ControlP.SensirionSht11 -> HalSensirionSht11C.SensirionSht11[ ADV_KEY ];
+  enum { ADV_KEY = unique("Sht11.Resource") };
+  components HalSht11ControlP;
+  HalSht11Advanced = HalSht11ControlP;
+  HalSht11ControlP.Resource -> HalSensirionSht11C.Resource[ ADV_KEY ];
+  HalSht11ControlP.SensirionSht11 -> HalSensirionSht11C.SensirionSht11[ ADV_KEY ];
 }
index a6dcd00fa1cdbdcb287cbe5b5c3b8a62b5e6c6f6..4ab2610f826b2aac6194acd12aa10f9fe786acec 100644 (file)
@@ -66,6 +66,7 @@ implementation {
   HplTSL256x = Internal.HplTSL256x;
   Internal.ToHPLC -> Logic.HplTSL256x;
   Internal.SubInit -> Logic.Init;
+  Internal.InterruptAlert -> GeneralIOC.GpioInterrupt[GPIO_TSL2561_LIGHT_INT];
   SplitControl = Logic;
   MainC.SoftwareInit -> Internal;
 
index c797c06f36ed831ce8f21d1803f641289cd35998..1bbbad46ccadc4bbde1efdf571bec79ff25c6d87 100644 (file)
@@ -113,7 +113,7 @@ implementation {
     signal HplTSL256x.alertThreshold[currentId]();
   }
 
-  async event InterruptAlert.fired() {}
+  async event void InterruptAlert.fired() {}
 
   default async event void HplTSL256x.measureCh0Done[uint8_t id]( error_t error, uint16_t val ){ return; }
   default async event void HplTSL256x.measureCh1Done[uint8_t id]( error_t error, uint16_t val ){ return; }
diff --git a/tos/sensorboards/im2sb/examples/Makefile b/tos/sensorboards/im2sb/examples/Makefile
new file mode 100644 (file)
index 0000000..a7f2208
--- /dev/null
@@ -0,0 +1,7 @@
+
+TestSensor.class: $(wildcard *.java) TestSensorMsg.java
+       javac *.java
+
+TestSensorMsg.java:
+       mig java -target=null $(CFLAGS) -java-classname=TestSensorMsg TestSensor.h TestSensorMsg -o $@
+
diff --git a/tos/sensorboards/im2sb/examples/TestLis3l02dq/Makefile b/tos/sensorboards/im2sb/examples/TestLis3l02dq/Makefile
new file mode 100644 (file)
index 0000000..19fc878
--- /dev/null
@@ -0,0 +1,5 @@
+COMPONENT=TestSensorC
+
+SENSORBOARD ?= im2sb
+
+include $(MAKERULES)
\ No newline at end of file
diff --git a/tos/sensorboards/im2sb/examples/TestLis3l02dq/TestSensorC.nc b/tos/sensorboards/im2sb/examples/TestLis3l02dq/TestSensorC.nc
new file mode 100644 (file)
index 0000000..cb60fb9
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the STMicroelectronics LIS3L02DQ . Originally 
+ * developed for the Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+
+configuration TestSensorC{}
+implementation {
+  components MainC, TestSensorM, LedsC;
+  components new LIS3L02DQC() as Sensor;
+
+  MainC.Boot <- TestSensorM;
+  TestSensorM.Leds -> LedsC;
+
+  TestSensorM.ReadAccelX -> Sensor.AccelX;
+  TestSensorM.ReadAccelY -> Sensor.AccelY;
+  TestSensorM.ReadAccelZ -> Sensor.AccelZ;
+  TestSensorM.SubControl -> Sensor.SplitControl;
+  TestSensorM.Advanced -> Sensor.HalLIS3L02DQAdvanced;
+
+  components new TimerMilliC() as Timer0;
+  TestSensorM.Timer0 -> Timer0;
+
+  components SerialActiveMessageC as AM;
+  TestSensorM.AMSend -> AM.AMSend[AM_TESTSENSORMSG];
+  TestSensorM.Packet -> AM;
+  TestSensorM.SubControl -> AM;
+}
diff --git a/tos/sensorboards/im2sb/examples/TestLis3l02dq/TestSensorM.nc b/tos/sensorboards/im2sb/examples/TestLis3l02dq/TestSensorM.nc
new file mode 100644 (file)
index 0000000..7b54e38
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the STMicroelectronics LIS3L02DQ . Originally 
+ * developed for the Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+#include "../TestSensor.h"
+
+/* Uncomment the flag below to test the interrupt functions of the chip */
+//#define USE_INTERRUPTS
+
+module TestSensorM
+{
+  uses interface Boot;
+  
+  uses interface Timer<TMilli> as Timer0;
+
+  uses interface Read<uint16_t> as ReadAccelX;
+  uses interface Read<uint16_t> as ReadAccelY;
+  uses interface Read<uint16_t> as ReadAccelZ;
+  uses interface SplitControl as SubControl;
+
+  uses interface HalLIS3L02DQAdvanced as Advanced;
+
+  uses interface Leds;
+  uses interface AMSend;
+  uses interface Packet;
+}
+implementation
+{
+  message_t packet;
+
+  event void Boot.booted() {
+    call SubControl.start();
+  }
+
+  event void Timer0.fired() {
+    call ReadAccelX.read();
+    call ReadAccelY.read();
+    call ReadAccelZ.read();
+  }
+
+  event void SubControl.startDone(error_t result) {
+#ifndef USE_INTERRUPTS
+   call Timer0.startPeriodic( 100 );
+#else
+    call Advanced.setTLow(0xA0);
+#endif
+  }
+
+  event void SubControl.stopDone(error_t result) { }
+  
+  event void ReadAccelX.readDone(error_t result, uint16_t val) {
+    TestSensorMsg *rcm = (TestSensorMsg *)call Packet.getPayload(&packet, NULL);
+    call Leds.led0Toggle();    
+
+    if (call Packet.maxPayloadLength() < sizeof(TestSensorMsg)) {
+      return;
+    }
+    rcm->value = val;
+
+    call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(TestSensorMsg));
+  }
+
+  event void ReadAccelY.readDone(error_t result, uint16_t val) {
+    if(val > 0x800)
+      call Leds.led1Toggle();    
+  }
+  event void ReadAccelZ.readDone(error_t result, uint16_t val) {
+    if(val > 0x800)
+      call Leds.led2Toggle();    
+  }
+
+  event void Advanced.setDecimationDone(error_t error) {}
+  event void Advanced.enableAxisDone(error_t error) {}
+  event void Advanced.enableAlertDone(error_t error) {
+    call Leds.led2Toggle();
+  }
+  event void Advanced.getAlertSourceDone(error_t error, uint8_t vector) {}
+  event void Advanced.setTLowDone(error_t error) {
+    call Advanced.setTHigh(0xF);
+  }
+  event void Advanced.setTHighDone(error_t error) {
+    call Advanced.enableAlert(LIS_AFLAGS_HIGH,
+                             LIS_AFLAGS_NONE,
+                             LIS_AFLAGS_NONE,
+                             FALSE);
+  }
+
+  event void Advanced.alertThreshold() {
+    call Leds.led0Toggle();
+  }
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
+    return;
+  }
+}
diff --git a/tos/sensorboards/im2sb/examples/TestMax136/Makefile b/tos/sensorboards/im2sb/examples/TestMax136/Makefile
new file mode 100644 (file)
index 0000000..19fc878
--- /dev/null
@@ -0,0 +1,5 @@
+COMPONENT=TestSensorC
+
+SENSORBOARD ?= im2sb
+
+include $(MAKERULES)
\ No newline at end of file
diff --git a/tos/sensorboards/im2sb/examples/TestMax136/TestSensorC.nc b/tos/sensorboards/im2sb/examples/TestMax136/TestSensorC.nc
new file mode 100644 (file)
index 0000000..0ec2b79
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the Maxim MAX136X. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+
+configuration TestSensorC{}
+implementation {
+  components MainC, TestSensorM, LedsC;
+  components new MAX136xC() as Sensor;
+
+  MainC.Boot <- TestSensorM;
+  TestSensorM.Leds -> LedsC;
+
+  TestSensorM.ADC -> Sensor;
+  TestSensorM.SensorControl -> Sensor.SplitControl;
+  TestSensorM.HalMAX136xAdvanced -> Sensor;
+
+  components new TimerMilliC() as Timer0;
+  TestSensorM.Timer0 -> Timer0;
+
+  components SerialActiveMessageC as AM;
+  TestSensorM.AMSend -> AM.AMSend[AM_TESTSENSORMSG];
+  TestSensorM.Packet -> AM;
+  TestSensorM.MsgControl -> AM;
+}
diff --git a/tos/sensorboards/im2sb/examples/TestMax136/TestSensorM.nc b/tos/sensorboards/im2sb/examples/TestMax136/TestSensorM.nc
new file mode 100644 (file)
index 0000000..f069be8
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the Maxim MAX136X. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+#include "MAX136x.h"
+#include "../TestSensor.h"
+
+/* Uncomment the flag below to test the interrupt functions of the chip */
+//#define USE_INTERRUPTS
+
+module TestSensorM
+{
+  uses interface Boot;
+  
+  uses interface Timer<TMilli> as Timer0;
+
+  uses interface Read<max136x_data_t> as ADC;
+  uses interface HalMAX136xAdvanced;
+  uses interface SplitControl as SensorControl;
+  uses interface SplitControl as MsgControl;
+
+  uses interface Leds;
+  uses interface AMSend;
+  uses interface Packet;
+}
+
+implementation
+{
+  message_t packet;
+
+  event void Boot.booted() {
+    call SensorControl.start();
+  }
+
+  event void Timer0.fired() {
+    call ADC.read();
+  }
+
+  event void SensorControl.startDone(error_t result) {
+    call MsgControl.start();
+  }
+
+  event void SensorControl.stopDone(error_t result) { return; }
+
+
+  event void MsgControl.startDone(error_t result) {
+#ifndef USE_INTERRUPTS
+    call Timer0.startPeriodic( 100 );
+#else
+    uint16_t chan0Low = 200;
+    uint16_t chan0High = 700;
+    uint8_t ucThresholds[12];
+    uint8_t i;
+
+    ucThresholds[0] = (chan0Low >> 4);
+    ucThresholds[1] = ( ((chan0Low & 0xF) << 4) | (chan0High >> 8));
+    ucThresholds[2] = chan0High & 0xFF;
+    for (i=3;i<12;i+=3) {
+      ucThresholds[i] = 0x00;
+      ucThresholds[i+1] = 0x0F;
+      ucThresholds[i+2] = 0xFF;
+    }
+    call HalMAX136xAdvanced.setMonitorMode(0,0,MAX136X_DELAY_1_0,ucThresholds);
+#endif
+  }
+
+  event void MsgControl.stopDone(error_t result) { return; }
+  
+  event void ADC.readDone(error_t result, max136x_data_t val) {
+    TestSensorMsg *rcm = (TestSensorMsg *)call Packet.getPayload(&packet, NULL);
+    call Leds.led0Toggle();
+    if (call Packet.maxPayloadLength() < sizeof(TestSensorMsg)) {
+      return;
+    }
+    rcm->value = val & 0x3FF;
+
+    call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(TestSensorMsg));
+  }
+
+  event void HalMAX136xAdvanced.setScanModeDone(error_t error) {}
+  event void HalMAX136xAdvanced.setMonitorModeDone(error_t error) {
+    call Leds.set(LEDS_LED1);
+    call HalMAX136xAdvanced.enableAlert(TRUE);
+  }
+  event void HalMAX136xAdvanced.setConversionModeDone(error_t error) {}  
+  event void HalMAX136xAdvanced.setClockDone(error_t error) {} 
+  event void HalMAX136xAdvanced.setRefDone(error_t error) {}
+  event void HalMAX136xAdvanced.getStatusDone(error_t error, uint8_t status, 
+                                             max136x_data_t data) {}
+  event void HalMAX136xAdvanced.enableAlertDone(error_t error) {
+    call Leds.set(LEDS_LED1 | LEDS_LED2);
+    return;
+  }
+  event void HalMAX136xAdvanced.alertThreshold() {
+    call Leds.led0Toggle();
+    call HalMAX136xAdvanced.enableAlert(TRUE); // Clears interrupt
+    return;
+  }
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error) { return; }
+}
diff --git a/tos/sensorboards/im2sb/examples/TestSensor.h b/tos/sensorboards/im2sb/examples/TestSensor.h
new file mode 100644 (file)
index 0000000..4cb2637
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef TEST_SENSOR_H\r
+#define TEST_SENSOR_H\r
+\r
+typedef nx_struct TestSensorMsg {\r
+  nx_uint16_t value;\r
+} TestSensorMsg;\r
+\r
+enum {\r
+  AM_TESTSENSORMSG = 10,\r
+};\r
+\r
+#endif\r
diff --git a/tos/sensorboards/im2sb/examples/TestSensor.java b/tos/sensorboards/im2sb/examples/TestSensor.java
new file mode 100644 (file)
index 0000000..625978d
--- /dev/null
@@ -0,0 +1,108 @@
+/*                                                                     tab:4
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/**
+ * Java-side application for testing serial port communication.
+ * 
+ *
+ * @author Phil Levis <pal@cs.berkeley.edu>
+ * @date August 12 2005
+ */
+
+import java.io.IOException;
+
+import net.tinyos.message.*;
+import net.tinyos.packet.*;
+import net.tinyos.util.*;
+
+public class TestSensor implements MessageListener {
+
+    private MoteIF moteIF;
+  
+    public TestSensor(MoteIF moteIF) {
+                               this.moteIF = moteIF;
+                               this.moteIF.registerListener(new TestSensorMsg(), this);
+    }
+
+    public void sendPackets() {
+                               int counter = 0;
+                               TestSensorMsg payload = new TestSensorMsg();
+    
+                               try {
+                                               while (true) {
+                                                               /*
+                                                                       System.out.println("Sending packet " + counter);
+                                                                       payload.set_counter(counter);
+                                                                       moteIF.send(0, payload);
+                                                                       counter++;
+                                                               */
+                                                               try {Thread.sleep(1000);}
+                                                               catch (InterruptedException exception) {}
+                                               }
+                               }
+                               catch (Exception exception) {
+                                               System.err.println("Exception thrown when sending packets. Exiting.");
+                                               System.err.println(exception);
+                               }
+    }
+
+    public void messageReceived(int to, Message message) {
+                               TestSensorMsg msg = (TestSensorMsg)message;
+                               System.out.println("Received packet. Value= " + msg.get_value());
+    }
+  
+    private static void usage() {
+                               System.err.println("usage: TestSensor [-comm <source>]");
+    }
+  
+    public static void main(String[] args) throws Exception {
+                               String source = null;
+                               if (args.length == 2) {
+                                               if (!args[0].equals("-comm")) {
+                                                               usage();
+                                                               System.exit(1);
+                                               }
+                                               source = args[1];
+                               }
+                               else if (args.length != 0) {
+                                               usage();
+                                               System.exit(1);
+                               }
+    
+                               PhoenixSource phoenix;
+    
+                               if (source == null) {
+                                               phoenix = BuildSource.makePhoenix(PrintStreamMessenger.err);
+                               }
+                               else {
+                                               phoenix = BuildSource.makePhoenix(source, PrintStreamMessenger.err);
+                               }
+
+                               MoteIF mif = new MoteIF(phoenix);
+                               TestSensor serial = new TestSensor(mif);
+                               serial.sendPackets();
+    }
+
+
+}
diff --git a/tos/sensorboards/im2sb/examples/TestSensorMsg.java b/tos/sensorboards/im2sb/examples/TestSensorMsg.java
new file mode 100644 (file)
index 0000000..461de73
--- /dev/null
@@ -0,0 +1,158 @@
+/**
+ * This class is automatically generated by mig. DO NOT EDIT THIS FILE.
+ * This class implements a Java interface to the 'TestSensorMsg'
+ * message type.
+ */
+
+public class TestSensorMsg extends net.tinyos.message.Message {
+
+    /** The default size of this message type in bytes. */
+    public static final int DEFAULT_MESSAGE_SIZE = 2;
+
+    /** The Active Message type associated with this message. */
+    public static final int AM_TYPE = 10;
+
+    /** Create a new TestSensorMsg of size 2. */
+    public TestSensorMsg() {
+        super(DEFAULT_MESSAGE_SIZE);
+        amTypeSet(AM_TYPE);
+    }
+
+    /** Create a new TestSensorMsg of the given data_length. */
+    public TestSensorMsg(int data_length) {
+        super(data_length);
+        amTypeSet(AM_TYPE);
+    }
+
+    /**
+     * Create a new TestSensorMsg with the given data_length
+     * and base offset.
+     */
+    public TestSensorMsg(int data_length, int base_offset) {
+        super(data_length, base_offset);
+        amTypeSet(AM_TYPE);
+    }
+
+    /**
+     * Create a new TestSensorMsg using the given byte array
+     * as backing store.
+     */
+    public TestSensorMsg(byte[] data) {
+        super(data);
+        amTypeSet(AM_TYPE);
+    }
+
+    /**
+     * Create a new TestSensorMsg using the given byte array
+     * as backing store, with the given base offset.
+     */
+    public TestSensorMsg(byte[] data, int base_offset) {
+        super(data, base_offset);
+        amTypeSet(AM_TYPE);
+    }
+
+    /**
+     * Create a new TestSensorMsg using the given byte array
+     * as backing store, with the given base offset and data length.
+     */
+    public TestSensorMsg(byte[] data, int base_offset, int data_length) {
+        super(data, base_offset, data_length);
+        amTypeSet(AM_TYPE);
+    }
+
+    /**
+     * Create a new TestSensorMsg embedded in the given message
+     * at the given base offset.
+     */
+    public TestSensorMsg(net.tinyos.message.Message msg, int base_offset) {
+        super(msg, base_offset, DEFAULT_MESSAGE_SIZE);
+        amTypeSet(AM_TYPE);
+    }
+
+    /**
+     * Create a new TestSensorMsg embedded in the given message
+     * at the given base offset and length.
+     */
+    public TestSensorMsg(net.tinyos.message.Message msg, int base_offset, int data_length) {
+        super(msg, base_offset, data_length);
+        amTypeSet(AM_TYPE);
+    }
+
+    /**
+    /* Return a String representation of this message. Includes the
+     * message type name and the non-indexed field values.
+     */
+    public String toString() {
+      String s = "Message <TestSensorMsg> \n";
+      try {
+        s += "  [value=0x"+Long.toHexString(get_value())+"]\n";
+      } catch (ArrayIndexOutOfBoundsException aioobe) { /* Skip field */ }
+      return s;
+    }
+
+    // Message-type-specific access methods appear below.
+
+    /////////////////////////////////////////////////////////
+    // Accessor methods for field: value
+    //   Field type: int, unsigned
+    //   Offset (bits): 0
+    //   Size (bits): 16
+    /////////////////////////////////////////////////////////
+
+    /**
+     * Return whether the field 'value' is signed (false).
+     */
+    public static boolean isSigned_value() {
+        return false;
+    }
+
+    /**
+     * Return whether the field 'value' is an array (false).
+     */
+    public static boolean isArray_value() {
+        return false;
+    }
+
+    /**
+     * Return the offset (in bytes) of the field 'value'
+     */
+    public static int offset_value() {
+        return (0 / 8);
+    }
+
+    /**
+     * Return the offset (in bits) of the field 'value'
+     */
+    public static int offsetBits_value() {
+        return 0;
+    }
+
+    /**
+     * Return the value (as a int) of the field 'value'
+     */
+    public int get_value() {
+        return (int)getUIntBEElement(offsetBits_value(), 16);
+    }
+
+    /**
+     * Set the value of the field 'value'
+     */
+    public void set_value(int value) {
+        setUIntBEElement(offsetBits_value(), 16, value);
+    }
+
+    /**
+     * Return the size, in bytes, of the field 'value'
+     */
+    public static int size_value() {
+        return (16 / 8);
+    }
+
+    /**
+     * Return the size, in bits, of the field 'value'
+     */
+    public static int sizeBits_value() {
+        return 16;
+    }
+
+}
diff --git a/tos/sensorboards/im2sb/examples/TestSht11/README.txt b/tos/sensorboards/im2sb/examples/TestSht11/README.txt
new file mode 100644 (file)
index 0000000..98694b9
--- /dev/null
@@ -0,0 +1,7 @@
+Sht11 Test Sensor
+
+A simple application to demonstrate/test the SHT11 on the Intel Mote 2 sensorboard.
+
+NOTE: If using the debug/programming board you must set SW5 to either the 
+SPI or I2C settings for the SHT11 to work correctly.
+
diff --git a/tos/sensorboards/im2sb/examples/TestSht11/TestSensorC.nc b/tos/sensorboards/im2sb/examples/TestSht11/TestSensorC.nc
new file mode 100644 (file)
index 0000000..aa53b13
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the Sensirion SHT11. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+
+configuration TestSensorC{}
+implementation {
+  components MainC, TestSensorM, LedsC;
+  components new SensirionSht11C() as Sensor;
+
+  MainC.Boot <- TestSensorM;
+  TestSensorM.Leds -> LedsC;
+
+  TestSensorM.Temperature -> Sensor.Temperature;
+  TestSensorM.Humidity -> Sensor.Humidity;
+  TestSensorM.HalSht11Advanced -> Sensor;
+  TestSensorM.SensorControl -> Sensor.SplitControl;
+
+  components new TimerMilliC() as Timer0;
+  TestSensorM.Timer0 -> Timer0;
+
+  components SerialActiveMessageC as AM;
+  TestSensorM.AMSend -> AM.AMSend[AM_TESTSENSORMSG];
+  TestSensorM.Packet -> AM;
+  TestSensorM.MsgControl -> AM;
+}
diff --git a/tos/sensorboards/im2sb/examples/TestSht11/TestSensorM.nc b/tos/sensorboards/im2sb/examples/TestSht11/TestSensorM.nc
new file mode 100644 (file)
index 0000000..4ec1f90
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the TAOS Tsl2561. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+#include "../TestSensor.h"
+
+module TestSensorM
+{
+  uses interface Boot;
+  
+  uses interface Timer<TMilli> as Timer0;
+
+  uses interface Read<uint16_t> as Temperature;
+  uses interface Read<uint16_t> as Humidity;  
+  uses interface HalSht11Advanced;
+  uses interface SplitControl as SensorControl;
+  uses interface SplitControl as MsgControl;
+
+  uses interface Leds;
+  uses interface AMSend;
+  uses interface Packet;
+}
+
+implementation
+{
+  message_t packet;
+
+  event void Boot.booted() {
+    call SensorControl.start();
+  }
+
+  event void SensorControl.startDone(error_t error) {
+    call MsgControl.start();
+  }
+
+  event void SensorControl.stopDone(error_t error) {  }
+
+  event void MsgControl.startDone(error_t error) {
+    call HalSht11Advanced.getVoltageStatus();
+    call Timer0.startPeriodic( 100 );
+  }
+
+  event void MsgControl.stopDone(error_t error) { }
+
+  event void Timer0.fired() {
+    //call Temperature.read();
+    call Humidity.read();
+  }
+
+  event void Temperature.readDone(error_t result, uint16_t val) {
+    call Leds.led0Toggle();
+  }
+
+  event void Humidity.readDone(error_t result, uint16_t val) {
+    TestSensorMsg *rcm = (TestSensorMsg *)call Packet.getPayload(&packet, NULL);
+    call Leds.led1Toggle();
+    if (call Packet.maxPayloadLength() < sizeof(TestSensorMsg)) {
+      return;
+    }
+    rcm->value = val;
+
+    call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(TestSensorMsg));
+  }
+
+  event void HalSht11Advanced.getVoltageStatusDone(error_t error, bool isLow) {}
+
+  event void HalSht11Advanced.setHeaterDone(error_t error) {}
+
+  event void HalSht11Advanced.setResolutionDone(error_t error) {}
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
+    return;
+  }
+
+}
diff --git a/tos/sensorboards/im2sb/examples/TestTmp175/Makefile b/tos/sensorboards/im2sb/examples/TestTmp175/Makefile
new file mode 100644 (file)
index 0000000..c21cfd0
--- /dev/null
@@ -0,0 +1,5 @@
+COMPONENT=TestSensorC
+CFLAGS += -I%T/lib/oski
+SENSORBOARD ?= im2sb
+
+include $(MAKERULES)
\ No newline at end of file
diff --git a/tos/sensorboards/im2sb/examples/TestTmp175/TestSensorC.nc b/tos/sensorboards/im2sb/examples/TestTmp175/TestSensorC.nc
new file mode 100644 (file)
index 0000000..68a2ffa
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the TI TMP175. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+
+configuration TestSensorC{}
+implementation {
+  components MainC, TestSensorM, LedsC;
+  components new TMP175C() as Sensor;
+
+  MainC.Boot <- TestSensorM;
+  TestSensorM.Leds -> LedsC;
+
+  TestSensorM.Temperature -> Sensor;
+  TestSensorM.SubControl -> Sensor.SplitControl;
+  TestSensorM.HalTMP175Advanced -> Sensor;
+
+  components new TimerMilliC() as Timer0;
+  TestSensorM.Timer0 -> Timer0;
+
+  components SerialActiveMessageC as AM;
+  TestSensorM.AMSend -> AM.AMSend[AM_TESTSENSORMSG];
+  TestSensorM.Packet -> AM;
+  TestSensorM.SubControl -> AM;
+}
diff --git a/tos/sensorboards/im2sb/examples/TestTmp175/TestSensorM.nc b/tos/sensorboards/im2sb/examples/TestTmp175/TestSensorM.nc
new file mode 100644 (file)
index 0000000..c06ad2c
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the TI TMP175. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+#include "../TestSensor.h"
+
+/* Uncomment the flag below to test the interrupt functions of the chip */
+//#define USE_INTERRUPTS
+
+module TestSensorM
+{
+  uses interface Boot;
+  
+  uses interface Timer<TMilli> as Timer0;
+
+  uses interface Read<uint16_t> as Temperature;
+  uses interface SplitControl as SubControl;
+
+  uses interface HalTMP175Advanced;
+
+  uses interface Leds;
+  uses interface AMSend;
+  uses interface Packet;
+}
+implementation
+{
+  uint8_t ledcount = 0;
+  message_t packet;
+
+  event void Boot.booted() {
+    call SubControl.start();
+  }
+
+  event void Timer0.fired() {
+    call Temperature.read();
+  }
+
+  event void SubControl.startDone(error_t result) {
+#ifdef USE_INTERRUPTS
+    call HalTMP175Advanced.setPolarity(TRUE);
+#else
+    call Timer0.startPeriodic( 100 );
+#endif
+  }
+
+  event void SubControl.stopDone(error_t result) { }
+  
+  event void Temperature.readDone(error_t result, uint16_t val) {
+    TestSensorMsg *rcm = (TestSensorMsg *)call Packet.getPayload(&packet, NULL);
+    call Leds.led0Toggle();
+
+    if (call Packet.maxPayloadLength() < sizeof(TestSensorMsg)) {
+      return;
+    }
+    rcm->value = val;
+
+    call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(TestSensorMsg));
+
+  }
+
+  event void HalTMP175Advanced.setTHighDone(error_t error) {
+    call HalTMP175Advanced.setTLow(352);
+  }
+  event void HalTMP175Advanced.setThermostatModeDone(error_t error){
+    call HalTMP175Advanced.setTHigh(448);
+  } 
+
+  event void HalTMP175Advanced.setPolarityDone(error_t error){
+    call HalTMP175Advanced.setThermostatMode(TRUE);
+  }
+  event void HalTMP175Advanced.setFaultQueueDone(error_t error){ return; }
+  event void HalTMP175Advanced.setResolutionDone(error_t error){ return; }
+  event void HalTMP175Advanced.setTLowDone(error_t error){
+    //call Timer0.startPeriodic( 1000 );
+    call Leds.led2Toggle();
+  }
+  event void HalTMP175Advanced.alertThreshold() {
+#ifdef USE_INTERRUPTS
+    call Temperature.read();
+    call Leds.led0Toggle();
+#endif
+  }
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
+    return;
+  }
+
+}
diff --git a/tos/sensorboards/im2sb/examples/TestTsl2561/Makefile b/tos/sensorboards/im2sb/examples/TestTsl2561/Makefile
new file mode 100644 (file)
index 0000000..19fc878
--- /dev/null
@@ -0,0 +1,5 @@
+COMPONENT=TestSensorC
+
+SENSORBOARD ?= im2sb
+
+include $(MAKERULES)
\ No newline at end of file
diff --git a/tos/sensorboards/im2sb/examples/TestTsl2561/TestSensorC.nc b/tos/sensorboards/im2sb/examples/TestTsl2561/TestSensorC.nc
new file mode 100644 (file)
index 0000000..e5ac78f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the TAOS Tsl2561. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+
+configuration TestSensorC{}
+implementation {
+  components MainC, TestSensorM, LedsC;
+  components new Tsl2561C() as Sensor;
+
+  MainC.Boot <- TestSensorM;
+  TestSensorM.Leds -> LedsC;
+
+  TestSensorM.ReadBroadband -> Sensor.BroadbandPhoto;
+  TestSensorM.SubControl -> Sensor.SplitControl;
+  TestSensorM.ReadIR -> Sensor.IRPhoto;
+  TestSensorM.HalTsl2561Advanced -> Sensor;
+
+  components new TimerMilliC() as Timer0;
+  TestSensorM.Timer0 -> Timer0;
+
+  components SerialActiveMessageC as AM;
+  TestSensorM.AMSend -> AM.AMSend[AM_TESTSENSORMSG];
+  TestSensorM.Packet -> AM;
+  TestSensorM.SubControl -> AM;
+}
diff --git a/tos/sensorboards/im2sb/examples/TestTsl2561/TestSensorM.nc b/tos/sensorboards/im2sb/examples/TestTsl2561/TestSensorM.nc
new file mode 100644 (file)
index 0000000..f172d15
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Demo application of the TAOS Tsl2561. Originally developed for the
+ * Intel Mote 2 sensorboard.
+ *
+ * @author Kaisen Lin
+ * @author Philip Buonadonna
+ */
+#include "../TestSensor.h"
+
+/* Uncomment the flag below to test the interrupt functions of the chip */
+//#define USE_INTERRUPTS
+
+module TestSensorM
+{
+  uses interface Boot;
+  
+  uses interface Timer<TMilli> as Timer0;
+
+  uses interface Read<uint16_t> as ReadIR;
+  uses interface Read<uint16_t> as ReadBroadband;
+  uses interface SplitControl as SubControl;
+
+  uses interface HalTsl2561Advanced;
+
+  uses interface Leds;
+  uses interface AMSend;
+  uses interface Packet;
+}
+implementation
+{
+  message_t packet;
+  uint8_t initCounter = 0;
+
+  event void Boot.booted() {
+    call SubControl.start();
+  }
+
+  event void Timer0.fired() {
+    call ReadBroadband.read();
+  }
+
+  event void SubControl.startDone(error_t result) {
+#ifndef USE_INTERRUPTS
+    call Timer0.startPeriodic( 100 );
+#else
+    call HalTsl2561Advanced.enableAlert(FALSE);
+#endif
+    return;
+  }
+
+  event void SubControl.stopDone(error_t result) { }
+  
+  event void ReadBroadband.readDone(error_t result, uint16_t val) {
+    TestSensorMsg *rcm = (TestSensorMsg *)call Packet.getPayload(&packet, NULL);
+
+    call Leds.led0Toggle();
+
+    if (call Packet.maxPayloadLength() < sizeof(TestSensorMsg)) {
+      return;
+    }
+    rcm->value = val;
+
+    call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(TestSensorMsg));
+  }
+  
+  event void ReadIR.readDone(error_t result, uint16_t val) { }
+  
+  event void HalTsl2561Advanced.setGainDone(error_t error) { }
+  event void HalTsl2561Advanced.setIntegrationDone(error_t error) { }
+
+  event void HalTsl2561Advanced.setPersistenceDone(error_t error) {
+    call HalTsl2561Advanced.enableAlert(TRUE);
+  }
+  event void HalTsl2561Advanced.setTLowDone(error_t error) {
+    call HalTsl2561Advanced.setTHigh(7000);
+  }
+  event void HalTsl2561Advanced.setTHighDone(error_t error) { 
+    call HalTsl2561Advanced.setPersistence(1);
+  }
+  event void HalTsl2561Advanced.enableAlertDone(error_t error) {
+    switch (initCounter) {
+    case 0:
+      call HalTsl2561Advanced.setTLow(200);
+      initCounter++;
+      break;
+    case 1:
+      call Leds.set(LEDS_LED2 | LEDS_LED0);    
+      initCounter++;
+      break;
+    default:
+      break;
+    }
+  }
+
+  event void HalTsl2561Advanced.alertThreshold() {
+    call Leds.led1Toggle();
+    call HalTsl2561Advanced.enableAlert(TRUE); // Clears interrupt
+  }
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
+    return;
+  }
+
+}
index a696b08a5aa05923188d7e42e89fd427c3bbb921..1b1cd72d1fb513fdb684e037a08bebe851f48b15 100644 (file)
@@ -51,6 +51,6 @@
 \r
 #define TSL2561_SLAVE_ADDR (0x49)\r
 #define TMP175_SLAVE_ADDR (0x48)\r
-#define MAX136_SLAVE_ADDR (0x35)\r
+#define MAX136_SLAVE_ADDR (0x34)\r
 \r
 #endif /* _IM2SB_H */\r
index 69106ae333cddc0acc47b1bddb5fcf5a4fb97e1e..a293657e0d62216ccc08b00a91e911719612df1e 100644 (file)
@@ -109,13 +109,13 @@ implementation {
     uint8_t rval;
     atomic {
       rval = 0;
-      if (call Led0.get()) {
+      if (!call Led0.get()) {
        rval |= LEDS_LED0;
       }
-      if (call Led1.get()) {
+      if (!call Led1.get()) {
        rval |= LEDS_LED1;
       }
-      if (call Led2.get()) {
+      if (!call Led2.get()) {
        rval |= LEDS_LED2;
       }
     }
diff --git a/tos/system/State.nc b/tos/system/State.nc
deleted file mode 100644 (file)
index 0b5507f..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*\r
- * Copyright (c) 2005-2006 Rincon Research Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * - Redistributions of source code must retain the above copyright\r
- *   notice, this list of conditions and the following disclaimer.\r
- * - Redistributions in binary form must reproduce the above copyright\r
- *   notice, this list of conditions and the following disclaimer in the\r
- *   documentation and/or other materials provided with the\r
- *   distribution.\r
- * - Neither the name of the Arch Rock Corporation nor the names of\r
- *   its contributors may be used to endorse or promote products derived\r
- *   from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
- * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE\r
- */\r
-\r
-\r
-/**\r
- * State machine interface\r
- * @author David Moss - dmm@rincon.com\r
- */\r
\r
-interface State {\r
-\r
-  /**\r
-   * This will allow a state change so long as the current\r
-   * state is S_IDLE.\r
-   * @return SUCCESS if the state is change, FAIL if it isn't\r
-   */\r
-  async command error_t requestState(uint8_t reqState);\r
-  \r
-  /**\r
-   * Force the state machine to go into a certain state,\r
-   * regardless of the current state it's in.\r
-   */\r
-  async command void forceState(uint8_t reqState);\r
-  \r
-  /**\r
-   * Set the current state back to S_IDLE\r
-   */\r
-  async command void toIdle();\r
-  \r
-  /**\r
-   * @return TRUE if the state machine is in S_IDLE\r
-   */\r
-  async command bool isIdle();\r
-  \r
-  /**\r
-   * Get the current state\r
-   */\r
-  async command uint8_t getState();\r
-\r
-}\r
index 38292e8f013ed4d11d084927067c8577348f69e7..18d8bb4c18f921594679153670c65c40ac9ad8de 100644 (file)
@@ -19,7 +19,7 @@
 typedef uint8_t bool;
 enum { FALSE = 0, TRUE = 1 };
 
-typedef int8_t nx_bool __attribute__((nx_base(int8)));
+typedef nx_int8_t nx_bool;
 uint16_t TOS_NODE_ID = 1;
 
 /* This macro is used to mark pointers that represent ownership