[Tinyos-beta-commits] CVS: tinyos-1.x/beta/TOSSIM-CC2420 PowerState.nc, NONE, 1.1 PowerStateM.nc, NONE, 1.1 TimerJiffyAsyncC.nc, NONE, 1.1 TimerJiffyAsyncM.nc, NONE, 1.1 hardware.h, NONE, 1.1 HPLCC2420M.nc, 1.1, 1.2

Yang overbored at users.sourceforge.net
Sat Mar 12 23:23:10 PST 2005


Update of /cvsroot/tinyos/tinyos-1.x/beta/TOSSIM-CC2420
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27290

Modified Files:
	HPLCC2420M.nc 
Added Files:
	PowerState.nc PowerStateM.nc TimerJiffyAsyncC.nc 
	TimerJiffyAsyncM.nc hardware.h 
Log Message:
Added support for PowerTOSSIM, including MSP430 CPU cycle counting.
Added specific support for Telos Revision A and B.
Updated the HPL to support starting/stopping.



--- NEW FILE: PowerState.nc ---
/**
 * Interface for the PowerState functions.
 *
 * Authors: Victor Shnayder, Bor-rong Chen
 *
 */

interface PowerState {
     async command double get_mote_cycles(int mote);

     /*
      * profile=1 if doing profiling, 0 else
      */
     async command result_t init(int profile, int cpu_prof);

     /* Do any necessary finalization.  In particular, dump out
      * details to a file if necessary. */
     async command result_t stop();

     /* Used by the main event loop to notify us to record/process the
      * current CPU Cycle Count */
     async command void CPUCycleCheckpoint();



     /************ ADC functions **********/
     /* The current mote (at the current time) is accessing
      * the specified port */
     async command void ADCsample(uint8_t port);
     async command void ADCdataReady();
     async command void ADCon();
     async command void ADCoff();

     /************ LED functions **********/

     async command void redOn();
     async command void redOff();
     async command void greenOn();
     async command void greenOff();
     async command void yellowOn();
     async command void yellowOff();

     /************ RADIO functions **********/     

     async command void radioTxMode();
     async command void radioRxMode();
     async command void radioRFPower(uint8_t power_level);
     async command void radioStart();
     async command void radioStop();
     async command void radio(const char* state);

     /************ CPU state funtions *******/
     async command void cpuState(uint8_t sm);

     /************ SENSOR functions *********/
     async command void sensorPhotoOn(); 
     async command void sensorPhotoOff();
     async command void sensorTempOn();
     async command void sensorTempOff();
     async command void sensorAccelOn();
     async command void sensorAccelOff();

     /************ EEPROM functions ********/
     async command void eepromReadStart();
     async command void eepromReadStop();
     async command void eepromWriteStart();
     async command void eepromWriteStop();


     /************ SNOOZE functions *********/
     async command void snoozeStart();
     async command void snoozeWakeup();
}

--- NEW FILE: PowerStateM.nc ---
/**
 *
 * Author: Victor Shnayder, Bor-rong Chen
 */

includes powermod;
includes sensorboard;

