[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