[Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/handhelds/hwtest/shimmer/GyroTilt GyroAccelApp.nc, NONE, 1.1 GyroAccelAppM.nc, NONE, 1.1 GyroTiltApp.nc, NONE, 1.1 GyroTiltAppM.nc, NONE, 1.1 Makefile, NONE, 1.1 Makefile.gyroaccel, NONE, 1.1

steve ayer ayer1 at users.sourceforge.net
Thu Sep 7 11:36:09 PDT 2006


Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/hwtest/shimmer/GyroTilt
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv32673/hwtest/shimmer/GyroTilt

Added Files:
	GyroAccelApp.nc GyroAccelAppM.nc GyroTiltApp.nc 
	GyroTiltAppM.nc Makefile Makefile.gyroaccel 
Log Message:

added mma7260 accelerometer interface/lib
updated shimmer hardware.h adding adc6&7 pins
added hwtest for shimmer gyro board to hwtest; two versions, one three
channel, one six channel
updated interfaces for above and dma.adcinterrupt event now provides
register number 


--- NEW FILE: GyroAccelApp.nc ---
/*
 * Copyright (c) 2006 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: Steve Ayer
 *          August 2006
 */

configuration GyroAccelApp {
}
implementation {
  components 
    Main, 
    GyroAccelAppM, 
    DMA_M, 
    MMA7260_AccelM,
    TimerC, 
    LedsC, 	
    IPCLIENT as IPClientC,
    TelnetM,
    ParamViewM;

  Main.StdControl->GyroAccelAppM;
  Main.StdControl->TimerC;

  /* have to fix compile time channel limitation */
  GyroAccelAppM.DMA0         -> DMA_M.DMA[0];
  GyroAccelAppM.DMA1         -> DMA_M.DMA[1];
  GyroAccelAppM.DMA2         -> DMA_M.DMA[2];
  GyroAccelAppM.Leds         -> LedsC;
  GyroAccelAppM.yTimer       -> TimerC.Timer[unique("Timer")];
 
  //  GyroAccelAppM.SDStdControl      -> SDC;
  //  GyroAccelAppM.SD                -> SD_M;

  GyroAccelAppM.AccelStdControl   -> MMA7260_AccelM;
  GyroAccelAppM.Accel             -> MMA7260_AccelM;

  /* telnet stuff */
  GyroAccelAppM.IPStdControl  -> IPClientC;
  GyroAccelAppM.UIP           -> IPClientC;
  GyroAccelAppM.Client        -> IPClientC;
  GyroAccelAppM.TCPClient     -> IPClientC.TCPClient[unique("TCPClient")];
  GyroAccelAppM.UDPClient     -> IPClientC.UDPClient[unique("UDPClient")];

  GyroAccelAppM.TelnetRun         -> TelnetM.Telnet[unique("Telnet")];

  GyroAccelAppM.PVStdControl      -> ParamViewM;
  GyroAccelAppM.TelnetStdControl  -> TelnetM;

  TelnetM.TCPServer            -> IPClientC.TCPServer[unique("TCPServer")];

  ParamViewM.TelnetShow         -> TelnetM.Telnet[unique("Telnet")];
  ParamViewM.ParamView          -> IPClientC.ParamView;
  ParamViewM.ParamView          -> GyroAccelAppM.ParamView;
  /* end telnet stuff */
}

--- NEW FILE: GyroAccelAppM.nc ---
/*
 * Copyright (c) 2006, 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: Steve Ayer
 *          August 2006
 */

includes DMA;
includes Message;
includes NVTParse;
includes MMA7260_Accel;
includes msp430baudrates;

module GyroAccelAppM {
  provides{
    interface StdControl;
    interface ParamView;
  }
  uses {
    interface DMA as DMA0;
    interface DMA as DMA1;
    interface DMA as DMA2;

    /* telnet stuff */
    interface StdControl as IPStdControl;
    interface StdControl as TelnetStdControl;
    interface StdControl as PVStdControl;

    interface StdControl as AccelStdControl;

    interface MMA7260_Accel as Accel;

    interface Telnet as TelnetRun;

    interface UIP;
    interface Client; 
    interface TCPClient;
    interface UDPClient;

    /* end telnet stuff */
    interface Leds;

    interface Timer as yTimer;
  }
}

implementation {
  extern int sprintf(char *str, const char *format, ...) __attribute__ ((C));
  extern int snprintf(char *str, size_t len, const char *format, ...) __attribute__ ((C));

#define MAX_SIZE 512
#define PACKET_PAYLOAD 128
#define MESSAGE_MAX_LENGTH 128

  uint8_t dma_transfers, myreason = 0, enable_shipping = 0, enable_gyros = 0, adcregnum;
  uint16_t inbuf0[128], inbuf1[128], inbuf2[128], *curr0, *curr1, *curr2;
  uint16_t abuf[6], gbuf[3];
  uint8_t msgbuf[128];

  struct udp_address udpaddr;

  uint16_t adcifg_count = 0;

  void setupDMA() {
    call DMA0.init();
    call DMA1.init();
    call DMA2.init();

    atomic {
      call DMA0.setDestinationAddress((uint16_t)inbuf0);
      call DMA1.setDestinationAddress((uint16_t)inbuf1);
      call DMA2.setDestinationAddress((uint16_t)inbuf2);

      call DMA0.setBlockSize(1);
      call DMA1.setBlockSize(1);
      call DMA2.setBlockSize(1);

      SET_FLAG(DMACTL1, ROUNDROBIN);  // round-robin
    }
  }
	
  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_1);         // clk from aclk
      
      SET_FLAG(ADC12CTL1, ADC12DIV_7);         // divide clk by 8
      // 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);  // x accel
    SET_FLAG(ADC12MCTL1, INCH_4);  // y accel
    SET_FLAG(ADC12MCTL2, INCH_3);  // z accel
    SET_FLAG(ADC12MCTL3, INCH_1);  // x accel
    SET_FLAG(ADC12MCTL4, INCH_6);  // y accel
    SET_FLAG(ADC12MCTL5, INCH_2);  // z accel
    SET_FLAG(ADC12MCTL5, EOS);       // sez "this is the last reg" 

    //    SET_FLAG(ADC12MCTL5, EOS);       //sez "this is the last reg" 

    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 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_3);      // repeat sequence of channels
    /*
    SET_FLAG(ADC12MCTL6, INCH_11);       // (avcc - avss)/2
    SET_FLAG(ADC12MCTL6, SREF_1);        //  ref = vref+ and vr- = avss
    SET_FLAG(ADC12MCTL6, EOS);       // sez "this is the last reg" 
    */
    //    SET_FLAG(ADC12IE, 0x0008);       // wait to enable until after the three dma-mapped channels

    setupDMA();

    call DMA0.beginTransfer();
    call DMA1.beginTransfer();
    call DMA2.beginTransfer();

    call DMA0.ADCbeginConversion();
	
    *curr0 = ADC12MEM0;
    *curr0 = 0;
    *curr1 = ADC12MEM1;
    *curr1 = 0;
    *curr2 = ADC12MEM2;
    *curr2 = 0;
    *curr0 = ADC12MEM3;
    *curr0 = 0;
    *curr1 = ADC12MEM4;
    *curr1 = 0;
    *curr2 = ADC12MEM5;
    *curr2 = 0;

  }

  task void ship_contents() {
    if(enable_shipping){
      call Leds.redToggle(); 
      call UDPClient.send((uint8_t *)abuf, 12);
    }
    //      call TCPClient.write((uint8_t *)abuf, 12);
  }

  task void adc3Results() { 
    atomic gbuf[0] = ADC12MEM3;
    //    SET_FLAG(ADC12IE, 0x0038);
  } 

  task void adc4Results() { 
    atomic gbuf[1] = ADC12MEM4;
    //    SET_FLAG(ADC12IE, 0x0038);
  } 

  task void adc5Results() { 
  } 

  task void dma0Results() { 
  }	 
    
  task void dma1Results() { 
  }	 
    
  task void dma2Results() { 
    atomic{
      abuf[0] = inbuf0[dma_transfers];
      abuf[1] = inbuf1[dma_transfers];
      abuf[2] = inbuf2[dma_transfers];
    }
    //    post ship_contents();

    dma_transfers++;
    call Leds.orangeToggle();

    if(dma_transfers == 128){
      call DMA0.ADCstopConversion();

      dma_transfers = 0;
      atomic{
	DMA0DA = (uint16_t)inbuf0;
	DMA1DA = (uint16_t)inbuf1;
	DMA2DA = (uint16_t)inbuf2;
      }
      /*
      call DMA0.setDestinationAddress(inbuf0);
      call DMA1.setDestinationAddress(inbuf1);
      call DMA2.setDestinationAddress(inbuf2);
      */
      call DMA0.ADCbeginConversion();
    }

    SET_FLAG(ADC12IE, 0x0008);
  }	
    
  command result_t StdControl.init() {
    call PVStdControl.init();
    call TelnetStdControl.init();
    call IPStdControl.init();

    call AccelStdControl.init();

    udpaddr.ip[0] = 63;
    udpaddr.ip[1] = 118;
    udpaddr.ip[2] = 194;
    udpaddr.ip[3] = 100;
    udpaddr.port = 5666;

    dma_transfers = 0;
    
    // 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();

    TOSH_MAKE_PROG_OUT_OUTPUT();
    TOSH_SEL_PROG_OUT_IOFUNC();

    memset(inbuf0, 0, sizeof(inbuf0));
    curr0 = inbuf0;
    memset(inbuf1, 0, sizeof(inbuf1));
    curr1 = inbuf1;
    memset(inbuf2, 0, sizeof(inbuf2));
    curr2 = inbuf2;
    call Leds.init();

    return SUCCESS;
  }

  command result_t StdControl.start() {
    call IPStdControl.start();
    call TelnetStdControl.start();

    call AccelStdControl.start();

    call Accel.setSensitivity(RANGE_4_0G);

    sampleADC();

    return SUCCESS;
  }

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

  char * do_gyros(char * in, char * out, char * outmax) { 
    if(!enable_gyros){
      TOSH_CLR_PROG_OUT_PIN();   // turn on, logical false
      enable_gyros = 1;
    }
    else{
      TOSH_SET_PROG_OUT_PIN();
      enable_gyros = 0;
    }
    return out;
  }
      
  char * do_sends(char * in, char * out, char * outmax) { 
    if(!enable_shipping){
      enable_shipping = 1;
      //      call TCPClient.connect(63, 118, 194, 100, 5067);
      call UDPClient.connect(&udpaddr);
    }
    else{
      enable_shipping = 0;
      //      call TCPClient.close();
      call UDPClient.connect(NULL);   // unbinds socket
      call Leds.greenOff();
    }
    sprintf(msgbuf, "sending enable now %d", enable_shipping);

    return out;
  }
  
  event void TCPClient.connectionMade(uint8_t status) {
    call Leds.greenOn();

    enable_shipping = 1;
  }  

  event void TCPClient.writeDone() {
  }

  event void UDPClient.sendDone() {
  }

  event    void     TCPClient.dataAvailable(uint8_t *buf, uint16_t len) {}

  event    void     UDPClient.receive(const struct udp_address *addr, uint8_t *buf, uint16_t len) {}

  event    void     TCPClient.connectionFailed(uint8_t reason) { 
    myreason = reason;
  }

  event result_t yTimer.fired() {
    return SUCCESS;
  }

  async event void DMA0.transferComplete() {
    atomic DMA0DA += 2;
  }

  async event void DMA1.transferComplete() {
    atomic DMA1DA += 2;
  }

  async event void DMA2.transferComplete() {
    atomic DMA2DA += 2;
    post dma2Results();
  }

  async event void DMA0.ADCInterrupt(uint8_t regnum) {
    //    adcregnum = regnum;
    atomic{
      abuf[3] = ADC12MEM3;
      ADC12IE = 0x0010;
    }
    /*    atomic {
      if(adcifg_count++ > 128){
	ADC12CTL0 = 0;
	ADC12IE = 0;
      }
    }	
    */       
    //    post adc3Results();
  } 
  async event void DMA1.ADCInterrupt(uint8_t regnum) {
    atomic {
      abuf[4] = ADC12MEM4;
      ADC12IE = 0x0020;
    }
    /*
    atomic {
      if(adcifg_count++ > 128){
	ADC12CTL0 = 0;
	ADC12IE = 0;
      }
    }	
    */       
    //    post adc4Results();
  }
  async event void DMA2.ADCInterrupt(uint8_t regnum) {
    atomic{
      abuf[5] = ADC12MEM5;
      ADC12IE = 0;
    }
    call Leds.yellowToggle();
    post ship_contents();

    /*
    atomic {
      if(adcifg_count++ > 128){
	ADC12CTL0 = 0;
	ADC12IE = 0;
      }
    }	
    */       
    //    post adc5Results();
  }

  event void Client.connected( bool isConnected ) {
  }

  const struct Param s_ADCRegs[] = {
    { "ivregnum",     PARAM_TYPE_HEX8,  (uint8_t *)&adcregnum },
    { "adcctl0",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12CTL0 },
    { "adcctl1",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12CTL1 },
    { "adcmem3",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12MEM3},
    { "adcmem4",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12MEM4},
    { "adcmem5",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12MEM5},
    { "adc<-battery",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12MEM6},
    { "adcmemctl3",    PARAM_TYPE_HEX8, (uint8_t *)&ADC12MCTL3},
    { "adcmemctl4",    PARAM_TYPE_HEX8, (uint8_t *)&ADC12MCTL4},
    { "adcmemctl5",    PARAM_TYPE_HEX8, (uint8_t *)&ADC12MCTL5},
    { "adciv",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12IV},
    { "adcifg",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12IFG},
    { "adcie",    PARAM_TYPE_HEX16, (uint16_t *)&ADC12IE},
    { "adcifgcount",    PARAM_TYPE_HEX16, (uint16_t *)&adcifg_count},
    { NULL, 0, NULL }
  };

  const struct Param s_DMA0Output[] = {
    { "dma transfers",   PARAM_TYPE_UINT8, &dma_transfers },
    { "error_reason",   PARAM_TYPE_UINT8, &myreason },
    { "a0",    PARAM_TYPE_UINT16, (uint16_t *)&abuf[0] },
    { "a1",    PARAM_TYPE_UINT16, (uint16_t *)&abuf[1] },
    { "a2",    PARAM_TYPE_UINT16, (uint16_t *)&abuf[2] },
    { "g0",    PARAM_TYPE_UINT16, (uint16_t *)&abuf[3] },
    { "g1",    PARAM_TYPE_UINT16, (uint16_t *)&abuf[4] },
    { "g2",    PARAM_TYPE_UINT16, (uint16_t *)&abuf[5] },
    { NULL, 0, NULL }
  };
  struct ParamList g_DMA0OutList = { "output0", &s_DMA0Output[0] };
  struct ParamList g_ADCRegsList = { "adcregs", &s_ADCRegs[0] };

  const struct Param s_msg[] = {
    { "msg",    PARAM_TYPE_STRING, &msgbuf[0] },
    { NULL, 0, NULL }
  };
  struct ParamList msgList = { "msgs", &s_msg[0] };

  command result_t ParamView.init(){
    signal ParamView.add( &msgList );
    signal ParamView.add( &g_DMA0OutList );
    signal ParamView.add( &g_ADCRegsList );
    return SUCCESS;
  }
  struct TelnetCommand {
    char *name;
    char * (*func)( char *, char *, char * );
  };

  const struct TelnetCommand operations[] = {
    { "ship", &do_sends },
    { "gyro", &do_gyros },
    { 0, NULL }
  };
 
  event const char * TelnetRun.token() { return "run"; }
  event const char * TelnetRun.help() { return "Run network operations\r\n"; }
    
  event char * TelnetRun.process( char * in, char * out, char * outmax ) {
    char * next, * extrastuff;
    char * cmd = next_token(in, &next, ' ');

    if(cmd) {
      const struct TelnetCommand *c = operations;
      
      for ( ;c->name; c++) {
	if (strcmp(cmd, c->name) == 0) {
	  extrastuff = (*c->func)( next, out, outmax );
	  //this is a hack to prevent hanging telnet.process if nothing is returned from service function
	  if(extrastuff)
	    out += snprintf(out, outmax - out, "%s\r\n", extrastuff);
	  else
	    out += snprintf(out, outmax - out, "%s\r\n", "dummy");
	  break;
	}
      }
    }
    else
      out += snprintf(out, outmax - out, "must provide command with 'run'\r\n");
	    
    return out;
  }
}