module PowerStateM {
     provides interface PowerState;
}
implementation
{
     /*
      * Variable defs in powermod.h-that way they stay global instead of
      * being transformed to be per-mote
      */

     // prototypes
     int num_bbs();
     void dump_power_details();
     
     async command result_t PowerState.init(int prof, int cpu_prof) {
	  FILE* cycle_file;
	  char cycle_map[] = "bb_cycle_map";
	  int bb;
	  double bbcyc;
	  if(power_init == 1) {
	       fprintf(stderr,"PowerState.init() called twice...\n");
	       return SUCCESS;
	  }
	  power_init = 1;
	  prof_on = prof;
	  cpu_prof_on = cpu_prof;
	  
	  if(cpu_prof_on) {
	       cycle_file = fopen(cycle_map, "r");
	       if(!cycle_file) {
		    fprintf(stderr,"Couldn't open '%s', exiting\n", cycle_map);
		    exit(-1);
	       }
      
	       cycles = calloc(num_bbs(), sizeof(double));
      
	       while(EOF != fscanf(cycle_file, " %d %lf", &bb, &bbcyc)) {
		    cycles[bb] = bbcyc;
	       }
	       fclose(cycle_file);
	  }
	  return SUCCESS;
     }


     async command result_t PowerState.stop() {
	  if(cpu_prof_on)
	       dump_power_details();
	  return SUCCESS;
     }

/*************** STATE TRANSITION CODE ****************************/
     /******* ADC state functions ***/

     async command void PowerState.ADCon() {
	  if(!prof_on) return;
	  dbg(DBG_POWER, "POWER: Mote %d ADC ON at %lld \n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.ADCoff() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d ADC OFF at %lld \n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.ADCdataReady() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d ADC DATA_READY at %lld \n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.ADCsample(uint8_t port) {
	  if(!prof_on) return;

	  dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE PORT %d at %lld \n", NODE_NUM, port,
		   tos_state.tos_time);
	  
/** It would be nice to know which port it is, but not portable.  So
 * instead just printing the port number
 */
/*  switch(port) {
	  case TOS_ADC_CC_RSSI_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE RSSI_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	  case TOS_ADC_PHOTO_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE PHOTO_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	       break;
	  case TOS_ADC_TEMP_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE TEMP_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	       break;
	  case TOS_ADC_MIC_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE MIC_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	       break;
	  case TOS_ADC_ACCEL_X_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE ACCEL_X_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	       break;
	  case TOS_ADC_ACCEL_Y_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE ACCEL_Y_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	       break;
	  case TOS_ADC_MAG_X_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE MAG_X_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	       break;
	  case TOS_ADC_MAG_Y_PORT:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE MAG_Y_PORT at %lld \n", NODE_NUM,
		   tos_state.tos_time);
	       break;
	  default:
	       dbg(DBG_POWER, "POWER: Mote %d ADC SAMPLE unknown_port_%i at %lld \n", NODE_NUM,
		   port, tos_state.tos_time);
	  }
*/
     }

     /******* LED state functions ***/
     async command void PowerState.redOn() {
	  if(!prof_on) return;
	  dbg(DBG_POWER, "POWER: Mote %d LED_STATE RED_ON at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.redOff() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d LED_STATE RED_OFF at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.greenOn() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d LED_STATE GREEN_ON at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.greenOff() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d LED_STATE GREEN_OFF at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.yellowOn() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d LED_STATE YELLOW_ON at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.yellowOff() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d LED_STATE YELLOW_OFF at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     /******* RADIO state functions ***/
     async command void PowerState.radio(const char *state) {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d RADIO_STATE %s at %lld\n", NODE_NUM,
	      state, tos_state.tos_time);
     }

     async command void PowerState.radioTxMode() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d RADIO_STATE TX at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.radioRxMode() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d RADIO_STATE RX at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.radioRFPower(uint8_t power_level) {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d RADIO_STATE SetRFPower %X at %lld\n", NODE_NUM, power_level,
	      tos_state.tos_time);
     }

     async command void PowerState.radioStart() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d RADIO_STATE ON at %lld\n", NODE_NUM, 
	      tos_state.tos_time);
     }

     async command void PowerState.radioStop() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d RADIO_STATE OFF at %lld\n", NODE_NUM, 
	      tos_state.tos_time);
     }

     /************ CPU state funtions *******/
  
     async command void PowerState.cpuState(uint8_t sm) {

	  char cpu_power_state[8][20] = {"IDLE", \
					 "ADC_NOISE_REDUCTION", \
					 "POWER_DOWN", \
					 "POWER_SAVE", \
					 "RESERVED", \
					 "RESERVED", \
					 "STANDBY", \
					 "EXTENDED_STANDBY"};
       
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d CPU_STATE %s at %lld\n", NODE_NUM, cpu_power_state[sm],
	      tos_state.tos_time);

     }

     /************ SENSOR functions *********/
     async command void PowerState.sensorPhotoOn() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d SENSOR_STATE PHOTO ON at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.sensorPhotoOff() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d SENSOR_STATE PHOTO OFF at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.sensorTempOn() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d SENSOR_STATE TEMP ON at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
                                                                                         
     async command void PowerState.sensorTempOff() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d SENSOR_STATE TEMP OFF at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.sensorAccelOn() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d SENSOR_STATE ACCEL ON at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
                                                                                         
     async command void PowerState.sensorAccelOff() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d SENSOR_STATE ACCEL OFF at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }

     /************ EEPROM functions *********/
     async command void PowerState.eepromReadStart() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d EEPROM READ START at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.eepromReadStop() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d EEPROM READ STOP at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }

     async command void PowerState.eepromWriteStart() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d EEPROM WRITE START at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     async command void PowerState.eepromWriteStop() {
	  if(!prof_on) return; 
	  dbg(DBG_POWER, "POWER: Mote %d EEPROM WRITE STOP at %lld\n", NODE_NUM,
	      tos_state.tos_time);
     }
  
     /************ SNOOZE functions *********/

     async command void PowerState.snoozeStart() {
//       if(!prof_on) return; 
// dbg(DBG_POWER, "POWER: Mote %d SNOOZE START at %lld\n", NODE_NUM,
//           tos_state.tos_time);
     }

     async command void PowerState.snoozeWakeup() {
//       if(!prof_on) return; 
// dbg(DBG_POWER, "POWER: Mote %d SNOOZE END at %lld\n", NODE_NUM,
//           tos_state.tos_time);
     }

