[Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/harvard/spaulding/src/dataStore/testDMA DMA.h, NONE, 1.1 DMA.nc, NONE, 1.1 DMA_M.nc, NONE, 1.1 Makefile, NONE, 1.1 TestDMA.nc, NONE, 1.1 TestDMA_M.nc, NONE, 1.1

Konrad Lorincz konradlorincz at users.sourceforge.net
Thu May 1 20:33:46 PDT 2008


Update of /cvsroot/tinyos/tinyos-1.x/contrib/harvard/spaulding/src/dataStore/testDMA
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv20579

Added Files:
	DMA.h DMA.nc DMA_M.nc Makefile TestDMA.nc TestDMA_M.nc 
Log Message:
Added DMA test

--- NEW FILE: DMA.h ---
/*
 * Copyright (c) 2005 Hewlett-Packard Company
 * 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 Hewlett-Packard Company 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
 *           April 2005
***********************************************************************
Revised by Stephen Linder spl at alum.mit.edu
			October 2007
Added enumerations and structures to augment the DMA.NC interface.

 *
 */

#define DMA_CHANNELS 3
#define  CHANNELS_USED  uniqueCount("DMA")

typedef enum  {
    ADDR_FIXED,
    ADDR_DECREMENT = 2,
    ADDR_INCREMENT
} addressIncrement;

////////////////////////////////////////////////////////////////////////////////////
// Added by SPL 10/16/07
// This was taken from MSP430DMA.h written by Ben Greenstein <ben at cs.ucla.edu>
// can not include the whole file because they both use DMA_CHANNELS

enum {
  DMA_CHANNEL0 = 0,
  DMA_CHANNEL1 = 1,
  DMA_CHANNEL2 = 2,
  DMA_CHANNEL_UNKNOWN = 3
};

enum {
  DMA_CHANNEL_AVAILABLE = 0,
  DMA_CHANNEL_IN_USE = 1
};

// HPL constants

enum {
  DMA0TSEL_SHIFT = (0),
  DMA1TSEL_SHIFT = (4),
  DMA2TSEL_SHIFT = (8),
  DMATSEL_MASK   = (0xF)
};
enum {
  DMASRCINCR_SHIFT = (8),
  DMADSTINCR_SHIFT = (10),
  DMAINCR_MASK = (0x3)
};
enum {
  DMADT_SHIFT = (12),
  DMADT_MASK = (0x3)
};
typedef enum {
    DMA_TRIGGER_DMAREQ =          0x0, // software trigger
    DMA_TRIGGER_TACCR2 =          0x1,
    DMA_TRIGGER_TBCCR2 =          0x2,
    DMA_TRIGGER_USARTRX =         0x3, // URXIFG0 (UART/SPI), data received (I2C)
    DMA_TRIGGER_USARTTX =         0x4, // UTXIFG0 (UART/SPI), transmit ready (I2C)
    DMA_TRIGGER_DAC12IFG =        0x5, // DAC12_0CTL DAC12IFG bit
    DMA_TRIGGER_ADC12IFGx =       0x6,
    DMA_TRIGGER_TACCR0 =          0x7, // CCIFG bit
    DMA_TRIGGER_TBCCR0 =          0x8, // CCIFG bit
    DMA_TRIGGER_URXIFG1 =         0x9,
    DMA_TRIGGER_UTXIFG1 =         0xa,
    DMA_TRIGGER_MULT =            0xb, // Hardware Multiplier Ready
    DMA_TRIGGER_DMAxIFG =         0xe, // DMA0IFG triggers DMA channel 1
                                       // DMA1IFG triggers DMA channel 2
                                       // DMA2IFG triggers DMA channel 0
    DMA_TRIGGER_DMAE0 =           0xf  // External Trigger DMAE0
} dma_trigger_t;


enum {
  DISABLE_NMI = 0,
  ENABLE_NMI = 1
};
enum {
  NOT_ROUND_ROBIN = 0,
  ROUND_ROBIN = 1,
};
enum {
  NOT_ON_FETCH = 0,
  ON_FETCH = 1
};
typedef enum {
  DMA_EDGE_SENSITIVE = 0x0,
  DMA_LEVEL_SENSITIVE = 0x1
} dma_level_t;
typedef enum {
  DMA_WORD = 0x0,
  DMA_BYTE = 0x1
} dma_byte_t;
typedef enum {
  DMA_ADDRESS_UNCHANGED = 0x0,
  DMA_ADDRESS_DECREMENTED = 0x2,
  DMA_ADDRESS_INCREMENTED = 0x3
} dma_incr_t;
typedef enum {
  DMA_SINGLE_TRANSFER = 0x0,
  DMA_BLOCK_TRANSFER = 0x1,
  DMA_BURST_BLOCK_TRANSFER = 0x2,
  DMA_REPEATED_SINGLE_TRANSFER = 0x4,
  DMA_REPEATED_BLOCK_TRANSFER = 0x5,
  DMA_REPEATED_BURST_BLOCK_TRANSFER = 0x7
} dma_transfer_mode_t;

typedef struct  {					//dma_state_s
  unsigned int enableNMI : 1;
  unsigned int roundRobin : 1;
  unsigned int onFetch : 1;
  unsigned int reserved : 13;
} __attribute__ ((packed)) dma_state_t;

typedef struct {
  unsigned int trigger : 4;
  unsigned int reserved : 12;

  unsigned int request : 1;
  unsigned int abort : 1;
  unsigned int interruptEnable : 1;
  unsigned int interruptFlag : 1;
  unsigned int enable : 1;
  unsigned int level : 1;            /* or edge- triggered */
  unsigned int srcByte : 1;          /* or word */
  unsigned int dstByte : 1;
  unsigned int srcIncrement : 2;     /* or no-increment, decrement */
  unsigned int dstIncrement : 2;
  unsigned int transferMode : 3;
  unsigned int reserved2 : 1;

  uint16_t  srcAddr;
  uint16_t  dstAddr;
  uint16_t  size;
} __attribute__ ((packed)) dma_channel_state_t;




--- NEW FILE: DMA.nc ---
/*
 * Copyright (c) 2005 Hewlett-Packard Company
 * 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 Hewlett-Packard Company 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
 *           April 2005
 *
 */

interface DMA {
    
  command void init();

  command void beginTransfer();
  command void stopTransfer();

  command void setSourceAddress(uint16_t src);
  command void setDestinationAddress(uint16_t dest);
    
  command void setBlockSize(uint16_t size);
    
  command void setTransferMode(uint16_t mode);

  command void setChannelPriority(bool roundrobin);

  command void setDestinationAddressIncrement(addressIncrement ai);
  command void setSourceAddressIncrement(addressIncrement ai);
    
  command void setSourceByteSize(bool byteSize);
  command void setDestinationByteSize(bool byteSize);

  async default event void transferComplete();

  // Analog to Digital Converter code that should be move at some point
  command void ADCinit();
  command void ADCbeginConversion(); 
  command void ADCstopConversion();
  command void ADCsetMemRegisterInputChannel(uint8_t reg_num, uint8_t ch);
    
  async default event void ADCInterrupt(uint8_t regnum);
  
  ///////////////////////////////////////////////////////////////////////
    // augmented interface added by SPL 10-16-07 to enable the abstraction
    // of DMA access to the SD card. When possible uses the conventions found
    // in MSP430DMAChannelControl.nc by Ben Greenstein <ben at cs.ucla.edu>
    ///////////////////////////////////////////////////////////////////////

    async command result_t setTrigger(dma_trigger_t trigger);
    async command void clearTrigger();

    async command void setOnFetch(); 
    async command void clearOnFetch(); 
    async command void setRoundRobin(); 
    async command void clearRoundRobin(); 
    async command void setENNMI(); 
    async command void clearENNMI(); 
    async command void 			setControllerState(dma_state_t s);
    async command dma_state_t 	getControllerState();


    async command void setSingleMode();
    async command void setBlockMode();
    async command void setBurstMode();
    async command void setRepeatedSingleMode();
    async command void setRepeatedBlockMode();
    async command void setRepeatedBurstMode();

    async command void setSrcNoIncrement();
    async command void setSrcDecrement();
    async command void setSrcIncrement();
    async command void setDstNoIncrement();
    async command void setDstDecrement();
    async command void setDstIncrement();

    async command void setWordToWord(); 
    async command void setByteToWord(); 
    async command void setWordToByte(); 
    async command void setByteToByte(); 


    async command void setEdgeSensitive();
    async command void setLevelSensitive();

    async command void enableDMA();		// different than beginTransfer() found above
    async command void disableDMA();
    async command bool getBusyState();
    async command void enableInterrupt(); 
    async command void disableInterrupt(); 

    async command bool interruptPending();
    async command void reset();
    async command bool aborted();
    async command void triggerDMA();
    // not tested
    async command void 					setState(dma_channel_state_t s);
    async command dma_channel_state_t 	getState();
  
}    

--- NEW FILE: DMA_M.nc ---
/*
 * Copyright (c) 2005 Hewlett-Packard Company
 * 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 Hewlett-Packard Company 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.
 *
 *
 * A parameterized interface for DMA
 * You should use this as 'foo.DMA -> DMA[unique("DMA")]'
 *
 * Authors:  Steven Ayer
 *           April 2005
 ////////////////////////////////////////////////////////////////////////
 Revised: Stephen Linder October 19
 
 Added methods to support DMA transfers to SD card over an SPI interface.
 
 */

includes DMA;
 
module DMA_M {
  provides interface DMA[uint8_t id];
}
implementation {
  MSP430REG_NORACE(ADC12IV);

  MSP430REG_NORACE(DMACTL0);
  MSP430REG_NORACE(DMACTL1);

  MSP430REG_NORACE(DMA0CTL);
  MSP430REG_NORACE(DMA1CTL);
  MSP430REG_NORACE(DMA2CTL);

  MSP430REG_NORACE(DMA0SA);
  MSP430REG_NORACE(DMA1SA);
  MSP430REG_NORACE(DMA2SA);

  MSP430REG_NORACE(DMA0DA);
  MSP430REG_NORACE(DMA1DA);
  MSP430REG_NORACE(DMA2DA);

  MSP430REG_NORACE(DMA0SZ);
  MSP430REG_NORACE(DMA1SZ);
  MSP430REG_NORACE(DMA2SZ);

  uint8_t ch_id;
  
  volatile uint16_t* channelSourceRegisters[] = 	 {&DMA0SA, &DMA1SA, &DMA2SA};
  volatile uint16_t* channelDestinationRegisters[] = {&DMA0DA, &DMA1DA, &DMA2DA};
  volatile uint16_t* channelSizeRegisters[] = 		 {&DMA0SZ, &DMA1SZ, &DMA2SZ};
  volatile uint16_t* channelControlRegisters[] =     {&DMA0CTL, &DMA1CTL, &DMA2CTL};
  // number of bits left that the trigger mask needs to be shifted
  // for each channel
  uint8_t channelTriggerBitShift[] = {DMA0TSEL_SHIFT, DMA1TSEL_SHIFT, DMA2TSEL_SHIFT};
  
  
  command void DMA.ADCinit[uint8_t id]() {
    atomic {
      ADC12CTL0 = ADC12ON;       // self-explanatory

      ADC12CTL0 |= REFON;               // reference generator on

      ADC12CTL0 |= MSC;                 // multiple conversions without more triggers

      CLR_FLAG(ADC12CTL0, SHT0_15);     //clear sample and hold time bits
      CLR_FLAG(ADC12CTL0, SHT1_15);
      ADC12CTL1 = SHS_0 + SHP + CONSEQ_2;     // s&h from adc12sc bit; sample from sampling timer;  repeat single-channel conversion
      ADC12CTL1 |= ADC12SSEL_3;         // clk from smclk
	
      ADC12MCTL0 |= INCH_0;             // use input channel 1 for all mem regs

      ADC12MCTL0 |= SREF_1;             // Vref = Vref+ and avss-
      ADC12MCTL1 |= SREF_1;             // Vref = Vref+ and avss-
      ADC12MCTL2 |= SREF_1;             // Vref = Vref+ and avss-
    }
  }
	
  command void DMA.ADCbeginConversion[uint8_t id]() {
    atomic{
      ADC12CTL0 |= ENC + ADC12SC;   // start conversion
    }
  }

  command void DMA.ADCstopConversion[uint8_t id]() {
    atomic ADC12CTL0 &= ~(ENC + ADC12SC);
  }
  /**
   * each of 16 mem registers selects its own input channel, 8 external, 4 internal
   * 
   **/
  command void DMA.ADCsetMemRegisterInputChannel[uint8_t id](uint8_t reg_num, uint8_t ch) {
    uint16_t mreg = ADC12MCTL0;
    mreg += reg_num;
	
    mreg |= ch;
  }

  command void DMA.init[uint8_t id]() {
    uint16_t inbuf[256];

    switch (id) {
    case 0:
      atomic {
	DMA0SA = ADC12MEM0_;               // src first adc buf register

	DMA0SZ = sizeof(inbuf) >> 1;       // oddly, setting this to 1 breaks code;  this is nominal word block
	// default is word transfer, set in DMA0CTL with DMASRCBYTE and DMADSTBYTE == 0

	DMACTL0 = DMA0TSEL_3 << 1;         // trigger from ADC12IFGx

	// repeat single transfer (no ie reset), increment dest addr, static src addr
	DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMASRCINCR_0;    
	
      }
      break;
    case 1:
      atomic{
	DMA1SA = ADC12MEM1_;               // src next adc buf register
	//	  DMA1DA = inbuf1;           // set dest thus in app.
	DMA1SZ = sizeof(inbuf) >> 1;       // see dma0sz

	DMACTL0 |= DMA1TSEL_3 << 1;                     // trigger from ADC12IFGx

	DMA1CTL = DMADT_4 + DMADSTINCR_3 + DMASRCINCR_0;    
      }
      break;
    case 2:
      atomic{
	DMA2SA = ADC12MEM2_;               // src next adc buf register
	//   DMA2DA = inbuf2;                  // set dest thus in application
	DMA2SZ = sizeof(inbuf) >> 1;                        // see dma0sz

	DMACTL0 |= DMA2TSEL_3 << 1;

	DMA2CTL = DMADT_4 + DMADSTINCR_3 + DMASRCINCR_0;    
      }
      break;
    }
  }

  command void DMA.beginTransfer[uint8_t id]() {
    if(id == 0){
      SET_FLAG(DMA0CTL, DMAEN + DMAIE);      // enabled and interrupt enabled
      CLR_FLAG(DMA0CTL, DMAIFG);
    }
    else if(id == 1){
      SET_FLAG(DMA1CTL, DMAEN + DMAIE);      // enabled and interrupt enabled
      CLR_FLAG(DMA1CTL, DMAIFG);
    }
    else if(id == 2){
      SET_FLAG(DMA2CTL, DMAEN + DMAIE);      // enabled and interrupt enabled
      CLR_FLAG(DMA2CTL, DMAIFG);
    }
  }

  // this one requires some interrupt manipulation if in progress; use after transfer completes
  command void DMA.stopTransfer[uint8_t id]() {
    if(id == 0)
      CLR_FLAG(DMA0CTL, DMAEN + DMAIE);      // enable and interrupt enable
    else if(id == 1)
      CLR_FLAG(DMA1CTL, DMAEN + DMAIE);      // enable and interrupt enable
    else if(id == 2)
      CLR_FLAG(DMA2CTL, DMAEN + DMAIE);      // enable and interrupt enable
  }

  command void DMA.setSourceAddress[uint8_t id](uint16_t src){
    if(id == 0)
      DMA0SA = src;
    else if(id == 1)
      DMA1SA = src;
    else if(id == 2)
      DMA2SA = src;
  }

  command void DMA.setDestinationAddress[uint8_t id](uint16_t dest){
    if(id == 0)
      DMA0DA = dest;
    else if(id == 1)
      DMA1DA = dest;
    else if(id == 2)
      DMA2DA = dest;
  }
    
  // size is number of bytes or words, depending upon dmaxctl; 
  command void DMA.setBlockSize[uint8_t id](uint16_t size){
    if(id == 0)
      DMA0SZ = size;
    else if(id == 1)
      DMA1SZ = size;
    else if(id == 2)
      DMA2SZ = size;
  }

  /**
   * DMADT_0 transfer mode 0: single
   * DMADT_1 transfer mode 1: block 
   * DMADT_2 transfer mode 2: interleaved 
   * DMADT_3 transfer mode 3: interleaved 
   * DMADT_4 transfer mode 4: single, repeat 
   * DMADT_5 transfer mode 5: block, repeat 
   * DMADT_6 transfer mode 6: interleaved, repeat 
   * DMADT_7 transfer mode 7: interleaved, repeat 
   **/
  command void DMA.setTransferMode[uint8_t id](uint16_t mode){
    if(id == 0){
      CLR_FLAG(DMA0CTL, DMADT_7);
      SET_FLAG(DMA0CTL, mode);
    }
    else if(id == 1){
      CLR_FLAG(DMA1CTL, DMADT_7);
      SET_FLAG(DMA1CTL, mode);
    }
    else if(id == 2){
      CLR_FLAG(DMA2CTL, DMADT_7);
      SET_FLAG(DMA2CTL, mode);
    }
  }

  // sets round-robin bit
  command void DMA.setChannelPriority[uint8_t id](bool roundrobin){
    if(roundrobin)
      SET_FLAG(DMACTL1, ROUNDROBIN);
    else
      CLR_FLAG(DMACTL1, ROUNDROBIN);
  }

  command void DMA.setDestinationAddressIncrement[uint8_t id](addressIncrement ai){
    if(id == 0){
      SET_FLAG(DMA0CTL, ai << 8);
    }
    else if(id == 1){
      SET_FLAG(DMA1CTL, ai << 8);
    }
    else if(id == 2){
      SET_FLAG(DMA2CTL, ai << 8);
    }
  }

  command void DMA.setSourceAddressIncrement[uint8_t id](addressIncrement ai) {
    if(id == 0){
      SET_FLAG(DMA0CTL, ai << 10);
    }
    else if(id == 1){
      SET_FLAG(DMA1CTL, ai << 10);
    }
    else if(id == 2){
      SET_FLAG(DMA2CTL, ai << 10);
    }
  }
    
  // alternative is word
  command void DMA.setSourceByteSize[uint8_t id](bool byteSize){
    if(byteSize){
      if(id == 0){
	SET_FLAG(DMA0CTL, DMASRCBYTE);
      }
      else if(id == 1){
	SET_FLAG(DMA1CTL, DMASRCBYTE);
      }
      else if(id == 2){
	SET_FLAG(DMA2CTL, DMASRCBYTE);
      }
    }
    else{
      if(id == 0){
	CLR_FLAG(DMA0CTL, DMASRCBYTE);
      }
      else if(id == 1){
	CLR_FLAG(DMA1CTL, DMASRCBYTE);
      }
      else if(id == 2){
	CLR_FLAG(DMA2CTL, DMASRCBYTE);
      }
    }
  }

  command void DMA.setDestinationByteSize[uint8_t id](bool byteSize) {
    if(byteSize){
      if(id == 0){
	SET_FLAG(DMA0CTL, DMADSTBYTE);
      }
      else if(id == 1){
	SET_FLAG(DMA1CTL, DMADSTBYTE);
      }
      else if(id == 2){
	SET_FLAG(DMA2CTL, DMADSTBYTE);
      }
    }
    else{
      if(id == 0){
	CLR_FLAG(DMA0CTL, DMADSTBYTE);
      }
      else if(id == 1){
	CLR_FLAG(DMA1CTL, DMADSTBYTE);
      }
      else if(id == 2){
	CLR_FLAG(DMA2CTL, DMADSTBYTE);
      }
    }
  }

  async default event void DMA.transferComplete[uint8_t id](){}
  TOSH_SIGNAL(DACDMA_VECTOR) {
    volatile uint16_t v  = DMA0CTL;
	
    if(v & DMAIFG) { 
      DMA0CTL &= ~DMAIFG;
      signal DMA.transferComplete[0]();
    }
    v = DMA1CTL;
    if(v & DMAIFG) { 
      DMA1CTL &= ~DMAIFG;
      signal DMA.transferComplete[1]();
    }
    v = DMA2CTL;
    if(v & DMAIFG) { 
      DMA2CTL &= ~DMAIFG;
      signal DMA.transferComplete[2]();
    }
  }

  async default event void DMA.ADCInterrupt[uint8_t id](uint8_t regnum) {} ;
  TOSH_SIGNAL(ADC_VECTOR) {
    volatile uint16_t vec = ADC12IV;
	
    if( vec ) { 
      vec = vec >> 1;
      /*	     original generic trigger
      if( vec >= 3 )
	signal DMA.ADCInterrupt[0](vec);
      */
      switch (vec) {
      case 6:
	signal DMA.ADCInterrupt[0](vec);
	break;
      case 7:
	signal DMA.ADCInterrupt[1](vec);
	break;
      case 8:
	signal DMA.ADCInterrupt[2](vec);
	break;
      default:
	break;
      }
    }
  } 

  ///////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////
  
	// Should a DMA transfer occur immediately (FALSE),
	// on the next instruction fetch after the trigger (TRUE)
  	// Note: DMAONFETCH Must Be Used When The DMA Writes To Flash
  	// If the DMA controller is used to write to flash memory, the DMAONFETCH
  	// bit must be set. Otherwise, unpredictable operation can result.
	async command void DMA.setOnFetch[uint8_t id]() {
	  DMACTL1 |= DMAONFETCH;
	}
	async command void DMA.clearOnFetch[uint8_t id]() {
	  DMACTL1 &= ~(DMAONFETCH);
	}

	// Should the DMA channel priority be 0, 1, 2 (FALSE), or 
	// should it change with each transfer (TRUE)
	async command void DMA.setRoundRobin[uint8_t id]() {
		DMACTL1 |= ROUNDROBIN;
	}
	async command void DMA.clearRoundRobin[uint8_t id]() {
	  DMACTL1 &= ~(ROUNDROBIN);
	}

	// enables the interruption of a DMA transfer by an NMI
	// interrupt. WHen an NMI interrupts a DMA transfer, the current
	// transfer is completed normally, further transfers are stopped,
	// and DMAABORT is set.
	async command void DMA.setENNMI[uint8_t id]() {
	  DMACTL1 |= ENNMI;
	}
	async command void DMA.clearENNMI[uint8_t id]() {
	  DMACTL1 &= ~(ENNMI);
	}

	async command void DMA.setControllerState[uint8_t id](dma_state_t s) {
	  uint16_t dmactl1 = 0;
	  dmactl1 |= (s.enableNMI       ? ENNMI      : 0);
	  dmactl1 |= (s.roundRobin      ? ROUNDROBIN : 0);
	  dmactl1 |= (s.onFetch         ? DMAONFETCH : 0);
	  DMACTL1 = dmactl1;
	}
	async command dma_state_t DMA.getControllerState[uint8_t id]() {
	  dma_state_t s;
	  s.enableNMI = (DMACTL1 & ENNMI ? 1 : 0);
	  s.roundRobin = (DMACTL1 & ROUNDROBIN ? 1 : 0);
	  s.onFetch = (DMACTL1 & DMAONFETCH ? 1 : 0);
	  s.reserved = 0;
	  return s;
	}
 
 
	/////////////////////////////////
	// ----- DMA Trigger Mode -----
	/////////////////////////////////
	async command result_t DMA.setTrigger[uint8_t id](dma_trigger_t trigger) {
	  	if(*(channelControlRegisters[id])& DMAEN) {
	  		return FAIL;
  		}
		DMACTL0 &= ~( (DMA0TSEL0 | DMA0TSEL1 | DMA0TSEL2 | DMA0TSEL3) 
								<< channelTriggerBitShift[id]);
				DMACTL0 |= ((DMATSEL_MASK & trigger) 
								<< channelTriggerBitShift[id]);
	  	return SUCCESS;
	}
	async command void DMA.clearTrigger[uint8_t id]() {
		DMACTL0 &= ~( (DMA0TSEL0 | DMA0TSEL1 | DMA0TSEL2 | DMA0TSEL3) 
							<< channelTriggerBitShift[id]);
	}
	
	/////////////////////////////////
	// ----- DMA Transfer Mode -----
	/////////////////////////////////
	async command void DMA.setSingleMode[uint8_t id]() {
	  *(channelControlRegisters[id]) &= ~(DMADT0 | DMADT1 | DMADT2);
	}
	async command void DMA.setBlockMode[uint8_t id]() {
	  *(channelControlRegisters[id]) &= ~(DMADT0 | DMADT1 | DMADT2);
	  *(channelControlRegisters[id]) |= DMADT0;
	}
	async command void DMA.setBurstMode[uint8_t id]() {
	  *(channelControlRegisters[id]) &= ~(DMADT0 | DMADT1 | DMADT2);
	  *(channelControlRegisters[id]) |= DMADT1;
	}
	async command void DMA.setRepeatedSingleMode[uint8_t id]() {
	  *(channelControlRegisters[id]) &= ~(DMADT0 | DMADT1 | DMADT2);
	  *(channelControlRegisters[id]) |= DMADT2;
	}
	async command void DMA.setRepeatedBlockMode[uint8_t id]() {
	  *(channelControlRegisters[id]) &= ~(DMADT0 | DMADT1 | DMADT2);
	  *(channelControlRegisters[id]) |= (DMADT2 | DMADT0);
	}
	async command void DMA.setRepeatedBurstMode[uint8_t id]() {
	  *(channelControlRegisters[id]) &= ~(DMADT0 | DMADT1 | DMADT2);
	  *(channelControlRegisters[id]) |= (DMADT2 | DMADT1);
	}

	/////////////////////////////////
	// ----- DMA Address Incrementation -----
	/////////////////////////////////
	async command void DMA.setSrcNoIncrement[uint8_t id]() {
	  *(channelControlRegisters[id]) &= ~(DMASRCINCR0 | DMASRCINCR1);
	}
	async command void DMA.setSrcDecrement[uint8_t id]() {
	  *channelControlRegisters[id] |= DMASRCINCR1;
	}
	async command void DMA.setSrcIncrement[uint8_t id]() {
	  *channelControlRegisters[id] |= (DMASRCINCR0 | DMASRCINCR1);
	}
	async command void DMA.setDstNoIncrement[uint8_t id]() {
	  *channelControlRegisters[id] &= ~(DMADSTINCR0 | DMADSTINCR1);
	}
	async command void DMA.setDstDecrement[uint8_t id]() {
	  *channelControlRegisters[id] |= DMADSTINCR1;
	}
	async command void DMA.setDstIncrement[uint8_t id]() {
	  *channelControlRegisters[id] |= (DMADSTINCR0 | DMADSTINCR1);
	}

	/////////////////////////////////
	// ----- DMA Word Size Mode -----
	/////////////////////////////////
	async command void DMA.setWordToWord[uint8_t id]() {
	  *channelControlRegisters[id] &= ~(DMASRCBYTE | DMADSTBYTE);
	  *channelControlRegisters[id] |= DMASWDW;
	}
	async command void DMA.setByteToWord[uint8_t id]() {
	  *channelControlRegisters[id] &= ~(DMASRCBYTE | DMADSTBYTE);
	  *channelControlRegisters[id] |= DMASBDW;
	}
	async command void DMA.setWordToByte[uint8_t id]() {
	  *channelControlRegisters[id] &= ~(DMASRCBYTE | DMADSTBYTE);
	  *channelControlRegisters[id] |= DMASWDB;
	}
	async command void DMA.setByteToByte[uint8_t id]() {
	  *channelControlRegisters[id] &= ~(DMASRCBYTE | DMADSTBYTE);
	  *channelControlRegisters[id] |= DMASBDB;
	}

	/////////////////////////////////
	// ----- DMA Level -----
	/////////////////////////////////

	async command void DMA.setEdgeSensitive[uint8_t id]() {
	  *channelControlRegisters[id] &= ~DMALEVEL;
	}
	async command void DMA.setLevelSensitive[uint8_t id]() {
	  *channelControlRegisters[id] |= DMALEVEL;
	}

	/////////////////////////////////
	// ----- DMA Enable -----
	/////////////////////////////////
	async command void DMA.enableDMA[uint8_t id]() {
		*channelControlRegisters[id] |= DMAEN; 
	}
	async command void DMA.disableDMA[uint8_t id]() {
		*channelControlRegisters[id] &= ~DMAEN; 
	}
	async command bool DMA.getBusyState[uint8_t id]() {
		if (*channelControlRegisters[id]& DMAEN) {
			return TRUE;
		} else {
			return FALSE; 
		}
	}


	/////////////////////////////////
	// ----- DMA Interrupt -----
	/////////////////////////////////
	async command void DMA.enableInterrupt[uint8_t id]() {
	  *channelControlRegisters[id]   |= DMAIE; 
	}
	async command void DMA.disableInterrupt[uint8_t id]() {
	  *channelControlRegisters[id]   &= ~DMAIE; 
	}
	async command bool DMA.interruptPending[uint8_t id]() {
	  bool ret = FALSE;
	  if (*channelControlRegisters[id] & DMAIFG) ret = TRUE;
	  return ret;
	}

	/////////////////////////////////
	// ----- DMA Abort -----
	/////////////////////////////////
	// todo: should this trigger an interrupt?
	async command bool DMA.aborted[uint8_t id]() {
	  bool ret = FALSE;
	  if (*channelControlRegisters[id] & DMAABORT) ret = TRUE;
	  return ret;
	}
	
	async command void DMA.reset[uint8_t id]() {
	  *channelControlRegisters[id] = 0;
//	  DMA0SA = 0;
//	  DMA0DA = 0;
//	  DMA0SZ = 0;
	}

	/////////////////////////////////
	// ----- DMA Software Request -----
	/////////////////////////////////
	async command void DMA.triggerDMA[uint8_t id]() {
		*channelControlRegisters[id]  |= DMAREQ; 
	}

	//****************** WARNING ********************
	//****************** NOT TESTED *****************
	async command void DMA.setState[uint8_t id](dma_channel_state_t s) {
 	  uint16_t dmactl0 = DMACTL0;
	  uint16_t dmaXctl = 0;

	  dmactl0 |= ((s.trigger & DMATSEL_MASK) << channelTriggerBitShift[id]);
	  dmaXctl |= (s.request         ? DMAREQ     : 0);
	  dmaXctl |= (s.abort           ? DMAABORT   : 0);
	  dmaXctl |= (s.interruptEnable ? DMAIE      : 0);
	  dmaXctl |= (s.interruptFlag   ? DMAIFG     : 0);
	  dmaXctl |= (s.enable          ? DMAEN      : 0);
	  dmaXctl |= (s.level           ? DMALEVEL   : 0);
	  dmaXctl |= (s.srcByte         ? DMASRCBYTE : 0);
	  dmaXctl |= (s.dstByte         ? DMADSTBYTE : 0);
	  dmaXctl |= ((s.srcIncrement & DMAINCR_MASK) << DMASRCINCR_SHIFT);
	  dmaXctl |= ((s.dstIncrement & DMAINCR_MASK) << DMADSTINCR_SHIFT);
	  dmaXctl |= ((s.transferMode & DMADT_MASK) << DMADT_SHIFT);

	  *channelSourceRegisters[id] = 		(s.srcAddr);
	  *channelDestinationRegisters[id] = (s.dstAddr);
	  *channelSizeRegisters[id] = 		  (s.size);
	  DMACTL0 = dmactl0;
	  *channelControlRegisters[id]= dmaXctl;
	}
	async command dma_channel_state_t DMA.getState[uint8_t id]() {
	  dma_channel_state_t s;
	  s.trigger = ((DMACTL0 >> channelTriggerBitShift[id]) & DMATSEL_MASK);
	  s.reserved = 0;
	  s.request         = (*channelControlRegisters[id] & DMAREQ     ? 1 : 0);
	  s.abort           = (*channelControlRegisters[id] & DMAABORT   ? 1 : 0);
	  s.interruptEnable = (*channelControlRegisters[id] & DMAIE      ? 1 : 0);
	  s.interruptFlag   = (*channelControlRegisters[id] & DMAIFG     ? 1 : 0);
	  s.enable          = (*channelControlRegisters[id] & DMAEN      ? 1 : 0);
	  s.level           = (*channelControlRegisters[id] & DMALEVEL   ? 1 : 0);
	  s.srcByte         = (*channelControlRegisters[id] & DMASRCBYTE ? 1 : 0);
	  s.dstByte         = (*channelControlRegisters[id] & DMADSTBYTE ? 1 : 0);
	  s.srcIncrement    = ((*channelControlRegisters[id] >> DMASRCINCR_SHIFT) & DMAINCR_MASK);
	  s.dstIncrement    = ((*channelControlRegisters[id] >> DMADSTINCR_SHIFT) & DMAINCR_MASK);
	  s.reserved2 = 0;
	  s.transferMode    = ((*channelControlRegisters[id] >> DMADT_SHIFT) & DMADT_MASK);
	  s.srcAddr = (uint16_t) *channelSourceRegisters[id];
	  s.dstAddr = (uint16_t) *channelDestinationRegisters[id];
	  s.size = *channelSizeRegisters[id];
	  return s;
	} 
	

	//********************* NOT TESTED ************************
	// This code was cut and pasted from a another function where
	// I was testing DMA transfers. I have not yet tested the code 
	// to see if I broke it when I wrapped it in this method
	//////////////////////////////////////////////////////
/*	void transferBlock_DMA  (uint8_t *sourcePtr, 
							uint8_t *destinationPtr,
							uint16_t blockLength) {

		//************************************************
		//  Must set trigger before enabling DMA channel
		//************************************************
		call DMA1.setTrigger(DMA_TRIGGER_DMAREQ);
		call DMA1.clearOnFetch();
		call DMA1.clearRoundRobin();
		call DMA1.clearENNMI();

		call DMA1.setSourceAddress ((uint16_t)  sourcePtr);
		call DMA1.setDestinationAddress ((uint16_t) destinationPtr);
		call DMA1.setBlockSize(blockLength);
		call DMA1.setBurstMode();
		call DMA1.setByteToByte();
		call DMA1.setSrcIncrement();
		call DMA1.setDstIncrement();

		call DMA1.enableDMA();triggerDMA
		call DMA1.triggerDMA();
	}
*/	
}

--- NEW FILE: Makefile ---
COMPONENT=TestDMA

CFLAGS += -I$(SPAULDINGSRC)/lib/
CFLAGS += -I$(SPAULDINGSRC)/lib/printfRadio
include $(SPAULDINGSRC)/Makefile.in

#CFLAGS += -DPRINTFUART_ENABLED
PFLAGS += -DPRINTFRADIO_ENABLED

USE_IP=True
SELECT_WIRED_OR_WIRELESS=True


include $(MAKERULES)

--- NEW FILE: TestDMA.nc ---
/*
 * Copyright (c) 2005 Hewlett-Packard Company
 * 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 Hewlett-Packard Company 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
 *          April 2005
 */

#include "PrintfRadio.h"

configuration TestDMA {
}
implementation {
    components 
	Main, 
	TestDMA_M, 
	DMA_M, 
	TimerC, 
	LedsC;//, 	
//	IPCLIENT as IPClientC,
//	TelnetM,
//	ParamViewM;

    Main.StdControl->TestDMA_M;
    Main.StdControl->TimerC;

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

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

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

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

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

    components PrintfRadioC;
    TestDMA_M.PrintfRadio -> PrintfRadioC;
}

--- NEW FILE: TestDMA_M.nc ---
/*
 * Copyright (c) 2005 Hewlett-Packard Company
 * 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 Hewlett-Packard Company 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
 *           April 2005
 *           rewritten by s.a. to account for a.c.'s rewritten interface, 3/06
 */

includes DMA;
#include "PrintfRadio.h"
//includes Message;

module TestDMA_M {
    provides{
	interface StdControl;
//	interface ParamView;
    }
    uses {
	interface DMA as DMA0;
	interface DMA as DMA1;
	interface DMA as DMA2;
	//	interface ADC as ADC0;

	/* telnet stuff */
/*	interface StdControl as IPStdControl;
	interface StdControl as TelnetStdControl;
	interface StdControl as PVStdControl;
	interface UIP;
	interface Client;
	interface TCPClient;
*/
	/* end telnet stuff */
	interface Leds;
	//	interface Telnet;     
	interface Timer as yTimer;
	interface Timer as gTimer;
	interface Timer as rTimer;
    }

    uses interface PrintfRadio;
}

implementation {

#define MESSAGE_MAX_LENGTH 128

  uint8_t dma_transfers, write_step, status = 0;
  uint16_t inbuf0[256], inbuf1[256], inbuf2[256], *curr0, *curr1, *curr2;

    uint16_t adcifg_count = 0;

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

	atomic {
	  //DMA0DA = (uint16_t *)inbuf0;       // directly to ram
	  //DMA1DA = (uint16_t *)inbuf1;
	  //DMA2DA = (uint16_t *)inbuf2;
	  
	  call DMA0.setDestinationAddress(inbuf0);
	  call DMA1.setDestinationAddress(inbuf1);
	  call DMA2.setDestinationAddress(inbuf2);

	  DMA0SZ = sizeof(inbuf0) >> 1;
	  DMA1SZ = sizeof(inbuf1) >> 1;
	  DMA2SZ = sizeof(inbuf2) >> 1;

	  DMACTL1 |= 0x0002;  // round-robin
	}
    }
*/
  void setupDMA() {
    call DMA0.init();
    call DMA1.init();
    call DMA2.init();

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

      call DMA0.setBlockSize(sizeof(inbuf0) >> 1);
      call DMA1.setBlockSize(sizeof(inbuf1) >> 1);
      call DMA2.setBlockSize(sizeof(inbuf2) >> 1);

      SET_FLAG(DMACTL1, ROUNDROBIN);  // round-robin
    }

  }
	
