From chien-liang at users.sourceforge.net Mon Apr 7 16:08:43 2008 From: chien-liang at users.sourceforge.net (Chien-Liang Fok) Date: Mon Apr 7 16:10:04 2008 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/wustl/websites/agilla/related_work index.html, NONE, 1.1 related_work.html, 1.1, NONE Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/related_work In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15580/related_work Added Files: index.html Removed Files: related_work.html Log Message: Updated the references, main page, and download sections --- NEW FILE: index.html --- Agilla Related Work

Work Related to Agilla

Below is a list of publications related to Agilla done by research groups from around the world. For a list of publications done by our group, see Agilla Publications.

Applications

Middleware for WSNs

Mobile Agents in WSNs

Reprogramming WSNs

Virtual Machines in WSNs

Vaguely Related Work

The following papers define "mobile agent" as a powerful physically mobile node:


This work is supported by the ONR MURI Project CONTESSA and the NSF under grant number CCR-9970939. --- related_work.html DELETED --- From chien-liang at users.sourceforge.net Mon Apr 7 16:08:43 2008 From: chien-liang at users.sourceforge.net (Chien-Liang Fok) Date: Mon Apr 7 16:10:04 2008 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/wustl/websites/agilla/docs/tutorials 1_installation.html, 1.8, 1.9 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/docs/tutorials In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15580/docs/tutorials Modified Files: 1_installation.html Log Message: Updated the references, main page, and download sections Index: 1_installation.html =================================================================== RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/docs/tutorials/1_installation.html,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** 1_installation.html 18 Oct 2006 11:57:23 -0000 1.8 --- 1_installation.html 7 Apr 2008 23:08:40 -0000 1.9 *************** *** 19,155 ****

Lesson 1: Agilla Installation

!

Last Updated on ! October 18, 2006 6:33 AM ! .

!

Note: As of 11/03/2005, the latest version of Agilla ! is distributed through TinyOS's CVS repository. For instructions ! on how to install previous versions, click here.

!
    ! !
  1. Install TinyOS. I recommend ! using the CVS version of TinyOS and have posted installation instructions here. ! If you already have TinyOS, be sure to grab washu.sh and ! put it in /etc/profile.d/. This script adds important aliases and ! environment variables used by Agilla.
  2. ! !
  3. Download Agilla according to the instructions here.
  4. !
  5. Create a Makefile.Agilla file ! containing local settings within $TOSROOT/contrib/wustl/apps/Agilla. ! Simply copy the example file ! included with Agilla:
    !
    !
    cd $TOSROOT/contrib/wustl/apps/Agilla
    cp Example\ Makefile.Agilla Makefile.Agilla
    !
    ! See $TOSROOT/contrib/wustl/apps/Agilla/README for details ! on how to customize Makefile.Agilla.
  6. !
  7. In order for Mica2 and ! MicaZ motes to communicate with Cricket motes, you need to change ! their UART ports to operate ! at 115.2kbps (the default is 57.6kbps). To change this, ! open $TOSROOT/tos/platforms/<platform>/HPLUART0M.nc and ! change outp(15, UBRR0L); to outp(7, ! UBRR0L);.
  8. !
  9. Download Makelocal to $TOSROOT/tools/make. ! Customize it to your liking, e.g., choose the appropriate radio ! frequency and group id.
  10. !
  11. Install Agilla onto every mote including the ! basestation. Be sure that every mote has a unique TinyOS address.
    !
    !
    cd $TOSROOT/contrib/wustl/apps/Agilla/
    ! make [platform]
    ! make [platform] reinstall.[id][programming board],[port]
    !
    ! For example, the following command will install Agilla on a TelosB ! mote on COM5 with TinyOS address 0:
    !
    !
    cd $TOSROOT/contrib/wustl/apps/Agilla/
    ! make telosb
    ! make telosb reinstall.0 bsl,4
    !
    ! As another example, the following command will install Agilla on ! a Mica2 mote on COM1 with TinyOS ! address ! 1:
    !
    !
    cd $TOSROOT/contrib/wustl/apps/Agilla/
    ! make mica2
    ! make mica2 reinstall.1 mib510,/dev/ttyS0
    !
  12. !
  13. Agilla's AgentInjector is a Java ! program that allows users to inject mobile agents ! in to ! a wireless sensor ! network. It is located ! in $TOSROOT/contrib/wustl/tools/java/. The main ! class is edu.wustl.mobilab.agilla.AgentInjector. !
    !
    ! Before compiling the AgentInjector, make sure the directory /opt/tinyos-1.x/contrib/wustl/tools/java ! is in the classpath. If you have washu.sh installed in /etc/profile.d, ! it will run /opt/tinyos-1.x/contrib/wustl/tools/java/javapath which ! will ensure the above directory is in your classpath. You can view your ! classpath by typing the following command:
    !
    !
    echo $CLASSPATH
    !
    ! Once the classpath is set, go into $TOSROOT/contrib/wustl/tools/java/edu/wustl/mobilab/agilla ! and copy ! the file "Example Makefile.Agilla" into "Makefile.Agilla".
    !
    cd $TOSROOT/contrib/wustl/tools/java/edu/wustl/mobilab/agilla
    ! cp Example\ Makefile.Agilla Makefile.Agilla
    ! make
    ! Finally, compile the AgentInjector:
    !
    make
    ! This will generate all of Agilla's messages using mig and compile the ! AgentInjector.
  14. !
  15. Create an agilla.properties file that contains local settings ! for the AgentInjector: !
    cd $TOSROOT/contrib/wustl/tools/java/
    ! cp Example\ agilla.properties agilla.properties
    ! This will tell the AgentInjector to by default open the 3Blink mobile ! agent that simply blinks all 3 LEDs three times and then dies.
  16. !
  17. If you want to use RMI to remotely inject mobile ! agents, download java.policy and ! install it in $TOSROOT/tools/java.
  18. !
  19. Test the installation by launching the AgentInjector. Attach ! a mote to the PC and launch the AgentInjector using the appropriate ! COM port:
    ! ! !
    !
    cd $TOSROOT/contrib/wustl/tools/java
    ! java -Djava.security.policy=java.policy edu.wustl.mobilab.agilla.AgentInjector \
    !   -comm COM1:57600 -d &
    !

    You should see the following GUI:

    !
    !
    ! Type Ctrl+r while looking at the motes. They should ! all turn on all 3 LEDs on for 1 second indicating that they are ! resetting. If this does not occur, ensure that a mote is correctly attached ! to the PC. ! Refer to the troubleshooting section if ! you continue to have problems injecting agents.
    !
    ! Type the address of the mote attached to the PC in the TOS Address box, and ! then click on the Inject Agent!! button. The 3Blink agent will then be compiled ! and injected into the network. Watch the mote attached to the PC. It should ! blink its LEDs 3 times each time you inject this agent.
    !
    ! You are now ready to inject mobile agents into the sensor network!
  20. !

This work is supported by the ONR MURI Project CONTESSA --- 19,191 ----

Lesson 1: Agilla Installation

!

The following instructions assume you have a working version of ! TinyOS installed on your machine. ! If you do not, either follow the official instructions on the TinyOS ! website, or view the instructions here.

!

Step 1: Download

!

Download the tarball of Agilla's source code from here. Alternatively, you ! can grab an older version of Agilla via the TinyOS ! 1.x CVS repository.

!

Step 2: Extract

!

Extract the files using the commands below. By default, the files go under ! $TOSROOT. On a Windows XP/Cygwin system, $TOSROOT is by default /opt/tinyos-1.x. ! On a Linux or OSX machine, $TOSROOT is wherever you have installed TinyOS 1.x.

!
! mv Agilla*.tar.gz $TOSROOT
! cd $TOSROOT
! tar zxvf Agilla*.tar.gz
! 
!

Once you have extracted the tarball, Agilla's source code will be located ! in the following directory:

! !

There are three subdirectories within Agilla's main directory:

! !

Step 3: Create Makefile.Agilla

!

Create a file called "Makefile.Agilla" that contains local settings ! in $TOSROOT/contrib/wustl/agilla/nesc. To do this, you can simply copy the ! example file that comes with Agilla.

! !

See $TOSROOT/contrib/wustl/agilla/nesc/README for details on how to ! customize this file.

!

Step 4: Compile and Install Agilla on a Mote

!

Compile and install Agilla onto every mote including the one that is attached ! to the programming board. Be sure that every mote has a unique TinyOS address.

! !

The actual command may differ slightly between Windows XP and Linux/OSX platforms, ! mostly because of the different ways serial ports are named. The following ! example commands assume a Windows XP environment.

!

Here's a command that will install Agilla on a TelosB mote on COM5 with TinyOS ! address 0:

! !

Here's a command that will install Agilla on a Mica2 mote on COM1 with TinyOS ! address 1:

! !

Step 5: Compile the AgentInjector

!

The AgentInjector is a Java application that enables users to inject mobile ! agents into an Agilla WSN. It is located in $TOSROOT/contrib/wustl/tools/java/. ! The main class is edu.wustl.mobilab.agilla.AgentInjector. In order to compile ! the AgentInjector, $TOSROOT/contrib/wustl/tools/java must be in the classpath. ! View the classpath using the following command:

! !

If it is not in the classpath, add it:

! !

Once the classpath is set, create a file called "Makefile.Agilla" within ! $TOSROOT/tools/java/edu/wustl/mobilab/agilla using the following command:

! !

This file defines the MIG variable, which specifies what type of target environment ! the AgentInjector is connecting to. The default content of this file contains:

! !

If the AgentInjector is to connect to a real WSN, leave the default content ! as it is. If it is going to be used with TOSSIM, uncomment the first line and ! comment out the second line.

!

Once you have configured Makefile.Agilla, compile the AgentInjector:

! !

This will generate all of Agilla's messages and compile the AgentInjector.

!

Step 6: Creating an agilla.properties file

!

Create a file called "agilla.properties" within $TOSROOT/contrib/wustl/tools/java/ ! that contains local settings for the AgentInjector:

! !

Step 7: Adding RMI Support

!

This step is only required if you plan on remotely injecting agents using ! Java RMI. To enable the RMI feature, create a file called "java.policy" in ! $TOSROOT/tools/java with the following text:

!
! grant {
!    permission java.net.SocketPermission "*:1024-65535","accept,connect,listen,resolve";
!    permission java.io.FilePermission "<<ALL FILES>>","read,write,execute"; 
!    permission java.util.PropertyPermission "user.dir","read,write";
! };
!

Step 8: Launch the AgentInjector !

!

You are now ready to inject mobile agents into the WSN! See lesson 2 of the ! tutorial on how to inject a mobile agent into the WSN.

!

Optional Step 1: Creating a Makelocal file

!

A Makelocal file is used by TinyOS to record settings that ! are specific to the local platform. Here are ! instructions on how to install a Makelocal file. !

!

Optional Step 2: Configuring Environment Variables

+

There are several environment variables that will make using Agilla + easier. They are not required, but provide shortcuts when performing + common tasks. + In a Windows XP/Cygwin environment, the following commands may be included + in a file called "washu.sh" located within /etc/profile.d/. In + a Linux or OSX environment, they can be included in ~/.bash_profile or ~/.bashrc + depending on your specific shell. +

+

+
         export WUBASE=$TOSROOT/contrib/wustl
+          alias cdwu="cd $WUBASE"
+          alias cdwuj="cd $WUBASE/tools/java"
+          alias cdwua="cd $WUBASE/apps"
+          alias runsf_pc="java net.tinyos.sf.SerialForwarder -comm tossim-serial &"
+          alias runsf_com1="java net.tinyos.sf.SerialForwarder -comm serial@COM1:mica2 &"
+
         export AGILLA=$WUBASE/apps/Agilla
+          alias cda="cd $AGILLA"
+          alias cdaa="cd $WUBASE/apps/AgillaAgents"
+          alias cdaj="cd $WUBASE/tools/java/edu/wustl/mobilab/agilla"
+

Optional Step 3: Enabling direct serial communication between Mica2 + and Imote2 motes

+

In order for Mica2 and MicaZ motes to communicate with Cricket motes, + you need to change their UART ports to operate at 115.2kbps (the default + is 57.6kbps). + To change this, open $TOSROOT/tos/platforms/<platform>/HPLUART0M.nc + and change outp(15, UBRR0L); to outp(7, UBRR0L);.

+

Optional Step 4: Configuring a Text Editor to Edit Agilla Agents

+

For Windows users, I recommend using TextPad to edit NesC and Mobile + Agent files. Here are the color-syntax configurations for NesC and Agilla + Agent + files. Install them in <Program Files>\TextPad 4\system.

+

* NesC
+ * Mobile Agent

+

If you are using Linux, I recommend gEdit. Here are the syntax files. Install + them in /usr/share/gtksourceview-1.0/language-specs/

+

* NesC
+ * Mobile Agent

+

This page was last Updated on + April 7, 2008 5:12 PM + .


This work is supported by the ONR MURI Project CONTESSA From chien-liang at users.sourceforge.net Mon Apr 7 16:08:43 2008 From: chien-liang at users.sourceforge.net (Chien-Liang Fok) Date: Mon Apr 7 16:10:04 2008 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/wustl/websites/agilla/download index.html, 1.4, 1.5 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/download In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15580/download Modified Files: index.html Log Message: Updated the references, main page, and download sections Index: index.html =================================================================== RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/download/index.html,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** index.html 18 Oct 2006 11:57:23 -0000 1.4 --- index.html 7 Apr 2008 23:08:40 -0000 1.5 *************** *** 20,117 ****

Download Agilla

!

There are two ways of downloading Agilla. They are through a pre-packaged ! zip file, or through CVS. In both cases, Agilla ! will be located in three directories:

!
    !
  • /opt/tinyos-1.x/contrib/wustl/apps/Agilla: Agilla's firmware
  • !
  • /opt/tinyos-1.x/contrib/wustl/tools/java: Agilla's ! Agent Injector Application
  • !
  • /opt/tinyos-1.x/contrib/wustl/apps/AgillaAgents: ! Example Mobile Agents.
  • !

!

Pre-Packaged Zip File

!

Agilla can be downloaded as a pre-packaged ! zip file. ! This option is for users who do not need the latest code and would ! like a more stable code base. After downloading the zip file, extract ! it to /opt/tinyos-1.x. ! !

CVS

!
!

The latest version of Agilla can be downloaded using CVS. It is ! available through the TinyOS CVS repository located on Sourceforge. ! Instructions for accessing TinyOS's CVS repository are available ! here. Checkout ! module tinyos-1.x/contrib/wustl using the following ! command:

!
$ cvs -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos login
! $ cvs -z3 -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos co \
!   -P tinyos-1.x/contrib/wustl
!

If you are TinyOS developer, you can download it using: !

$ export CVS_RSH=ssh
! $ cvs -z3 -d:ext:developername@tinyos.cvs.sourceforge.net:/cvsroot/tinyos co \
!   -P tinyos-1.x/contrib/wustl
!

See Tutorial ! 1 for ! more details on how to install Agilla.

! !

Demo Releases

!

Remote Injection using RMI

!

RMI is used to remotely inject agents into the sensor network. To ! ! do this, you need to install this java policy ! ! file in /opt/tinyos-1.x/contrib/wustl/tools/java. ! ! See the tutorial on how to remote inject agents via RMI.

!

Useful Text Editing Tools

!

For Windows users, I recommend using TextPad to ! ! edit NesC and Mobile Agent files. Here are the color-syntax configurations ! ! for NesC and Agilla Agent files:

! !

Install them in <Program Files>\TextPad 4\system.

If you are using Linux, I recommend gEdit. Here are the syntax files: !

Install them in /usr/share/gtksourceview-1.0/language-specs/

This page was last updated on ! October 18, 2006 6:01 AM by Chien-Liang Fok.

--- 20,199 ----

Download Agilla

!

Agilla source code is distributed as a tarball. Below is a list ! of releases that are publicly available. For installation instructions, ! see Lesson 1 of ! the Tutorial.

!
!

Version 3.0.3

!

Changes:

!
    !
  1. Added #if statements around cc2420-specific code
  2. !
  3. Modified the ! AgentInjector to check whether clustering is enabled before it ! resets the LocationMgr
  4. !
  5. Modified some default settings to use ! relative paths for portability.
  6. !
!
!

Version 3.0.2

    !
  • Release date: 05-22-2006
  • !
  • Download
!

Changes:

!
    !
  1. Added a file called "Example Makefile.Agilla", which ! contains the default local settings.
  2. !
  3. Updated the README to describe the flags ! in it
  4. !
!
!

Version 3.0.1

    !
  • Release date: 05-16-2006
  • !
  • Download
!

Changes:

!
    !
  1. A bug fix that rectifies the "QUEUE_ENQUEUE" error ! that sometimes occurs when there are numerous agents in the network.
  2. !
!
!

Version 3.0

!

* Release date: 05-14-2006
! * Download

!

Changes:

!

1. Added support for TelosB platform
! 2. Allow the user to disable the grid topology filter and greedy routing
! 3. The Java Makefile now assumes an $AGILLA environment variable that specifies ! the root directory of Agilla's NesC code. The default value of this variable ! is $TOSROOT/contrib/wustl/apps/Agilla/.

!
!

Version 2.2

!

* Release date: 07-14-2005
! * Download

!

Changes:

!

1. Reduced memory usage to avoid stack overflow when large agents ! are injected.

!
!

Version 2.1

!
    !
  • Release date: 05-25-2005
  • !
  • Download
  • !
!

Changes:

!
    !
  1. Fixed a bug that prevented a mote from moving more than once.
  2. !
  3. Changes ! the "reset all" function to only reset nodes that are ! reachable from the base station that broadcasted the reset message.
  4. !
!
!

Version 2.0

!
    !
  • Release datea: 05-17-2005
  • !
  • Download
  • !
!

Changes:

!
    !
  1. The grid size can be changed using the AgentInjector (you no ! longer have to reprogram all the motes to change the grid size)
  2. !
  3. When ! specifying the grid size, you only specify the number of columns ! (you no longer need to specify the number of rows). The ! node’s TinyOS address ! still determines the mote’s location. Mote 0 is at (1,1) located at ! the lower-left corner of the grid. TinyOS address’s increase in row ! major order.
  4. !
  5. A mote’s location can be changed using the AgentInjector ! (you no longer need to reprogram the mote to change its address/location). ! The original ID ! of the mote is always used to specify which mote to modify, e.g., “move ! mote 1 to location (2,3).”
  6. !
  7. The AgentInjector enters a modal state for ! ~3 seconds after a reset to allow the network components to reinitialize ! themselves. This is especially ! critical ! now that I’m sending the base station a message immediately after it ! resets telling it that it is a base station.
  8. !
  9. The nodes periodically broadcast ! a beacon, neighbor discovery is done by each node
  10. !
  11. The base station can be ! any node in the network. It no longer has a special address. ! There can be multiple base stations. Base stations can ! also move, ! their location is set like any other node using the AgentInjector.
  12. !
  13. Since ! the location of a base station is no longer known by the non-base ! station nodes, Agilla no longer performs multi-hop routing to (uart_x, ! uart_y). Only the base station can perform a remote tuple space operation ! to (uart_x, ! uart_y). It is now up to the application to route messages to the base ! station. If an agent knows the location of the base station, Agilla ! can still perform ! the greedy multi-hop routing to it.
  14. !
!
!

Version 1.6

!

* Release date: 03-30-2005
! * Download

!

Changes:

!

1. Fixed a bug in OPcompare preventing comparisons between variables ! of two different types. Now, whenever you try to compare two variables ! of different types, the condition code will always be set to 0.

!

Known issues:

!

1. Linux's timing seems to be different from Windows resulting ! in agents being corrupted when injected. To solve this, open <agilla>/types/MigrationMsgs.h, ! uncomment lines 63-66, and comment out lines 77-84.

!
!

Version 1.5

!

* Release date: 03-24-2005
! * Download

!

Changes:

!

1. Fixed a bug preventing agents in the WSN from inserting tuples ! into the laptop's tuple space. Added an Oscilloscope example to demonstrate ! how a Java application running on the laptop can access the laptop's ! tuple space.

!
!

Version 1.4

!

* Release date: 03-23-2005
! * Download

!

Changes:

!

1. Fixed the tuple space and modified assembler to report line ! numbers in errors.

!
!

Version 1.3

!
    !
  • Release date: 03-21-2005
  • !
  • Download
  • !
!

Changes:

!

1. Removes instruction shiftl and shiftr and replaces them with ! mul (multiply) and div (divide). Agents can perform operations on ! the laptop's tuple space by using location (uart_x, uart_y).

!

Known Issues:

!

1. The RMI code for allowing remote access to the laptop's tuple ! space has not been implemented yet.

!
!

Version 1.2 !

!
    !
  • Release date: 11-30-2004
  • !
  • Download
  • !
!

Note: This is the version used to write the IPSN 2005 SPOTS paper.

!

Known Issues:

!
    !
  1. The PC can access the tuple space on mote (0,0), but there is ! no clean interface for this yet. The PC cannot register reactions. ! The agents on the laptop cannot register reactions on tuple spaces ! within the WSN.
  2. !

This page was last updated on ! April 7, 2008 3:48 PM by Chien-Liang Fok.