/********************** End State Transition Code  *******************/

     /****************************************************************
      * CPU Cycle Counting stuff: this needs a little explanation.
      *
      * This code will be run through the nesc compiler together with all
      * the other application components to generate a single app.c.  So
      * it needs to pass standard nesc.
      *
      * Then, it is run through CIL, which tags all the basic blocks.
      * Then it is run through a perl script to fix up some of the
      * references to # of basic blocks and to the actual exec counts for
      * each BB.  And then it's finally compiled.
      * 
      * Hence the nonsensical code in these next two functions: they need
      * to be valid C to pass the first (and second) preprocessor, and
      * will be made sensical by a later post-pre-processing step
      *****************************************************************/

     int num_bbs() {
	  // Preprocessor will add an '= #' to set it correctly
	  int POWERPROF_NUM_BBS;  
	  return POWERPROF_NUM_BBS;  
     }

     int bb_exec_count(int mote,int bb) {
	  int POWERPROF_BB_EXEC_COUNT;  // will be replaced with bb_count[mote][bb]
	  return POWERPROF_BB_EXEC_COUNT;
     }

     async command double PowerState.get_mote_cycles(int mote) {
	  int bb;
	  double total;
	  if(!cpu_prof_on) {
	       fprintf(stderr,"get_mote_cycles() called when cpu prof is off!  Shouldn't happen!\n");
	       exit(-1);
	  }

	  total = 0;
	  for(bb=1; bb < num_bbs(); bb++) {
	       total += bb_exec_count(mote,bb) * cycles[bb];
	  }
	  return total;
     }

  
     /* Print current totals to the debug stream */
     void print_power_info() {
	  int mote;
	  if(!cpu_prof_on) {
	       fprintf(stderr,"print_power_info() called when cpu prof is off!  Shouldn't happen!\n");
	       exit(-1);
	  }


	  if(!power_init) {
	       fprintf(stderr, "print_power_info() called before init_power_info()! Should never happen!\n");
	       exit(-1);
	  }
    
	  for(mote=0; mote < tos_state.num_nodes; mote++) {
	       //fprintf(stderr,"%d: CPU: %.1f\n", i, total);
	       dbg(DBG_POWER,"POWER: Mote %d CPU_CYCLES %.1lf at %lld\n", mote,
		     call PowerState.get_mote_cycles(mote),
		     tos_state.tos_time);
	  }
     }  

     /* Dump details to a file */
     void dump_power_details() {
	  char exec_cnts[] = "bb_exec_cnt";  // File to write to
	  FILE* f;
	  int mote,bb;

	  if(!cpu_prof_on) {
	       fprintf(stderr,"dump_power_details() called when cpu prof is off!  Shouldn't happen!\n");
	       exit(-1);
	  }

	  f = fopen(exec_cnts,"w");
	  if(!f) {
	       fprintf(stderr,"Couldn't open '%s', exiting\n", exec_cnts);
	       exit(-1);
	  }
	  for(mote=0; mote < tos_state.num_nodes; mote++) {
	       fprintf(f,"mote %d total cycles: %.1lf\n", mote, call PowerState.get_mote_cycles(mote));
	       dbg(DBG_POWER,"POWER: Mote %d CPU_CYCLES %.1lf at %lld\n", mote, call PowerState.get_mote_cycles(mote), tos_state.tos_time);
      
	       for(bb=1; bb < num_bbs(); bb++) {
		    fprintf(f, "%6d %6d %8d\n", mote, bb, bb_exec_count(mote,bb));
		    // dbg(DBG_POWER, "%6d %6d %8d\n", mote, bb, bb_exec_count(mote,bb));
	       }
	  }
	  fclose(f);
     }


     async command void PowerState.CPUCycleCheckpoint() {
	  if(!cpu_prof_on) {
	       fprintf(stderr,"CPUCycleCheckpoint() called when cpu prof is off!  Shouldn't happen!\n");
	       exit(-1);
	  }

	  /* FIXME: what's the right thing to do here? */
	  print_power_info();
     }

     /***********************  END CPU CYCLE COUNT CODE ***************/
}

--- NEW FILE: TimerJiffyAsyncC.nc ---
//$Id: TimerJiffyAsyncC.nc,v 1.1 2005/03/13 07:23:06 overbored Exp $
// @author Cory Sharp, Yang Zhang

configuration TimerJiffyAsyncC
{
  provides interface StdControl;
  provides interface TimerJiffyAsync;
}
implementation
{
  components TimerJiffyAsyncM
	   , TimerC
	   ;

  StdControl = TimerJiffyAsyncM;
  StdControl = TimerC;

  TimerJiffyAsync = TimerJiffyAsyncM;

  TimerJiffyAsyncM.Timer -> TimerC.Timer[unique("Timer")];
}


--- NEW FILE: TimerJiffyAsyncM.nc ---
//$Id: TimerJiffyAsyncM.nc,v 1.1 2005/03/13 07:23:06 overbored Exp $
// @author Joe Polastre, Yang Zhang

module TimerJiffyAsyncM {
  provides {
    interface StdControl;
    interface TimerJiffyAsync;
  }
  uses {
    interface Timer;
  }
}