/*    void sampleADC() {
      call DMA0.ADCinit();   // this doesn't really need to be parameterized
	
	ADC12CTL1 &= ~ADC12SSEL_3;         // clr clk from smclk
	ADC12CTL1 |= ADC12SSEL_0;         // clk from aclk

	ADC12CTL1 |= ADC12DIV_7;         // divide clk by 8
	// sample and hold time four adc12clk cycles
	ADC12CTL0 |= SHT0_0;   

	// conversion start address
	ADC12CTL1 |= CSTARTADD_0;      // really a zero, for clarity
	// set input channel
	call DMA0.ADCsetMemRegisterInputChannel(0, 3);  // memreg 0 <= channel 0  the way shimmer is wired, really not a very useful interface
	call DMA0.ADCsetMemRegisterInputChannel(1, 4);  // memreg 1 <= channel 1
	call DMA0.ADCsetMemRegisterInputChannel(2, 5);  // memreg 2 <= channel 2

	// set up for three adc channels -> three adcmem regs -> three dma channels in round-robin
	// clear init defaults first
	ADC12CTL1 &= ~CONSEQ_2;     // clear default repeat single channel
	//	ADC12MCTL0 &= ~INCH_1;      // input channel for mem0 is a0
	ADC12CTL1 |= CONSEQ_3;      // repeat sequence of channels
    
	// test to try channel-mapping, though it's supposed to be auto in repeat-sequence...
 	ADC12MCTL2 |= EOS;       //sez "this is the last reg" 

	setupDMA();

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

	TOSH_SET_ACCEL_SLEEP_N_PIN();    // wakes up accel board

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

    }
*/

  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
      
      SET_FLAG(ADC12CTL1, ADC12DIV_4);         // 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 input channel
    /*    call DMA0.ADCsetMemRegisterInputChannel(0, 3);  // memreg 0 <= channel 0
    call DMA0.ADCsetMemRegisterInputChannel(1, 4);  // memreg 1 <= channel 1
    call DMA0.ADCsetMemRegisterInputChannel(2, 5);  // memreg 2 <= channel 2
    */
    SET_FLAG(ADC12MCTL0, INCH_3);
    SET_FLAG(ADC12MCTL1, INCH_4);
    SET_FLAG(ADC12MCTL2, INCH_5);
    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
    
    SET_FLAG(ADC12MCTL2, EOS);       // sez "this is the last reg" 

    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;

  }

    task void adcResults() { 
    } 

    task void dma0Results() { 
    }	 
    
    task void dma1Results() { 
    }	 

    task void dma2Results() { 
      	call Leds.greenToggle();

        call DMA0.ADCstopConversion();
            {
                uint16_t i = 0;
                uint16_t max0 = 0; 
                uint16_t max1 = 0; 
                uint16_t max2 = 0; 

                for (i = 0; i < 256; ++i) {
                    if (inbuf0[i] > max0)  max0 = inbuf0[i];
                    if (inbuf1[i] > max1)  max1 = inbuf1[i];
                    if (inbuf2[i] > max2)  max2 = inbuf2[i];
                }
                printfRadio("dma2: %u %u %u", max0, max1, max2);
            }
        call DMA0.ADCbeginConversion();
    }	
    
