[Tinyos-commits] CVS: tinyos-1.x/tos/platform/msp430/dma
HPLDMAChannelControl.nc, NONE, 1.1 HPLDMAControl.nc, NONE,
1.1 HPLDMAM.nc, NONE, 1.1 MSP430DMA.h, NONE, 1.1 MSP430DMA.nc,
NONE, 1.1 MSP430DMAC.nc, NONE, 1.1 MSP430DMAControl.nc, NONE,
1.1 MSP430DMAM.nc, NONE, 1.1
Joe Polastre
jpolastre at users.sourceforge.net
Wed Sep 28 03:41:13 PDT 2005
- Previous message: [Tinyos-commits]
CVS: tinyos-1.x/tos/platform/telosb .platform, 1.4, 1.5
- Next message: [Tinyos-commits] CVS: tinyos-1.x/tos/platform/msp430/adc ADCC.nc,
NONE, 1.1 ADCHIL.h, NONE, 1.1 ADCM.nc, NONE,
1.1 ADCMultiple.nc, NONE, 1.1 ADCSingle.nc, NONE,
1.1 ADC_README, NONE, 1.1 DemoSensorC.nc, NONE,
1.1 HPLADC12.nc, NONE, 1.1 HPLADC12M.nc, NONE,
1.1 InternalTemp.h, NONE, 1.1 InternalTempC.nc, NONE,
1.1 InternalTempM.nc, NONE, 1.1 InternalVoltage.h, NONE,
1.1 InternalVoltageC.nc, NONE, 1.1 InternalVoltageM.nc, NONE,
1.1 MSP430ADC12.h, NONE, 1.1 MSP430ADC12C.nc, NONE,
1.1 MSP430ADC12M.nc, NONE, 1.1 MSP430ADC12Multiple.nc, NONE,
1.1 MSP430ADC12Single.nc, NONE, 1.1 Voltage.h, NONE,
1.1 VoltageM.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/tos/platform/msp430/dma
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30738/msp430/dma
Added Files:
HPLDMAChannelControl.nc HPLDMAControl.nc HPLDMAM.nc
MSP430DMA.h MSP430DMA.nc MSP430DMAC.nc MSP430DMAControl.nc
MSP430DMAM.nc
Log Message:
complete reorganization of ADC to support DMA and DAC modules
Changes to the ADC include:
The ADC no longer directly accesses TimerA. Instead it uses
the TimerExclusive interface in MSP430TimerAExclusive to gain
exclusive lock on TimerA. It releases TimerA when it is done.
This is necessary for other components that would like to use
TimerA to do so, such as the DAC.
Commands for the DMA have been added to the MSP430Single and
MSP430Multiple ADC interfaces. These include startSampling,
stopSampling, pauseSampling, and resumeSampling. They should only
be used in conjunction with the DMA and never as standalone functions.
A TinyOS driver for the DAC is being committed that uses the
newly created TimerExclusive interface to get access to TimerA.
It also supports DMA use.
The DMA has been rearchitected to follow the namespace of the other
components with minor bug fixes.
The ADC, DAC, and DMA have been moved to their own subdirectories to
make life easier when viewing the msp430 platform. Platforms that
rely on these components must now include the following lines in the
@opts section of their .platform file:
-I%T/platform/msp430/adc
-I%T/platform/msp430/dac
-I%T/platform/msp430/dma
A sample application is being checked in to
apps/TestMSP430DMA/
that includes TestADC12DMAC for reading multiple samples from the ADC
and also TestDAC12DMAC for sending multiple readings via the DAC
Although I spearheaded much of the DAC efforts, credit goes to
Ben Greenstein for fixes to the ADC and much of the DMA code that I based
this new implementation on.
--- NEW FILE: HPLDMAChannelControl.nc ---
//$Id: HPLDMAChannelControl.nc,v 1.1 2005/09/28 10:41:11 jpolastre Exp $
/* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
/**
* @author Ben Greenstein <ben at cs.ucla.edu>
*/
interface HPLDMAChannelControl {
async command result_t setTrigger(dma_trigger_t trigger);
async command void clearTrigger();
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();
async command void disableDMA();
async command void enableInterrupt() ;
async command void disableInterrupt() ;
async command bool interruptPending();
async command bool aborted();
async command void triggerDMA();
async command void setSrc(void *saddr);
async command void setDst(void *daddr);
async command void setSize(uint16_t sz);
async command void setState(dma_channel_state_t s);
async command dma_channel_state_t getState();
async command void reset();
async event void transferDone(result_t success);
}
--- NEW FILE: HPLDMAControl.nc ---
//$Id: HPLDMAControl.nc,v 1.1 2005/09/28 10:41:11 jpolastre Exp $
/* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
includes MSP430DMA;
/**
* @author Ben Greenstein <ben at cs.ucla.edu>
*/
interface HPLDMAControl {
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 setState(dma_state_t s);
async command dma_state_t getState();
async command void reset();
}
--- NEW FILE: HPLDMAM.nc ---
//$Id: HPLDMAM.nc,v 1.1 2005/09/28 10:41:11 jpolastre Exp $
/* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
/**
* @author Ben Greenstein <ben at cs.ucla.edu>
* @author Joe Polastre <info at moteiv.com>
*/
includes MSP430DMA;
module HPLDMAM {
provides {
interface HPLDMAControl as DMAControl;
interface HPLDMAChannelControl as DMAChannelCtrl0;
interface HPLDMAChannelControl as DMAChannelCtrl1;
interface HPLDMAChannelControl as DMAChannelCtrl2;
}
}
implementation {
MSP430REG_NORACE(DMACTL0);
MSP430REG_NORACE(DMACTL1);
MSP430REG_NORACE(DMA0CTL);
MSP430REG_NORACE(DMA0SA);
MSP430REG_NORACE(DMA0DA);
MSP430REG_NORACE(DMA0SZ);
MSP430REG_NORACE(DMA1CTL);
MSP430REG_NORACE(DMA1SA);
MSP430REG_NORACE(DMA1DA);
MSP430REG_NORACE(DMA1SZ);
MSP430REG_NORACE(DMA2CTL);
MSP430REG_NORACE(DMA2SA);
MSP430REG_NORACE(DMA2DA);
MSP430REG_NORACE(DMA2SZ);
TOSH_SIGNAL(DACDMA_VECTOR) {
// DMAIFG flags are not reset automatically and must be reset by software
if (DMA0CTL & DMAIFG) {
DMA0CTL &= ~DMAIFG;
if (DMA0CTL & DMAABORT){
DMA0CTL &= ~DMAABORT;
signal DMAChannelCtrl0.transferDone(FAIL);
}
else signal DMAChannelCtrl0.transferDone(SUCCESS);
}
if (DMA1CTL & DMAIFG) {
DMA1CTL &= ~DMAIFG;
if (DMA1CTL & DMAABORT){
DMA1CTL &= ~DMAABORT;
signal DMAChannelCtrl1.transferDone(FAIL);
}
else signal DMAChannelCtrl1.transferDone(SUCCESS);
}
if (DMA2CTL& DMAIFG) {
DMA2CTL &= ~DMAIFG;
if (DMA2CTL & DMAABORT){
DMA2CTL &= ~DMAABORT;
signal DMAChannelCtrl2.transferDone(FAIL);
}
else signal DMAChannelCtrl2.transferDone(SUCCESS);
}
}
// ----------------------------------------------------------
// DMA Control
// ----------------------------------------------------------
// Should a DMA transfer occur immediately (FALSE),
// on the next instruction fetch after the trigger (TRUE)
async command void DMAControl.setOnFetch(){
DMACTL1 |= DMAONFETCH;
}
async command void DMAControl.clearOnFetch(){
DMACTL1 &= ~(DMAONFETCH);
}
// Should the DMA channel priority be 0, 1, 2 (FALSE), or
// should it change with each transfer (TRUE)
async command void DMAControl.setRoundRobin(){
DMACTL1 |= ROUNDROBIN;
}
async command void DMAControl.clearRoundRobin(){
DMACTL1 &= ~(ROUNDROBIN);
}
// This 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 DMAControl.setENNMI(){
DMACTL1 |= ENNMI;
}
async command void DMAControl.clearENNMI(){
DMACTL1 &= ~(ENNMI);
}
async command void DMAControl.setState(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 DMAControl.getState(){
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;
}
async command void DMAControl.reset(){
DMACTL0 = 0;
DMACTL1 = 0;
}
// ----------------------------------------------------------
// DMA Channel 0 Control
// ----------------------------------------------------------
// ----- DMA Trigger Mode -----
async command result_t DMAChannelCtrl0.setTrigger(dma_trigger_t trigger){
result_t res = SUCCESS;
if (DMA0CTL & DMAEN) res = FAIL;
else {
DMACTL0 &= ~(DMA0TSEL0 | DMA0TSEL1 | DMA0TSEL2 | DMA0TSEL3);
DMACTL0 |= ((DMATSEL_MASK & trigger)<<DMA0TSEL_SHIFT);
}
return res;
}
async command void DMAChannelCtrl0.clearTrigger(){
DMACTL0 &= ~(DMA0TSEL0 | DMA0TSEL1 | DMA0TSEL2 | DMA0TSEL3);
}
// ----- DMA Transfer Mode -----
async command void DMAChannelCtrl0.setSingleMode(){
DMA0CTL &= ~(DMADT0 | DMADT1 | DMADT2);
}
async command void DMAChannelCtrl0.setBlockMode(){
DMA0CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA0CTL |= DMADT0;
}
async command void DMAChannelCtrl0.setBurstMode(){
DMA0CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA0CTL |= DMADT1;
}
async command void DMAChannelCtrl0.setRepeatedSingleMode(){
DMA0CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA0CTL |= DMADT2;
}
async command void DMAChannelCtrl0.setRepeatedBlockMode(){
DMA0CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA0CTL |= (DMADT2 | DMADT0);
}
async command void DMAChannelCtrl0.setRepeatedBurstMode(){
DMA0CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA0CTL |= (DMADT2 | DMADT1);
}
// ----- DMA Address Incrementation -----
async command void DMAChannelCtrl0.setSrcNoIncrement(){
DMA0CTL &= ~(DMASRCINCR0 | DMASRCINCR1);
}
async command void DMAChannelCtrl0.setSrcDecrement(){
DMA0CTL |= DMASRCINCR1;
}
async command void DMAChannelCtrl0.setSrcIncrement(){
DMA0CTL |= (DMASRCINCR0 | DMASRCINCR1);
}
async command void DMAChannelCtrl0.setDstNoIncrement(){
DMA0CTL &= ~(DMADSTINCR0 | DMADSTINCR1);
}
async command void DMAChannelCtrl0.setDstDecrement(){
DMA0CTL |= DMADSTINCR1;
}
async command void DMAChannelCtrl0.setDstIncrement(){
DMA0CTL |= (DMADSTINCR0 | DMADSTINCR1);
}
// ----- DMA Word Size Mode -----
async command void DMAChannelCtrl0.setWordToWord(){
DMA0CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA0CTL |= DMASWDW;
}
async command void DMAChannelCtrl0.setByteToWord(){
DMA0CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA0CTL |= DMASBDW;
}
async command void DMAChannelCtrl0.setWordToByte(){
DMA0CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA0CTL |= DMASWDB;
}
async command void DMAChannelCtrl0.setByteToByte(){
DMA0CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA0CTL |= DMASBDB;
}
// ----- DMA Level -----
async command void DMAChannelCtrl0.setEdgeSensitive(){
DMA0CTL &= ~DMALEVEL;
}
async command void DMAChannelCtrl0.setLevelSensitive(){
DMA0CTL |= DMALEVEL;
}
// ----- DMA Enable -----
async command void DMAChannelCtrl0.enableDMA(){ DMA0CTL |= DMAEN; }
async command void DMAChannelCtrl0.disableDMA(){ DMA0CTL &= ~DMAEN; }
// ----- DMA Interrupt -----
async command void DMAChannelCtrl0.enableInterrupt() {
DMA0CTL |= DMAIE;
}
async command void DMAChannelCtrl0.disableInterrupt() {
DMA0CTL &= ~DMAIE;
}
async command bool DMAChannelCtrl0.interruptPending(){
bool ret = FALSE;
if (DMA0CTL & DMAIFG) ret = TRUE;
return ret;
}
// ----- DMA Abort -----
// todo: should this trigger an interrupt
async command bool DMAChannelCtrl0.aborted(){
bool ret = FALSE;
if (DMA0CTL & DMAABORT) ret = TRUE;
return ret;
}
// ----- DMA Software Request -----
async command void DMAChannelCtrl0.triggerDMA() { DMA0CTL |= DMAREQ; }
// ----- DMA Source Address -----
async command void DMAChannelCtrl0.setSrc(void *saddr){
DMA0SA = (uint16_t)saddr;
}
// ----- DMA Destination Address ----
async command void DMAChannelCtrl0.setDst(void *daddr){
DMA0DA = (uint16_t)daddr;
}
// ----- DMA Destination Address ----
async command void DMAChannelCtrl0.setSize(uint16_t sz){
DMA0SZ = sz;
}
async command void DMAChannelCtrl0.setState(dma_channel_state_t s){
uint16_t dmactl0 = DMACTL0;
uint16_t dma0ctl = 0;
dmactl0 |= ((s.trigger & DMATSEL_MASK) << DMA0TSEL_SHIFT);
dma0ctl |= (s.request ? DMAREQ : 0);
dma0ctl |= (s.abort ? DMAABORT : 0);
dma0ctl |= (s.interruptEnable ? DMAIE : 0);
dma0ctl |= (s.interruptFlag ? DMAIFG : 0);
dma0ctl |= (s.enable ? DMAEN : 0);
dma0ctl |= (s.level ? DMALEVEL : 0);
dma0ctl |= (s.srcByte ? DMASRCBYTE : 0);
dma0ctl |= (s.dstByte ? DMADSTBYTE : 0);
dma0ctl |= ((s.srcIncrement & DMAINCR_MASK) << DMASRCINCR_SHIFT);
dma0ctl |= ((s.dstIncrement & DMAINCR_MASK) << DMADSTINCR_SHIFT);
dma0ctl |= ((s.transferMode & DMADT_MASK) << DMADT_SHIFT);
DMA0SA = (uint16_t)(s.srcAddr);
//DMA0SA = ADC12MEM_;
DMA0DA = (uint16_t)(s.dstAddr);
DMA0SZ = s.size;
DMACTL0 = dmactl0;
DMA0CTL= dma0ctl;
return;
}
async command dma_channel_state_t DMAChannelCtrl0.getState(){
dma_channel_state_t s;
s.trigger = ((DMACTL0 >> DMA0TSEL_SHIFT) & DMATSEL_MASK);
s.reserved = 0;
s.request = (DMA0CTL & DMAREQ ? 1 : 0);
s.abort = (DMA0CTL & DMAABORT ? 1 : 0);
s.interruptEnable = (DMA0CTL & DMAIE ? 1 : 0);
s.interruptFlag = (DMA0CTL & DMAIFG ? 1 : 0);
s.enable = (DMA0CTL & DMAEN ? 1 : 0);
s.level = (DMA0CTL & DMALEVEL ? 1 : 0);
s.srcByte = (DMA0CTL & DMASRCBYTE ? 1 : 0);
s.dstByte = (DMA0CTL & DMADSTBYTE ? 1 : 0);
s.srcIncrement = ((DMA0CTL >> DMASRCINCR_SHIFT) & DMAINCR_MASK);
s.dstIncrement = ((DMA0CTL >> DMADSTINCR_SHIFT) & DMAINCR_MASK);
s.reserved2 = 0;
s.transferMode = ((DMA0CTL >> DMADT_SHIFT) & DMADT_MASK);
s.srcAddr = (void *)DMA0SA;
s.dstAddr = (void *)DMA0DA;
s.size = DMA0SZ;
}
async command void DMAChannelCtrl0.reset(){
DMA0CTL = 0;
DMA0SA = 0;
DMA0DA = 0;
DMA0SZ = 0;
}
// ----------------------------------------------------------
// DMA Channel 1 Control
// ----------------------------------------------------------
// ----- DMA Trigger Mode -----
async command result_t DMAChannelCtrl1.setTrigger(dma_trigger_t trigger){
result_t res = SUCCESS;
if (DMA1CTL & DMAEN) res = FAIL;
else {
DMACTL0 &= ~(DMA1TSEL0 | DMA1TSEL1 | DMA1TSEL2 | DMA1TSEL3);
DMACTL0 |= ((DMATSEL_MASK & trigger)<<DMA1TSEL_SHIFT);
}
return res;
}
async command void DMAChannelCtrl1.clearTrigger(){
DMACTL0 &= ~(DMA1TSEL0 | DMA1TSEL1 | DMA1TSEL2 | DMA1TSEL3);
}
// ----- DMA Transfer Mode -----
async command void DMAChannelCtrl1.setSingleMode(){
DMA1CTL &= ~(DMADT0 | DMADT1 | DMADT2);
}
async command void DMAChannelCtrl1.setBlockMode(){
DMA1CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA1CTL |= DMADT0;
}
async command void DMAChannelCtrl1.setBurstMode(){
DMA1CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA1CTL |= DMADT1;
}
async command void DMAChannelCtrl1.setRepeatedSingleMode(){
DMA1CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA1CTL |= DMADT2;
}
async command void DMAChannelCtrl1.setRepeatedBlockMode(){
DMA1CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA1CTL |= (DMADT2 | DMADT0);
}
async command void DMAChannelCtrl1.setRepeatedBurstMode(){
DMA1CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA1CTL |= (DMADT2 | DMADT1);
}
// ----- DMA Address Incrementation -----
async command void DMAChannelCtrl1.setSrcNoIncrement(){
DMA1CTL &= ~(DMASRCINCR0 | DMASRCINCR1);
}
async command void DMAChannelCtrl1.setSrcDecrement(){
DMA1CTL |= DMASRCINCR1;
}
async command void DMAChannelCtrl1.setSrcIncrement(){
DMA1CTL |= (DMASRCINCR0 | DMASRCINCR1);
}
async command void DMAChannelCtrl1.setDstNoIncrement(){
DMA1CTL &= ~(DMADSTINCR0 | DMADSTINCR1);
}
async command void DMAChannelCtrl1.setDstDecrement(){
DMA1CTL |= DMADSTINCR1;
}
async command void DMAChannelCtrl1.setDstIncrement(){
DMA1CTL |= (DMADSTINCR0 | DMADSTINCR1);
}
// ----- DMA Word Size Mode -----
async command void DMAChannelCtrl1.setWordToWord(){
DMA1CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA1CTL |= DMASWDW;
}
async command void DMAChannelCtrl1.setByteToWord(){
DMA1CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA1CTL |= DMASBDW;
}
async command void DMAChannelCtrl1.setWordToByte(){
DMA1CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA1CTL |= DMASWDB;
}
async command void DMAChannelCtrl1.setByteToByte(){
DMA1CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA1CTL |= DMASBDB;
}
// ----- DMA Level -----
async command void DMAChannelCtrl1.setEdgeSensitive(){
DMA1CTL &= ~DMALEVEL;
}
async command void DMAChannelCtrl1.setLevelSensitive(){
DMA1CTL |= DMALEVEL;
}
// ----- DMA Enable -----
async command void DMAChannelCtrl1.enableDMA(){ DMA1CTL |= DMAEN; }
async command void DMAChannelCtrl1.disableDMA(){ DMA1CTL &= ~DMAEN; }
// ----- DMA Interrupt -----
async command void DMAChannelCtrl1.enableInterrupt() {
DMA1CTL |= DMAIE;
}
async command void DMAChannelCtrl1.disableInterrupt() {
DMA1CTL &= ~DMAIE;
}
async command bool DMAChannelCtrl1.interruptPending(){
bool ret = FALSE;
if (DMA1CTL & DMAIFG) ret = TRUE;
return ret;
}
// ----- DMA Abort -----
// todo: should this trigger an interrupt
async command bool DMAChannelCtrl1.aborted(){
bool ret = FALSE;
if (DMA1CTL & DMAABORT) ret = TRUE;
return ret;
}
// ----- DMA Software Request -----
async command void DMAChannelCtrl1.triggerDMA() { DMA1CTL |= DMAREQ; }
// ----- DMA Source Address -----
async command void DMAChannelCtrl1.setSrc(void *saddr){
DMA1SA = (uint16_t)saddr;
}
// ----- DMA Destination Address ----
async command void DMAChannelCtrl1.setDst(void *daddr){
DMA1DA = (uint16_t)daddr;
}
// ----- DMA Destination Address ----
async command void DMAChannelCtrl1.setSize(uint16_t sz){
DMA1SZ = sz;
}
async command void DMAChannelCtrl1.setState(dma_channel_state_t s){
uint16_t dmactl0 = DMACTL0;
uint16_t dma1ctl = 0;
dmactl0 |= ((s.trigger & DMATSEL_MASK) << DMA1TSEL_SHIFT);
dma1ctl |= (s.request ? DMAREQ : 0);
dma1ctl |= (s.abort ? DMAABORT : 0);
dma1ctl |= (s.interruptEnable ? DMAIE : 0);
dma1ctl |= (s.interruptFlag ? DMAIFG : 0);
dma1ctl |= (s.enable ? DMAEN : 0);
dma1ctl |= (s.level ? DMALEVEL : 0);
dma1ctl |= (s.srcByte ? DMASRCBYTE : 0);
dma1ctl |= (s.dstByte ? DMADSTBYTE : 0);
dma1ctl |= ((s.srcIncrement & DMAINCR_MASK) << DMASRCINCR_SHIFT);
dma1ctl |= ((s.dstIncrement & DMAINCR_MASK) << DMADSTINCR_SHIFT);
dma1ctl |= ((s.transferMode & DMADT_MASK) << DMADT_SHIFT);
DMA1SA = (uint16_t)(s.srcAddr);
DMA1DA = (uint16_t)(s.dstAddr);
DMA1SZ = s.size;
DMACTL0 = dmactl0;
DMA1CTL= dma1ctl;
return;
}
async command dma_channel_state_t DMAChannelCtrl1.getState(){
dma_channel_state_t s;
s.trigger = ((DMACTL0 >> DMA1TSEL_SHIFT) & DMATSEL_MASK);
s.reserved = 0;
s.request = (DMA1CTL & DMAREQ ? 1 : 0);
s.abort = (DMA1CTL & DMAABORT ? 1 : 0);
s.interruptEnable = (DMA1CTL & DMAIE ? 1 : 0);
s.interruptFlag = (DMA1CTL & DMAIFG ? 1 : 0);
s.enable = (DMA1CTL & DMAEN ? 1 : 0);
s.level = (DMA1CTL & DMALEVEL ? 1 : 0);
s.srcByte = (DMA1CTL & DMASRCBYTE ? 1 : 0);
s.dstByte = (DMA1CTL & DMADSTBYTE ? 1 : 0);
s.srcIncrement = ((DMA1CTL >> DMASRCINCR_SHIFT) & DMAINCR_MASK);
s.dstIncrement = ((DMA1CTL >> DMADSTINCR_SHIFT) & DMAINCR_MASK);
s.reserved2 = 0;
s.transferMode = ((DMA1CTL >> DMADT_SHIFT) & DMADT_MASK);
s.srcAddr = (void *)DMA1SA;
s.dstAddr = (void *)DMA1DA;
s.size = DMA1SZ;
}
async command void DMAChannelCtrl1.reset(){
DMA1CTL = 0;
DMA1SA = 0;
DMA1DA = 0;
DMA1SZ = 0;
}
// ----------------------------------------------------------
// DMA Channel 2 Control
// ----------------------------------------------------------
// ----- DMA Trigger Mode -----
async command result_t DMAChannelCtrl2.setTrigger(dma_trigger_t trigger){
result_t res = SUCCESS;
if (DMA2CTL & DMAEN) res = FAIL;
else {
DMACTL0 &= ~(DMA2TSEL0 | DMA2TSEL1 | DMA2TSEL2 | DMA2TSEL3);
DMACTL0 |= ((DMATSEL_MASK & trigger)<<DMA2TSEL_SHIFT);
}
return res;
}
async command void DMAChannelCtrl2.clearTrigger(){
DMACTL0 &= ~(DMA2TSEL0 | DMA2TSEL1 | DMA2TSEL2 | DMA2TSEL3);
}
// ----- DMA Transfer Mode -----
async command void DMAChannelCtrl2.setSingleMode(){
DMA2CTL &= ~(DMADT0 | DMADT1 | DMADT2);
}
async command void DMAChannelCtrl2.setBlockMode(){
DMA2CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA2CTL |= DMADT0;
}
async command void DMAChannelCtrl2.setBurstMode(){
DMA2CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA2CTL |= DMADT1;
}
async command void DMAChannelCtrl2.setRepeatedSingleMode(){
DMA2CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA2CTL |= DMADT2;
}
async command void DMAChannelCtrl2.setRepeatedBlockMode(){
DMA2CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA2CTL |= (DMADT2 | DMADT0);
}
async command void DMAChannelCtrl2.setRepeatedBurstMode(){
DMA2CTL &= ~(DMADT0 | DMADT1 | DMADT2);
DMA2CTL |= (DMADT2 | DMADT1);
}
// ----- DMA Address Incrementation -----
async command void DMAChannelCtrl2.setSrcNoIncrement(){
DMA2CTL &= ~(DMASRCINCR0 | DMASRCINCR1);
}
async command void DMAChannelCtrl2.setSrcDecrement(){
DMA2CTL |= DMASRCINCR1;
}
async command void DMAChannelCtrl2.setSrcIncrement(){
DMA2CTL |= (DMASRCINCR0 | DMASRCINCR1);
}
async command void DMAChannelCtrl2.setDstNoIncrement(){
DMA2CTL &= ~(DMADSTINCR0 | DMADSTINCR1);
}
async command void DMAChannelCtrl2.setDstDecrement(){
DMA2CTL |= DMADSTINCR1;
}
async command void DMAChannelCtrl2.setDstIncrement(){
DMA2CTL |= (DMADSTINCR0 | DMADSTINCR1);
}
// ----- DMA Word Size Mode -----
async command void DMAChannelCtrl2.setWordToWord(){
DMA2CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA2CTL |= DMASWDW;
}
async command void DMAChannelCtrl2.setByteToWord(){
DMA2CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA2CTL |= DMASBDW;
}
async command void DMAChannelCtrl2.setWordToByte(){
DMA2CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA2CTL |= DMASWDB;
}
async command void DMAChannelCtrl2.setByteToByte(){
DMA2CTL &= ~(DMASRCBYTE | DMADSTBYTE);
DMA2CTL |= DMASBDB;
}
// ----- DMA Level -----
async command void DMAChannelCtrl2.setEdgeSensitive(){
DMA2CTL &= ~DMALEVEL;
}
async command void DMAChannelCtrl2.setLevelSensitive(){
DMA2CTL |= DMALEVEL;
}
// ----- DMA Enable -----
async command void DMAChannelCtrl2.enableDMA(){ DMA2CTL |= DMAEN; }
async command void DMAChannelCtrl2.disableDMA(){ DMA2CTL &= ~DMAEN; }
// ----- DMA Interrupt -----
async command void DMAChannelCtrl2.enableInterrupt() {
DMA2CTL |= DMAIE;
}
async command void DMAChannelCtrl2.disableInterrupt() {
DMA2CTL &= ~DMAIE;
}
async command bool DMAChannelCtrl2.interruptPending(){
bool ret = FALSE;
if (DMA2CTL & DMAIFG) ret = TRUE;
return ret;
}
// ----- DMA Abort -----
// todo: should this trigger an interrupt
async command bool DMAChannelCtrl2.aborted(){
bool ret = FALSE;
if (DMA2CTL & DMAABORT) ret = TRUE;
return ret;
}
// ----- DMA Software Request -----
async command void DMAChannelCtrl2.triggerDMA() { DMA2CTL |= DMAREQ; }
// ----- DMA Source Address -----
async command void DMAChannelCtrl2.setSrc(void *saddr){
DMA2SA = (uint16_t)saddr;
}
// ----- DMA Destination Address ----
async command void DMAChannelCtrl2.setDst(void *daddr){
DMA2DA = (uint16_t)daddr;
}
// ----- DMA Destination Address ----
async command void DMAChannelCtrl2.setSize(uint16_t sz){
DMA2SZ = sz;
}
async command void DMAChannelCtrl2.setState(dma_channel_state_t s){
uint16_t dmactl0 = DMACTL0;
uint16_t dma2ctl = 0;
dmactl0 |= ((s.trigger & DMATSEL_MASK) << DMA2TSEL_SHIFT);
dma2ctl |= (s.request ? DMAREQ : 0);
dma2ctl |= (s.abort ? DMAABORT : 0);
dma2ctl |= (s.interruptEnable ? DMAIE : 0);
dma2ctl |= (s.interruptFlag ? DMAIFG : 0);
dma2ctl |= (s.enable ? DMAEN : 0);
dma2ctl |= (s.level ? DMALEVEL : 0);
dma2ctl |= (s.srcByte ? DMASRCBYTE : 0);
dma2ctl |= (s.dstByte ? DMADSTBYTE : 0);
dma2ctl |= ((s.srcIncrement & DMAINCR_MASK) << DMASRCINCR_SHIFT);
dma2ctl |= ((s.dstIncrement & DMAINCR_MASK) << DMADSTINCR_SHIFT);
dma2ctl |= ((s.transferMode & DMADT_MASK) << DMADT_SHIFT);
DMA2SA = (uint16_t)(s.srcAddr);
DMA2DA = (uint16_t)(s.dstAddr);
DMA2SZ = s.size;
DMACTL0 = dmactl0;
DMA2CTL= dma2ctl;
return;
}
async command dma_channel_state_t DMAChannelCtrl2.getState(){
dma_channel_state_t s;
s.trigger = ((DMACTL0 >> DMA2TSEL_SHIFT) & DMATSEL_MASK);
s.reserved = 0;
s.request = (DMA2CTL & DMAREQ ? 1 : 0);
s.abort = (DMA2CTL & DMAABORT ? 1 : 0);
s.interruptEnable = (DMA2CTL & DMAIE ? 1 : 0);
s.interruptFlag = (DMA2CTL & DMAIFG ? 1 : 0);
s.enable = (DMA2CTL & DMAEN ? 1 : 0);
s.level = (DMA2CTL & DMALEVEL ? 1 : 0);
s.srcByte = (DMA2CTL & DMASRCBYTE ? 1 : 0);
s.dstByte = (DMA2CTL & DMADSTBYTE ? 1 : 0);
s.srcIncrement = ((DMA2CTL >> DMASRCINCR_SHIFT) & DMAINCR_MASK);
s.dstIncrement = ((DMA2CTL >> DMADSTINCR_SHIFT) & DMAINCR_MASK);
s.reserved2 = 0;
s.transferMode = ((DMA2CTL >> DMADT_SHIFT) & DMADT_MASK);
s.srcAddr = (void *)DMA2SA;
s.dstAddr = (void *)DMA2DA;
s.size = DMA2SZ;
}
async command void DMAChannelCtrl2.reset(){
DMA2CTL = 0;
DMA2SA = 0;
DMA2DA = 0;
DMA2SZ = 0;
}
}
--- NEW FILE: MSP430DMA.h ---
/* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
//@author Ben Greenstein <ben at cs.ucla.edu>
#ifndef MSP430DMA_H
#define MSP430DMA_H
enum {
DMA_CHANNELS = 3
};
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 dma_channel_state_s {
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;
void *srcAddr;
void *dstAddr;
unsigned int size;
} __attribute__ ((packed)) dma_channel_state_t;
#endif
--- NEW FILE: MSP430DMA.nc ---
//$Id: MSP430DMA.nc,v 1.1 2005/09/28 10:41:11 jpolastre Exp $
/* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
/**
* @author Ben Greenstein <ben at cs.ucla.edu>
*/
includes MSP430DMA;
interface MSP430DMA {
async command result_t setupTransfer(dma_transfer_mode_t transfer_mode,
dma_trigger_t trigger,
dma_level_t level,
void *src_addr,
void *dst_addr,
uint16_t size,
dma_byte_t src_byte,
dma_byte_t dst_byte,
dma_incr_t src_incr,
dma_incr_t dst_incr);
async command result_t startTransfer();
async command result_t repeatTransfer (void *src_addr,
void *dst_addr,
uint16_t size);
async command result_t softwareTrigger();
async command result_t stopTransfer();
async event void transferDone(result_t success);
}
--- NEW FILE: MSP430DMAC.nc ---
//$Id: MSP430DMAC.nc,v 1.1 2005/09/28 10:41:11 jpolastre Exp $
/* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
/**
* @author Ben Greenstein <ben at cs.ucla.edu>
*/
configuration MSP430DMAC {
provides {
interface MSP430DMA[uint8_t channel];
interface MSP430DMAControl;
}
}
implementation {
components MSP430DMAM, HPLDMAM;
MSP430DMA = MSP430DMAM;
MSP430DMAControl = MSP430DMAM;
MSP430DMAM.HPLDMAControl -> HPLDMAM.DMAControl;
MSP430DMAM.DMAChannelCtrl0 -> HPLDMAM.DMAChannelCtrl0;
MSP430DMAM.DMAChannelCtrl1 -> HPLDMAM.DMAChannelCtrl1;
MSP430DMAM.DMAChannelCtrl2 -> HPLDMAM.DMAChannelCtrl2;
}
--- NEW FILE: MSP430DMAControl.nc ---
//$Id: MSP430DMAControl.nc,v 1.1 2005/09/28 10:41:11 jpolastre Exp $
/* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
/**
* @author Ben Greenstein <ben at cs.ucla.edu>
*/
includes MSP430DMA;
interface MSP430DMAControl {
async command void init();
async command void setFlags(bool enable_nmi,
bool round_robin,
bool on_fetch);
}
--- NEW FILE: MSP430DMAM.nc ---
/* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
//@author Ben Greenstein <ben at cs.ucla.edu>
includes MSP430DMA;
module MSP430DMAM {
provides {
interface MSP430DMAControl as DMAControl;
interface MSP430DMA as DMA[uint8_t channel];
}
uses {
interface HPLDMAControl;
interface HPLDMAChannelControl as DMAChannelCtrl0;
interface HPLDMAChannelControl as DMAChannelCtrl1;
interface HPLDMAChannelControl as DMAChannelCtrl2;
}
}
implementation {
norace dma_channel_state_t gChannelState[DMA_CHANNELS];
async command void DMAControl.init(){
call HPLDMAControl.reset();
call DMAChannelCtrl0.reset();
call DMAChannelCtrl1.reset();
call DMAChannelCtrl2.reset();
}
async command void DMAControl.setFlags(bool enable_nmi,
bool round_robin,
bool on_fetch){
// NOTE: on_fetch must be true when dst addr is flash
if (enable_nmi) call HPLDMAControl.setENNMI();
else call HPLDMAControl.clearENNMI();
if (round_robin) call HPLDMAControl.setRoundRobin();
else call HPLDMAControl.clearRoundRobin();
if (on_fetch) call HPLDMAControl.setOnFetch();
else call HPLDMAControl.clearOnFetch();
}
async command result_t DMA.setupTransfer[uint8_t channel]
(dma_transfer_mode_t transfer_mode,
dma_trigger_t trigger,
dma_level_t level,
void *src_addr, void *dst_addr, uint16_t size,
dma_byte_t src_byte, dma_byte_t dst_byte,
dma_incr_t src_incr, dma_incr_t dst_incr){
if (channel >= DMA_CHANNELS) return FAIL;
gChannelState[channel].trigger = trigger;
gChannelState[channel].reserved = 0;
gChannelState[channel].request = 0;
gChannelState[channel].abort = 0;
gChannelState[channel].interruptEnable = 1;
gChannelState[channel].interruptFlag = 0;
gChannelState[channel].enable = 0; /* don't start an xfer */
gChannelState[channel].level = level;
gChannelState[channel].srcByte = src_byte;
gChannelState[channel].dstByte = dst_byte;
gChannelState[channel].srcIncrement = src_incr;
gChannelState[channel].dstIncrement = dst_incr;
gChannelState[channel].transferMode = transfer_mode;
gChannelState[channel].reserved2 = 0;
gChannelState[channel].srcAddr = src_addr;
gChannelState[channel].dstAddr = dst_addr;
gChannelState[channel].size = size;
switch (channel){
case 0:
call DMAChannelCtrl0.setState(gChannelState[0]); break;
case 1:
call DMAChannelCtrl1.setState(gChannelState[1]); break;
case 2:
call DMAChannelCtrl2.setState(gChannelState[2]); break;
default: return FAIL;
}
return SUCCESS;
return SUCCESS;
}
async command result_t DMA.startTransfer[uint8_t channel](){
switch (channel){
case 0: call DMAChannelCtrl0.enableDMA(); break;
case 1: call DMAChannelCtrl1.enableDMA(); break;
case 2: call DMAChannelCtrl2.enableDMA(); break;
default: return FAIL;
}
return SUCCESS;
}
async command result_t DMA.repeatTransfer[uint8_t channel]
( void *src_addr, void *dst_addr, uint16_t size){
if (channel >= DMA_CHANNELS) return FAIL;
if (src_addr != NULL)
gChannelState[channel].srcAddr = src_addr;
if (dst_addr != NULL)
gChannelState[channel].dstAddr = dst_addr;
if (size != 0)
gChannelState[channel].size = size;
switch (channel){
case 0:
call DMAChannelCtrl0.setSrc(gChannelState[0].srcAddr);
call DMAChannelCtrl0.setDst(gChannelState[0].dstAddr);
call DMAChannelCtrl0.setSize(gChannelState[0].size);
call DMAChannelCtrl0.enableDMA();
break;
case 1:
call DMAChannelCtrl1.setSrc(gChannelState[1].srcAddr);
call DMAChannelCtrl1.setDst(gChannelState[1].dstAddr);
call DMAChannelCtrl1.setSize(gChannelState[1].size);
call DMAChannelCtrl1.enableDMA();
break;
case 2:
call DMAChannelCtrl2.setSrc(gChannelState[2].srcAddr);
call DMAChannelCtrl2.setDst(gChannelState[2].dstAddr);
call DMAChannelCtrl2.setSize(gChannelState[2].size);
call DMAChannelCtrl2.enableDMA();
break;
default: return FAIL;
}
return SUCCESS;
}
async command result_t DMA.softwareTrigger[uint8_t channel](){
result_t ret = SUCCESS;
if (channel >= DMA_CHANNELS) return FAIL;
if (gChannelState[channel].trigger != DMA_TRIGGER_DMAREQ) return FAIL;
switch (channel){
case 0: call DMAChannelCtrl0.triggerDMA(); break;
case 1: call DMAChannelCtrl1.triggerDMA(); break;
case 2: call DMAChannelCtrl2.triggerDMA(); break;
default: return FAIL;
}
return SUCCESS;
}
async command result_t DMA.stopTransfer[uint8_t channel](){
if (gChannelState[channel].transferMode == DMA_BURST_BLOCK_TRANSFER &&
gChannelState[channel].transferMode == DMA_REPEATED_BURST_BLOCK_TRANSFER){
switch(channel){
case 0: call DMAChannelCtrl0.disableDMA(); return SUCCESS;
case 1: call DMAChannelCtrl1.disableDMA(); return SUCCESS;
case 2: call DMAChannelCtrl2.disableDMA(); return SUCCESS;
default: return FAIL;
}
}
}
async event void DMAChannelCtrl0.transferDone(result_t success){
signal DMA.transferDone[0](success);
}
async event void DMAChannelCtrl1.transferDone(result_t success){
signal DMA.transferDone[1](success);
}
async event void DMAChannelCtrl2.transferDone(result_t success){
signal DMA.transferDone[2](success);
}
default async event void DMA.transferDone[uint8_t channel](result_t success){
return;
}
}
- Previous message: [Tinyos-commits]
CVS: tinyos-1.x/tos/platform/telosb .platform, 1.4, 1.5
- Next message: [Tinyos-commits] CVS: tinyos-1.x/tos/platform/msp430/adc ADCC.nc,
NONE, 1.1 ADCHIL.h, NONE, 1.1 ADCM.nc, NONE,
1.1 ADCMultiple.nc, NONE, 1.1 ADCSingle.nc, NONE,
1.1 ADC_README, NONE, 1.1 DemoSensorC.nc, NONE,
1.1 HPLADC12.nc, NONE, 1.1 HPLADC12M.nc, NONE,
1.1 InternalTemp.h, NONE, 1.1 InternalTempC.nc, NONE,
1.1 InternalTempM.nc, NONE, 1.1 InternalVoltage.h, NONE,
1.1 InternalVoltageC.nc, NONE, 1.1 InternalVoltageM.nc, NONE,
1.1 MSP430ADC12.h, NONE, 1.1 MSP430ADC12C.nc, NONE,
1.1 MSP430ADC12M.nc, NONE, 1.1 MSP430ADC12Multiple.nc, NONE,
1.1 MSP430ADC12Single.nc, NONE, 1.1 Voltage.h, NONE,
1.1 VoltageM.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-commits
mailing list