implementation
{
  bool bSet;

  command result_t StdControl.init()
  {
    return SUCCESS;
  }

  command result_t StdControl.start()
  {
    atomic bSet = FALSE;
    return SUCCESS;
  }

  command result_t StdControl.stop()
  {
    atomic bSet = FALSE;
    return SUCCESS;
  }

  async command result_t TimerJiffyAsync.setOneShot( uint32_t jiffy )
  {
    result_t result;
    atomic {
      bSet = TRUE;
      result = call Timer.start(TIMER_ONE_SHOT, jiffy);
    }
    return result;
  }

  async command bool TimerJiffyAsync.isSet( )
  {
    bool value;
    atomic value = bSet;
    return value;
  }

  async command result_t TimerJiffyAsync.stop()
  {
    atomic {
      bSet = FALSE;
    }
    return SUCCESS;
  }

  event result_t Timer.fired()
  {
    return signal TimerJiffyAsync.fired();
  }
}


--- NEW FILE: hardware.h ---
// $Id: hardware.h,v 1.1 2005/03/13 07:23:06 overbored Exp $

/*									tab:4
 * "Copyright (c) 2000-2003 The Regents of the University  of California.  
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 * Copyright (c) 2002-2003 Intel Corporation
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE     
 * file. If you do not find these files, copies can be found by writing to
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
 * 94704.  Attention:  Intel License Inquiry.
 */
/*
 *
 */
#ifndef __HARDWARE_H__
#define __HARDWARE_H__

// Allow use of atomic in C code
#undef atomic

#include <stdio.h>
//#include <time.h>
#include <signal.h>
#include <nido.h>
#include <hardware.nido.h>

// We need norace for tossim to declare tossim's state variables
// as norace (they are in "async" handlers, but tossim has no true
// concurrency)
#undef norace

#define TOS_INTERRUPT_HANDLER(name, params) \
void name##_interrupt params __attribute__((C))

#define TOS_SIGNAL_HANDLER(signame, params) \
void signame##_signal params __attribute__((C))

#define TOS_ISSUE_INTERRUPT(name) \
name##_interrupt

#define TOS_ISSUE_SIGNAL(signame) \
signame##_signal

#include <external_comm.h>

#include <dbg.h>
extern norace TOS_dbg_mode dbg_modes;


norace TOS_state_t tos_state;

// ADDED
// TODO YANG is this appropriate?
void TOSH_wait()
{
}

void TOSH_wait_250ns()
{
}

void TOSH_uwait(int u_sec)
{
}

void TOSH_sleep()
{
}

// atomic statement runtime support
// For nido, nothing needs to be done...

typedef uint8_t __nesc_atomic_t;

inline __nesc_atomic_t __nesc_atomic_start(void) __attribute__((spontaneous))
{
  return 0;
}

inline void __nesc_atomic_end(__nesc_atomic_t oldSreg) __attribute__((spontaneous))
{
}

inline void __nesc_enable_interrupt() 
{
}

enum {
  TOSH_ADC_PORTMAPSIZE = 255,
};

//".c" files needed for the simulator
#include <heap_array.c>
#include <hardware.c>
#include <event_queue.c>
#include <events.c>
#include <hpl.c>
#include <dbg.c>
#include <external_comm.c>
#include <tos.c>
#include <adc_model.c>
#include <spatial_model.c>
#include <eeprom.c>
#endif /* __HARDWARE_H__ */

Index: HPLCC2420M.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/TOSSIM-CC2420/HPLCC2420M.nc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** HPLCC2420M.nc	15 Feb 2005 04:15:12 -0000	1.1
--- HPLCC2420M.nc	13 Mar 2005 07:23:06 -0000	1.2
***************
*** 42,45 ****
--- 42,47 ----
  // CC2420Lib.
  