--- NEW FILE: GyroTiltApp.nc ---
/*
 * Copyright (c) 2006 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: Steve Ayer
 *          August 2006
 */

configuration GyroTiltApp {
}
implementation {
  components 
    Main, 
    GyroTiltAppM, 
    DMA_M, 
    SD_M,
    SDC,
    //    MMA7260_AccelM,
    TimerC, 
    LedsC, 	
    //    TimeM,
    IPCLIENT as IPClientC,
    TelnetM,
    ParamViewM;

  Main.StdControl->GyroTiltAppM;
  Main.StdControl->TimerC;

  /* have to fix compile time channel limitation */
  GyroTiltAppM.DMA0         -> DMA_M.DMA[0];
  GyroTiltAppM.DMA1         -> DMA_M.DMA[1];
  GyroTiltAppM.DMA2         -> DMA_M.DMA[2];
  GyroTiltAppM.Leds         -> LedsC;
  GyroTiltAppM.yTimer       -> TimerC.Timer[unique("Timer")];
 
  GyroTiltAppM.SDStdControl      -> SDC;
  GyroTiltAppM.SD                -> SD_M;

  //  GyroTiltAppM.AccelStdControl   -> MMA7260_AccelM;
  //  GyroTiltAppM.Accel             -> MMA7260_AccelM;

  //  TimeM.LocalTime              -> TimerC;
  //  TimeM.Timer                  -> TimerC.Timer[unique("Timer")];
  //  GyroTiltAppM.LocalTime       -> TimerC;

  /* telnet stuff */
  GyroTiltAppM.IPStdControl  -> IPClientC;
  GyroTiltAppM.UIP           -> IPClientC;
  GyroTiltAppM.Client        -> IPClientC;
  GyroTiltAppM.TCPClient     -> IPClientC.TCPClient[unique("TCPClient")];

  //  GyroTiltAppM.TelnetRun         -> TelnetM.Telnet[unique("Telnet")];

  GyroTiltAppM.PVStdControl      -> ParamViewM;
  //  GyroTiltAppM.TelnetStdControl  -> TelnetM;

  TelnetM.TCPServer            -> IPClientC.TCPServer[unique("TCPServer")];

  ParamViewM.TelnetShow         -> TelnetM.Telnet[unique("Telnet")];
  ParamViewM.ParamView          -> IPClientC.ParamView;
  ParamViewM.ParamView          -> GyroTiltAppM.ParamView;
  /* end telnet stuff */
}