From chien-liang at users.sourceforge.net Mon Apr 7 16:08:43 2008 From: chien-liang at users.sourceforge.net (Chien-Liang Fok) Date: Mon Apr 7 16:10:05 2008 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/wustl/websites/agilla/download/pre3 index.html, 1.5, 1.6 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/download/pre3 In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15580/download/pre3 Modified Files: index.html Log Message: Updated the references, main page, and download sections Index: index.html =================================================================== RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/download/pre3/index.html,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** index.html 13 May 2007 19:13:07 -0000 1.5 --- index.html 7 Apr 2008 23:08:40 -0000 1.6 *************** *** 12,16 **** installation instructions.

    !
  • 05-13-2007 Version 3.0.3 - Source
    Added #if statements around cc2420-specific code, modified the AgentInjector to check whether clustering is enabled before it resets the LocationMgr, --- 12,16 ---- installation instructions.

      !
    • 05-13-2007 Version 3.0.3 - Source
      Added #if statements around cc2420-specific code, modified the AgentInjector to check whether clustering is enabled before it resets the LocationMgr, From chien-liang at users.sourceforge.net Mon Apr 7 16:08:43 2008 From: chien-liang at users.sourceforge.net (Chien-Liang Fok) Date: Mon Apr 7 16:10:05 2008 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/wustl/websites/agilla/pubs index.html, 1.3, 1.4 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/pubs In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15580/pubs Modified Files: index.html Log Message: Updated the references, main page, and download sections Index: index.html =================================================================== RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/pubs/index.html,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** index.html 12 Dec 2006 06:33:03 -0000 1.3 --- index.html 7 Apr 2008 23:08:41 -0000 1.4 *************** *** 1,97 **** ! ! ! ! ! ! Agilla Publications ! ! ! ! ! ! ! ! ! ! ! ! ! !

      Agilla Publications

      ! !

      Conference Papers

      !
        !
      1. Chien-Liang Fok, Gruia-Catalin Roman, Chenyang Lu. "Rapid ! Development and Flexible Deployment of Adaptive Wireless Sensor ! Network Applications" In Proceedings of the 24th ! International Conference on Distributed Computing Systems (ICDCS'05), ! Columbus, ! Ohio, June 6-10, 2005, pp. 653-662. PDF, ! PPT ! Presenation, Bib
      2. !
      3. Chien-Liang Fok, Gruia-Catalin Roman, Chenyang Lu. "Mobile ! Agent Middleware for Sensor Networks: An Application Case Study" In ! Proceedings of the 4th ! International Conference on Information Processing in Sensor ! Networks (IPSN'05), Los Angeles, California, ! April 25-27, 2005, pp. 382-387. PDF, Poster ! PDF, Bib
      4. !
      5. Gregory Hackmann, Chien-Liang Fok, Gruia-Catalin Roman, Chenyang ! Lu, Christopher Zuver, Kent English and John Meier. "Demo ! Abstract: Agile Cargo Tracking Using Mobile Agents." In ! Proceedings of the Third ! Annual Conference on Embedded Networked Sensor Systems ! (SenSys 2005). November 2-4, 2005. Page 303. PDF, ! Bib
      6. !
      7. Gregory Hackmann, Chien-Liang Fok, Gruia-Catalin Roman, and Chenyang ! Lu. "Agimone: Middleware Support for Seamless Integration ! of Sensor and IP Networks." Proceedings of 2006 International ! Conference on Distributed Computing in Sensor Systems (DCOSS '06). PDF, Bib
      8. !
      ! !

      Technical Reports

      !
      1. Chien-Liang Fok, Gruia-Catalin Roman, and Chenyang ! Lu. "Agilla: A Mobile Agent Middleware for Sensor Networks." Technical ! Report, Washington University in St. Louis, WUCSE-2006-16. PDF, Bib
      2. !
      !

      Presentations

      !
        !
      1. MURI ! ONR 4-Year Review, University of Illinois, Urbana-Champaign. Oct ! 7, 2005. PPT
      2. !
      ! !

      Posters

      !
        !
      1. "Efficient Network Exploration ! and Fire Detection using Mobile Agents in a Wireless Sensor Network" - ! (MURI ONR 3-Year Review, Baltimore, MD. ! Nov 19, 2004) PDF
      2. !
      3. "Fluid Software Infrastructure for Wireless Sensor Networks." ! (NSF NOSS PI Meeting, Harvard ! University, Oct 17-18, 2005) PDF
      4. !
      5. "AgiTrack: Agile Cargo Tracking Using Mobile Agents." (SenSys'05, ! San Diego, CA, Nov 2-4, 2005), PDF
      6. !
      ! !

      Handouts

      !
        !
      1. "Agilla: The Rapid ! Development and Flexible Deployment of Adaptive Wireless Sensor ! Network Applications" - (MURI ! ONR 3-Year Review, Baltimore, MD. Nov 19, 2004). PDF
      2. !
      3. "Efficient Fire Detection and ! Tracking Using Mobile Agents in a Wireless Sensor Network" - ! (MURI ! ONR 3-Year Review, Baltimore, MD. Nov 19, 2004). PDF
      4. !
      5. "Multi Mobile Agent Deployment on Wireless Sensor Networks" - ! (MURI ONR 3-Year Review, ! Baltimore, MD. Nov 19, 2004)
      6. ! . PDF !
      ! !
      This work is supported by the ONR MURI Project CONTESSA ! and the NSF under grant number CCR-9970939. ! ! ! --- 1,176 ---- ! ! ! ! ! ! Agilla Publications ! ! ! ! ! ! ! ! ! ! ! ! ! !

      Agilla Publications

      ! !

      Agilla and its related projects have been published ! as peer-reviewed conference papers, workshop ! papers, book chapters, demo ! abstracts, technical ! reports, presentations, posters, and handouts. ! A journal paper ! on Agilla is currently in the works. For related work done by other ! research groups around the world, see Agilla's related ! work.

      !

      Conference Papers

      !
        !
      • Rapid ! Development and Flexible Deployment of Adaptive Wireless Sensor ! Network Applications, by Chien-Liang ! Fok, Gruia-Catalin Roman, Chenyang Lu. In Proceedings ! of the 24th International Conference on Distributed Computing Systems ! (ICDCS'05), Columbus, Ohio, June 6-10, 2005, pp. 653-662. One of ! 5 papers nominated ! for Best Paper Award (543 papers submitted), ! Presenation, Bib
      • !
      • Mobile ! Agent Middleware for Sensor Networks: An Application Case Study, ! by Chien-Liang Fok, Gruia-Catalin Roman, Chenyang Lu. ! In Proceedings of the ! 4th International Conference on Information Processing in Sensor Networks ! (IPSN'05), Los Angeles, ! California, April 25-27, 2005, pp. 382-387. Poster, Bib
      • !
      • Agimone: ! Middleware Support for Seamless Integration of Sensor and IP ! Networks, by Gregory Hackmann, Chien-Liang Fok, Gruia-Catalin ! Roman, and ! Chenyang Lu. In the proceedings of the 2006 International Conference on ! Distributed Computing in Sensor Systems (DCOSS '06) , Bib
      • !
      • Roadmap Query ! for Sensor Network Assisted Navigation in Dynamic Environments, ! by Sangeeta Bhattacharya, Nuzhet Atay, Gazihan Alankus, ! Chenyang Lu, O. Burchan ! Bayazit, and Gruia-Catalin Roman. In the proceedings of the 2006 International ! Conference on Distributed Computing in Sensor Systems (DCOSS '06) Best ! Paper Award!
      • !
      • Exploring Sensor Networks using Mobile Agents, International ! Joint Conference on Autonomous Agents & Multi Agent Systems ! (AAMAS'06), May 2006, pp. 323-325.
      • !
      • Design and Implementation of ! a Flexible Location Directory Service for Tiered Sensor Networks, ! by Sangeeta Bhattacharya, Chien-Liang ! Fok, Chenyang ! Lu, and Gruia-Catalin Roman. In the proceedings of the 2007 International ! Conference on Distributed Computing in Sensor Systems (DCOSS '07)
      • !
      !

      Workshops

      ! !

      Book Chapters !

      !
        !
      • Software Support for Application Development ! in Wireless Sensor Network, by Chien-Liang Fok, Gruia-Catalin ! Roman and Chenyang ! Lu, Handbook of Mobile ! Middleware, CRC Press, September 2006.
      • !
      !

      Demo Abstracts

      ! !

      Technical Reports

      ! !

      Presentations

      !
        !
      • MURI ONR 4-Year Review, University of Illinois, Urbana-Champaign. ! Oct 7, 2005. PPT
      • !
      !

      Posters

      ! !

      Handouts

      ! ! !
      This work is supported by the ONR MURI Project CONTESSA ! and the NSF under grant number CCR-9970939. ! ! ! From chien-liang at users.sourceforge.net Mon Apr 7 16:08:43 2008 From: chien-liang at users.sourceforge.net (Chien-Liang Fok) Date: Mon Apr 7 16:10:05 2008 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/wustl/websites/agilla index.html, 1.2, 1.3 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15580 Modified Files: index.html Log Message: Updated the references, main page, and download sections Index: index.html =================================================================== RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/wustl/websites/agilla/index.html,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** index.html 21 Jan 2006 02:11:33 -0000 1.2 --- index.html 7 Apr 2008 23:08:38 -0000 1.3 *************** *** 23,102 ****

      A Mobile Agent Middleware for Wireless Sensor Networks

      Download | Documentation | Examples ! | Publications | Related ! Work | Forum

      ! Agilla is a middleware that provides a mobile-agent paradigm ! for programming and using wireless sensor networks (WSNs) ! . Agilla applications consist of mobile ! agents that can proactively migrate their code and state across the ! network. Mobile agents offer more flexibility by allowing applications to ! control ! the way they spread. They can position ! themselves in the optimal locations for performing application-specific ! tasks. They can save energy by bringing computation to the data rather than ! requiring that the data be sent over unreliable wireless links. They can ! increase the ! utility of a WSN by constraining themselves to the specific locals that are ! relevant to their application's requirements (in contrast to spreading ! throughout an entire network), and sharing the resources of a single node, ! i.e., multiple mobile agents can reside on each WSN node. Other systems like ! Deluge and Maté allow ! in-network reprogramming. Agilla, however, goes one step further by allowing ! programs to control where they go and ! to maintain both their code and state across migrations. ! !

      Since ! new agents can be ! ! injected into a pre-existing network, the network can be re-tasked. Since ! each agent executes autonomously and multiple agents can simultaneously ! run on a node, multiple applications can co-exist. Since ! mobile ! agents ! can move ! and clone, they ! can quickly morph an application's installation base to handle unexpected ! changes in an environment. There are many other inherent ! advantages of ! using mobile agents, especially in a wireless sensor network. However, there ! are also many challenges, the foremost being the lack of computational ! resources and unreliable network connectivity. Agilla is the first mobile ! agent middleware ! for WSNs that is implemented entirely in TinyOS. It has been tested on ! Mica2 and MicaZ motes. It abstracts away complexities associated ! with developing WSN applications, and provides mechanisms that ! overcome ! the challenges associated with limited resources and unreliable network ! communication. It demonstrates the feasibility of using mobile agents within ! WSNs and, furthermore, it takes the first steps at identifying a minimal ! set of primitives that should be provided ! for facilitating highly flexible WSN applications.

      !

      There are many applications of mobile agents in WSNs. Three of them include ! intruder detection, wildfire tracking, and cargo tracking. In intruder detection, ! detection agents are deployed around the perimeter of a WSN. When an intruder ! breaches a perimeter, the agents near the breach follow the intruder and clone ! themselves to form a perimeter around the intruder. Note that only the ! nodes next to the intruder are involved with tracking process. All other nodes ! are free to service other applications. In wildfire tracking, ! as shown in Figure 1, mobile agents swarm around a fire forming a ! perimeter, and dynamically adjusting it based on the movements of the fire. ! The algorithm ! for adjusting ! the perimeter is fully distributed, ensuring scalability. In cargo tracking, ! a multi-hop WSN is deployed on cargo containers. Each container ! has a mote that contains an electronic manifest. These motes go one step beyond ! RFID tags in that they can perform computation, such as monitoring sensors ! for intrusions or contract violations. When a ship docks, ! agents are deployed onto the ship's WSN. These ! agents ! scour the ! cargo containers identifying those that contain specific items or require inspection. ! Mobile agents are necessary in this case since the port authorities do ! not trust the code of other countries to ! return valid results. Also changing security levels and policies require a ! flexible software infrastructure, which is provided by mobile agents.

      ! --- 23,87 ----

      A Mobile Agent Middleware for Wireless Sensor Networks

      Download | Documentation | Examples ! | Publications | Related ! Work

      !

      Introduction

      !

      Agilla is a middleware for wireless sensor networks (WSNs) that provides a ! mobile-agent style of programming. Agilla applications consist of mobile ! agents that can proactively ! migrate their code and state across the network. Mobile agents offer more ! flexibility by allowing applications to control the way they spread. They can ! position ! themselves in the optimal locations for performing application-specific tasks. ! They can ! save energy by bringing computation to the data rather than requiring that ! the data be sent over unreliable wireless links to the location containing ! the computation. ! They can increase the utility of a WSN by constraining themselves to the ! specific locales that are relevant to their application's requirements (in ! contrast ! to spreading throughout an entire network), and sharing the resources of ! a single ! node, i.e., multiple mobile agents can reside on each WSN node. Other systems ! like Deluge and Maté allow in-network reprogramming. Agilla, however, ! allows programs to control where they go and to maintain both their code ! and state across migrations.

      !

      Since new agents can be injected into a pre-existing network, the network ! can be re-tasked. Since each agent executes autonomously and multiple agents ! can simultaneously run on a node, multiple applications can co-exist. Since ! mobile agents can move and clone, they can quickly morph an application's installation ! base to handle unexpected changes in an environment. There are many other inherent ! advantages of using mobile agents, especially in a wireless sensor network.

      !

      However, there are also many challenges, the foremost being the lack of resources ! and an unreliable network. Agilla is the first mobile agent middleware for ! WSNs that is implemented entirely in TinyOS. It has been tested on Mica2, MicaZ, ! and Tmote Sky motes. It hides complexities associated with developing WSN applications, ! and provides mechanisms that overcome the challenges associated with limited ! resources and unreliable network communication. It demonstrates the feasibility ! of using mobile agents within WSNs and, furthermore, takes the first steps ! towards identifying a minimal set of primitives that should be provided for ! facilitating highly flexible WSN applications.

      !

      Applications

      !

      There are many applications of mobile agents in WSNs. Three include intruder ! detection, wildfire tracking, and cargo tracking. In intruder detection, detection ! agents are deployed around the perimeter of a WSN. When an intruder breaches ! a perimeter, the agents near the breach follow the intruder and clone themselves ! to form a perimeter around the intruder. Note that only the nodes next to the ! intruder are involved with tracking process. All other nodes are free to service ! other applications. In wildfire tracking, as shown in Figure 1, mobile agents ! swarm around a fire forming a perimeter, and dynamically adjusts it based on ! the movements of the fire. The algorithm for adjusting the perimeter is distributed, ! ensuring scalability. In cargo tracking, a multi-hop WSN is deployed on cargo ! containers. Each container has a mote that contains an electronic manifest. ! These motes differ from RFID tags in that they can perform computation, such ! as monitoring sensors for intrusions or contract violations. When a ship docks, ! agents are deployed onto the ship's WSN. These agents scour the cargo containers ! identifying those that contain specific items or require inspection. Mobile ! agents are necessary in this case since the port authorities do not trust the ! code of foreign origin. In addition, changing security levels and policies ! require a flexible software infrastructure that mobile agents provide.

      ! *************** *** 114,195 ****

       

      Motivation

      !

      Most contemporary ! wireless sensor networks (WSNs) are inflexible application-specific systems; ! they are ! closed-systems that provide a limited set of services for ! a specific pre-determined ! set of users. As WSNs mature and motes become more sophisticated, large-scale ! WSNs consisting of thousands of nodes that span vast geographic areas will ! be deployed for longer periods of time. ! The large scale of these networks will inevitably lead to them being shared ! by multiple users, possibly simultaneously. These users are transient; they may come and go, sporadically using the network whenever ! and wherever they need to. The long deployment intervals ensure that the ! application requirements will change mid-deployment. The existing software ! infrastructure for WSNs does not provide the flexibility necessary ! for supporting ! these ! large-scale WSNs.

      !

      Presently, most WSNs are programmed prior to deployment and, once deployed, ! can only be tweaked through a static set of pre-defined parameters, ! severely limiting the WSNs flexibility. The network ! is limited to ! run a single application, which, as WSNs are deployed ! for longer intervals, becomes increasingly unacceptable. Also, the application ! itself may not be able to adapt to unpredictable changes ! in ! user ! requirements; it's simply not possible for software developers to foresee ! all possible uses of a WSN prior deployment. This is especially so as WSNs ! become larger, ! more sophisticated, deployed for longer ! periods of time, and over larger areas.

      Related Work

      !

      The latest version ! of TinyOS (version ! 1.1.14) takes the first steps at increasing the flexibility of WSNs by including ! a Deluge boot ! loader by default. Deluge enables you to wirelessly reprogram a WSN. It floods ! a new ROM image over the network and re-flashes each mote's ! instruction memory once the entire ROM image has been delivered. Since the ! entire operating system and application needs to be transferred, reprogramming ! a network is a slow energy-consuming process. It is not a process that can be ! done frequently due to lack of power and wireless ! bandwidth. Also, since the images are flooded, the network can only run ! one application at a time. ! One ! benefit ! of ! using Deluge, ! however, ! is ! that ! ! it reprograms a network using native code; the new application runs as efficiently ! as if it were installed prior to ! the network being deployed.

      !

      Another approach to increasing WSN flexibility is through a virtual ! machine that facilitates the distribution of virtual-machine-specific code. ! The canonical example of such a system for TinyOS-based networks is Maté. ! ! Maté programs are implemented as a set of capsules of various types. Each ! type ! of ! capsule ! performs a specific function, e.g., run-once, run-periodically, ! send-message, ! receive message, or function calls. The virtual machine supports a static set ! of capsules, which limits the number of capsules of a particular type that a ! developer can use. The ! capsule ! contains ! a ! sequence of virtual-machine instructions and a version number. Whenever a new ! capsule is ! injected, Maté epidemically spreads ! it throughout the WSN. Like Deluge, Maté only supports one application ! at a time. It does not allow fine-grain control over where new capsules are propagated, ! nor does it allow the capsules to carry run-time state, e.g., a stack or program ! counter, as it moves.

      Agilla Middleware Architecture

      The Agilla middleware architecture is shown in Figure 2. Agilla runs on top --- 99,146 ----

       

      Motivation

      !

      Most WSNs are inflexible application-specific systems; they are closed-systems ! that provide a limited set of services for a specific pre-determined set of ! users. As WSNs mature and motes become more sophisticated, large-scale WSNs ! consisting of thousands of nodes that span vast geographic areas will be deployed ! for longer periods of time. The large scale of these networks will inevitably ! lead to them being shared by multiple users, possibly simultaneously. These users are transient; they may come and go, sporadically using the network whenever ! and wherever they need to. The long deployment intervals ensure that the application ! requirements will change mid-deployment. The existing software infrastructure ! for WSNs does not provide the flexibility necessary for supporting these large-scale ! WSNs.

      !

      Presently, most WSNs are programmed prior to deployment and, once deployed, ! can only be tweaked through a static set of pre-defined parameters, severely ! limiting the WSNs flexibility. The network is limited to run a single application, ! which, as WSNs are deployed for longer intervals, becomes increasingly unacceptable. ! Also, the application itself may not be able to adapt to unpredictable changes ! in user requirements; it's simply not possible for software developers to foresee ! all possible uses of a WSN prior deployment. This is especially so as WSNs ! become larger, more sophisticated, deployed for longer periods of time, and ! over larger areas.

      Related Work

      !

      TinyOS includes Deluge, a system that enables in-network reprogramming. Deluge ! allows a user to install a new ROM image on a node wirelessly. It allows targeted ! deployment in which a new image is installed on a specific node in a WSN, or ! flooding, which which every node in the WSN is re-programmed with the new image. ! Since the entire program image is transferred, reprogramming a network is a ! slow and energy-consuming process. It cannot be done frequently due to lack ! of power and wireless bandwidth. Also, since the images are flooded, the network ! can only run one application at a time. One benefit of using Deluge, however, ! is that it reprograms a network using native code. This means the new application ! can be optimized for the specific platform and, thus, run more efficiently.

      !

      Another approach to increasing WSN flexibility is through a virtual machine ! that facilitates the distribution of interpreted code. One example of such ! a system for TinyOS-based networks is Maté. Maté programs are ! implemented as a set of capsules of various types. Each type of capsule performs ! a specific function, e.g., run-once, run-periodically, send-message, receive ! message, or function calls. The virtual machine supports a static set of capsules, ! which limits the number of capsules of a particular type that a developer can ! use. The capsule contains a sequence of instructions and a version number. ! Whenever a new capsule is injected, Maté epidemically spreads it throughout ! the WSN. Like Deluge, Maté only supports one application at a time. ! It does not allow fine-grain control over where new capsules are propagated, ! nor does it allow the capsules to carry state, e.g., a stack or program counter, ! as it is spread throughout a network.

      Agilla Middleware Architecture

      The Agilla middleware architecture is shown in Figure 2. Agilla runs on top *************** *** 197,214 **** agents is variable and is determined primarily by the amount of memory available. Each agent is autonomous, but shares middleware resources with other agents ! in the ! system. ! Agilla provides two fundamental resources on each node: a neighbor list and ! a tuple space. The neighbor list contains the addresses of neighboring nodes. ! This is necessary for agents to decide where they want to move or clone to ! next. The tuple space provides an elegant decoupled-style of communication between agents. It is a shared memory architecture that is addressed by field-matching ! rather than memory addresses. A tuple is a sequence of typed data ! objects that is inserted into the tuple space. The tuple is remains in the ! tuple space even if the agent that inserted it dies or moves away. Later, another ! agent may retrieve the tuple by issuing a query for a tuple with the same sequence ! of fields. Note that tuple spaces decouples the sending agent from the receiving ! agent: they do not have to be co-located, or even aware of each other's ! existence, for them to communicate.

      --- 148,163 ---- agents is variable and is determined primarily by the amount of memory available. Each agent is autonomous, but shares middleware resources with other agents ! in the system. Agilla provides two fundamental resources on each node: a neighbor ! list and a tuple space. The neighbor list contains the addresses of neighboring ! nodes. This is necessary for agents to decide where they want to move or clone ! to next. The tuple space provides an elegant decoupled-style of communication between agents. It is a shared memory architecture that is addressed by field-matching ! rather than memory addresses. A tuple is a sequence of typed data objects that ! is inserted into the tuple space. The tuple is remains in the tuple space even ! if the agent that inserted it dies or moves away. Later, another agent may ! retrieve the tuple by issuing a query for a tuple with the same sequence of ! fields. Note that tuple spaces decouples the sending agent from the receiving ! agent: they do not have to be co-located, or even aware of each other's existence, ! for them to communicate.

      *************** *** 223,257 **** Challenges !

      There are several ! challenges with developing Agilla. First, sensor ! network nodes have limited computational resources. For example, the MICA2 ! ! motes we use have a mere 128KB of instruction and 4KB of data memory. ! They ! also have ! ! a relatively slow 8MHz Atmel 128 microprocessor. Second, the wireless connectivity ! ! between motes is highly unreliable and provides very little bandwidth (38.4 ! ! Kbaud). Mobile agents are particularly susceptible to message loss because ! ! it interferes ! ! with the agent's ability to migrate and clone. Third, the Agilla primitives ! ! must be carefully tailored to address and/or take advantage of the salient ! ! properties ! ! of sensor network applications. For example, one property of sensor networks ! ! is that they place a greater emphasis on spatial properties. This is because ! taking ! sensor measurements without knowing from where the measurements are comming ! from is meaningless. In designing Agilla, we must recognize these properties ! and tailor ! ! Agilla's primitives accordingly.

      Approaches

      --- 172,188 ---- Challenges !

      There are several challenges with developing Agilla. First, sensor network ! nodes have limited computational resources. For example, the MICA2 motes we ! use have a mere 128KB of instruction and 4KB of data memory. They also have ! a relatively slow 8MHz Atmel 128 microprocessor. Second, the wireless connectivity ! between motes is highly unreliable and provides very little bandwidth (38.4 ! Kbaud). Mobile agents are particularly susceptible to message loss because ! it interferes with the agent's ability to migrate and clone. Third, the Agilla ! primitives must be carefully tailored to address and/or take advantage of the ! salient properties of sensor network applications. For example, one property ! of sensor networks is that they place a greater emphasis on spatial properties. ! This is because taking sensor measurements without knowing from where the measurements ! are comming from is meaningless. In designing Agilla, we must recognize these ! properties and tailor Agilla's primitives accordingly.

      Approaches

      *************** *** 271,307 ****
      !

      Agilla provides ! a stack-based architecture for each agent, as ! ! shown in in Figure 3. This reduces overhead by allowing most instructions ! ! to be one byte. To allow inter-agent communication, Agilla maintains a ! ! tuple space on each node that is shared by all agents residing on the node, ! ! and is accessible remotely. By interacting through a tuple space, each ! ! agent remains autonomous, decoupled both spatially and temporally. To minimize ! ! the impact of message loss, agents are divided into tiny packets (< 41 bytes), ! ! are migrated a single hop at a time, and utilize timeouts and retransmits. ! ! Since this hop-by-hop process introduces a significant amount of store-and-forward ! ! delay, it is only used while migrating or cloning agents, not for remote tuple ! space ! operations. Remote tuple space operations are non-blocking, preventing ! ! an agent from deadlocking due to message loss. In recognition of the importance ! ! of spatial data within sensor networks, Agilla addresses nodes by their location. ! All remote operations take a location as a parameter. For example, ! instead of cloning to a node with id=1, an agent would clone to a node at location ! ! (1,1). By tailoring Agilla's primitives to sensor networks, Agilla provides ! ! a foundation for rapidly developing applications for WSNs with unprecedented ! levels of flexibility.

      --- 202,222 ----
      !

      Agilla provides a stack-based architecture for each agent, as shown in in ! Figure 3. This reduces overhead by allowing most instructions to be one byte. ! To allow inter-agent communication, Agilla maintains a tuple space on each ! node that is shared by all agents residing on the node, and is accessible remotely. ! By interacting through a tuple space, each agent remains autonomous, decoupled ! both spatially and temporally. To minimize the impact of message loss, agents ! are divided into tiny packets (< 41 bytes), are migrated a single hop at ! a time, and utilize timeouts and retransmits. Since this hop-by-hop process ! introduces a significant amount of store-and-forward delay, it is only used ! while migrating or cloning agents, not for remote tuple space operations. Remote ! tuple space operations are non-blocking, preventing an agent from deadlocking ! due to message loss. In recognition of the importance of spatial data within ! sensor networks, Agilla addresses nodes by their location. All remote operations ! take a location as a parameter. For example, instead of cloning to a node with ! id=1, an agent would clone to a node at location (1,1). By tailoring Agilla's ! primitives to sensor networks, Agilla provides a foundation for rapidly developing ! applications for WSNs with unprecedented levels of flexibility.

      *************** *** 330,334 **** Roman and Chenyang Lu.

      !

      Fun Fact

      The term "Agilla" is a play on words. Agilla's implementation is based on Bombilla, the --- 245,249 ---- Roman and Chenyang Lu.

      !

      Trivia

      The term "Agilla" is a play on words. Agilla's implementation is based on Bombilla, the *************** *** 336,340 **** Agilla is, thus, a combination of the terms "Agile" and "Bombilla."

      This page was last updated on ! January 20, 2006 4:29 PM by Chien-Liang Fok. 

      --- 251,255 ---- Agilla is, thus, a combination of the terms "Agile" and "Bombilla."

      This page was last updated on ! April 7, 2008 5:14 PM by Chien-Liang Fok. 

      From ayer1 at users.sourceforge.net Thu Apr 10 07:24:17 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:24:17 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/tos/lib/RovingNetworks RovingNetworksM.nc, 1.7, 1.8 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/tos/lib/RovingNetworks In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv5332 Modified Files: RovingNetworksM.nc Log Message: adrian burns (intel ireland) sent me these updates: - reset-hold time in module init increased to 400 cycles - uart clock rate adjusted to reflect "exactly 115200 baud" Index: RovingNetworksM.nc =================================================================== RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/tos/lib/RovingNetworks/RovingNetworksM.nc,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** RovingNetworksM.nc 19 Nov 2007 21:24:26 -0000 1.7 --- RovingNetworksM.nc 10 Apr 2008 14:24:15 -0000 1.8 *************** *** 99,103 **** */ TOSH_SET_BT_RESET_PIN(); ! for(i = 0; i < 200 ; i++) // == 500k us TOSH_uwait(5000); --- 99,103 ---- */ TOSH_SET_BT_RESET_PIN(); ! for(i = 0; i < 400 ; i++) // == 500k us TOSH_uwait(5000); *************** *** 109,114 **** call ConnectionInterrupt.edge(TRUE); // initially, we look for a connection - call ConnectionInterrupt.enable(); // interrupt upon connection state change (raises when connected, falls when dropped) call ConnectionInterrupt.clear(); TOSH_CLR_BT_CTS_PIN(); // toggling cts wakes it up --- 109,114 ---- call ConnectionInterrupt.edge(TRUE); // initially, we look for a connection call ConnectionInterrupt.clear(); + call ConnectionInterrupt.enable(); // interrupt upon connection state change (raises when connected, falls when dropped) TOSH_CLR_BT_CTS_PIN(); // toggling cts wakes it up *************** *** 120,124 **** void setupUART() { call UARTControl.setClockSource(SSEL_SMCLK); ! call UARTControl.setClockRate(UBR_SMCLK_115200, UMCTL_SMCLK_115200); call UARTControl.setModeUART(); call UARTControl.enableTxIntr(); --- 120,126 ---- void setupUART() { call UARTControl.setClockSource(SSEL_SMCLK); ! //call UARTControl.setClockRate(UBR_SMCLK_115200, UMCTL_SMCLK_115200); ! call UARTControl.setClockRate(8, 0xee); /* make it exactly 115200 baud, see MSP user guide */ ! call UARTControl.setModeUART(); call UARTControl.enableTxIntr(); From ayer1 at users.sourceforge.net Thu Apr 10 07:26:58 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:26:58 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS - New directory Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7284/BioMOBIUS Log Message: Directory /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS added to the repository From ayer1 at users.sourceforge.net Thu Apr 10 07:27:17 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:27:17 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelECG - New directory Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelECG In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7648/BioMOBIUS/AccelECG Log Message: Directory /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelECG added to the repository From ayer1 at users.sourceforge.net Thu Apr 10 07:27:17 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:27:17 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/ECG - New directory Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/ECG In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7648/BioMOBIUS/ECG Log Message: Directory /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/ECG added to the repository From ayer1 at users.sourceforge.net Thu Apr 10 07:27:17 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:27:17 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AnEx - New directory Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AnEx In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7648/BioMOBIUS/AnEx Log Message: Directory /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AnEx added to the repository From ayer1 at users.sourceforge.net Thu Apr 10 07:27:17 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:27:17 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelGyro - New directory Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelGyro In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7648/BioMOBIUS/AccelGyro Log Message: Directory /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelGyro added to the repository From ayer1 at users.sourceforge.net Thu Apr 10 07:27:17 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:27:17 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/SixAxisCmdCtrl - New directory Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/SixAxisCmdCtrl In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7648/BioMOBIUS/SixAxisCmdCtrl Log Message: Directory /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/SixAxisCmdCtrl added to the repository From ayer1 at users.sourceforge.net Thu Apr 10 07:28:27 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:28:27 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelGyro AccelGyro.h, NONE, 1.1 AccelGyro.nc, NONE, 1.1 AccelGyroM.nc, NONE, 1.1 Makefile, NONE, 1.1 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelGyro In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7732/BioMOBIUS/AccelGyro Added Files: AccelGyro.h AccelGyro.nc AccelGyroM.nc Makefile Log Message: from adrian burns (intel ireland): All files in apps/BioMOBIUS/*.* Generic app (Tested on SHIMMER) compatible with BioMOBIUS 1.0 PC Software, see http://www.biomobius.org for more info. --- NEW FILE: AccelGyro.h --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ #ifndef ACCELGYRO_H #define ACCELGYRO_H enum { NUM_ACCEL_CHANS = 3 }; enum { NUM_GYRO_CHANS = 3 }; enum { SHIMMER_REV1 = 0 }; enum { PROPRIETARY_DATA_TYPE = 0xFF, STRING_DATA_TYPE = 0xFE }; enum { SAMPLING_1000HZ = 1, SAMPLING_500HZ = 2, SAMPLING_250HZ = 4, SAMPLING_200HZ = 5, SAMPLING_166HZ = 6, SAMPLING_125HZ = 8, SAMPLING_100HZ = 10, SAMPLING_50HZ = 20, SAMPLING_10HZ = 100, SAMPLING_0HZ_OFF = 255 }; enum { FRAMING_SIZE = 0x4, FRAMING_CE_COMP = 0x20, FRAMING_CE_CE = 0x5D, FRAMING_CE = 0x7D, FRAMING_BOF = 0xC0, FRAMING_EOF = 0xC1, FRAMING_BOF_CE = 0xE0, FRAMING_EOF_CE = 0xE1, }; #endif // ACCELGYRO_H --- NEW FILE: AccelGyro.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app uses Bluetooth to stream 3 Accelerometer channels and 3 Gyro channels of data to a BioMOBIUS PC application. Tested on SHIMMER Base Board Rev 1.3, SHIMMER GyroDB 1.0 board. ***********************************************************************************/ configuration AccelGyro { } implementation { components Main, DMA_M, MMA7260_AccelM, AccelGyroM, RovingNetworksC, TimerC, LedsC; Main.StdControl -> AccelGyroM; Main.StdControl -> TimerC; AccelGyroM.Leds -> LedsC; AccelGyroM.SampleTimer -> TimerC.Timer[unique("Timer")]; AccelGyroM.SetupTimer -> TimerC.Timer[unique("Timer")]; AccelGyroM.ActivityTimer -> TimerC.Timer[unique("Timer")]; AccelGyroM.LocalTime -> TimerC; AccelGyroM.BTStdControl -> RovingNetworksC; AccelGyroM.Bluetooth -> RovingNetworksC; /* have to fix compile time channel limitation */ AccelGyroM.DMA0 -> DMA_M.DMA[0]; //AccelGyroM.DMA1 -> DMA_M.DMA[1]; //AccelGyroM.DMA2 -> DMA_M.DMA[2]; AccelGyroM.AccelStdControl -> MMA7260_AccelM; AccelGyroM.Accel -> MMA7260_AccelM; } --- NEW FILE: AccelGyroM.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app uses Bluetooth to stream 3 Accelerometer channels and 3 Gyro channels of data to a BioMOBIUS PC application. Tested on SHIMMER Base Board Rev 1.3, SHIMMER GyroDB 1.0 board. LOW_BATTERY_INDICATION if defined stops the app streaming data just after the battery voltage drops below the regulator value of 3V. Default Sample Frequency: 50 hz Packet Format: BOF| Sensor ID | Data Type | Seq No. | TimeStamp | Len | Acc | Acc | Acc | Gyro | Gyro | Gyro | CRC | EOF Byte: 1 | 2 | 3 | 4 | 5-6 | 7 | 8-9 | 10-11| 12-13| 14-15 | 16-17| 18-19| 20-21| 22 ***********************************************************************************/ includes crc; includes AccelGyro; includes DMA; includes MMA7260_Accel; includes Message; includes RovingNetworks; module AccelGyroM { provides{ interface StdControl; } uses { interface DMA as DMA0; interface StdControl as AccelStdControl; interface MMA7260_Accel as Accel; interface StdControl as BTStdControl; interface Bluetooth; interface Leds; interface Timer as SetupTimer; interface Timer as ActivityTimer; interface Timer as SampleTimer; interface LocalTime; } } implementation { extern int sprintf(char *str, const char *format, ...) __attribute__ ((C)); #define USE_8MHZ_CRYSTAL #define LOW_BATTERY_INDICATION #define USE_AVCC_REF /* approx 0.5 milliamps saving when using AVCC compared to 2.5V or 1.5V internal ref */ #ifdef LOW_BATTERY_INDICATION //#define DEBUG_LOW_BATTERY_INDICATION /* during testing of the the (AVcc-AVss)/2 value from the ADC on various SHIMMERS, to get a reliable cut off point to recharge the battery it is important to find the baseline (AVcc-AVss)/2 value coming from the ADC as it varies from SHIMMER to SHIMMER, however the range of fluctuation is pretty constant and (AVcc-AVss)/2 provides an accurate battery low indication that prevents getting any voltage skewed data from the accelerometer or add-on board sensors */ #define TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD 1000 #define BATTERY_LOW_INDICATION_OFFSET 20 /* (AVcc - AVss)/2 = Approx 3V-0V/2 = 1.5V, 12 bit ADC with 2.5V REF, 4096/2500 = 1mV=1.6384 units */ bool need_baseline_voltage, linkDisconnecting; uint16_t num_baseline_voltage_samples, baseline_voltage; uint32_t sum_batt_volt_samples; #ifdef DEBUG_LOW_BATTERY_INDICATION uint16_t debug_counter; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ #define FIXED_PACKET_SIZE 22 #define FIXED_PAYLOAD_SIZE 12 uint8_t tx_packet[(FIXED_PACKET_SIZE*2)+1]; /* (*2)twice size because of byte stuffing */ /* (+1)MSP430 CPU can only read/write 16-bit values at even addresses, /* so use an empty byte to even up the memory locations for 16-bit values */ const uint8_t personality[17] = { 0,1,2,3,4,5,0xFF,0xFF, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_0HZ_OFF,SAMPLING_0HZ_OFF,FRAMING_EOF }; norace uint8_t current_buffer = 0, dma_blocks = 0; uint16_t sbuf0[36], sbuf1[36], timestamp0, timestamp1; /* default sample frequency every time the sensor boots up */ uint16_t sample_freq = SAMPLING_50HZ; bool enable_sending, command_mode_complete, activity_led_on; /* Internal function to calculate 16 bit CRC */ uint16_t calc_crc(uint8_t *ptr, uint8_t count) { uint16_t crc; crc = 0; while (count-- > 0) crc = crcByte(crc, *ptr++); return crc; } void setupDMA() { call DMA0.init(); call DMA0.setSourceAddress((uint16_t)ADC12MEM0_); call DMA0.setDestinationAddress((uint16_t)&sbuf0[0]); /* * we'll transfer from six sequential adcmem registers * to six sequential addresses in a buffer */ call DMA0.setBlockSize(7); // we want block transfer, single DMA0CTL = DMADT_1 + DMADSTINCR_3 + DMASRCINCR_3; } void sampleADC() { call DMA0.ADCinit(); // this doesn't really need to be parameterized atomic{ CLR_FLAG(ADC12CTL1, ADC12SSEL_3); // clr clk from smclk SET_FLAG(ADC12CTL1, ADC12SSEL_3); // clk from aclk /* with a 125khz clock (_7) its 136usec per conversion, 136*6=816usec in total */ SET_FLAG(ADC12CTL1, ADC12DIV_7); // sample and hold time four adc12clk cycles SET_FLAG(ADC12CTL0, SHT0_0); // set reference voltage to 2.5v SET_FLAG(ADC12CTL0, REF2_5V); // conversion start address SET_FLAG(ADC12CTL1, CSTARTADD_0); // really a zero, for clarity } SET_FLAG(ADC12MCTL0, INCH_5); // accel x SET_FLAG(ADC12MCTL1, INCH_4); // accel y SET_FLAG(ADC12MCTL2, INCH_3); // accel z SET_FLAG(ADC12MCTL3, INCH_1); // x gyro SET_FLAG(ADC12MCTL4, INCH_6); // y gyro SET_FLAG(ADC12MCTL5, INCH_2); // z gyro SET_FLAG(ADC12MCTL6, INCH_11); // (AVcc-AVss)/2 to monitor battery voltage SET_FLAG(ADC12MCTL6, EOS); //sez "this is the last reg" #ifdef USE_AVCC_REF // set reference to analog voltage AVcc CLR_FLAG(ADC12CTL0, REFON); CLR_FLAG(ADC12MCTL0, SREF_7); CLR_FLAG(ADC12MCTL1, SREF_7); CLR_FLAG(ADC12MCTL2, SREF_7); CLR_FLAG(ADC12MCTL3, SREF_7); CLR_FLAG(ADC12MCTL4, SREF_7); CLR_FLAG(ADC12MCTL5, SREF_7); CLR_FLAG(ADC12MCTL6, SREF_7); #else SET_FLAG(ADC12MCTL0, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL1, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL2, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL3, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL4, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL5, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL6, SREF_1); // Vref = Vref+ and Vr- #endif /* USE_AVCC_REF */ /* set up for three adc channels -> three adcmem regs -> three dma channels in round-robin */ /* clear init defaults first */ CLR_FLAG(ADC12CTL1, CONSEQ_2); // clear default repeat single channel SET_FLAG(ADC12CTL1, CONSEQ_1); // single sequence of channels setupDMA(); call DMA0.beginTransfer(); } command result_t StdControl.init() { register uint8_t i; call Leds.init(); #ifdef USE_8MHZ_CRYSTAL /* * set up 8mhz clock to max out * msp430 throughput */ atomic CLR_FLAG(BCSCTL1, XT2OFF); // basic clock system control reg, turn off XT2 osc call Leds.redOn(); do{ CLR_FLAG(IFG1, OFIFG); for(i = 0; i < 0xff; i++); } while(READ_FLAG(IFG1, OFIFG)); call Leds.redOff(); call Leds.yellowOn(); TOSH_uwait(50000UL); atomic{ BCSCTL2 = 0; SET_FLAG(BCSCTL2, SELM_2); /* select master clock source, XT2CLK when XT2 oscillator present */ } /*on-chip. LFXT1CLK when XT2 oscillator not present on-chip. */ call Leds.yellowOff(); atomic{ SET_FLAG(BCSCTL2, SELS); // smclk from xt2 SET_FLAG(BCSCTL2, DIVS_3); // divide it by 8 } /* * end clock set up */ #endif /* USE_8MHZ_CRYSTAL */ call AccelStdControl.init(); // pins for gyro, gyro enable TOSH_MAKE_ADC_1_INPUT(); // x TOSH_MAKE_ADC_2_INPUT(); // z TOSH_MAKE_ADC_6_INPUT(); // y TOSH_SEL_ADC_1_MODFUNC(); TOSH_SEL_ADC_2_MODFUNC(); TOSH_SEL_ADC_6_MODFUNC(); atomic { memset(tx_packet, 0, (FIXED_PACKET_SIZE*2)); enable_sending = FALSE; command_mode_complete = FALSE; activity_led_on = FALSE; } call BTStdControl.init(); call Bluetooth.disableRemoteConfig(TRUE); /* if CPU=8Mhz then customise roving networks baudrate to suit 8Mhz/9 baud */ /* call Bluetooth.setBaudrate("452"); */ dma_blocks = 0; return SUCCESS; } command result_t StdControl.start() { call BTStdControl.start(); /* so that the clinicians know the sensor is on */ call Leds.redOn(); #ifdef LOW_BATTERY_INDICATION /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); #ifdef DEBUG_LOW_BATTERY_INDICATION debug_counter = 0; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ return SUCCESS; } command result_t StdControl.stop() { call BTStdControl.stop(); return SUCCESS; } #ifdef LOW_BATTERY_INDICATION task void sendBatteryLowIndication() { uint16_t crc; char batt_low_str[] = "BATTERY LOW!"; /* stop all sensing - battery is below the threshold */ call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); /* send the battery low indication packet to BioMOBIUS */ tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = STRING_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; tx_packet[7] = FIXED_PAYLOAD_SIZE; memcpy(&tx_packet[8], &batt_low_str[0], 12); #ifdef DEBUG_LOW_BATTERY_INDICATION tx_packet[8] = (baseline_voltage) & 0xff; tx_packet[9] = ((baseline_voltage) >> 8) & 0xff; #endif /* DEBUG_LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); atomic enable_sending = FALSE; /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); } /* all samples are got so set the baseline voltage for this SHIMMER hardware */ void setBattVoltageBaseline() { baseline_voltage = (sum_batt_volt_samples / TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD); } /* check voltage level and if it is low then stop sampling, send message and disconnect */ void checkBattVoltageLevel(uint16_t battery_voltage) { #ifndef DEBUG_LOW_BATTERY_INDICATION if(battery_voltage < (baseline_voltage-BATTERY_LOW_INDICATION_OFFSET)) { #else //if(debug_counter++ == 500) { if(0) { #endif /* DEBUG_LOW_BATTERY_INDICATION */ linkDisconnecting = TRUE; } } /* keep checking the voltage level of the battery until it drops below the offset */ void monitorBattery() { uint16_t battery_voltage; if(current_buffer == 1) { battery_voltage = sbuf0[6]; } else { battery_voltage = sbuf1[6]; } if(need_baseline_voltage) { num_baseline_voltage_samples++; if(num_baseline_voltage_samples <= TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD) { /* add this sample to the total so that an average baseline can be obtained */ sum_batt_volt_samples += battery_voltage; } else { setBattVoltageBaseline(); need_baseline_voltage = FALSE; call Leds.orangeOff(); } } else { checkBattVoltageLevel(battery_voltage); } } #endif /* LOW_BATTERY_INDICATION */ /* The MSP430 CPU is byte addressed and little endian */ /* packets are sent little endian so the word 0xABCD will be sent as bytes 0xCD 0xAB */ void preparePacket() { uint16_t *p_packet, *p_ADCsamples, crc; tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = PROPRIETARY_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[7] = FIXED_PAYLOAD_SIZE; p_packet = (uint16_t *)&tx_packet[8]; if(current_buffer == 1) { p_ADCsamples = &sbuf0[0]; tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; } else { p_ADCsamples = &sbuf1[0]; tx_packet[5] = timestamp1 & 0xff; tx_packet[6] = (timestamp1 >> 8) & 0xff; } /* copy all the data samples into the outgoing packet */ *p_packet++ = *p_ADCsamples++; //tx_packet[8] *p_packet++ = *p_ADCsamples++; //tx_packet[10] *p_packet++ = *p_ADCsamples++; //tx_packet[12] *p_packet++ = *p_ADCsamples++; //tx_packet[14] *p_packet++ = *p_ADCsamples++; //tx_packet[16] *p_packet = *p_ADCsamples; //tx_packet[18] /* debug stuff - capture battery voltage to monitor discharge */ #ifdef DEBUG_LOW_BATTERY_INDICATION if(current_buffer == 1) { tx_packet[18] = (sbuf0[6]) & 0xff; tx_packet[19] = ((sbuf0[6]) >> 8) & 0xff; } else { tx_packet[18] = (sbuf1[6]) & 0xff; tx_packet[19] = ((sbuf1[6]) >> 8) & 0xff; } #endif /* LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; } task void sendSensorData() { #ifdef LOW_BATTERY_INDICATION monitorBattery(); #endif /* LOW_BATTERY_INDICATION */ atomic if(enable_sending) { preparePacket(); /* send data over the air */ call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); atomic enable_sending = FALSE; } } task void startSensing() { call ActivityTimer.start(TIMER_REPEAT, 1000); call AccelStdControl.start(); call Accel.setSensitivity(RANGE_4_0G); call SampleTimer.start(TIMER_REPEAT, sample_freq); TOSH_CLR_PROG_OUT_PIN(); // gyro enable low sampleADC(); } task void sendPersonality() { atomic if(enable_sending) { /* send data over the air */ call Bluetooth.write(&personality[0], 17); atomic enable_sending = FALSE; } } task void stopSensing() { call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); TOSH_SET_PROG_OUT_PIN(); // disable gyro } async event void Bluetooth.connectionMade(uint8_t status) { atomic enable_sending = TRUE; call Leds.greenOn(); } async event void Bluetooth.commandModeEnded() { atomic command_mode_complete = TRUE; } async event void Bluetooth.connectionClosed(uint8_t reason){ atomic enable_sending = FALSE; call Leds.greenOff(); //call Leds.redOn(); post stopSensing(); } async event void Bluetooth.dataAvailable(uint8_t data){ /* start capturing on ^G */ if(7 == data) { atomic if(command_mode_complete) { post startSensing(); } else { /* give config a chance, wait 5 secs */ call SetupTimer.start(TIMER_REPEAT, 5000); } } else if (data == 1) { post sendPersonality(); } /* stop capturing on spacebar */ else if (data == 32) { post stopSensing(); } else { /* were done */ } } event void Bluetooth.writeDone(){ atomic enable_sending = TRUE; #ifdef LOW_BATTERY_INDICATION if(linkDisconnecting) { linkDisconnecting = FALSE; /* signal battery low to master and let the master disconnect the link */ post sendBatteryLowIndication(); } #endif /* LOW_BATTERY_INDICATION */ } event result_t SetupTimer.fired() { atomic if(command_mode_complete){ call ActivityTimer.stop(); post startSensing(); } return SUCCESS; } event result_t ActivityTimer.fired() { atomic { /* toggle activity led every second */ if(activity_led_on) { call Leds.yellowOn(); activity_led_on = FALSE; } else { call Leds.yellowOff(); activity_led_on = TRUE; } } return SUCCESS; } event result_t SampleTimer.fired() { call DMA0.beginTransfer(); call DMA0.ADCbeginConversion(); return SUCCESS; } async event void DMA0.transferComplete() { dma_blocks++; //atomic DMA0DA += 12; if(dma_blocks == 1){ //this should be about 6 but for this test its 1 dma_blocks = 0; if(current_buffer == 0){ atomic DMA0DA = (uint16_t)&sbuf1[0]; atomic timestamp1 = call LocalTime.read(); current_buffer = 1; } else { atomic DMA0DA = (uint16_t)&sbuf0[0]; atomic timestamp0 = call LocalTime.read(); current_buffer = 0; } post sendSensorData(); } } async event void DMA0.ADCInterrupt(uint8_t regnum) { // we should *not* see this, as the adc interrupts are eaten by the dma controller! /* Turn on all LEDs */ call Leds.set(0x0F); } } --- NEW FILE: Makefile --- COMPONENT=AccelGyro include ../../Makerules From ayer1 at users.sourceforge.net Thu Apr 10 07:28:27 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:28:27 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AnEx AnEx.h, NONE, 1.1 AnEx.nc, NONE, 1.1 AnExM.nc, NONE, 1.1 Makefile, NONE, 1.1 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AnEx In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7732/BioMOBIUS/AnEx Added Files: AnEx.h AnEx.nc AnExM.nc Makefile Log Message: from adrian burns (intel ireland): All files in apps/BioMOBIUS/*.* Generic app (Tested on SHIMMER) compatible with BioMOBIUS 1.0 PC Software, see http://www.biomobius.org for more info. --- NEW FILE: AnEx.h --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Authors: Adrian Burns * September, 2007 */ #ifndef ANEX_H #define ANEX_H enum { NUM_ACCEL_CHANS = 3 }; enum { NUM_GYRO_CHANS = 3 }; enum { SHIMMER_REV1 = 0 }; enum { PROPRIETARY_DATA_TYPE = 0xFF, STRING_DATA_TYPE = 0xFE }; enum { SAMPLING_1000HZ = 1, SAMPLING_500HZ = 2, SAMPLING_250HZ = 4, SAMPLING_200HZ = 5, SAMPLING_166HZ = 6, SAMPLING_100HZ = 10, SAMPLING_50HZ = 20, SAMPLING_0HZ_OFF = 255 }; enum { FRAMING_SIZE = 0x4, FRAMING_CE_COMP = 0x20, FRAMING_CE_CE = 0x5D, FRAMING_CE = 0x7D, FRAMING_BOF = 0xC0, FRAMING_EOF = 0xC1, FRAMING_BOF_CE = 0xE0, FRAMING_EOF_CE = 0xE1, }; #endif // ANEX_H --- NEW FILE: AnEx.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app uses Bluetooth to stream 2 channels of raw ADC data from the SHIMMER Analog Extension board to a BioMOBIUS PC application. Tested on SHIMMER Base Board Rev 1.3, SHIMMER AnEx Rev A Board. ***********************************************************************************/ configuration AnEx { } implementation { components Main, DMA_M, MMA7260_AccelM, AnExM, RovingNetworksC, TimerC, LedsC; Main.StdControl -> AnExM; Main.StdControl -> TimerC; AnExM.Leds -> LedsC; AnExM.SampleTimer -> TimerC.Timer[unique("Timer")]; AnExM.SetupTimer -> TimerC.Timer[unique("Timer")]; AnExM.ActivityTimer -> TimerC.Timer[unique("Timer")]; AnExM.LocalTime -> TimerC; AnExM.BTStdControl -> RovingNetworksC; AnExM.Bluetooth -> RovingNetworksC; /* have to fix compile time channel limitation */ AnExM.DMA0 -> DMA_M.DMA[0]; //AnExM.DMA1 -> DMA_M.DMA[1]; //AnExM.DMA2 -> DMA_M.DMA[2]; AnExM.AccelStdControl -> MMA7260_AccelM; AnExM.Accel -> MMA7260_AccelM; } --- NEW FILE: AnExM.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app uses Bluetooth to stream 2 channels of raw ADC data from the SHIMMER Analog Extension board to a BioMOBIUS PC application. Tested on SHIMMER Base Board Rev 1.3, SHIMMER AnEx Rev A Board. LOW_BATTERY_INDICATION if defined stops the app streaming data just after the battery voltage drops below the regulator value of 3V. Default Sample Frequency: 500 hz Packet Format: BOF| Sensor ID | Data Type | Seq No. | TimeStamp | Len | AnEx (ADC0) | AnEx (ADC7) | CRC | EOF Byte: 1 | 2 | 3 | 4 | 5-6 | 7 | 8-9 | 10-11 | 12-13| 14 ***********************************************************************************/ includes crc; includes AnEx; includes DMA; includes MMA7260_Accel; includes Message; includes RovingNetworks; module AnExM { provides{ interface StdControl; } uses { interface DMA as DMA0; interface StdControl as AccelStdControl; interface MMA7260_Accel as Accel; interface StdControl as BTStdControl; interface Bluetooth; interface Leds; interface Timer as SetupTimer; interface Timer as ActivityTimer; interface Timer as SampleTimer; interface LocalTime; } } implementation { extern int sprintf(char *str, const char *format, ...) __attribute__ ((C)); #define USE_8MHZ_CRYSTAL #define LOW_BATTERY_INDICATION #define USE_AVCC_REF /* approx 0.5 milliamps saving when using AVCC compared to 2.5V or 1.5V internal ref */ #ifdef LOW_BATTERY_INDICATION //#define DEBUG_LOW_BATTERY_INDICATION /* during testing of the the (AVcc-AVss)/2 value from the ADC on various SHIMMERS, to get a reliable cut off point to recharge the battery it is important to find the baseline (AVcc-AVss)/2 value coming from the ADC as it varies from SHIMMER to SHIMMER, however the range of fluctuation is pretty constant and (AVcc-AVss)/2 provides an accurate battery low indication that prevents getting any voltage skewed data from the accelerometer or add-on board sensors */ #define TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD 1000 #define BATTERY_LOW_INDICATION_OFFSET 20 /* (AVcc - AVss)/2 = Approx 3V-0V/2 = 1.5V, 12 bit ADC with 2.5V REF, 4096/2500 = 1mV=1.6384 units */ #define FIXED_STRING_PACKET_SIZE 22 #define FIXED_STRING_PAYLOAD_SIZE 12 uint8_t tx_string_packet[(FIXED_STRING_PACKET_SIZE*2)+1]; bool need_baseline_voltage, link_disconnecting; uint16_t num_baseline_voltage_samples, baseline_voltage; uint32_t sum_batt_volt_samples; #ifdef DEBUG_LOW_BATTERY_INDICATION uint16_t debug_counter; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ #define FIXED_PACKET_SIZE 14 #define FIXED_PAYLOAD_SIZE 4 #define TX_BUFFER_SIZE (FIXED_PACKET_SIZE*2)+1 /* (*2)twice size because of byte stuffing */ uint8_t tx_packet[TX_BUFFER_SIZE]; /* (+1)MSP430 CPU can only read/write 16-bit values at even addresses, /* so use an empty byte to even up the memory locations for 16-bit values */ const uint8_t personality[17] = { 0,1,2,3,4,5,0xFF,0xFF, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_0HZ_OFF,SAMPLING_0HZ_OFF,FRAMING_EOF }; norace uint8_t current_buffer = 0, dma_blocks = 0; uint16_t sbuf0[36], sbuf1[36], timestamp0, timestamp1; /* default sample frequency every time the sensor boots up */ uint16_t sample_freq = SAMPLING_500HZ; bool enable_sending, command_mode_complete, activity_led_on; /* Internal function to calculate 16 bit CRC */ uint16_t calc_crc(uint8_t *ptr, uint8_t count) { uint16_t crc; crc = 0; while (count-- > 0) crc = crcByte(crc, *ptr++); return crc; } void setupDMA() { call DMA0.init(); call DMA0.setSourceAddress((uint16_t)ADC12MEM0_); call DMA0.setDestinationAddress((uint16_t)&sbuf0[0]); /* * we'll transfer from six sequential adcmem registers * to six sequential addresses in a buffer */ call DMA0.setBlockSize(3); // we want block transfer, single DMA0CTL = DMADT_1 + DMADSTINCR_3 + DMASRCINCR_3; } void sampleADC() { call DMA0.ADCinit(); // this doesn't really need to be parameterized atomic{ CLR_FLAG(ADC12CTL1, ADC12SSEL_3); // clr clk from smclk SET_FLAG(ADC12CTL1, ADC12SSEL_3); // clk from aclk /* with a 125khz clock (_7) it 136usec per conversion, 136*6=816usec in total */ SET_FLAG(ADC12CTL1, ADC12DIV_7); // sample and hold time four adc12clk cycles SET_FLAG(ADC12CTL0, SHT0_0); // set reference voltage to 2.5v SET_FLAG(ADC12CTL0, REF2_5V); // conversion start address SET_FLAG(ADC12CTL1, CSTARTADD_0); // really a zero, for clarity } SET_FLAG(ADC12MCTL0, INCH_0); // AnEx_LALL SET_FLAG(ADC12MCTL1, INCH_7); // AnEx_RALL SET_FLAG(ADC12MCTL2, INCH_11); // (AVcc-AVss)/2 to monitor battery voltage SET_FLAG(ADC12MCTL2, EOS); //sez "this is the last reg" #ifdef USE_AVCC_REF // set reference to analog voltage AVcc CLR_FLAG(ADC12CTL0, REFON); CLR_FLAG(ADC12MCTL0, SREF_7); CLR_FLAG(ADC12MCTL1, SREF_7); CLR_FLAG(ADC12MCTL2, SREF_7); #else SET_FLAG(ADC12MCTL0, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL1, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL2, SREF_1); // Vref = Vref+ and Vr- #endif /* USE_AVCC_REF */ /* set up for three adc channels -> three adcmem regs -> three dma channels in round-robin */ /* clear init defaults first */ CLR_FLAG(ADC12CTL1, CONSEQ_2); // clear default repeat single channel SET_FLAG(ADC12CTL1, CONSEQ_1); // single sequence of channels setupDMA(); call DMA0.beginTransfer(); } command result_t StdControl.init() { register uint8_t i; call Leds.init(); #ifdef USE_8MHZ_CRYSTAL /* * set up 8mhz clock to max out * msp430 throughput */ atomic CLR_FLAG(BCSCTL1, XT2OFF); // basic clock system control reg, turn off XT2 osc call Leds.redOn(); do{ CLR_FLAG(IFG1, OFIFG); for(i = 0; i < 0xff; i++); } while(READ_FLAG(IFG1, OFIFG)); call Leds.redOff(); call Leds.yellowOn(); TOSH_uwait(50000UL); atomic{ BCSCTL2 = 0; SET_FLAG(BCSCTL2, SELM_2); /* select master clock source, XT2CLK when XT2 oscillator present */ } /*on-chip. LFXT1CLK when XT2 oscillator not present on-chip. */ call Leds.yellowOff(); atomic{ SET_FLAG(BCSCTL2, SELS); // smclk from xt2 SET_FLAG(BCSCTL2, DIVS_3); // divide it by 8 } /* * end clock set up */ #endif /* USE_8MHZ_CRYSTAL */ /* let SER0_RTS be output, pin high enables the -/+5VDC regulator on AnEx Board */ TOSH_MAKE_SER0_RTS_OUTPUT(); TOSH_SEL_SER0_RTS_IOFUNC(); TOSH_SET_SER0_RTS_PIN(); call AccelStdControl.init(); TOSH_MAKE_ADC_0_INPUT(); // x TOSH_MAKE_ADC_7_INPUT(); // z TOSH_SEL_ADC_0_MODFUNC(); // x TOSH_SEL_ADC_7_MODFUNC(); // z atomic { memset(tx_packet, 0, TX_BUFFER_SIZE); //memset(&packet, 0, sizeof(Packet_t)); enable_sending = FALSE; command_mode_complete = FALSE; activity_led_on = FALSE; } call BTStdControl.init(); call Bluetooth.disableRemoteConfig(TRUE); /* if CPU=8Mhz then customise roving networks baudrate to suit 8Mhz/9 baud */ /* call Bluetooth.setBaudrate("452"); */ dma_blocks = 0; return SUCCESS; } command result_t StdControl.start() { call BTStdControl.start(); /* so that the clinicians know the sensor is on */ call Leds.redOn(); #ifdef LOW_BATTERY_INDICATION /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); #ifdef DEBUG_LOW_BATTERY_INDICATION debug_counter = 0; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ return SUCCESS; } command result_t StdControl.stop() { call BTStdControl.stop(); return SUCCESS; } #ifdef LOW_BATTERY_INDICATION task void sendBatteryLowIndication() { uint16_t crc; char batt_low_str[] = "BATTERY LOW!"; /* stop all sensing - battery is below the threshold */ call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); /* send the battery low indication packet to BioMOBIUS */ tx_string_packet[1] = FRAMING_BOF; tx_string_packet[2] = SHIMMER_REV1; tx_string_packet[3] = STRING_DATA_TYPE; tx_string_packet[4]++; /* increment sequence number */ tx_string_packet[5] = timestamp0 & 0xff; tx_string_packet[6] = (timestamp0 >> 8) & 0xff; tx_string_packet[7] = FIXED_STRING_PAYLOAD_SIZE; memcpy(&tx_string_packet[8], &batt_low_str[0], 12); #ifdef DEBUG_LOW_BATTERY_INDICATION tx_string_packet[8] = (baseline_voltage) & 0xff; tx_string_packet[9] = ((baseline_voltage) >> 8) & 0xff; #endif /* DEBUG_LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_string_packet[2], (FIXED_STRING_PACKET_SIZE-FRAMING_SIZE)); tx_string_packet[FIXED_STRING_PACKET_SIZE - 2] = crc & 0xff; tx_string_packet[FIXED_STRING_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_string_packet[FIXED_STRING_PACKET_SIZE] = FRAMING_EOF; call Bluetooth.write(&tx_string_packet[1], FIXED_STRING_PACKET_SIZE); atomic enable_sending = FALSE; /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); } /* all samples are got so set the baseline voltage for this SHIMMER hardware */ void setBattVoltageBaseline() { baseline_voltage = (sum_batt_volt_samples / TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD); } /* check voltage level and if it is low then stop sampling, send message and disconnect */ void checkBattVoltageLevel(uint16_t battery_voltage) { #ifndef DEBUG_LOW_BATTERY_INDICATION if(battery_voltage < (baseline_voltage-BATTERY_LOW_INDICATION_OFFSET)) { #else if(debug_counter++ == 2500) { #endif /* DEBUG_LOW_BATTERY_INDICATION */ link_disconnecting = TRUE; } } /* keep checking the voltage level of the battery until it drops below the offset */ void monitorBattery() { uint16_t battery_voltage; if(current_buffer == 1) { battery_voltage = sbuf0[2]; } else { battery_voltage = sbuf1[2]; } if(need_baseline_voltage) { num_baseline_voltage_samples++; if(num_baseline_voltage_samples <= TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD) { /* add this sample to the total so that an average baseline can be obtained */ sum_batt_volt_samples += battery_voltage; } else { setBattVoltageBaseline(); need_baseline_voltage = FALSE; call Leds.orangeOff(); } } else { checkBattVoltageLevel(battery_voltage); } } #endif /* LOW_BATTERY_INDICATION */ /* The MSP430 CPU is byte addressed and little endian */ /* packets are sent little endian so the word 0xABCD will be sent as bytes 0xCD 0xAB */ void preparePacket() { uint16_t *p_packet, *p_ADCsamples, crc; tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = PROPRIETARY_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[7] = FIXED_PAYLOAD_SIZE; p_packet = (uint16_t *)&tx_packet[8]; if(current_buffer == 1) { p_ADCsamples = &sbuf0[0]; tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; } else { p_ADCsamples = &sbuf1[0]; tx_packet[5] = timestamp1 & 0xff; tx_packet[6] = (timestamp1 >> 8) & 0xff; } /* copy all the data samples into the outgoing packet */ *p_packet++ = *p_ADCsamples++; //tx_packet[8] *p_packet = *p_ADCsamples; //tx_packet[10] /* debug stuff - capture battery voltage to monitor discharge */ #ifdef DEBUG_LOW_BATTERY_INDICATION if(current_buffer == 1) { tx_packet[8] = (sbuf0[2]) & 0xff; tx_packet[9] = ((sbuf0[2]) >> 8) & 0xff; } else { tx_packet[8] = (sbuf1[2]) & 0xff; tx_packet[9] = ((sbuf1[2]) >> 8) & 0xff; } #endif /* LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; } task void sendSensorData() { #ifdef LOW_BATTERY_INDICATION monitorBattery(); #endif /* LOW_BATTERY_INDICATION */ atomic if(enable_sending) { preparePacket(); /* send data over the air */ call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); enable_sending = FALSE; } } task void startSensing() { call ActivityTimer.start(TIMER_REPEAT, 1000); call AccelStdControl.start(); call Accel.setSensitivity(RANGE_4_0G); call SampleTimer.start(TIMER_REPEAT, sample_freq); sampleADC(); } task void sendPersonality() { atomic if(enable_sending) { /* send data over the air */ call Bluetooth.write(&personality[0], 17); atomic enable_sending = FALSE; } } task void stopSensing() { call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); } async event void Bluetooth.connectionMade(uint8_t status) { atomic enable_sending = TRUE; call Leds.greenOn(); } async event void Bluetooth.commandModeEnded() { atomic command_mode_complete = TRUE; //call Leds.orangeOn(); } async event void Bluetooth.connectionClosed(uint8_t reason){ atomic enable_sending = FALSE; call Leds.greenOff(); post stopSensing(); } async event void Bluetooth.dataAvailable(uint8_t data){ /* start capturing on ^G */ if(7 == data) { atomic if(command_mode_complete) { post startSensing(); } else { //call Leds.redOn(); /* give config a chance, wait 5 secs */ call SetupTimer.start(TIMER_REPEAT, 5000); } } else if (data == 1) { post sendPersonality(); } /* stop capturing on spacebar */ else if (data == 32) { post stopSensing(); } else { /* were done */ } } event void Bluetooth.writeDone(){ atomic enable_sending = TRUE; #ifdef LOW_BATTERY_INDICATION if(link_disconnecting) { link_disconnecting = FALSE; /* signal battery low to master and let the master disconnect the link */ post sendBatteryLowIndication(); } #endif /* LOW_BATTERY_INDICATION */ } event result_t SetupTimer.fired() { atomic if(command_mode_complete){ call ActivityTimer.stop(); post startSensing(); } return SUCCESS; } event result_t ActivityTimer.fired() { atomic { /* toggle activity led every second */ if(activity_led_on) { call Leds.yellowOn(); activity_led_on = FALSE; } else { call Leds.yellowOff(); activity_led_on = TRUE; } } return SUCCESS; } event result_t SampleTimer.fired() { call DMA0.beginTransfer(); call DMA0.ADCbeginConversion(); return SUCCESS; } async event void DMA0.transferComplete() { dma_blocks++; //atomic DMA0DA += 12; if(dma_blocks == 1){ //this should be about 6 but for this test its 1 dma_blocks = 0; if(current_buffer == 0){ atomic DMA0DA = (uint16_t)&sbuf1[0]; atomic timestamp1 = call LocalTime.read(); current_buffer = 1; } else { atomic DMA0DA = (uint16_t)&sbuf0[0]; atomic timestamp0 = call LocalTime.read(); current_buffer = 0; } post sendSensorData(); } } async event void DMA0.ADCInterrupt(uint8_t regnum) { // we should *not* see this, as the adc interrupts are eaten by the dma controller! /* Turn on all LEDs */ call Leds.set(0x0F); } } --- NEW FILE: Makefile --- COMPONENT=AnEx include ../../Makerules From ayer1 at users.sourceforge.net Thu Apr 10 07:28:27 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:28:27 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelECG AccelECG.h, NONE, 1.1 AccelECG.nc, NONE, 1.1 AccelECGM.nc, NONE, 1.1 Makefile, NONE, 1.1 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/AccelECG In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7732/BioMOBIUS/AccelECG Added Files: AccelECG.h AccelECG.nc AccelECGM.nc Makefile Log Message: from adrian burns (intel ireland): All files in apps/BioMOBIUS/*.* Generic app (Tested on SHIMMER) compatible with BioMOBIUS 1.0 PC Software, see http://www.biomobius.org for more info. --- NEW FILE: AccelECG.h --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ #ifndef ACCELECG_H #define ACCELECG_H enum { NUM_ACCEL_CHANS = 3 }; enum { NUM_GYRO_CHANS = 3 }; enum { SHIMMER_REV1 = 0 }; enum { PROPRIETARY_DATA_TYPE = 0xFF, STRING_DATA_TYPE = 0xFE }; enum { SAMPLING_1000HZ = 1, SAMPLING_500HZ = 2, SAMPLING_250HZ = 4, SAMPLING_200HZ = 5, SAMPLING_166HZ = 6, SAMPLING_125HZ = 8, SAMPLING_100HZ = 10, SAMPLING_50HZ = 20, SAMPLING_10HZ = 100, SAMPLING_0HZ_OFF = 255 }; enum { FRAMING_SIZE = 0x4, FRAMING_CE_COMP = 0x20, FRAMING_CE_CE = 0x5D, FRAMING_CE = 0x7D, FRAMING_BOF = 0xC0, FRAMING_EOF = 0xC1, FRAMING_BOF_CE = 0xE0, FRAMING_EOF_CE = 0xE1, }; #endif // ACCELECG_H --- NEW FILE: AccelECG.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /* This app uses Bluetooth to stream 3 Accelerometer channels and 2 ECG channels of data to a BioMOBIUS PC application. Tested on SHIMMER Base Board Rev 1.3, SHIMMER ECG board Rev 1.1. */ configuration AccelECG { } implementation { components Main, DMA_M, MMA7260_AccelM, AccelECGM, RovingNetworksC, TimerC, LedsC; Main.StdControl -> AccelECGM; Main.StdControl -> TimerC; AccelECGM.Leds -> LedsC; AccelECGM.SampleTimer -> TimerC.Timer[unique("Timer")]; AccelECGM.SetupTimer -> TimerC.Timer[unique("Timer")]; AccelECGM.ActivityTimer -> TimerC.Timer[unique("Timer")]; AccelECGM.LocalTime -> TimerC; AccelECGM.BTStdControl -> RovingNetworksC; AccelECGM.Bluetooth -> RovingNetworksC; /* have to fix compile time channel limitation */ AccelECGM.DMA0 -> DMA_M.DMA[0]; //AccelECGM.DMA1 -> DMA_M.DMA[1]; //AccelECGM.DMA2 -> DMA_M.DMA[2]; AccelECGM.AccelStdControl -> MMA7260_AccelM; AccelECGM.Accel -> MMA7260_AccelM; } --- NEW FILE: AccelECGM.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app uses Bluetooth to stream 3 Accelerometer channels and 2 ECG channels of data to a BioMOBIUS PC application. Tested on SHIMMER Base Board Rev 1.3, SHIMMER ECG board Rev 1.1. LOW_BATTERY_INDICATION if defined stops the app streaming data just after the battery voltage drops below the regulator value of 3V. Default Sample Frequency: 100 hz Packet Format: BOF| Sensor ID | Data Type | Seq No. | TimeStamp | Len | Acc | Acc | Acc | ECG | ECG | Dummy| CRC | EOF Byte: 1 | 2 | 3 | 4 | 5-6 | 7 | 8-9 | 10-11| 12-13| 14-15 | 16-17| 18-19| 20-21| 22 ***********************************************************************************/ includes crc; includes AccelECG; includes DMA; includes MMA7260_Accel; includes Message; includes RovingNetworks; module AccelECGM { provides{ interface StdControl; } uses { interface DMA as DMA0; interface StdControl as AccelStdControl; interface MMA7260_Accel as Accel; interface StdControl as BTStdControl; interface Bluetooth; interface Leds; interface Timer as SetupTimer; interface Timer as ActivityTimer; interface Timer as SampleTimer; interface LocalTime; } } implementation { extern int sprintf(char *str, const char *format, ...) __attribute__ ((C)); #define USE_8MHZ_CRYSTAL #define LOW_BATTERY_INDICATION #define USE_AVCC_REF /* approx 0.5 milliamps saving when using AVCC compared to 2.5V or 1.5V internal ref */ #ifdef LOW_BATTERY_INDICATION //#define DEBUG_LOW_BATTERY_INDICATION /* during testing of the the (AVcc-AVss)/2 value from the ADC on various SHIMMERS, to get a reliable cut off point to recharge the battery it is important to find the baseline (AVcc-AVss)/2 value coming from the ADC as it varies from SHIMMER to SHIMMER, however the range of fluctuation is pretty constant and (AVcc-AVss)/2 provides an accurate battery low indication that prevents getting any voltage skewed data from the accelerometer or add-on board sensors */ #define TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD 1000 #define BATTERY_LOW_INDICATION_OFFSET 20 /* (AVcc - AVss)/2 = Approx 3V-0V/2 = 1.5V, 12 bit ADC with 2.5V REF, 4096/2500 = 1mV=1.6384 units */ bool need_baseline_voltage, linkDisconnecting; uint16_t num_baseline_voltage_samples, baseline_voltage; uint32_t sum_batt_volt_samples; #ifdef DEBUG_LOW_BATTERY_INDICATION #error "were going for debug mode yea?, comment me out then" uint16_t debug_counter; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ #define FIXED_PACKET_SIZE 22 #define FIXED_PAYLOAD_SIZE 12 uint8_t tx_packet[(FIXED_PACKET_SIZE*2)+1]; /* (*2)twice size because of byte stuffing */ /* (+1)MSP430 CPU can only read/write 16-bit values at even addresses, /* so use an empty byte to even up the memory locations for 16-bit values */ const uint8_t personality[17] = { 0,1,2,3,4,5,0xFF,0xFF, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_0HZ_OFF,SAMPLING_0HZ_OFF,FRAMING_EOF }; norace uint8_t current_buffer = 0, dma_blocks = 0; uint16_t sbuf0[36], sbuf1[36], timestamp0, timestamp1; /* default sample frequency every time the sensor boots up */ uint16_t sample_freq = SAMPLING_100HZ; bool enable_sending, command_mode_complete, activity_led_on; /* Internal function to calculate 16 bit CRC */ uint16_t calc_crc(uint8_t *ptr, uint8_t count) { uint16_t crc; crc = 0; while (count-- > 0) crc = crcByte(crc, *ptr++); return crc; } void setupDMA() { call DMA0.init(); call DMA0.setSourceAddress((uint16_t)ADC12MEM0_); call DMA0.setDestinationAddress((uint16_t)&sbuf0[0]); /* * we'll transfer from six sequential adcmem registers * to six sequential addresses in a buffer */ call DMA0.setBlockSize(6); // we want block transfer, single DMA0CTL = DMADT_1 + DMADSTINCR_3 + DMASRCINCR_3; } void sampleADC() { call DMA0.ADCinit(); // this doesn't really need to be parameterized atomic{ CLR_FLAG(ADC12CTL1, ADC12SSEL_3); // clr clk from smclk SET_FLAG(ADC12CTL1, ADC12SSEL_3); // clk from aclk /* with a 125khz clock (_7) its 136usec per conversion, 136*6=816usec in total */ SET_FLAG(ADC12CTL1, ADC12DIV_7); // sample and hold time four adc12clk cycles SET_FLAG(ADC12CTL0, SHT0_0); // set reference voltage to 2.5v SET_FLAG(ADC12CTL0, REF2_5V); // conversion start address SET_FLAG(ADC12CTL1, CSTARTADD_0); // really a zero, for clarity } SET_FLAG(ADC12MCTL0, INCH_5); // accel x SET_FLAG(ADC12MCTL1, INCH_4); // accel y SET_FLAG(ADC12MCTL2, INCH_3); // accel z SET_FLAG(ADC12MCTL3, INCH_1); // ECG_LALL SET_FLAG(ADC12MCTL4, INCH_2); // ECG_RALL SET_FLAG(ADC12MCTL5, INCH_11); // (AVcc-AVss)/2 to monitor battery voltage SET_FLAG(ADC12MCTL5, EOS); //sez "this is the last reg" #ifdef USE_AVCC_REF // set reference to analog voltage AVcc CLR_FLAG(ADC12CTL0, REFON); CLR_FLAG(ADC12MCTL0, SREF_7); CLR_FLAG(ADC12MCTL1, SREF_7); CLR_FLAG(ADC12MCTL2, SREF_7); CLR_FLAG(ADC12MCTL3, SREF_7); CLR_FLAG(ADC12MCTL4, SREF_7); CLR_FLAG(ADC12MCTL5, SREF_7); #else SET_FLAG(ADC12MCTL0, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL1, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL2, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL3, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL4, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL5, SREF_1); // Vref = Vref+ and Vr- #endif /* USE_AVCC_REF */ /* set up for three adc channels -> three adcmem regs -> three dma channels in round-robin */ /* clear init defaults first */ CLR_FLAG(ADC12CTL1, CONSEQ_2); // clear default repeat single channel SET_FLAG(ADC12CTL1, CONSEQ_1); // single sequence of channels setupDMA(); call DMA0.beginTransfer(); } command result_t StdControl.init() { register uint8_t i; call Leds.init(); #ifdef USE_8MHZ_CRYSTAL /* * set up 8mhz clock to max out * msp430 throughput */ atomic CLR_FLAG(BCSCTL1, XT2OFF); // basic clock system control reg, turn off XT2 osc call Leds.redOn(); do{ CLR_FLAG(IFG1, OFIFG); for(i = 0; i < 0xff; i++); } while(READ_FLAG(IFG1, OFIFG)); call Leds.redOff(); call Leds.yellowOn(); TOSH_uwait(50000UL); atomic{ BCSCTL2 = 0; SET_FLAG(BCSCTL2, SELM_2); /* select master clock source, XT2CLK when XT2 oscillator present */ } /*on-chip. LFXT1CLK when XT2 oscillator not present on-chip. */ call Leds.yellowOff(); atomic{ SET_FLAG(BCSCTL2, SELS); // smclk from xt2 SET_FLAG(BCSCTL2, DIVS_3); // divide it by 8 } /* * end clock set up */ #endif /* USE_8MHZ_CRYSTAL */ call AccelStdControl.init(); TOSH_MAKE_ADC_1_INPUT(); // ECG_LALL TOSH_MAKE_ADC_2_INPUT(); // ECG_RALL TOSH_SEL_ADC_1_MODFUNC(); TOSH_SEL_ADC_2_MODFUNC(); atomic { memset(tx_packet, 0, (FIXED_PACKET_SIZE*2)); enable_sending = FALSE; command_mode_complete = FALSE; activity_led_on = FALSE; } call BTStdControl.init(); call Bluetooth.disableRemoteConfig(TRUE); /* if CPU=8Mhz then customise roving networks baudrate to suit 8Mhz/9 baud */ /* call Bluetooth.setBaudrate("452"); */ dma_blocks = 0; return SUCCESS; } command result_t StdControl.start() { //call Bluetooth.resetDefaults(); call BTStdControl.start(); /* so that the clinicians know the sensor is on */ call Leds.redOn(); #ifdef LOW_BATTERY_INDICATION /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); #ifdef DEBUG_LOW_BATTERY_INDICATION debug_counter = 0; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ return SUCCESS; } command result_t StdControl.stop() { call BTStdControl.stop(); return SUCCESS; } #ifdef LOW_BATTERY_INDICATION task void sendBatteryLowIndication() { uint16_t crc; char batt_low_str[] = "BATTERY LOW!"; /* stop all sensing - battery is below the threshold */ call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); /* send the battery low indication packet to BioMOBIUS */ tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = STRING_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; tx_packet[7] = FIXED_PAYLOAD_SIZE; memcpy(&tx_packet[8], &batt_low_str[0], 12); #ifdef DEBUG_LOW_BATTERY_INDICATION tx_packet[8] = (baseline_voltage) & 0xff; tx_packet[9] = ((baseline_voltage) >> 8) & 0xff; #endif /* DEBUG_LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); atomic enable_sending = FALSE; /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); } /* all samples are got so set the baseline voltage for this SHIMMER hardware */ void setBattVoltageBaseline() { baseline_voltage = (sum_batt_volt_samples / TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD); } /* check voltage level and if it is low then stop sampling, send message and disconnect */ void checkBattVoltageLevel(uint16_t battery_voltage) { #ifndef DEBUG_LOW_BATTERY_INDICATION if(battery_voltage < (baseline_voltage-BATTERY_LOW_INDICATION_OFFSET)) { #else if(debug_counter++ == 2500) { #endif /* DEBUG_LOW_BATTERY_INDICATION */ linkDisconnecting = TRUE; } } /* keep checking the voltage level of the battery until it drops below the offset */ void monitorBattery() { uint16_t battery_voltage; if(current_buffer == 1) { battery_voltage = sbuf0[5]; } else { battery_voltage = sbuf1[5]; } if(need_baseline_voltage) { num_baseline_voltage_samples++; if(num_baseline_voltage_samples <= TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD) { /* add this sample to the total so that an average baseline can be obtained */ sum_batt_volt_samples += battery_voltage; } else { setBattVoltageBaseline(); need_baseline_voltage = FALSE; call Leds.orangeOff(); } } else { checkBattVoltageLevel(battery_voltage); } } #endif /* LOW_BATTERY_INDICATION */ /* The MSP430 CPU is byte addressed and little endian */ /* packets are sent little endian so the word 0xABCD will be sent as bytes 0xCD 0xAB */ void preparePacket() { uint16_t *p_packet, *p_ADCsamples, crc; tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = PROPRIETARY_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[7] = FIXED_PAYLOAD_SIZE; p_packet = (uint16_t *)&tx_packet[8]; if(current_buffer == 1) { p_ADCsamples = &sbuf0[0]; tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; } else { p_ADCsamples = &sbuf1[0]; tx_packet[5] = timestamp1 & 0xff; tx_packet[6] = (timestamp1 >> 8) & 0xff; } /* copy all the data samples into the outgoing packet */ *p_packet++ = *p_ADCsamples++; //tx_packet[8] *p_packet++ = *p_ADCsamples++; //tx_packet[10] *p_packet++ = *p_ADCsamples++; //tx_packet[12] *p_packet++ = *p_ADCsamples++; //tx_packet[14] *p_packet = *p_ADCsamples; //tx_packet[16] /* spare room in the packet so send the battery voltage data */ if(current_buffer == 1) { tx_packet[18] = (sbuf0[5]) & 0xff; tx_packet[19] = ((sbuf0[5]) >> 8) & 0xff; } else { tx_packet[18] = (sbuf1[5]) & 0xff; tx_packet[19] = ((sbuf1[5]) >> 8) & 0xff; } crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; } task void sendSensorData() { #ifdef LOW_BATTERY_INDICATION monitorBattery(); #endif /* LOW_BATTERY_INDICATION */ atomic if(enable_sending) { preparePacket(); /* send data over the air */ call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); atomic enable_sending = FALSE; } } task void startSensing() { call ActivityTimer.start(TIMER_REPEAT, 1000); call AccelStdControl.start(); call Accel.setSensitivity(RANGE_4_0G); call SampleTimer.start(TIMER_REPEAT, sample_freq); sampleADC(); } task void sendPersonality() { atomic if(enable_sending) { /* send data over the air */ call Bluetooth.write(&personality[0], 17); atomic enable_sending = FALSE; } } task void stopSensing() { call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); } async event void Bluetooth.connectionMade(uint8_t status) { atomic enable_sending = TRUE; call Leds.greenOn(); } async event void Bluetooth.commandModeEnded() { atomic command_mode_complete = TRUE; } async event void Bluetooth.connectionClosed(uint8_t reason){ atomic enable_sending = FALSE; call Leds.greenOff(); post stopSensing(); } async event void Bluetooth.dataAvailable(uint8_t data){ /* start capturing on ^G */ if(7 == data) { atomic if(command_mode_complete) { post startSensing(); } else { /* give config a chance, wait 5 secs */ call SetupTimer.start(TIMER_REPEAT, 5000); } } else if (data == 1) { post sendPersonality(); } /* stop capturing on spacebar */ else if (data == 32) { post stopSensing(); } else { /* were done */ } } event void Bluetooth.writeDone(){ atomic enable_sending = TRUE; #ifdef LOW_BATTERY_INDICATION if(linkDisconnecting) { linkDisconnecting = FALSE; /* signal battery low to master and let the master disconnect the link */ post sendBatteryLowIndication(); } #endif /* LOW_BATTERY_INDICATION */ } event result_t SetupTimer.fired() { atomic if(command_mode_complete){ call ActivityTimer.stop(); post startSensing(); } return SUCCESS; } event result_t ActivityTimer.fired() { atomic { /* toggle activity led every second */ if(activity_led_on) { call Leds.yellowOn(); activity_led_on = FALSE; } else { call Leds.yellowOff(); activity_led_on = TRUE; } } return SUCCESS; } event result_t SampleTimer.fired() { call DMA0.beginTransfer(); call DMA0.ADCbeginConversion(); return SUCCESS; } async event void DMA0.transferComplete() { dma_blocks++; //atomic DMA0DA += 12; if(dma_blocks == 1){ //this should be about 6 but for this test its 1 dma_blocks = 0; if(current_buffer == 0){ atomic DMA0DA = (uint16_t)&sbuf1[0]; atomic timestamp1 = call LocalTime.read(); current_buffer = 1; } else { atomic DMA0DA = (uint16_t)&sbuf0[0]; atomic timestamp0 = call LocalTime.read(); current_buffer = 0; } post sendSensorData(); } } async event void DMA0.ADCInterrupt(uint8_t regnum) { // we should *not* see this, as the adc interrupts are eaten by the dma controller! /* Turn on all LEDs */ call Leds.set(0x0F); } } --- NEW FILE: Makefile --- COMPONENT=AccelECG include ../../Makerules From ayer1 at users.sourceforge.net Thu Apr 10 07:28:27 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:28:27 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/ECG ECG.h, NONE, 1.1 ECG.nc, NONE, 1.1 ECGM.nc, NONE, 1.1 Makefile, NONE, 1.1 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/ECG In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7732/BioMOBIUS/ECG Added Files: ECG.h ECG.nc ECGM.nc Makefile Log Message: from adrian burns (intel ireland): All files in apps/BioMOBIUS/*.* Generic app (Tested on SHIMMER) compatible with BioMOBIUS 1.0 PC Software, see http://www.biomobius.org for more info. --- NEW FILE: ECG.h --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Authors: Adrian Burns * September, 2007 */ #ifndef ECG_H #define ECG_H enum { NUM_ACCEL_CHANS = 3 }; enum { NUM_GYRO_CHANS = 3 }; enum { SHIMMER_REV1 = 0 }; enum { PROPRIETARY_DATA_TYPE = 0xFF, STRING_DATA_TYPE = 0xFE }; enum { SAMPLING_1000HZ = 1, SAMPLING_500HZ = 2, SAMPLING_250HZ = 4, SAMPLING_200HZ = 5, SAMPLING_100HZ = 10, SAMPLING_50HZ = 20, SAMPLING_0HZ_OFF = 255 }; enum { FRAMING_SIZE = 0x4, FRAMING_CE_COMP = 0x20, FRAMING_CE_CE = 0x5D, FRAMING_CE = 0x7D, FRAMING_BOF = 0xC0, FRAMING_EOF = 0xC1, FRAMING_BOF_CE = 0xE0, FRAMING_EOF_CE = 0xE1, }; #endif // ECG_H --- NEW FILE: ECG.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app uses Bluetooth to stream 2 channels of ECG data from the SHIMMER ECG board. The two ECG vectors are LeftArm->LeftLeg and RightArm->LeftLeg. Tested on SHIMMER Base Board Rev 1.3, SHIMMER ECG board Rev 1.1. ***********************************************************************************/ configuration ECG { } implementation { components Main, DMA_M, MMA7260_AccelM, ECGM, RovingNetworksC, TimerC, LedsC; Main.StdControl -> ECGM; Main.StdControl -> TimerC; ECGM.Leds -> LedsC; ECGM.SampleTimer -> TimerC.Timer[unique("Timer")]; ECGM.SetupTimer -> TimerC.Timer[unique("Timer")]; ECGM.ActivityTimer -> TimerC.Timer[unique("Timer")]; ECGM.LocalTime -> TimerC; ECGM.BTStdControl -> RovingNetworksC; ECGM.Bluetooth -> RovingNetworksC; /* have to fix compile time channel limitation */ ECGM.DMA0 -> DMA_M.DMA[0]; //ECGM.DMA1 -> DMA_M.DMA[1]; //ECGM.DMA2 -> DMA_M.DMA[2]; ECGM.AccelStdControl -> MMA7260_AccelM; ECGM.Accel -> MMA7260_AccelM; } --- NEW FILE: ECGM.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app uses Bluetooth to stream 2 channels of ECG data from the SHIMMER ECG board. The two ECG vectors are LeftArm->LeftLeg and RightArm->LeftLeg. Tested on SHIMMER Base Board Rev 1.3, SHIMMER ECG board Rev 1.1. LOW_BATTERY_INDICATION if defined stops the app streaming data just after the battery voltage drops below the regulator value of 3V. Default Sample Frequency: 500 hz Packet Format: BOF| Sensor ID | Data Type | Seq No. | TimeStamp | Len | ECG_LALL | ECG_RALL | CRC | EOF Byte: 1 | 2 | 3 | 4 | 5-6 | 7 | 8-9 | 10-11 | 12-13| 14 ***********************************************************************************/ includes crc; includes ECG; includes DMA; includes MMA7260_Accel; includes Message; includes RovingNetworks; module ECGM { provides{ interface StdControl; } uses { interface DMA as DMA0; interface StdControl as AccelStdControl; interface MMA7260_Accel as Accel; interface StdControl as BTStdControl; interface Bluetooth; interface Leds; interface Timer as SetupTimer; interface Timer as ActivityTimer; interface Timer as SampleTimer; interface LocalTime; } } implementation { extern int sprintf(char *str, const char *format, ...) __attribute__ ((C)); #define USE_8MHZ_CRYSTAL #define LOW_BATTERY_INDICATION #define USE_AVCC_REF /* approx 0.5 milliamps saving when using AVCC compared to 2.5V or 1.5V internal ref */ #ifdef LOW_BATTERY_INDICATION //#define DEBUG_LOW_BATTERY_INDICATION /* during testing of the the (AVcc-AVss)/2 value from the ADC on various SHIMMERS, to get a reliable cut off point to recharge the battery it is important to find the baseline (AVcc-AVss)/2 value coming from the ADC as it varies from SHIMMER to SHIMMER, however the range of fluctuation is pretty constant and (AVcc-AVss)/2 provides an accurate battery low indication that prevents getting any voltage skewed data from the accelerometer or add-on board sensors */ #define TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD 1000 #define BATTERY_LOW_INDICATION_OFFSET 20 /* (AVcc - AVss)/2 = Approx 3V-0V/2 = 1.5V, 12 bit ADC with 2.5V REF, 4096/2500 = 1mV=1.6384 units */ #define FIXED_STRING_PACKET_SIZE 22 #define FIXED_STRING_PAYLOAD_SIZE 12 uint8_t tx_string_packet[(FIXED_STRING_PACKET_SIZE*2)+1]; bool need_baseline_voltage, link_disconnecting; uint16_t num_baseline_voltage_samples, baseline_voltage; uint32_t sum_batt_volt_samples; #ifdef DEBUG_LOW_BATTERY_INDICATION uint16_t debug_counter; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ #define FIXED_PACKET_SIZE 14 #define FIXED_PAYLOAD_SIZE 4 #define TX_BUFFER_SIZE (FIXED_PACKET_SIZE*2)+1 /* (*2)twice size because of byte stuffing */ uint8_t tx_packet[TX_BUFFER_SIZE]; /* (+1)MSP430 CPU can only read/write 16-bit values at even addresses, /* so use an empty byte to even up the memory locations for 16-bit values */ const uint8_t personality[17] = { 0,1,2,3,4,5,0xFF,0xFF, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_0HZ_OFF,SAMPLING_0HZ_OFF,FRAMING_EOF }; norace uint8_t current_buffer = 0, dma_blocks = 0; uint16_t sbuf0[36], sbuf1[36], timestamp0, timestamp1; /* default sample frequency every time the sensor boots up */ uint16_t sample_freq = SAMPLING_500HZ; bool enable_sending, command_mode_complete, activity_led_on; /* Internal function to calculate 16 bit CRC */ uint16_t calc_crc(uint8_t *ptr, uint8_t count) { uint16_t crc; crc = 0; while (count-- > 0) crc = crcByte(crc, *ptr++); return crc; } void setupDMA() { call DMA0.init(); call DMA0.setSourceAddress((uint16_t)ADC12MEM0_); call DMA0.setDestinationAddress((uint16_t)&sbuf0[0]); /* * we'll transfer from six sequential adcmem registers * to six sequential addresses in a buffer */ call DMA0.setBlockSize(3); // we want block transfer, single DMA0CTL = DMADT_1 + DMADSTINCR_3 + DMASRCINCR_3; } void sampleADC() { call DMA0.ADCinit(); // this doesn't really need to be parameterized atomic{ CLR_FLAG(ADC12CTL1, ADC12SSEL_3); // clr clk from smclk SET_FLAG(ADC12CTL1, ADC12SSEL_3); // clk from aclk /* with a 125khz clock (_7) it 136usec per conversion, 136*6=816usec in total */ SET_FLAG(ADC12CTL1, ADC12DIV_7); // sample and hold time four adc12clk cycles SET_FLAG(ADC12CTL0, SHT0_0); // set reference voltage to 2.5v SET_FLAG(ADC12CTL0, REF2_5V); // conversion start address SET_FLAG(ADC12CTL1, CSTARTADD_0); // really a zero, for clarity } SET_FLAG(ADC12MCTL0, INCH_1); // ECG_LALL SET_FLAG(ADC12MCTL1, INCH_2); // ECG_RALL SET_FLAG(ADC12MCTL2, INCH_11); // (AVcc-AVss)/2 to monitor battery voltage SET_FLAG(ADC12MCTL2, EOS); //sez "this is the last reg" #ifdef USE_AVCC_REF // set reference to analog voltage AVcc CLR_FLAG(ADC12CTL0, REFON); CLR_FLAG(ADC12MCTL0, SREF_7); CLR_FLAG(ADC12MCTL1, SREF_7); CLR_FLAG(ADC12MCTL2, SREF_7); #else SET_FLAG(ADC12MCTL0, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL1, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL2, SREF_1); // Vref = Vref+ and Vr- #endif /* USE_AVCC_REF */ /* set up for three adc channels -> three adcmem regs -> three dma channels in round-robin */ /* clear init defaults first */ CLR_FLAG(ADC12CTL1, CONSEQ_2); // clear default repeat single channel SET_FLAG(ADC12CTL1, CONSEQ_1); // single sequence of channels setupDMA(); call DMA0.beginTransfer(); } command result_t StdControl.init() { register uint8_t i; call Leds.init(); #ifdef USE_8MHZ_CRYSTAL /* * set up 8mhz clock to max out * msp430 throughput */ atomic CLR_FLAG(BCSCTL1, XT2OFF); // basic clock system control reg, turn off XT2 osc call Leds.redOn(); do{ CLR_FLAG(IFG1, OFIFG); for(i = 0; i < 0xff; i++); } while(READ_FLAG(IFG1, OFIFG)); call Leds.redOff(); call Leds.yellowOn(); TOSH_uwait(50000UL); atomic{ BCSCTL2 = 0; SET_FLAG(BCSCTL2, SELM_2); } call Leds.yellowOff(); atomic{ SET_FLAG(BCSCTL2, SELS); // smclk from xt2 SET_FLAG(BCSCTL2, DIVS_3); // divide it by 8 } /* * end clock set up */ #endif /* USE_8MHZ_CRYSTAL */ call AccelStdControl.init(); TOSH_MAKE_ADC_1_INPUT(); // ECG_LALL TOSH_MAKE_ADC_2_INPUT(); // ECG_RALL TOSH_SEL_ADC_1_MODFUNC(); TOSH_SEL_ADC_2_MODFUNC(); atomic { memset(tx_packet, 0, TX_BUFFER_SIZE); //memset(&packet, 0, sizeof(Packet_t)); enable_sending = FALSE; command_mode_complete = FALSE; activity_led_on = FALSE; } call BTStdControl.init(); call Bluetooth.disableRemoteConfig(TRUE); /* if CPU=8Mhz then customise roving networks baudrate to suit 8Mhz/9 baud */ /* call Bluetooth.setBaudrate("452"); */ dma_blocks = 0; return SUCCESS; } command result_t StdControl.start() { call BTStdControl.start(); /* so that the clinicians know the sensor is on */ call Leds.redOn(); #ifdef LOW_BATTERY_INDICATION /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); #ifdef DEBUG_LOW_BATTERY_INDICATION debug_counter = 0; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ return SUCCESS; } command result_t StdControl.stop() { call BTStdControl.stop(); return SUCCESS; } #ifdef LOW_BATTERY_INDICATION task void sendBatteryLowIndication() { uint16_t crc; char batt_low_str[] = "BATTERY LOW!"; /* stop all sensing - battery is below the threshold */ call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); /* send the battery low indication packet to BioMOBIUS */ tx_string_packet[1] = FRAMING_BOF; tx_string_packet[2] = SHIMMER_REV1; tx_string_packet[3] = STRING_DATA_TYPE; tx_string_packet[4]++; /* increment sequence number */ tx_string_packet[5] = timestamp0 & 0xff; tx_string_packet[6] = (timestamp0 >> 8) & 0xff; tx_string_packet[7] = FIXED_STRING_PAYLOAD_SIZE; memcpy(&tx_string_packet[8], &batt_low_str[0], 12); #ifdef DEBUG_LOW_BATTERY_INDICATION tx_string_packet[8] = (baseline_voltage) & 0xff; tx_string_packet[9] = ((baseline_voltage) >> 8) & 0xff; #endif /* DEBUG_LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_string_packet[2], (FIXED_STRING_PACKET_SIZE-FRAMING_SIZE)); tx_string_packet[FIXED_STRING_PACKET_SIZE - 2] = crc & 0xff; tx_string_packet[FIXED_STRING_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_string_packet[FIXED_STRING_PACKET_SIZE] = FRAMING_EOF; call Bluetooth.write(&tx_string_packet[1], FIXED_STRING_PACKET_SIZE); atomic enable_sending = FALSE; /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); } /* all samples are got so set the baseline voltage for this SHIMMER hardware */ void setBattVoltageBaseline() { baseline_voltage = (sum_batt_volt_samples / TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD); } /* check voltage level and if it is low then stop sampling, send message and disconnect */ void checkBattVoltageLevel(uint16_t battery_voltage) { #ifndef DEBUG_LOW_BATTERY_INDICATION if(battery_voltage < (baseline_voltage-BATTERY_LOW_INDICATION_OFFSET)) { #else if(debug_counter++ == 2500) { #endif /* DEBUG_LOW_BATTERY_INDICATION */ link_disconnecting = TRUE; } } /* keep checking the voltage level of the battery until it drops below the offset */ void monitorBattery() { uint16_t battery_voltage; if(current_buffer == 1) { battery_voltage = sbuf0[2]; } else { battery_voltage = sbuf1[2]; } if(need_baseline_voltage) { num_baseline_voltage_samples++; if(num_baseline_voltage_samples <= TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD) { /* add this sample to the total so that an average baseline can be obtained */ sum_batt_volt_samples += battery_voltage; } else { setBattVoltageBaseline(); need_baseline_voltage = FALSE; call Leds.orangeOff(); } } else { checkBattVoltageLevel(battery_voltage); } } #endif /* LOW_BATTERY_INDICATION */ /* The MSP430 CPU is byte addressed and little endian */ /* packets are sent little endian so the word 0xABCD will be sent as bytes 0xCD 0xAB */ void preparePacket() { uint16_t *p_packet, *p_ADCsamples, crc; tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = PROPRIETARY_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[7] = FIXED_PAYLOAD_SIZE; p_packet = (uint16_t *)&tx_packet[8]; if(current_buffer == 1) { p_ADCsamples = &sbuf0[0]; tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; } else { p_ADCsamples = &sbuf1[0]; tx_packet[5] = timestamp1 & 0xff; tx_packet[6] = (timestamp1 >> 8) & 0xff; } /* copy all the data samples into the outgoing packet */ *p_packet++ = *p_ADCsamples++; //tx_packet[8] *p_packet = *p_ADCsamples; //tx_packet[10] /* debug stuff - capture battery voltage to monitor discharge */ #ifdef DEBUG_LOW_BATTERY_INDICATION if(current_buffer == 1) { tx_packet[8] = (sbuf0[2]) & 0xff; tx_packet[9] = ((sbuf0[2]) >> 8) & 0xff; } else { tx_packet[8] = (sbuf1[2]) & 0xff; tx_packet[9] = ((sbuf1[2]) >> 8) & 0xff; } #endif /* LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; } task void sendSensorData() { #ifdef LOW_BATTERY_INDICATION monitorBattery(); #endif /* LOW_BATTERY_INDICATION */ atomic if(enable_sending) { preparePacket(); /* send data over the air */ call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); enable_sending = FALSE; } } task void startSensing() { call ActivityTimer.start(TIMER_REPEAT, 1000); call AccelStdControl.start(); call Accel.setSensitivity(RANGE_4_0G); call SampleTimer.start(TIMER_REPEAT, sample_freq); sampleADC(); } task void sendPersonality() { atomic if(enable_sending) { /* send data over the air */ call Bluetooth.write(&personality[0], 17); atomic enable_sending = FALSE; } } task void stopSensing() { call SetupTimer.stop(); call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); } async event void Bluetooth.connectionMade(uint8_t status) { atomic enable_sending = TRUE; call Leds.greenOn(); } async event void Bluetooth.commandModeEnded() { atomic command_mode_complete = TRUE; //call Leds.orangeOn(); } async event void Bluetooth.connectionClosed(uint8_t reason){ atomic enable_sending = FALSE; call Leds.greenOff(); post stopSensing(); } async event void Bluetooth.dataAvailable(uint8_t data){ /* start capturing on ^G */ if(7 == data) { atomic if(command_mode_complete) { post startSensing(); } else { //call Leds.redOn(); /* give config a chance, wait 5 secs */ call SetupTimer.start(TIMER_REPEAT, 5000); } } else if (data == 1) { post sendPersonality(); } /* stop capturing on spacebar */ else if (data == 32) { post stopSensing(); } else { /* were done */ } } event void Bluetooth.writeDone(){ atomic enable_sending = TRUE; #ifdef LOW_BATTERY_INDICATION if(link_disconnecting) { link_disconnecting = FALSE; /* signal battery low to master and let the master disconnect the link */ post sendBatteryLowIndication(); } #endif /* LOW_BATTERY_INDICATION */ } event result_t SetupTimer.fired() { atomic if(command_mode_complete){ call ActivityTimer.stop(); post startSensing(); } return SUCCESS; } event result_t ActivityTimer.fired() { atomic { /* toggle activity led every second */ if(activity_led_on) { call Leds.yellowOn(); activity_led_on = FALSE; } else { call Leds.yellowOff(); activity_led_on = TRUE; } } return SUCCESS; } event result_t SampleTimer.fired() { call DMA0.beginTransfer(); call DMA0.ADCbeginConversion(); return SUCCESS; } async event void DMA0.transferComplete() { dma_blocks++; //atomic DMA0DA += 12; if(dma_blocks == 1){ //this should be about 6 but for this test its 1 dma_blocks = 0; if(current_buffer == 0){ atomic DMA0DA = (uint16_t)&sbuf1[0]; atomic timestamp1 = call LocalTime.read(); current_buffer = 1; } else { atomic DMA0DA = (uint16_t)&sbuf0[0]; atomic timestamp0 = call LocalTime.read(); current_buffer = 0; } post sendSensorData(); } } async event void DMA0.ADCInterrupt(uint8_t regnum) { // we should *not* see this, as the adc interrupts are eaten by the dma controller! /* Turn on all LEDs */ call Leds.set(0x0F); } } --- NEW FILE: Makefile --- COMPONENT=ECG include ../../Makerules From ayer1 at users.sourceforge.net Thu Apr 10 07:28:27 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:28:27 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/SixAxisCmdCtrl Makefile, NONE, 1.1 SixAxisCmdCtrl.h, NONE, 1.1 SixAxisCmdCtrl.nc, NONE, 1.1 SixAxisCmdCtrlM.nc, NONE, 1.1 Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/BioMOBIUS/SixAxisCmdCtrl In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7732/BioMOBIUS/SixAxisCmdCtrl Added Files: Makefile SixAxisCmdCtrl.h SixAxisCmdCtrl.nc SixAxisCmdCtrlM.nc Log Message: from adrian burns (intel ireland): All files in apps/BioMOBIUS/*.* Generic app (Tested on SHIMMER) compatible with BioMOBIUS 1.0 PC Software, see http://www.biomobius.org for more info. --- NEW FILE: Makefile --- COMPONENT=SixAxisCmdCtrl include ../../Makerules #PFLAGS += -DLOW_BATTERY_INDICATION ifndef USE_ID_CHIP $(error You can only build this against a platform that has an ID chip) else PFLAGS += -DID_CHIP=$(USE_ID_CHIP) ifdef HAS_ID_CHIP_POWER PFLAGS += -DID_CHIP_POWER endif endif --- NEW FILE: SixAxisCmdCtrl.h --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Authors: Adrian Burns * October, 2007 */ #ifndef SIXAXISCMDCTRL_H #define SIXAXISCMDCTRL_H enum { NUM_ACCEL_CHANS = 3 }; enum { NUM_GYRO_CHANS = 3 }; enum { SHIMMER_REV1 = 0 }; enum { PROPRIETARY_DATA_TYPE = 0xFF, STRING_DATA_TYPE = 0xFE, COMMAND_DATA_TYPE = 0xFC }; enum { SAMPLING_1000HZ = 1, SAMPLING_500HZ = 2, SAMPLING_250HZ = 4, SAMPLING_200HZ = 5, SAMPLING_166HZ = 6, SAMPLING_125HZ = 8, SAMPLING_100HZ = 10, SAMPLING_50HZ = 20, SAMPLING_10HZ = 100, SAMPLING_0HZ_OFF = 255 }; enum { FRAMING_SIZE = 0x4, FRAMING_CE_COMP = 0x20, FRAMING_CE_CE = 0x5D, FRAMING_CE = 0x7D, FRAMING_BOF = 0xC0, FRAMING_EOF = 0xC1, FRAMING_BOF_CE = 0xE0, FRAMING_EOF_CE = 0xE1, }; #endif // SIXAXISCMDCTRL_H --- NEW FILE: SixAxisCmdCtrl.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app is an example that shows how the SerialCommandParser interface can be used to control and configure SHIMMER from a BioMOBIUS PC application. ***********************************************************************************/ configuration SixAxisCmdCtrl { } implementation { components Main, DMA_M, MMA7260_AccelM, SixAxisCmdCtrlM, RovingNetworksC, TimerC, LedsC, SerialCommandParserC; Main.StdControl -> SixAxisCmdCtrlM; Main.StdControl -> TimerC; SixAxisCmdCtrlM.Leds -> LedsC; SixAxisCmdCtrlM.SampleTimer -> TimerC.Timer[unique("Timer")]; SixAxisCmdCtrlM.ActivityTimer -> TimerC.Timer[unique("Timer")]; SixAxisCmdCtrlM.LocalTime -> TimerC; SixAxisCmdCtrlM.BTStdControl -> RovingNetworksC; SixAxisCmdCtrlM.Bluetooth -> RovingNetworksC; /* have to fix compile time channel limitation */ SixAxisCmdCtrlM.DMA0 -> DMA_M.DMA[0]; //SixAxisCmdCtrlM.DMA1 -> DMA_M.DMA[1]; //SixAxisCmdCtrlM.DMA2 -> DMA_M.DMA[2]; SixAxisCmdCtrlM.AccelStdControl -> MMA7260_AccelM; SixAxisCmdCtrlM.Accel -> MMA7260_AccelM; //SixAxisCmdCtrlM.SensorControl -> SixAxisCmdCtrlM; SixAxisCmdCtrlM.SerialCommandStdControl -> SerialCommandParserC; SixAxisCmdCtrlM.SerialCommandParser -> SerialCommandParserC; } --- NEW FILE: SixAxisCmdCtrlM.nc --- /* * Copyright (c) 2007, Intel 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 Intel 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 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. * * Author: Adrian Burns * November, 2007 */ /*********************************************************************************** This app is an example that shows how the SerialCommandParser interface can be used to control and configure SHIMMER from a BioMOBIUS PC application. Default Sample Frequency: 100 hz Packet Format: BOF| Sensor ID | Data Type | Seq No. | TimeStamp | Len | Acc | Acc | Acc | Gyro | Gyro | Gyro | CRC | EOF Byte: 1 | 2 | 3 | 4 | 5-6 | 7 | 8-9 | 10-11| 12-13| 14-15 | 16-17| 18-19| 20-21| 22 ***********************************************************************************/ includes crc; includes SixAxisCmdCtrl; includes DMA; includes MMA7260_Accel; includes Message; includes RovingNetworks; module SixAxisCmdCtrlM { provides{ interface StdControl; interface SensorControl; } uses { interface DMA as DMA0; interface StdControl as AccelStdControl; interface StdControl as SerialCommandStdControl; interface MMA7260_Accel as Accel; interface StdControl as BTStdControl; interface Bluetooth; interface Leds; interface Timer as ActivityTimer; interface Timer as SampleTimer; interface LocalTime; interface SerialCommandParser; } } implementation { #define USE_8MHZ_CRYSTAL #define USE_AVCC_REF /* approx 0.5 milliamps saving when using AVCC compared to 2.5V or 1.5V internal ref */ #ifdef LOW_BATTERY_INDICATION //#define DEBUG_LOW_BATTERY_INDICATION /* during testing of the the (AVcc-AVss)/2 value from the ADC on various SHIMMERS, to get a reliable cut off point to recharge the battery it is important to find the baseline (AVcc-AVss)/2 value coming from the ADC as it varies from SHIMMER to SHIMMER, however the range of fluctuation is pretty constant and (AVcc-AVss)/2 provides an accurate battery low indication that prevents getting any voltage skewed data from the accelerometer or add-on board sensors */ #define TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD 1000 #define BATTERY_LOW_INDICATION_OFFSET 20 /* (AVcc - AVss)/2 = Approx 3V-0V/2 = 1.5V, 12 bit ADC with 2.5V REF, 4096/2500 = 1mV=1.6384 units */ bool need_baseline_voltage, linkDisconnecting, battPacketPending; uint16_t num_baseline_voltage_samples, baseline_voltage; uint32_t sum_batt_volt_samples; #ifdef DEBUG_LOW_BATTERY_INDICATION uint16_t debug_counter; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ task void startSensing(); task void stopSensing(); #define FIXED_PACKET_SIZE 22 #define FIXED_PAYLOAD_SIZE 12 uint8_t tx_packet[(FIXED_PACKET_SIZE*2)+1]; /* (*2)twice size because of byte stuffing */ /* (+1)MSP430 CPU can only read/write 16-bit values at even addresses, /* so use an empty byte to even up the memory locations for 16-bit values */ #define MAX_CMD_PACKET_SIZE 50 uint8_t tx_cmd_packet[MAX_CMD_PACKET_SIZE*2]; /* (*2)twice size because of byte stuffing */ const uint8_t personality[17] = { 0,1,2,3,4,5,0xFF,0xFF, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_50HZ, SAMPLING_50HZ,SAMPLING_50HZ,SAMPLING_0HZ_OFF,SAMPLING_0HZ_OFF,FRAMING_EOF }; norace uint8_t current_buffer = 0, dma_blocks = 0, g_data; uint16_t sbuf0[36], sbuf1[36], timestamp0, timestamp1, sample_freq = SAMPLING_100HZ, new_sample_freq = SAMPLING_0HZ_OFF; bool enable_sending, command_mode_complete, activity_led_on, sensor_sampling=FALSE, cmdPacketPending; /* Internal function to calculate 16 bit CRC */ uint16_t calc_crc(uint8_t *ptr, uint8_t count) { uint16_t crc; crc = 0; while (count-- > 0) crc = crcByte(crc, *ptr++); return crc; } void setupDMA() { call DMA0.init(); call DMA0.setSourceAddress((uint16_t)ADC12MEM0_); call DMA0.setDestinationAddress((uint16_t)&sbuf0[0]); /* * we'll transfer from six sequential adcmem registers * to six sequential addresses in a buffer */ call DMA0.setBlockSize(7); // we want block transfer, single DMA0CTL = DMADT_1 + DMADSTINCR_3 + DMASRCINCR_3; } void sampleADC() { call DMA0.ADCinit(); // this doesn't really need to be parameterized atomic{ CLR_FLAG(ADC12CTL1, ADC12SSEL_3); // clr clk from smclk SET_FLAG(ADC12CTL1, ADC12SSEL_3); // clk from aclk /* with a 125khz clock (_7) its 136usec per conversion, 136*6=816usec in total */ SET_FLAG(ADC12CTL1, ADC12DIV_7); // sample and hold time four adc12clk cycles SET_FLAG(ADC12CTL0, SHT0_0); // set reference voltage to 2.5v SET_FLAG(ADC12CTL0, REF2_5V); // conversion start address SET_FLAG(ADC12CTL1, CSTARTADD_0); // really a zero, for clarity } SET_FLAG(ADC12MCTL0, INCH_5); // accel x SET_FLAG(ADC12MCTL1, INCH_4); // accel y SET_FLAG(ADC12MCTL2, INCH_3); // accel z SET_FLAG(ADC12MCTL3, INCH_1); // x gyro SET_FLAG(ADC12MCTL4, INCH_6); // y gyro SET_FLAG(ADC12MCTL5, INCH_2); // z gyro SET_FLAG(ADC12MCTL6, INCH_11); // (AVcc-AVss)/2 to monitor battery voltage SET_FLAG(ADC12MCTL6, EOS); //sez "this is the last reg" #ifdef USE_AVCC_REF // set reference to analog voltage AVcc CLR_FLAG(ADC12CTL0, REFON); CLR_FLAG(ADC12MCTL0, SREF_7); CLR_FLAG(ADC12MCTL1, SREF_7); CLR_FLAG(ADC12MCTL2, SREF_7); CLR_FLAG(ADC12MCTL3, SREF_7); CLR_FLAG(ADC12MCTL4, SREF_7); CLR_FLAG(ADC12MCTL5, SREF_7); CLR_FLAG(ADC12MCTL6, SREF_7); #else SET_FLAG(ADC12MCTL0, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL1, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL2, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL3, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL4, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL5, SREF_1); // Vref = Vref+ and Vr- SET_FLAG(ADC12MCTL6, SREF_1); // Vref = Vref+ and Vr- #endif /* USE_AVCC_REF */ /* set up for three adc channels -> three adcmem regs -> three dma channels in round-robin */ /* clear init defaults first */ CLR_FLAG(ADC12CTL1, CONSEQ_2); // clear default repeat single channel SET_FLAG(ADC12CTL1, CONSEQ_1); // single sequence of channels setupDMA(); call DMA0.beginTransfer(); } /***************************************** * StdControl interface *****************************************/ command result_t StdControl.init() { register uint8_t i; call Leds.init(); #ifdef USE_8MHZ_CRYSTAL /* * set up 8mhz clock to max out * msp430 throughput */ atomic CLR_FLAG(BCSCTL1, XT2OFF); // basic clock system control reg, turn off XT2 osc call Leds.redOn(); do{ CLR_FLAG(IFG1, OFIFG); for(i = 0; i < 0xff; i++); } while(READ_FLAG(IFG1, OFIFG)); call Leds.redOff(); call Leds.yellowOn(); TOSH_uwait(50000UL); atomic{ BCSCTL2 = 0; SET_FLAG(BCSCTL2, SELM_2); /* select master clock source, XT2CLK when XT2 oscillator present */ } /*on-chip. LFXT1CLK when XT2 oscillator not present on-chip. */ call Leds.yellowOff(); atomic{ SET_FLAG(BCSCTL2, SELS); // smclk from xt2 SET_FLAG(BCSCTL2, DIVS_3); // divide it by 8, 8MHZ/8=1MHZ } /* * end clock set up */ #endif /* USE_8MHZ_CRYSTAL */ call AccelStdControl.init(); // pins for gyro, gyro enable TOSH_MAKE_ADC_1_INPUT(); // x TOSH_MAKE_ADC_2_INPUT(); // z TOSH_MAKE_ADC_6_INPUT(); // y TOSH_SEL_ADC_1_MODFUNC(); TOSH_SEL_ADC_2_MODFUNC(); TOSH_SEL_ADC_6_MODFUNC(); atomic { memset(tx_packet, 0, (FIXED_PACKET_SIZE*2)); memset(tx_cmd_packet, 0, (MAX_CMD_PACKET_SIZE*2)); enable_sending = FALSE; cmdPacketPending = FALSE; command_mode_complete = FALSE; activity_led_on = FALSE; } call BTStdControl.init(); call Bluetooth.disableRemoteConfig(TRUE); /* if CPU=8Mhz then customise roving networks baudrate to suit 8Mhz/9 baud */ /* call Bluetooth.setBaudrate("452"); */ call SerialCommandStdControl.init(); dma_blocks = 0; return SUCCESS; } command result_t StdControl.start() { call BTStdControl.start(); call SerialCommandStdControl.start(); /* so that the clinicians know the sensor is on */ call Leds.redOn(); #ifdef LOW_BATTERY_INDICATION /* initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; linkDisconnecting = FALSE; battPacketPending = FALSE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); #ifdef DEBUG_LOW_BATTERY_INDICATION debug_counter = 0; #endif /* DEBUG_LOW_BATTERY_INDICATION */ #endif /* LOW_BATTERY_INDICATION */ return SUCCESS; } command result_t StdControl.stop() { call Leds.redOff(); call BTStdControl.stop(); call SerialCommandStdControl.stop(); return SUCCESS; } task void setSampleFrequency() { result_t result; sample_freq = new_sample_freq; if(sensor_sampling) { call SampleTimer.stop(); call SampleTimer.start(TIMER_REPEAT, sample_freq); } signal SensorControl.sampleFrequencyChanged(SUCCESS); } /***************************************** * SensorControl interface *****************************************/ command result_t SensorControl.startStreaming(){ if(command_mode_complete) { post startSensing(); return SUCCESS; } else { return FAIL; } } command result_t SensorControl.stopStreaming(){ post stopSensing(); return SUCCESS; } command result_t SensorControl.startLogging(){ } command result_t SensorControl.stopLogging(){ } command result_t SensorControl.getCardData(){ } command uint8_t SensorControl.getActiveRadio(){ return 'B'; /* Bluetooth */ } command result_t SensorControl.changeSampleFrequency(uint16_t new_freq){ switch ( new_freq ) { case 1000: new_freq = SAMPLING_1000HZ; break; case 500: new_freq = SAMPLING_500HZ; break; case 250: new_freq = SAMPLING_250HZ; break; case 200: new_freq = SAMPLING_200HZ; break; case 166: new_freq = SAMPLING_166HZ; break; case 125: new_freq = SAMPLING_125HZ; break; case 100: new_freq = SAMPLING_100HZ; break; case 50: new_freq = SAMPLING_50HZ; break; case 10: new_freq = SAMPLING_10HZ; break; } if(new_freq == sample_freq) { signal SensorControl.sampleFrequencyChanged(SUCCESS); return SUCCESS; } new_sample_freq = new_freq; post setSampleFrequency(); } command uint16_t SensorControl.getSampleFrequency(){ switch ( sample_freq ) { case SAMPLING_1000HZ: return 1000; case SAMPLING_500HZ: return 500; case SAMPLING_250HZ: return 250; case SAMPLING_200HZ: return 200; case SAMPLING_166HZ: return 166; case SAMPLING_125HZ: return 125; case SAMPLING_100HZ: return 100; case SAMPLING_50HZ: return 50; case SAMPLING_10HZ: return 10; default: return 0; } } task void sendCmdPacket() { atomic if(enable_sending) { call Bluetooth.write(tx_cmd_packet, (tx_cmd_packet[6]+10)); atomic enable_sending = FALSE; cmdPacketPending = FALSE; } else cmdPacketPending = TRUE; } event result_t SerialCommandParser.responseReady(const uint8_t *buf, uint16_t len) { uint16_t crc; tx_cmd_packet[0] = FRAMING_BOF; tx_cmd_packet[1] = SHIMMER_REV1; tx_cmd_packet[2] = COMMAND_DATA_TYPE; tx_cmd_packet[3]++; /* increment sequence number */ tx_cmd_packet[4] = tx_cmd_packet[5] = 0; /* no use for time stamp */ tx_cmd_packet[6] = len; memcpy(&tx_cmd_packet[7], buf, len); crc = calc_crc(&tx_cmd_packet[1], ((10+len)-FRAMING_SIZE)); tx_cmd_packet[len+7] = crc & 0xff; tx_cmd_packet[len+8] = (crc >> 8) & 0xff; tx_cmd_packet[len+9] = FRAMING_EOF; post sendCmdPacket(); return SUCCESS; } #ifdef LOW_BATTERY_INDICATION task void sendBattMessage() { atomic if(enable_sending) { call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); atomic enable_sending = FALSE; battPacketPending = FALSE; } else battPacketPending = TRUE; } task void sendBatteryLowIndication() { uint16_t crc; char batt_low_str[] = "BATTERY LOW!"; /* stop all sensing - battery is below the threshold */ call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); /* send the battery low indication packet to BioMOBIUS */ tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = STRING_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; tx_packet[7] = FIXED_PAYLOAD_SIZE; memcpy(&tx_packet[8], &batt_low_str[0], 12); #ifdef DEBUG_LOW_BATTERY_INDICATION tx_packet[8] = (baseline_voltage) & 0xff; tx_packet[9] = ((baseline_voltage) >> 8) & 0xff; #endif /* DEBUG_LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; /* re-initialise baseline voltage measurement stuff */ need_baseline_voltage = TRUE; num_baseline_voltage_samples = baseline_voltage = sum_batt_volt_samples = 0; call Leds.orangeOn(); post sendBattMessage(); } /* all samples are got so set the baseline voltage for this SHIMMER hardware */ void setBattVoltageBaseline() { baseline_voltage = (sum_batt_volt_samples / TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD); } /* check voltage level and if it is low then stop sampling, send message and disconnect */ void checkBattVoltageLevel(uint16_t battery_voltage) { #ifndef DEBUG_LOW_BATTERY_INDICATION if(battery_voltage < (baseline_voltage-BATTERY_LOW_INDICATION_OFFSET)) { #else if(debug_counter++ == 2500) { #endif /* DEBUG_LOW_BATTERY_INDICATION */ linkDisconnecting = TRUE; } } /* keep checking the voltage level of the battery until it drops below the offset */ void monitorBattery() { uint16_t battery_voltage; if(current_buffer == 1) { battery_voltage = sbuf0[6]; } else { battery_voltage = sbuf1[6]; } if(need_baseline_voltage) { num_baseline_voltage_samples++; if(num_baseline_voltage_samples <= TOTAL_BASELINE_BATT_VOLT_SAMPLES_TO_RECORD) { /* add this sample to the total so that an average baseline can be obtained */ sum_batt_volt_samples += battery_voltage; } else { setBattVoltageBaseline(); need_baseline_voltage = FALSE; call Leds.orangeOff(); } } else { checkBattVoltageLevel(battery_voltage); } } #endif /* LOW_BATTERY_INDICATION */ /* The MSP430 CPU is byte addressed and little endian */ /* packets are sent little endian so the word 0xABCD will be sent as bytes 0xCD 0xAB */ void preparePacket() { uint16_t *p_packet, *p_ADCsamples, crc; tx_packet[1] = FRAMING_BOF; tx_packet[2] = SHIMMER_REV1; tx_packet[3] = PROPRIETARY_DATA_TYPE; tx_packet[4]++; /* increment sequence number */ tx_packet[7] = FIXED_PAYLOAD_SIZE; p_packet = (uint16_t *)&tx_packet[8]; if(current_buffer == 1) { p_ADCsamples = &sbuf0[0]; tx_packet[5] = timestamp0 & 0xff; tx_packet[6] = (timestamp0 >> 8) & 0xff; } else { p_ADCsamples = &sbuf1[0]; tx_packet[5] = timestamp1 & 0xff; tx_packet[6] = (timestamp1 >> 8) & 0xff; } /* copy all the data samples into the outgoing packet */ *p_packet++ = *p_ADCsamples++; //tx_packet[8] *p_packet++ = *p_ADCsamples++; //tx_packet[10] *p_packet++ = *p_ADCsamples++; //tx_packet[12] *p_packet++ = *p_ADCsamples++; //tx_packet[14] *p_packet++ = *p_ADCsamples++; //tx_packet[16] *p_packet = *p_ADCsamples; //tx_packet[18] /* debug stuff - capture battery voltage to monitor discharge */ #ifdef DEBUG_LOW_BATTERY_INDICATION if(current_buffer == 1) { tx_packet[18] = (sbuf0[6]) & 0xff; tx_packet[19] = ((sbuf0[6]) >> 8) & 0xff; } else { tx_packet[18] = (sbuf1[6]) & 0xff; tx_packet[19] = ((sbuf1[6]) >> 8) & 0xff; } #endif /* LOW_BATTERY_INDICATION */ crc = calc_crc(&tx_packet[2], (FIXED_PACKET_SIZE-FRAMING_SIZE)); tx_packet[FIXED_PACKET_SIZE - 2] = crc & 0xff; tx_packet[FIXED_PACKET_SIZE - 1] = (crc >> 8) & 0xff; tx_packet[FIXED_PACKET_SIZE] = FRAMING_EOF; } task void sendSensorData() { #ifdef LOW_BATTERY_INDICATION monitorBattery(); #endif /* LOW_BATTERY_INDICATION */ atomic if(enable_sending) { preparePacket(); /* send data over the air */ call Bluetooth.write(&tx_packet[1], FIXED_PACKET_SIZE); atomic enable_sending = FALSE; } } task void startSensing() { register uint16_t i; signal SensorControl.streamingStarted(SUCCESS); for(i = 0; i < 400 ; i++) // give the receiver a chance to receive the command response TOSH_uwait(5000); call ActivityTimer.start(TIMER_REPEAT, 1000); call AccelStdControl.start(); call Accel.setSensitivity(RANGE_4_0G); call SampleTimer.start(TIMER_REPEAT, sample_freq); TOSH_CLR_PROG_OUT_PIN(); // gyro enable low sampleADC(); sensor_sampling = TRUE; } task void sendPersonality() { atomic if(enable_sending) { /* send data over the air */ call Bluetooth.write(&personality[0], 17); atomic enable_sending = FALSE; } } task void stopSensing() { call SampleTimer.stop(); call ActivityTimer.stop(); call DMA0.ADCstopConversion(); call AccelStdControl.stop(); call Leds.yellowOff(); signal SensorControl.streamingStopped(SUCCESS); sensor_sampling = FALSE; } async event void Bluetooth.connectionMade(uint8_t status) { atomic enable_sending = TRUE; call Leds.greenOn(); } async event void Bluetooth.commandModeEnded() { atomic command_mode_complete = TRUE; } async event void Bluetooth.connectionClosed(uint8_t reason){ atomic enable_sending = FALSE; call Leds.greenOff(); //call Leds.redOn(); post stopSensing(); } async event void Bluetooth.dataAvailable(uint8_t data){ call SerialCommandParser.handleByte(data); } event void Bluetooth.writeDone(){ atomic enable_sending = TRUE; #ifdef LOW_BATTERY_INDICATION if(linkDisconnecting) { linkDisconnecting = FALSE; /* signal battery low to master and let the master disconnect the link */ post sendBatteryLowIndication(); return; } atomic if(battPacketPending) { post sendBattMessage(); } #endif /* LOW_BATTERY_INDICATION */ atomic if(cmdPacketPending) { post sendCmdPacket(); } } event result_t ActivityTimer.fired() { atomic { /* toggle activity led every second */ if(activity_led_on) { call Leds.yellowOn(); activity_led_on = FALSE; } else { call Leds.yellowOff(); activity_led_on = TRUE; } } return SUCCESS; } event result_t SampleTimer.fired() { call DMA0.beginTransfer(); call DMA0.ADCbeginConversion(); return SUCCESS; } async event void DMA0.transferComplete() { dma_blocks++; //atomic DMA0DA += 12; if(dma_blocks == 1){ //this should be about 6 but for this test its 1 dma_blocks = 0; if(current_buffer == 0){ atomic DMA0DA = (uint16_t)&sbuf1[0]; atomic timestamp1 = call LocalTime.read(); current_buffer = 1; } else { atomic DMA0DA = (uint16_t)&sbuf0[0]; atomic timestamp0 = call LocalTime.read(); current_buffer = 0; } post sendSensorData(); } } async event void DMA0.ADCInterrupt(uint8_t regnum) { // we should *not* see this, as the adc interrupts are eaten by the dma controller! /* Turn on all LEDs */ call Leds.set(0x0F); } } From ayer1 at users.sourceforge.net Thu Apr 10 07:30:52 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:30:52 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/MOBIUS/ECG ECG.h, 1.1, NONE ECG.nc, 1.1, NONE ECGM.nc, 1.3, NONE Makefile, 1.1, NONE Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/MOBIUS/ECG In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8976/MOBIUS/ECG Removed Files: ECG.h ECG.nc ECGM.nc Makefile Log Message: removed in favor of BioMOBIUS release as per adrian burns, intel ireland --- ECG.h DELETED --- --- ECG.nc DELETED --- --- ECGM.nc DELETED --- --- Makefile DELETED --- From ayer1 at users.sourceforge.net Thu Apr 10 07:30:52 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:30:52 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/MOBIUS/AccelGyro AccelGyro.h, 1.1, NONE AccelGyro.nc, 1.1, NONE AccelGyroM.nc, 1.3, NONE Makefile, 1.1, NONE Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/MOBIUS/AccelGyro In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8976/MOBIUS/AccelGyro Removed Files: AccelGyro.h AccelGyro.nc AccelGyroM.nc Makefile Log Message: removed in favor of BioMOBIUS release as per adrian burns, intel ireland --- AccelGyro.h DELETED --- --- AccelGyro.nc DELETED --- --- AccelGyroM.nc DELETED --- --- Makefile DELETED --- From ayer1 at users.sourceforge.net Thu Apr 10 07:30:52 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:30:52 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/MOBIUS/AccelECG AccelECG.h, 1.1, NONE AccelECG.nc, 1.1, NONE AccelECGM.nc, 1.3, NONE Makefile, 1.1, NONE Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/MOBIUS/AccelECG In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8976/MOBIUS/AccelECG Removed Files: AccelECG.h AccelECG.nc AccelECGM.nc Makefile Log Message: removed in favor of BioMOBIUS release as per adrian burns, intel ireland --- AccelECG.h DELETED --- --- AccelECG.nc DELETED --- --- AccelECGM.nc DELETED --- --- Makefile DELETED --- From ayer1 at users.sourceforge.net Thu Apr 10 07:30:56 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:30:56 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/MOBIUS/SixAxisCmdCtrl Makefile, 1.1, NONE SixAxisCmdCtrl.h, 1.1, NONE SixAxisCmdCtrl.nc, 1.1, NONE SixAxisCmdCtrlM.nc, 1.3, NONE Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/MOBIUS/SixAxisCmdCtrl In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8976/MOBIUS/SixAxisCmdCtrl Removed Files: Makefile SixAxisCmdCtrl.h SixAxisCmdCtrl.nc SixAxisCmdCtrlM.nc Log Message: removed in favor of BioMOBIUS release as per adrian burns, intel ireland --- Makefile DELETED --- --- SixAxisCmdCtrl.h DELETED --- --- SixAxisCmdCtrl.nc DELETED --- --- SixAxisCmdCtrlM.nc DELETED --- From ayer1 at users.sourceforge.net Thu Apr 10 07:30:52 2008 From: ayer1 at users.sourceforge.net (steve ayer) Date: Thu, 10 Apr 2008 07:30:52 -0700 Subject: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/apps/MOBIUS/AnEx AnEx.h, 1.1, NONE AnEx.nc, 1.1, NONE AnExM.nc, 1.3, NONE Makefile, 1.1, NONE Message-ID: Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/apps/MOBIUS/AnEx In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8976/MOBIUS/AnEx Removed Files: AnEx.h AnEx.nc AnExM.nc Makefile Log Message: removed in favor of BioMOBIUS release as per adrian burns, intel ireland --- AnEx.h DELETED --- --- AnEx.nc DELETED --- --- AnExM.nc DELETED --- --- Makefile DELETED --- From bogus@does.not.exist.com Sun Apr 27 08:38:55 2008 From: bogus@does.not.exist.com () Date: Sun, 27 Apr 2008 15:38:55 -0000 Subject: No subject Message-ID: This page describes how to set up and use TOSNIC (the successor to Hostmote/MoteNIC) with SCP-MAC as the MAC layer. So far this has only been tested with Mica2 motes. Contents * 1 Basic EmStar Setup * 2 Compiling SCPBase * 3 Running TOSNIC * 4 Interpreting LEDs Basic EmStar Setup You will first need to do the following (which are not specific to this application): * Download and compile EmStar * Download and unpack the latest version of SCP-MAC into a * subdirectory of the EmStar tos-contrib directory * Insert the fusd.ko kernel module * Run fusdd as root Compiling SCPBase SCPBase is the mote-side application which communicates with the TOSNIC application on the host side. You will find it in I-LENSE CVS under ilense/tos/commstack/apps/SCPBase. If SCPMAC_ROOT is where you placed scp-mac in the EmStar tos-contrib directory, then SCPBase will be in SCPMAC_ROOT/apps/SCPBase. Currently, due to a bug in SCP-MAC, you will have to perform a small workaround to get serial communications working properly with SCPBase. Find the file SCPMAC_ROOT/tos/platform/mica2/HPLUART0M.nc. Rename this file to something else (like HPLUART0M.nc.bak). Renaming this file prevents you from using SCP-MAC UART debugging, but you can't do that an TOSNIC at the same time anyway - just remember to put it back if you need something else with UART debugging in the future. Next, look at the Makefile in SCPMAC_ROOT/apps/SCPBase. Make sure that SCPMAC_ROOT and TOSNIC_ROOT are pointing to the right directories (they should be by default). Then, look at the config.h file and modify any SCP-MAC settings that you wish to customize. Then, simply make mica2, and make install., and your mote is ready. Running TOSNIC Once you have compiled EmStar, the tosnicd application is found in emstar/obj./mote/. Tosnicd requires the fusd module to be inserted and fusdd to be running. Run tosnicd (as root or using sudo) with the following options: ./tosnicd --port --tosbase 512 --node_id where is replaced by the serial port that the mote is attached to, and is the id that you passed to make install (this can be omitted if /etc/id exists). After this is running, the /dev/link/mote devices are available for use by TOSNIC-aware applications. Interpreting LEDs SCPBase toggles the three LEDs for status information: * Yellow: Serial communication * Green: Radio communication * Red: Errors If an application attempts to send multiple packets before SCP-MAC has acquired a schedule, you may see rapid blinking of the red and yellow lights until the schedule is acquired and the packets are sent. Red LED errors are usually not fatal - the most common red LED event indicates that a packet failed to send and will be retried. --- NEW FILE: SCPBase.nc --- includes AM; includes Timer; includes config; includes protocols; includes AM_emstar; includes ScpMsg; includes SCPBaseMsg; configuration SCPBase { } implementation { #include "PlatformConstants.h" components Main, SCPBaseM, Scp as Mac, UART, FramerM, LedsC, NoLeds, TOSMsgTranslateM; Main.StdControl -> SCPBaseM; SCPBaseM.UARTControl -> FramerM; SCPBaseM.Framer -> FramerM.Framer[unique("Framer")]; SCPBaseM.FramerSendDone -> FramerM.Framer[unique("Framer")]; SCPBaseM.FramerStatus -> FramerM.Framer[unique("Framer")]; SCPBaseM.Leds -> LedsC; SCPBaseM.TOSMsgTranslate -> TOSMsgTranslateM; SCPBaseM.MacMsg -> Mac; SCPBaseM.MacStdControl -> Mac; #ifdef RADIO_TX_POWER SCPBaseM.RadioTxPower -> Mac; #endif FramerM.ByteControl -> UART; FramerM.ByteComm -> UART; FramerM.Leds -> NoLeds; } --- NEW FILE: SCPBaseM.nc --- includes SCPBaseMsg; /* Led indicators: * * Green = radio activity * Yellow = serial activity * Red = error activity * */ module SCPBaseM { provides interface StdControl; uses { interface StdControl as UARTControl; interface Framer; interface Framer as FramerSendDone; interface Framer as FramerStatus; interface Leds; interface TOSMsgTranslate; interface StdControl as MacStdControl; interface MacMsg; #ifdef RADIO_TX_POWER interface GetSetU8 as RadioTxPower; #endif } } implementation { #include "PlatformConstants.h" typedef struct { uint16_t radioRxPkts; uint16_t radioCRCFail; uint16_t radioQDropFail; uint16_t radioTxPkts; uint16_t uartDataRxPkts; uint16_t uartDataTxPkts; uint16_t uartSendDoneTxPkts; uint16_t radioRxBytes; uint16_t radioTxBytes; uint16_t uartDataRxBytes; uint16_t uartDataTxBytes; uint16_t uartSendDoneTxBytes; uint16_t radioTxAckedPkts; uint16_t radioTxFailPkts; uint16_t uartDataRxFailPkts; uint16_t uartDataTxFailPkts; uint16_t uartSendDoneTxFailPkts; } emstar_base_stats_t; typedef struct { bool hwAcksEnabled; uint8_t reserved; uint32_t baudrate; } emstar_base_config_t; typedef struct { emstar_base_config_t config; emstar_base_stats_t stats; } emstar_base_status_msg_t; enum { OUTBOUND_IDLE=0, OUTBOUND_SENDING, OUTBOUND_ACKING }; enum { INBOUND_IDLE=0, INBOUND_SENDING }; enum { CONF_MAX=20, INBOUND_QUEUE_MAX=4 }; uint8_t conf_request[CONF_MAX]; TOS_Msg_emstar_t gRecvBuffer, gSendBuffer; // for the Framer send_done_msg_t gSendDoneBuffer; emstar_base_stats_t stats; emstar_base_config_t config; SCPBasePkt outbound_pkt; uint8_t outbound_state; uint8_t outbound_seqno; uint8_t outbound_retval; uint8_t inbound_state; void* inbound_queue[INBOUND_QUEUE_MAX]; uint8_t inbound_head; uint8_t inbound_count; /* INITIALIZATION */ command result_t StdControl.init() { call UARTControl.init(); call MacStdControl.init(); #ifdef RADIO_TX_POWER call RadioTxPower.set(RADIO_TX_POWER); #endif call Leds.init(); return SUCCESS; } command result_t StdControl.start() { call Framer.register_client(TOSNIC_DATA_PACKET, (uint8_t *)&gRecvBuffer, sizeof(gRecvBuffer)); call FramerSendDone.register_client(TOSNIC_UNKNOWN_PACKET, NULL, 0); call FramerStatus.register_client(TOSNIC_STATUS_PACKET, (uint8_t *)&conf_request, sizeof(conf_request)); call UARTControl.start(); call MacStdControl.start(); outbound_state = OUTBOUND_IDLE; inbound_state = INBOUND_IDLE; return SUCCESS; } command result_t StdControl.stop() { call MacStdControl.stop(); call UARTControl.stop(); return SUCCESS; } /* CRC */ uint16_t update_crc(uint8_t data, uint16_t crc) { uint8_t i; uint16_t tmp; tmp = (uint16_t)(data); crc = crc ^ (tmp << 8); for (i = 0; i < 8; i++) { if (crc & 0x8000) crc = crc << 1 ^ 0x1021; // << is done before ^ else crc = crc << 1; } return crc; } /* QUEUEING */ uint8_t iq_empty() { return inbound_count == 0; } uint8_t iq_full() { return inbound_count >= INBOUND_QUEUE_MAX; } void* iq_pop() { void* retval = NULL; if (inbound_count > 0) { retval = inbound_queue[inbound_head]; inbound_count--; inbound_head++; if (inbound_head >= INBOUND_QUEUE_MAX) inbound_head = 0; } return retval; } uint8_t iq_get_tail() { uint8_t tail = (inbound_head + inbound_count); if (tail >= INBOUND_QUEUE_MAX) tail -= INBOUND_QUEUE_MAX; return tail; } void* iq_swap_push(void* msg) { void* retval = NULL; if (!iq_full()) { uint8_t tail = iq_get_tail(); retval = inbound_queue[tail]; inbound_queue[tail] = msg; inbound_count++; } return retval; } /* SEND / RECV TASKS */ void run_rx() { void* msg = NULL; Mini_TOS_Msg *mtos_msgptr; TOS_Msg tmp_tos_msg; if (inbound_state == INBOUND_IDLE && !iq_empty()) { /* dequeue */ msg = iq_pop(); mtos_msgptr = (Mini_TOS_Msg*)msg; if (msg == NULL || mtos_msgptr == NULL) { call Leds.redToggle(); return; } /* translate */ tmp_tos_msg.addr = mtos_msgptr->addr; tmp_tos_msg.type = mtos_msgptr->type; tmp_tos_msg.group = mtos_msgptr->group; tmp_tos_msg.length = mtos_msgptr->length; memcpy(tmp_tos_msg.data, mtos_msgptr->data, tmp_tos_msg.length); tmp_tos_msg.crc = mtos_msgptr->crc; call TOSMsgTranslate.moteToHost(&tmp_tos_msg, &gSendBuffer); /* push to framer */ if (call Framer.send(TOSNIC_DATA_PACKET, (uint8_t *)&gSendBuffer, gSendBuffer.hdr.length + sizeof(TOS_Msg_emstar_hdr_t), TOSNIC_PRIORITY_MEDIUM) == FAIL) { call Leds.redToggle(); } else { /* sending mode */ stats.uartDataTxPkts++; stats.uartDataTxBytes += gSendBuffer.hdr.length + sizeof(TOS_Msg_emstar_hdr_t); inbound_state = INBOUND_SENDING; } } } task void send_done_task(){ if (outbound_state != OUTBOUND_SENDING) { call Leds.redToggle(); return; } outbound_state = OUTBOUND_ACKING; gSendDoneBuffer.seqno = outbound_seqno; gSendDoneBuffer.result = outbound_retval; if ((call FramerSendDone.send (TOSNIC_SEND_DONE_PACKET, (uint8_t*)&gSendDoneBuffer, sizeof(send_done_msg_t), TOSNIC_PRIORITY_HIGH)) != SUCCESS) { call Leds.redToggle(); } } /* SERIAL COMMUNICATION */ /* Status Packets */ event result_t FramerStatus.receive(uint8_t *data, uint16_t length, uint8_t token) { // nothing to do return SUCCESS; } event void FramerStatus.sendDone(uint8_t *data, result_t success) { // nothing to do } /* Unknown packets */ event result_t FramerSendDone.receive(uint8_t *data, uint16_t length, uint8_t token) { // should not reach this point; indicate error call Leds.redToggle(); return SUCCESS; } event void FramerSendDone.sendDone(uint8_t *data, result_t success) { // not sure exactly what we're supposed to be doing here.. if (outbound_state != OUTBOUND_ACKING) { // confused state -> error call Leds.redToggle(); outbound_state = OUTBOUND_IDLE; return; } if (success == FAIL) { // transmission failure -> error call Leds.redToggle(); stats.uartSendDoneTxFailPkts++; } outbound_state = OUTBOUND_IDLE; } /* Data packets */ event result_t Framer.receive(uint8_t *data, uint16_t length, uint8_t token) { // got a message from host, direct to radio TOS_Msg_emstar_t *e = (TOS_Msg_emstar_t *)data; TOS_Msg tmp_tos_msg; int i; uint8_t *tmsg_itr = NULL; call Leds.yellowToggle(); if (length <= sizeof(TOS_Msg_emstar_hdr_t)) { // packet too small -> error call Leds.redToggle(); return FAIL; } if (outbound_state != OUTBOUND_IDLE) { // radio busy -> error call Leds.redToggle(); return FAIL; } outbound_seqno = e->hdr.seq_num; call TOSMsgTranslate.hostToMote(&tmp_tos_msg,e); outbound_state = OUTBOUND_SENDING; outbound_pkt.tos_msg.addr = tmp_tos_msg.addr; outbound_pkt.tos_msg.type = tmp_tos_msg.type; outbound_pkt.tos_msg.group = tmp_tos_msg.group; outbound_pkt.tos_msg.length = tmp_tos_msg.length; for (i = 0; i < TOSH_DATA_LENGTH; i++) { outbound_pkt.tos_msg.data[i] = 0; } memcpy(outbound_pkt.tos_msg.data, tmp_tos_msg.data, tmp_tos_msg.length); outbound_pkt.tos_msg.crc = 0; for (tmsg_itr = (uint8_t*)(&(outbound_pkt.tos_msg)); tmsg_itr < (uint8_t*)(&(outbound_pkt.tos_msg)) + offsetof(Mini_TOS_Msg, crc); tmsg_itr++) { outbound_pkt.tos_msg.crc = update_crc(*tmsg_itr, outbound_pkt.tos_msg.crc); } stats.uartDataRxPkts++; stats.uartDataRxBytes+=length; if (call MacMsg.send(&(outbound_pkt), sizeof(outbound_pkt), /* outbound_pkt.tos_msg.addr) != SUCCESS) { */ 0xFFFF) != SUCCESS) { // failed to send -> call Leds.redToggle(); } return SUCCESS; } event void Framer.sendDone(uint8_t *data, result_t success) { // finished sending message to host call Leds.yellowToggle(); if (success == FAIL) { // failed to send -> error call Leds.redToggle(); stats.uartDataTxFailPkts++; } inbound_state = INBOUND_IDLE; run_rx(); } /* RADIO COMMUNICATION */ event void MacMsg.sendDone(void* msg, result_t result) { // finished sending message over radio call Leds.greenToggle(); atomic { if (outbound_state != OUTBOUND_SENDING) { // confused state -> error call Leds.redToggle(); outbound_state = OUTBOUND_SENDING; } if (result != SUCCESS) { // failed send -> error // call Leds.redToggle(); outbound_retval = SEND_DONE_FAILED_TRANSMISSION; } else { outbound_retval = SEND_DONE_SUCCESS; } if ((post send_done_task()) != SUCCESS) { // task failed -> error call Leds.redToggle(); } } } event void* MacMsg.receiveDone(void* msg) { // got a message from radio, direct to host SCPBasePkt* pkt; TOS_MsgPtr retval; pkt = (SCPBasePkt*)msg; call Leds.greenToggle(); stats.radioRxPkts++; stats.radioRxBytes += (sizeof(ScpHeader) + ((PhyPktBuf*)msg)->hdr.length); retval = iq_swap_push((void*)(&(pkt->tos_msg))); run_rx(); return msg; } } --- NEW FILE: SCPBaseMsg.h --- #ifndef _SCPBASE_MSG_H_ #define _SCPBASE_MSG_H_ // Defines a TOS message encapsulated within an SCP packet typedef ScpHeader SCPBaseHeader; #define PAYLOAD_LEN (PHY_MAX_PKT_LEN - sizeof(SCPBaseHeader) - 2) typedef struct { uint8_t type; uint16_t addr; int8_t data[TOSH_DATA_LENGTH - 5]; uint16_t crc; } __attribute__ ((packed)) TOSNIC_Encap; typedef struct { uint16_t addr; uint8_t type; uint8_t group; uint8_t length; int8_t data[TOSH_DATA_LENGTH]; uint16_t crc; } __attribute__ ((packed)) Mini_TOS_Msg; typedef struct { SCPBaseHeader hdr; Mini_TOS_Msg tos_msg; int16_t crc; } __attribute__ ((packed)) SCPBasePkt; #endif --- NEW FILE: config.h --- #ifndef _SCPBASE_CONFIG_ #define _SCPBASE_CONFIG_ /* The following is REQUIRED for this application to work */ #define DISABLE_CPU_SLEEP /* The following are optional SCP-MAC parameters */ // Configure Physical layer. Definitions here override default values // Default values are defined in PhyMsg.h and PhyConst.h // -------------------------------------------------------------- #define PHY_MAX_PKT_LEN 250 // max: 250 (bytes), default: 100 // configure radio transmission power (0x01--0xff) // Following sample values are for 433MHz mica2: 0x0f=0dBm (TinyOS default) // 0x0B = -3dBm, 0x08 = -6dBm, 0x05 = -9dBm, 0x03 = -14dBm 0x01 = -20dBm // 0x0f = 0dBm, 0x50 = 3dBm, 0x80 = 6dBm, 0xe0 = 9dBm, 0xff = 10dBm //#define RADIO_TX_POWER 0x03 // tell PHY to measure radio energy usage, only for performace analysis //#define RADIO_MEASURE_ENERGY // Configure CSMA, look for CsmaConst.h for details // ----------------------------------------------- //#define CSMA_CW 32 // contention window size, must be 2^n //#define CSMA_BACKOFF_TIME 20 #define CSMA_RTS_THRESHOLD 101 //#define CSMA_BACKOFF_LIMIT 7 //#define CSMA_RETX_LIMIT 3 //#define CSMA_ENABLE_OVERHEARING // overhearing is disabled by default // Configure LPL, look for LplConst.h for details // ---------------------------------------------- // LPL specific configuration (binary ms) //#define LPL_POLL_PERIOD 512 // Configure SCP, look for ScpConst.h for details // ---------------------------------------------- // SCP specific configuration (binary ms) #define SCP_POLL_PERIOD 1024 // only one master node starts a schedule in the network // the master node will broadcast it schedule after it starts // slave nodes only performs LPL and wait to synchronize with master schedule // // adaptive listen is enabled by default // define the following macro to disable it //#define SCP_DISABLE_ADAPTIVE_LISTEN // debugging with LEDs //#define SCP_LED_DEBUG //#define LPL_LED_DEBUG //#define CSMA_LED_DEBUG //#define PHY_LED_DEBUG // include MAC message and header definitions #include "ScpMsg.h" typedef ScpHeader MacHeader; #endif // CONFIG