+ includes simplatform;
+ 
  module HPLCC2420M {
    provides {
***************
*** 62,65 ****
--- 64,68 ----
  
    // TODO try making all the events instantaneous instead of posted?
+   // TODO it is not completely safe to turn off the radio at any random time. for instance, we might break if we turn it off while sending a frame, or the opposite side might get a packet successfully, or.... analyze/address these possibilities?
  
    // Container for structure for a packet, along with various metadata.
***************
*** 106,109 ****
--- 109,114 ----
  #define CC2420_MDMCTRL0_CCAMODE_START CC2420_MDMCTRL0_CCAMODE
  #define CC2420_MDMCTRL0_CCAMODE_END 7
+ #define CC2420_TXCTRL_PAPWR_START CC2420_TXCTRL_PAPWR
+ #define CC2420_TXCTRL_PAPWR_END 4
  
    // The number of radio configuration registers.
***************
*** 244,274 ****
  #define TABLE_FIELDS 7
  
!   static double table[TABLE_SIZE][TABLE_FIELDS] = {
!     // { distance, recv mean, recv stddev, lqi mean, lqi stddev, rssi mean, rssi stddev }
!     { 1.00e+00, 1.00e+00, 0.00e+00, 9.32e-01, 4.07e-03, -5.00e+00, 0.00e+00 },
!     { 3.00e+00, 1.00e+00, 0.00e+00, 9.32e-01, 3.82e-03, -3.70e+01, 5.44e+00 },
!     { 9.00e+00, 1.00e+00, 0.00e+00, 9.28e-01, 4.89e-03, -3.76e+01, 3.71e+00 },
!     { 1.20e+01, 1.00e+00, 0.00e+00, 9.26e-01, 6.66e-03, -5.23e+01, 2.35e+00 },
!     { 1.50e+01, 1.00e+00, 0.00e+00, 9.27e-01, 6.01e-03, -5.82e+01, 3.49e+00 },
!     { 2.00e+01, 9.98e-01, 1.52e-06, 9.24e-01, 7.76e-03, -5.98e+01, 3.85e+00 },
!     { 2.50e+01, 9.93e-01, 1.60e-02, 9.11e-01, 3.15e-02, -6.28e+01, 3.52e+00 },
!     { 3.00e+01, 9.92e-01, 1.67e-02, 9.03e-01, 3.99e-02, -6.89e+01, 4.13e+00 },
!     { 3.50e+01, 9.71e-01, 8.58e-02, 8.78e-01, 9.75e-02, -7.06e+01, 3.45e+00 },
!     { 5.00e+01, 9.90e-01, 3.12e-02, 8.96e-01, 4.10e-02, -7.14e+01, 4.52e+00 },
!     { 5.50e+01, 9.00e-01, 1.59e-01, 7.96e-01, 1.70e-01, -7.06e+01, 7.69e+00 },
!     { 6.50e+01, 9.29e-01, 2.04e-01, 8.37e-01, 1.25e-01, -7.11e+01, 1.30e+01 },
!     { 7.50e+01, 6.71e-01, 2.77e-01, 5.87e-01, 1.75e-01, -7.02e+01, 1.73e+01 },
!     { 8.50e+01, 7.09e-01, 3.74e-01, 6.62e-01, 2.84e-01, -7.10e+01, 2.14e+01 },
!     { 9.50e+01, 7.73e-01, 2.57e-01, 6.36e-01, 1.80e-01, -7.03e+01, 1.49e+01 },
!     { 1.05e+02, 6.07e-01, 3.27e-01, 4.96e-01, 2.04e-01, -7.10e+01, 3.20e+01 },
!     { 1.15e+02, 4.84e-01, 1.16e-01, 3.31e-01, 1.21e-01, -7.00e+01, 2.35e+01 },
!     { 1.25e+02, 6.68e-01, 4.28e-01, 5.38e-01, 2.53e-01, -7.12e+01, 1.50e+00 },
!     { 1.35e+02, 5.07e-01, 3.13e-01, 3.55e-01, 1.41e-01, -7.61e+01, 1.40e+01 },
!     { 1.50e+02, 5.36e-01, 3.62e-01, 4.44e-01, 1.92e-01, -7.88e+01, 8.34e+00 },
!     { 1.75e+02, 3.67e-01, 2.98e-01, 3.69e-01, 1.56e-01, -8.00e+01, 3.43e+00 },
!     { 1.90e+02, 2.50e-01, 1.35e-01, 2.77e-01, 1.09e-01, -8.02e+01, 7.92e+00 },
!     { 2.00e+02, 1.24e-01, 2.67e-01, 1.47e-01, 3.37e-02, -8.20e+01, 1.40e+01 },
!     { 2.25e+02, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, -8.60e+01, 2.02e+00 }
!   };
  
    //
--- 249,281 ----
  #define TABLE_FIELDS 7
  
! //  static double table[TABLE_SIZE][TABLE_FIELDS] = {
! //    // { distance, recv mean, recv stddev, lqi mean, lqi stddev, rssi mean, rssi stddev }
! //    { 1.00e+00, 1.00e+00, 0.00e+00, 9.32e-01, 4.07e-03, -5.00e+00, 0.00e+00 },
! //    { 3.00e+00, 1.00e+00, 0.00e+00, 9.32e-01, 3.82e-03, -3.70e+01, 5.44e+00 },
! //    { 9.00e+00, 1.00e+00, 0.00e+00, 9.28e-01, 4.89e-03, -3.76e+01, 3.71e+00 },
! //    { 1.20e+01, 1.00e+00, 0.00e+00, 9.26e-01, 6.66e-03, -5.23e+01, 2.35e+00 },
! //    { 1.50e+01, 1.00e+00, 0.00e+00, 9.27e-01, 6.01e-03, -5.82e+01, 3.49e+00 },
! //    { 2.00e+01, 9.98e-01, 1.52e-06, 9.24e-01, 7.76e-03, -5.98e+01, 3.85e+00 },
! //    { 2.50e+01, 9.93e-01, 1.60e-02, 9.11e-01, 3.15e-02, -6.28e+01, 3.52e+00 },
! //    { 3.00e+01, 9.92e-01, 1.67e-02, 9.03e-01, 3.99e-02, -6.89e+01, 4.13e+00 },
! //    { 3.50e+01, 9.71e-01, 8.58e-02, 8.78e-01, 9.75e-02, -7.06e+01, 3.45e+00 },
! //    { 5.00e+01, 9.90e-01, 3.12e-02, 8.96e-01, 4.10e-02, -7.14e+01, 4.52e+00 },
! //    { 5.50e+01, 9.00e-01, 1.59e-01, 7.96e-01, 1.70e-01, -7.06e+01, 7.69e+00 },
! //    { 6.50e+01, 9.29e-01, 2.04e-01, 8.37e-01, 1.25e-01, -7.11e+01, 1.30e+01 },
! //    { 7.50e+01, 6.71e-01, 2.77e-01, 5.87e-01, 1.75e-01, -7.02e+01, 1.73e+01 },
! //    { 8.50e+01, 7.09e-01, 3.74e-01, 6.62e-01, 2.84e-01, -7.10e+01, 2.14e+01 },
! //    { 9.50e+01, 7.73e-01, 2.57e-01, 6.36e-01, 1.80e-01, -7.03e+01, 1.49e+01 },
! //    { 1.05e+02, 6.07e-01, 3.27e-01, 4.96e-01, 2.04e-01, -7.10e+01, 3.20e+01 },
! //    { 1.15e+02, 4.84e-01, 1.16e-01, 3.31e-01, 1.21e-01, -7.00e+01, 2.35e+01 },
! //    { 1.25e+02, 6.68e-01, 4.28e-01, 5.38e-01, 2.53e-01, -7.12e+01, 1.50e+00 },
! //    { 1.35e+02, 5.07e-01, 3.13e-01, 3.55e-01, 1.41e-01, -7.61e+01, 1.40e+01 },
! //    { 1.50e+02, 5.36e-01, 3.62e-01, 4.44e-01, 1.92e-01, -7.88e+01, 8.34e+00 },
! //    { 1.75e+02, 3.67e-01, 2.98e-01, 3.69e-01, 1.56e-01, -8.00e+01, 3.43e+00 },
! //    { 1.90e+02, 2.50e-01, 1.35e-01, 2.77e-01, 1.09e-01, -8.02e+01, 7.92e+00 },
! //    { 2.00e+02, 1.24e-01, 2.67e-01, 1.47e-01, 3.37e-02, -8.20e+01, 1.40e+01 },
! //    { 2.25e+02, 0.00e+00, 0.00e+00, 0.00e+00, 0.00e+00, -8.60e+01, 2.02e+00 }
! //  };
! 
!   static double table[TABLE_SIZE][TABLE_FIELDS];
  
    //
***************
*** 334,337 ****
--- 341,357 ----
  #define DEBUG_SENDING FALSE
  
+   // TODO use this to debug memory errors
+ //  void* alloc(size_t size) {
+ //    assert(size > 0 && "Size must be greater than 1");
+ //    size += 4;
+ //    uint8_t* pointer = malloc(size);
+ //    pointer[size - 4] = 0x00;
+ //    pointer[size - 4] = 0x01;
+ //    pointer[size - 4] = 0x02;
+ //    pointer[size - 4] = 0x03;
+ //    assert(pointer != NULL);
+ //    return pointer;
+ //  }
+ 
    void* alloc(size_t size) {
      void* pointer = malloc(size);
***************
*** 581,584 ****
--- 601,608 ----
      p("enter StdControl.stop()");
      setState(STATE_VREG_OFF);
+     if (receivingFrame != NULL) {
+       free(receivingFrame);
+       receivingFrame = NULL;
+     }
      return SUCCESS;
    }
***************
*** 593,596 ****
--- 617,646 ----
      hasInitialized = TRUE;
      radioState = STATE_VREG_OFF;
+ 
+     // TODO note that this is a hack around CIL's inability to parse the table structure that is commented out near the start of this file.
+     table[ 0][0] = 1.00e+00; table[ 0][1] = 1.00e+00; table[ 0][2] = 0.00e+00; table[ 0][3] = 9.32e-01; table[ 0][4] = 4.07e-03; table[ 0][5] = -5.00e+00; table[ 0][6] = 0.00e+00;
+     table[ 1][0] = 3.00e+00; table[ 1][1] = 1.00e+00; table[ 1][2] = 0.00e+00; table[ 1][3] = 9.32e-01; table[ 1][4] = 3.82e-03; table[ 1][5] = -3.70e+01; table[ 1][6] = 5.44e+00;
+     table[ 2][0] = 9.00e+00; table[ 2][1] = 1.00e+00; table[ 2][2] = 0.00e+00; table[ 2][3] = 9.28e-01; table[ 2][4] = 4.89e-03; table[ 2][5] = -3.76e+01; table[ 2][6] = 3.71e+00;
+     table[ 3][0] = 1.20e+01; table[ 3][1] = 1.00e+00; table[ 3][2] = 0.00e+00; table[ 3][3] = 9.26e-01; table[ 3][4] = 6.66e-03; table[ 3][5] = -5.23e+01; table[ 3][6] = 2.35e+00;
+     table[ 4][0] = 1.50e+01; table[ 4][1] = 1.00e+00; table[ 4][2] = 0.00e+00; table[ 4][3] = 9.27e-01; table[ 4][4] = 6.01e-03; table[ 4][5] = -5.82e+01; table[ 4][6] = 3.49e+00;
+     table[ 5][0] = 2.00e+01; table[ 5][1] = 9.98e-01; table[ 5][2] = 1.52e-06; table[ 5][3] = 9.24e-01; table[ 5][4] = 7.76e-03; table[ 5][5] = -5.98e+01; table[ 5][6] = 3.85e+00;
+     table[ 6][0] = 2.50e+01; table[ 6][1] = 9.93e-01; table[ 6][2] = 1.60e-02; table[ 6][3] = 9.11e-01; table[ 6][4] = 3.15e-02; table[ 6][5] = -6.28e+01; table[ 6][6] = 3.52e+00;
+     table[ 7][0] = 3.00e+01; table[ 7][1] = 9.92e-01; table[ 7][2] = 1.67e-02; table[ 7][3] = 9.03e-01; table[ 7][4] = 3.99e-02; table[ 7][5] = -6.89e+01; table[ 7][6] = 4.13e+00;
+     table[ 8][0] = 3.50e+01; table[ 8][1] = 9.71e-01; table[ 8][2] = 8.58e-02; table[ 8][3] = 8.78e-01; table[ 8][4] = 9.75e-02; table[ 8][5] = -7.06e+01; table[ 8][6] = 3.45e+00;
+     table[ 9][0] = 5.00e+01; table[ 9][1] = 9.90e-01; table[ 9][2] = 3.12e-02; table[ 9][3] = 8.96e-01; table[ 9][4] = 4.10e-02; table[ 9][5] = -7.14e+01; table[ 9][6] = 4.52e+00;
+     table[10][0] = 5.50e+01; table[10][1] = 9.00e-01; table[10][2] = 1.59e-01; table[10][3] = 7.96e-01; table[10][4] = 1.70e-01; table[10][5] = -7.06e+01; table[10][6] = 7.69e+00;
+     table[11][0] = 6.50e+01; table[11][1] = 9.29e-01; table[11][2] = 2.04e-01; table[11][3] = 8.37e-01; table[11][4] = 1.25e-01; table[11][5] = -7.11e+01; table[11][6] = 1.30e+01;
+     table[12][0] = 7.50e+01; table[12][1] = 6.71e-01; table[12][2] = 2.77e-01; table[12][3] = 5.87e-01; table[12][4] = 1.75e-01; table[12][5] = -7.02e+01; table[12][6] = 1.73e+01;
+     table[13][0] = 8.50e+01; table[13][1] = 7.09e-01; table[13][2] = 3.74e-01; table[13][3] = 6.62e-01; table[13][4] = 2.84e-01; table[13][5] = -7.10e+01; table[13][6] = 2.14e+01;
+     table[14][0] = 9.50e+01; table[14][1] = 7.73e-01; table[14][2] = 2.57e-01; table[14][3] = 6.36e-01; table[14][4] = 1.80e-01; table[14][5] = -7.03e+01; table[14][6] = 1.49e+01;
+     table[15][0] = 1.05e+02; table[15][1] = 6.07e-01; table[15][2] = 3.27e-01; table[15][3] = 4.96e-01; table[15][4] = 2.04e-01; table[15][5] = -7.10e+01; table[15][6] = 3.20e+01;
+     table[16][0] = 1.15e+02; table[16][1] = 4.84e-01; table[16][2] = 1.16e-01; table[16][3] = 3.31e-01; table[16][4] = 1.21e-01; table[16][5] = -7.00e+01; table[16][6] = 2.35e+01;
+     table[17][0] = 1.25e+02; table[17][1] = 6.68e-01; table[17][2] = 4.28e-01; table[17][3] = 5.38e-01; table[17][4] = 2.53e-01; table[17][5] = -7.12e+01; table[17][6] = 1.50e+00;
+     table[18][0] = 1.35e+02; table[18][1] = 5.07e-01; table[18][2] = 3.13e-01; table[18][3] = 3.55e-01; table[18][4] = 1.41e-01; table[18][5] = -7.61e+01; table[18][6] = 1.40e+01;
+     table[19][0] = 1.50e+02; table[19][1] = 5.36e-01; table[19][2] = 3.62e-01; table[19][3] = 4.44e-01; table[19][4] = 1.92e-01; table[19][5] = -7.88e+01; table[19][6] = 8.34e+00;
+     table[20][0] = 1.75e+02; table[20][1] = 3.67e-01; table[20][2] = 2.98e-01; table[20][3] = 3.69e-01; table[20][4] = 1.56e-01; table[20][5] = -8.00e+01; table[20][6] = 3.43e+00;
+     table[21][0] = 1.90e+02; table[21][1] = 2.50e-01; table[21][2] = 1.35e-01; table[21][3] = 2.77e-01; table[21][4] = 1.09e-01; table[21][5] = -8.02e+01; table[21][6] = 7.92e+00;
+     table[22][0] = 2.00e+02; table[22][1] = 1.24e-01; table[22][2] = 2.67e-01; table[22][3] = 1.47e-01; table[22][4] = 3.37e-02; table[22][5] = -8.20e+01; table[22][6] = 1.40e+01;
+     table[23][0] = 2.25e+02; table[23][1] = 0.00e+00; table[23][2] = 0.00e+00; table[23][3] = 0.00e+00; table[23][4] = 0.00e+00; table[23][5] = -8.60e+01; table[23][6] = 2.02e+00;
    }
  
***************
*** 670,689 ****
        case STATE_VREG_OFF:
          // TODO implement/fix
!         fail("not allowed to go to this state...yet (can't turn me off!)");
          break;
        case STATE_VREG_POWERUP:
          assert(radioState == STATE_VREG_OFF);
          break;
        case STATE_IDLE:
          break;
        case STATE_XOSC_POWERUP:
          assert(radioState == STATE_IDLE);
          break;
        case STATE_XOSC_ON:
          assert(radioState != STATE_IDLE);
          break;
        case STATE_RX_CALIBRATE:
          // TODO so apparently, we can accept multiple (quick) calls to SRXON, right?
          // (see TuneManual, followed by RxMode, in lib)
          assert(radioState == STATE_XOSC_ON ||
              radioState == STATE_RX_CALIBRATE ||
--- 720,745 ----
        case STATE_VREG_OFF:
          // TODO implement/fix
!         call PowerState.radioStop();
          break;
        case STATE_VREG_POWERUP:
          assert(radioState == STATE_VREG_OFF);
+         call PowerState.radioStart();
          break;
        case STATE_IDLE:
+         // In case we were coming in from some non-powerup state.
+         call PowerState.radioStart();
          break;
        case STATE_XOSC_POWERUP:
          assert(radioState == STATE_IDLE);
+         call PowerState.radio("OSC_ON");
          break;
        case STATE_XOSC_ON:
          assert(radioState != STATE_IDLE);
+         call PowerState.radio("OSC_ON");
          break;
        case STATE_RX_CALIBRATE:
          // TODO so apparently, we can accept multiple (quick) calls to SRXON, right?
          // (see TuneManual, followed by RxMode, in lib)
+         call PowerState.radioRxMode();
          assert(radioState == STATE_XOSC_ON ||
              radioState == STATE_RX_CALIBRATE ||
***************
*** 706,709 ****
--- 762,766 ----
          break;
        case STATE_TX_ACK_CALIBRATE:
+         call PowerState.radioTxMode();
          assert(radioState == STATE_RX_FRAME ||
              radioState == STATE_RX_SFD_SEARCH);
***************
*** 716,719 ****
--- 773,777 ----
          break;
        case STATE_TX_CALIBRATE:
+         call PowerState.radioTxMode();
          assert(radioState == STATE_TX_ACK ||
              radioState == STATE_RX_CALIBRATE ||
***************
*** 796,799 ****
--- 854,903 ----
            break;
          }
+       case CC2420_TXCTRL:
+         {
+           uint8_t powerLevel = getRegisterBits(CC2420_TXCTRL,
+               CC2420_TXCTRL_PAPWR_START, CC2420_TXCTRL_PAPWR_END);
+           int8_t powerLevelDbm;
+           uint8_t powerState;
+           switch (powerLevel) {
+             case 31:
+               powerLevelDbm = 0;
+               powerState = 0;
+               break;
+             case 27:
+               powerLevelDbm = -1;
+               powerState = 1;
+               break;
+             case 23:
+               powerLevelDbm = -3;
+               powerState = 2;
+               break;
+             case 19:
+               powerLevelDbm = -5;
+               powerState = 3;
+               break;
+             case 15:
+               powerLevelDbm = -7;
+               powerState = 4;
+               break;
+             case 11:
+               powerLevelDbm = -10;
+               powerState = 5;
+               break;
+             case 7:
+               powerLevelDbm = -15;
+               powerState = 6;
+               break;
+             case 3:
+               powerLevelDbm = -25;
+               powerState = 7;
+               break;
+             default:
+               fail("invalid power level!");
+               break;
+           }
+           call PowerState.radioRFPower(powerState);
+         }
+         break;
      }
    }
***************
*** 1336,1340 ****
          data->sourceId, data->rssi);
  
!     // This is necessary to keep all forced events safe.
      checkInitialized();
  
--- 1440,1445 ----
          data->sourceId, data->rssi);
  
!     // This is necessary to keep all forced events safe, as we may be trying
!     // to access uninitialized variables.
      checkInitialized();
  
***************
*** 1709,1714 ****
      p("enter handleRxCalibratedEvent()");
  
!     // Start listening for SFDs.
!     setState(STATE_RX_SFD_SEARCH);
  
      event_cleanup(ev);
--- 1814,1822 ----
      p("enter handleRxCalibratedEvent()");
  
!     // Make sure that we did not get turned off since this event was issued.
!     if (getState() != STATE_VREG_OFF) {
!       // Start listening for SFDs.
!       setState(STATE_RX_SFD_SEARCH);
!     }
  
      event_cleanup(ev);



More information about the Tinyos-beta-commits mailing list