/*    task void dma2Results() { 
        dma_transfers++;
        call DMA0.ADCstopConversion();
        if(dma_transfers == 255){
        	// reset transfer destinations
        	//	call DMA0.ADCstopConversion();
            {
                uint16_t i = 0;
                uint16_t max0 = 0; 
                uint16_t max1 = 0; 
                uint16_t max2 = 0; 

                for (i = 0; i < 256; ++i) {
                    if (inbuf0[i] > max0)  max0 = inbuf0[i];
                    if (inbuf1[i] > max1)  max1 = inbuf1[i];
                    if (inbuf2[i] > max2)  max2 = inbuf2[i];
                }
                printfRadio("dma2[%u]: %u %u %u", dma_transfers, max0, max1, max2);
            }

        	atomic {
                dma_transfers = 0;

                DMA0DA = (uint16_t *)inbuf0;
                DMA1DA = (uint16_t *)inbuf1;
                DMA2DA = (uint16_t *)inbuf2;
            }
            //	if(server_present){
	        //	call DMA0.ADCbeginConversion();

        	call Leds.greenToggle();
        	//	  call TCPClient.connect(63, 118, 194, 100, 5067);
        	//	}
        }
        call DMA0.ADCbeginConversion();
    }*/	
    
    command result_t StdControl.init() {
      //	howbig = MESSAGE_MAX_LENGTH;
      
//	call PVStdControl.init();
// 	call TelnetStdControl.init();
//	call IPStdControl.init();

	TOSH_MAKE_ACCEL_SLEEP_N_OUTPUT();         // sleep for accel
	TOSH_SEL_ACCEL_SLEEP_N_IOFUNC();

	TOSH_MAKE_ADC_ACCELZ_INPUT();         // clock
	TOSH_SEL_ADC_ACCELZ_MODFUNC();

	TOSH_MAKE_ADC_ACCELY_INPUT();         // clock
	TOSH_SEL_ADC_ACCELY_MODFUNC();

	TOSH_MAKE_ADC_ACCELX_INPUT();         // clock
	TOSH_SEL_ADC_ACCELX_MODFUNC();
	/*
	TOSH_MAKE_UTXD0_OUTPUT();         // sleep for accel
	TOSH_SEL_UTXD0_IOFUNC();
	*/
	/*
	TOSH_MAKE_ADC0_INPUT();         // clock
	TOSH_SEL_ADC0_MODFUNC();

	TOSH_MAKE_ADC1_INPUT();         // clock
	TOSH_SEL_ADC1_MODFUNC();

	TOSH_MAKE_ADC2_INPUT();         // clock
	TOSH_SEL_ADC2_MODFUNC();
	*/
	
	SVSCTL |= VLD_14;
	SVSCTL &= ~PORON;
	
	dma_transfers = 0;

	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();

	sampleADC();

	//	call yTimer.start(TIMER_REPEAT, 250);
	return SUCCESS;
    }

    command result_t StdControl.stop() {
      //	call TelnetStdControl.stop();
    //	return call IPStdControl.stop();
      return SUCCESS;
    }

    event result_t yTimer.fired() {
      //	call Leds.yellowToggle();
	//	DMA0CTL |= DMAREQ;    // software start by setting this bit
	
	return SUCCESS;
    }

    event result_t gTimer.fired() {
//	call Leds.greenToggle();
	//	DMA0CTL |= DMAREQ;    // software start by setting this bit
	
	return SUCCESS;
    }

    event result_t rTimer.fired() {
	call Leds.redToggle();
	
	return SUCCESS;
    }

    async event void DMA0.transferComplete() {
	/*	ADC12IE = 0;   // stop 
	ADC12CTL0 = 0;   // stop 
	DMA0CTL &= ~DMAEN;
	*/
      //      TOSH_TOGGLE_UTXD0_PIN();
	post dma0Results();
    }

    async event void DMA1.transferComplete() {
      //      TOSH_TOGGLE_UTXD0_PIN();
      post dma1Results();
    }

    async event void DMA2.transferComplete() {
      //      TOSH_TOGGLE_UTXD0_PIN();
      post dma2Results();
    }

    async event void DMA0.ADCInterrupt(uint8_t regnum) {
      //      call Leds.yellowToggle();
	atomic {
	    if(adcifg_count++ > 255){
		ADC12CTL0 = 0;
		ADC12IE = 0;
		//		post adcResults();
	    }
	}	       
    } 
    /*
    command result_t connect( uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4, uint16_t port );
    command result_t write( const uint8_t *buf, uint16_t len );
    command result_t close();
    */