--- NEW FILE: GyroTiltAppM.nc ---
/*
 * Copyright (c) 2006, 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: Steve Ayer
 *          August 2006
 */

includes DMA;
includes Message;
includes NVTParse;
//includes SD;
includes msp430baudrates;

module GyroTiltAppM {
  provides{
    interface StdControl;
    interface ParamView;
  }
  uses {
    interface DMA as DMA0;
    interface DMA as DMA1;
    interface DMA as DMA2;

    /* telnet stuff */
    interface StdControl as IPStdControl;
    //    interface StdControl as TelnetStdControl;
    interface StdControl as PVStdControl;

    interface StdControl as SDStdControl;

    interface SD;

    interface Telnet as TelnetRun;

    interface UIP;
    interface Client; 
    interface TCPClient;

    //    interface LocalTime;
    

    /* end telnet stuff */
    interface Leds;

    interface Timer as yTimer;
  }
}

implementation {
  extern int sprintf(char *str, const char *format, ...) __attribute__ ((C));
  extern int snprintf(char *str, size_t len, const char *format, ...) __attribute__ ((C));

#define MAX_SIZE 512
#define PACKET_PAYLOAD 128
#define MESSAGE_MAX_LENGTH 128

  uint8_t dma_transfers, myreason = 0, enable_shipping = 0, enable_gyros = 0, current_buffer = 0, write_step;
  uint16_t inbuf0[256], inbuf1[256], inbuf2[256], *curr0, *curr1, *curr2;
  //uint16_t sbuf0[36], sbuf1[36];
  uint8_t msgbuf[128], sectornum = 0, shipnum = 0;
  uint16_t cardbuf[256];
  norace uint32_t current_sector = 2222, shipping_sector;
  
  void initIP() {
    call Leds.redOn();
    //    call PVStdControl.init();
    //    call TelnetStdControl.init();
    call IPStdControl.init();
  }

  void startIP() {
    call IPStdControl.start();
    //    call TelnetStdControl.start();
  }

  void stopIP(){
    //    call TelnetStdControl.stop();
    call IPStdControl.stop();
    call Leds.redOff();
  }
    
  void setupDMA() {
    call DMA0.init();
    call DMA1.init();
    call DMA2.init();

    call DMA0.setDestinationAddress((uint16_t)inbuf0);
    call DMA1.setDestinationAddress((uint16_t)inbuf1);
    call DMA2.setDestinationAddress((uint16_t)inbuf2);

    call DMA0.setBlockSize(1);
    call DMA1.setBlockSize(1);
    call DMA2.setBlockSize(1);
    /*    
    CLR_FLAG(DMA0CTL, DMADSTINCR_3);    // clear increment (doesn't work?) for manual increment
    CLR_FLAG(DMA1CTL, DMADSTINCR_3);
    CLR_FLAG(DMA2CTL, DMADSTINCR_3);

    SET_FLAG(DMA0CTL, DMADSTINCR_0);    // non-increment for manual increment
    SET_FLAG(DMA1CTL, DMADSTINCR_0);
    SET_FLAG(DMA2CTL, DMADSTINCR_0);
    */
    SET_FLAG(DMACTL1, ROUNDROBIN);  // round-robin
  }
	
  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_1);         // clk from aclk
      
      SET_FLAG(ADC12CTL1, ADC12DIV_1);         // divide clk by 8
      // 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);  // x 
    SET_FLAG(ADC12MCTL1, INCH_6);  // y 
    SET_FLAG(ADC12MCTL2, INCH_2);  // z 
    SET_FLAG(ADC12MCTL2, EOS);       //sez "this is the last reg" 

    /* 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_3);      // repeat sequence of channels
    
    setupDMA();

    call DMA0.beginTransfer();
    call DMA1.beginTransfer();
    call DMA2.beginTransfer();

    call DMA0.ADCbeginConversion();
    /*	
    *curr0 = ADC12MEM0;
    *curr0 = 0;
    *curr1 = ADC12MEM1;
    *curr1 = 0;
    *curr2 = ADC12MEM2;
    *curr2 = 0;
    */
  }
  /*
  void ship_contents() {
    if(enable_shipping){
      if(current_buffer == 1)
 	call TCPClient.write((uint8_t *)sbuf0, 72);
      else
	call TCPClient.write((uint8_t *)sbuf1, 72);
    }
  }
  */
  
  task void adcResults() { 
  } 

  task void ship_contents() {
    uint8_t rval;

    if((rval = call SD.readSector(shipping_sector++, (uint8_t *)cardbuf)))
      sprintf(msgbuf, "bad read, error=%d", rval);

    call TCPClient.write((uint8_t *)cardbuf, 72);
  }

  task void dma0Results() { 
  }	 
    
  task void dma1Results() { 
  }	 
    
  task void dma2Results() { 
    uint8_t rval;
    //    tbuf[dma_transfers] = call LocalTime.read();

    dma_transfers++;
    if(dma_transfers == 255){
      call DMA0.ADCstopConversion();
      dma_transfers = 0;
      call Leds.orangeOn();

	/*
	  atomic{
	  if(current_buffer == 0){
	  current_buffer = 1;
	  DMA0DA = &sbuf1[0];
	  DMA1DA = &sbuf1[12];
	  DMA2DA = &sbuf1[24];
	  }
	  else{
	  current_buffer = 0;
	  DMA0DA = &sbuf0[0];
	  DMA1DA = &sbuf0[12];
	  DMA2DA = &sbuf0[24];
	  }
	  }
	  ship_contents(); 

      */
      call Leds.redOn();
      if((rval = call SD.writeSector(current_sector++, (uint8_t *)inbuf0)))
	sprintf(msgbuf, "bad write, error=%d", rval);
      if((rval = call SD.writeSector(current_sector++, (uint8_t *)inbuf1)))
	sprintf(msgbuf, "bad write, error=%d", rval);
      if((rval = call SD.writeSector(current_sector++, (uint8_t *)inbuf2)))
	sprintf(msgbuf, "bad write, error=%d", rval);
      call Leds.redOff();

      atomic{
	DMA0DA = (uint16_t)inbuf0;
	DMA1DA = (uint16_t)inbuf1;
	DMA2DA = (uint16_t)inbuf2;
      }

      write_step = 0;

      call TCPClient.connect(63, 118, 194, 100, 5067);
      //      initIP();
      //      startIP();

    }
  }	

  command result_t StdControl.init() {
    initIP();
    call SDStdControl.init();

    shipping_sector = current_sector;
    dma_transfers = 0;
    
    // 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();

    TOSH_MAKE_PROG_OUT_OUTPUT();
    TOSH_SEL_PROG_OUT_IOFUNC();

    /*
    memset(inbuf0, 0, sizeof(inbuf0));
    curr0 = inbuf0;
    memset(inbuf1, 0, sizeof(inbuf1));
    curr1 = inbuf1;
    memset(inbuf2, 0, sizeof(inbuf2));
    curr2 = inbuf2;
    */
    call Leds.init();

    return SUCCESS;
  }

  command result_t StdControl.start() {
    startIP();
    call SDStdControl.start();

    //    TOSH_CLR_PROG_OUT_PIN();   // this pin is gyro pwren, logical false

    sampleADC();

    return SUCCESS;
  }

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

  char * do_gyros(char * in, char * out, char * outmax) { 
    if(!enable_gyros){
      TOSH_CLR_PROG_OUT_PIN();   // turn on, logical false
      enable_gyros = 1;
    }
    else{
      TOSH_SET_PROG_OUT_PIN();
      enable_gyros = 0;
    }
    return out;
  }
      
  char * do_sends(char * in, char * out, char * outmax) { 
    if(!enable_shipping){
      call TCPClient.connect(63, 118, 194, 100, 5067);
    }
  else{
      enable_shipping = 0;
      call TCPClient.close();
      call Leds.greenOff();
    }
    sprintf(msgbuf, "sending enable now %d", enable_shipping);

    return out;
  }
  
  event void TCPClient.connectionMade(uint8_t status) {
    call Leds.greenOn();

    post ship_contents();
  }  

  event void TCPClient.writeDone() {
    write_step++;
    switch (write_step) {
    case 1:
      call TCPClient.write((uint8_t *)(cardbuf + 36), 72);
      break;
    case 2:
      call TCPClient.write((uint8_t *)(cardbuf + 72), 72);
      break;
    case 3:
      call TCPClient.write((uint8_t *)(cardbuf + 108), 72);
      break;
    case 4:
      call TCPClient.write((uint8_t *)(cardbuf + 144), 72);
      break;
    case 5:
      call TCPClient.write((uint8_t *)(cardbuf + 180), 72);
      break;
    case 6:
      call TCPClient.write((uint8_t *)(cardbuf + 216), 72);
      break;
    case 7:
      call TCPClient.write((uint8_t *)(cardbuf + 252), 8);
      break;
    case 8:
      post ship_contents();
      break;
    case 9:
      call TCPClient.write((uint8_t *)(cardbuf + 36), 72);
      break;
    case 10:
      call TCPClient.write((uint8_t *)(cardbuf + 72), 72);
      break;
    case 11:
      call TCPClient.write((uint8_t *)(cardbuf + 108), 72);
      break;
    case 12:
      call TCPClient.write((uint8_t *)(cardbuf + 144), 72);
      break;
    case 13:
      call TCPClient.write((uint8_t *)(cardbuf + 180), 72);
      break;
    case 14:
      call TCPClient.write((uint8_t *)(cardbuf + 216), 72);
      break;
    case 15:
      call TCPClient.write((uint8_t *)(cardbuf + 252), 8);
      break;
    case 16:
      post ship_contents();
      break;
    case 17:
      call TCPClient.write((uint8_t *)(cardbuf + 36), 72);
      break;
    case 18:
      call TCPClient.write((uint8_t *)(cardbuf + 72), 72);
      break;
    case 19:
      call TCPClient.write((uint8_t *)(cardbuf + 108), 72);
      break;
    case 20:
      call TCPClient.write((uint8_t *)(cardbuf + 144), 72);
      break;
    case 21:
      call TCPClient.write((uint8_t *)(cardbuf + 180), 72);
      break;
    case 22:
      call TCPClient.write((uint8_t *)(cardbuf + 216), 72);
      break;
    case 23:
      call TCPClient.write((uint8_t *)(cardbuf + 252), 8);
      break;
    default:
      call TCPClient.close();
      call Leds.greenOff();
      //      stopIP();
      write_step = 0;

      call Leds.orangeOff();
      
      call DMA0.ADCbeginConversion();

      break;
    }
  }

  event    void     TCPClient.dataAvailable(uint8_t *buf, uint16_t len) {}

  event    void     TCPClient.connectionFailed(uint8_t reason) { 
    myreason = reason;
  }

  event result_t yTimer.fired() {
    return SUCCESS;
  }

  async event void DMA0.transferComplete() {
    atomic DMA0DA += 2;
  }

  async event void DMA1.transferComplete() {
    atomic DMA1DA += 2;
  }

  async event void DMA2.transferComplete() {
    atomic DMA2DA += 2;
    post dma2Results();
  }

  async event void DMA0.ADCInterrupt(uint8_t regnum) {
  } 
  async event void DMA1.ADCInterrupt(uint8_t regnum) {}
  async event void DMA2.ADCInterrupt(uint8_t regnum) {}

  event void Client.connected( bool isConnected ) {
  }
  const struct Param s_DMA0Output[] = {
    { "dma transfers",   PARAM_TYPE_UINT8, &dma_transfers },
    { "error_reason",   PARAM_TYPE_UINT8, &myreason },
  /*

    { "0",    PARAM_TYPE_UINT16, (uint16_t *)&sbuf0[0] },
    { "1",    PARAM_TYPE_UINT16, (uint16_t *)&sbuf0[1] },
    { "2",    PARAM_TYPE_UINT16, (uint16_t *)&sbuf0[2] },
    { "3",    PARAM_TYPE_UINT16, (uint16_t *)&sbuf0[3] },
*/
    { NULL, 0, NULL }
  };
  struct ParamList g_DMA0OutList = { "output0", &s_DMA0Output[0] };

  /*
    { "dmactl0",    PARAM_TYPE_HEX16, (uint16_t *)&DMACTL0 },
    { "dmactl1",    PARAM_TYPE_HEX16, (uint16_t *)&DMACTL1 },
    { "dma0ctl",    PARAM_TYPE_HEX16, (uint16_t *)&DMA0CTL},
    { "dma1ctl",    PARAM_TYPE_HEX16, (uint16_t *)&DMA1CTL},
    { "dma2ctl",    PARAM_TYPE_HEX16, (uint16_t *)&DMA2CTL},
    { "dma0sa",    PARAM_TYPE_HEX16, (uint16_t *)&DMA0SA},

    { "dma0sz",    PARAM_TYPE_HEX16, (uint16_t *)&DMA0SZ},
    { "dma1sa",    PARAM_TYPE_HEX16, (uint16_t *)&DMA1SA},
    { "dma1sz",    PARAM_TYPE_HEX16, (uint16_t *)&DMA1SZ},
    { "dma2sa",    PARAM_TYPE_HEX16, (uint16_t *)&DMA2SA},
    { "dma2sz",    PARAM_TYPE_HEX16, (uint16_t *)&DMA2SZ},
  */
  const struct Param s_DMARegs[] = {
    { "dma0da",    PARAM_TYPE_HEX16, (uint16_t *)&DMA0DA},
    { "dma1da",    PARAM_TYPE_HEX16, (uint16_t *)&DMA1DA},
    { "dma2da",    PARAM_TYPE_HEX16, (uint16_t *)&DMA2DA},
    { NULL, 0, NULL }
  };

  struct ParamList g_DMARegsList = { "dmaregs", &s_DMARegs[0] };
  const struct Param s_msg[] = {
    { "msg",    PARAM_TYPE_STRING, &msgbuf[0] },
    { NULL, 0, NULL }
  };
  struct ParamList msgList = { "msgs", &s_msg[0] };
  command result_t ParamView.init(){
    signal ParamView.add( &msgList );
    signal ParamView.add( &g_DMA0OutList );
    signal ParamView.add( &g_DMARegsList );

    return SUCCESS;
  }

  struct TelnetCommand {
    char *name;
    char * (*func)( char *, char *, char * );
  };

  const struct TelnetCommand operations[] = {
    { "ship", &do_sends },
    { "gyro", &do_gyros },
    { 0, NULL }
  };

  event const char * TelnetRun.token() { return "run"; }
  event const char * TelnetRun.help() { return "Run network operations\r\n"; }

  event char * TelnetRun.process( char * in, char * out, char * outmax ) {
    char * next, * extrastuff;
    char * cmd = next_token(in, &next, ' ');

    if(cmd) {
      const struct TelnetCommand *c = operations;
      
      for ( ;c->name; c++) {
	if (strcmp(cmd, c->name) == 0) {
	  extrastuff = (*c->func)( next, out, outmax );
	  //this is a hack to prevent hanging telnet.process if nothing is returned from service function
	  if(extrastuff)
	    out += snprintf(out, outmax - out, "%s\r\n", extrastuff);
	  else
	    out += snprintf(out, outmax - out, "%s\r\n", "dummy");
	  break;
	}
      }
    }
    else
      out += snprintf(out, outmax - out, "must provide command with 'run'\r\n");
	    
    return out;
  }
}

--- NEW FILE: Makefile ---
COMPONENT=GyroTiltApp

USE_IP=True
SELECT_WIRED_OR_WIRELESS=True

include ../Makerules

--- NEW FILE: Makefile.gyroaccel ---
COMPONENT=GyroAccelApp

USE_IP=True
SELECT_WIRED_OR_WIRELESS=True

include ../Makerules



More information about the Tinyos-contrib-commits mailing list