/*    event void TCPClient.connectionMade( uint8_t status ) {
      write_step = 0;
      call Leds.redOff();
      call TCPClient.write(inbuf0, 128);
      call Leds.yellowOn();
    }
*/
    /*
     * version with 128 byte sends
     */
/*    event void TCPClient.writeDone(){
      call Leds.yellowOff();

      write_step++;
      switch (write_step) {
      case 1:
	call Leds.yellowOn();
	call TCPClient.write(inbuf0 + 64, 128);
	break;
      case 2:
	call Leds.yellowOn();
	call TCPClient.write(inbuf0 + 128, 128);
	break;
      case 3:
	call Leds.yellowOn();
	call TCPClient.write(inbuf0 + 192, 128);
	break;
      case 4:
	call Leds.yellowOn();
	call TCPClient.write(inbuf1, 128);
	break;
      case 5:
	call Leds.yellowOn();
	call TCPClient.write(inbuf1 + 64, 128);
	break;
      case 6:
	call Leds.yellowOn();
	call TCPClient.write(inbuf1 + 128, 128);
	break;
      case 7:
	call Leds.yellowOn();
	call TCPClient.write(inbuf1 + 192, 128);
	break;
      case 8:
	call Leds.yellowOn();
	call TCPClient.write(inbuf2, 128);
	break;
      case 9:
	call Leds.yellowOn();
	call TCPClient.write(inbuf2 + 64, 128);
	break;
      case 10:
	call Leds.yellowOn();
	call TCPClient.write(inbuf2 + 128, 128);
	break;
      case 11:
	call Leds.yellowOn();
	call TCPClient.write(inbuf2 + 192, 128);
	break;
      default:
	call TCPClient.close();

	write_step = 0;

	call DMA0.ADCbeginConversion();
	break;
      }
    }
*/
/*    event   void     TCPClient.dataAvailable( uint8_t *buf, uint16_t len ){}

    event   void     TCPClient.connectionFailed( uint8_t reason ){  // Reason = which end died
      status = reason;
      call Leds.redOn();
      //      call TCPClient.close();
      //      server_present = 0;
      //      call DMA0.ADCbeginConversion();
    }
*/
    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_ADCRegs[] = {
  	{ "svsreg",     PARAM_TYPE_HEX8, &SVSCTL },
	{ "adcctl0",    PARAM_TYPE_HEX16, &ADC12CTL0 },
	{ "adcctl1",    PARAM_TYPE_HEX16, &ADC12CTL1 },
	{ "adcmem0",    PARAM_TYPE_HEX16, &ADC12MEM0},
	{ "adcmem1",    PARAM_TYPE_HEX16, &ADC12MEM1},
	{ "adcmem2",    PARAM_TYPE_HEX16, &ADC12MEM2},
	{ "adcmemctl",    PARAM_TYPE_HEX8, &ADC12MCTL0},
	{ "adciv",    PARAM_TYPE_HEX16, &ADC12IV},
	{ "adcifg",    PARAM_TYPE_HEX16, &ADC12IFG},
	{ "adcie",    PARAM_TYPE_HEX16, &ADC12IE},
	{ "adcifgcount",    PARAM_TYPE_HEX16, &adcifg_count},
	//	{ "p6dir",    PARAM_TYPE_HEX8, &P6DIR},
	//	{ "p6sel",    PARAM_TYPE_HEX8, &P6SEL},
	{ NULL, 0, NULL }
    };
    const struct Param s_DMARegs[] = {
	{ "dmactl0",    PARAM_TYPE_HEX16, &DMACTL0 },
	{ "dmactl1",    PARAM_TYPE_HEX16, &DMACTL1 },
	{ "dma0ctl",    PARAM_TYPE_HEX16, &DMA0CTL},
	{ "dma1ctl",    PARAM_TYPE_HEX16, &DMA1CTL},
	{ "dma2ctl",    PARAM_TYPE_HEX16, &DMA2CTL},
	{ "dma0sa",    PARAM_TYPE_HEX16, &DMA0SA},
	{ "dma0da",    PARAM_TYPE_HEX16, &DMA0DA},
	{ "dma0sz",    PARAM_TYPE_HEX16, &DMA0SZ},
	{ "dma1sa",    PARAM_TYPE_HEX16, &DMA1SA},
	{ "dma1da",    PARAM_TYPE_HEX16, &DMA1DA},
	{ "dma1sz",    PARAM_TYPE_HEX16, &DMA1SZ},
	{ "dma2sa",    PARAM_TYPE_HEX16, &DMA2SA},
	{ "dma2da",    PARAM_TYPE_HEX16, &DMA2DA},
	{ "dma2sz",    PARAM_TYPE_HEX16, &DMA2SZ},
	{ NULL, 0, NULL }
    };

    const struct Param s_DMA0Output[] = {
	{ "status",    PARAM_TYPE_HEX8, &status },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[0] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[1] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[2] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[3] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[4] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[5] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[6] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[7] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[8] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[9] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[10] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[11] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[12] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[13] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[14] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[15] },
	{ "",    PARAM_TYPE_HEX16, &inbuf0[16] },
	{ NULL, 0, NULL }
    };
    const struct Param s_DMA1Output[] = {
	{ "",    PARAM_TYPE_HEX16, &inbuf1[0] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[1] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[2] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[3] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[4] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[5] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[6] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[7] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[8] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[9] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[10] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[11] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[12] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[13] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[14] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[15] },
	{ "",    PARAM_TYPE_HEX16, &inbuf1[16] },
	{ NULL, 0, NULL }
    };
    const struct Param s_DMA2Output[] = {
	{ "",    PARAM_TYPE_HEX16, &inbuf2[0] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[1] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[2] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[3] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[4] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[5] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[6] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[7] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[8] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[9] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[10] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[11] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[12] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[13] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[14] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[15] },
	{ "",    PARAM_TYPE_HEX16, &inbuf2[16] },
	{ NULL, 0, NULL }
    };

    struct ParamList g_ADCRegsList = { "adcregs", &s_ADCRegs[0] };
    struct ParamList g_DMA0OutList = { "output0", &s_DMA0Output[0] };
    struct ParamList g_DMA1OutList = { "output1", &s_DMA1Output[0] };
    struct ParamList g_DMA2OutList = { "output2", &s_DMA2Output[0] };
    struct ParamList g_DMARegsList = { "dmaregs", &s_DMARegs[0] };
*/
/*    command result_t ParamView.init(){
      signal ParamView.add( &g_ADCRegsList );
      signal ParamView.add( &g_DMARegsList );
      signal ParamView.add( &g_DMA0OutList );
      signal ParamView.add( &g_DMA1OutList );
      signal ParamView.add( &g_DMA2OutList );
      return SUCCESS;
    }
*/
}



More information about the Tinyos-contrib-commits mailing list