[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/handhelds/tos/platform/msp430_crl_base
DMA_M.nc, 1.3, 1.4
steve ayer
ayer1 at users.sourceforge.net
Thu Mar 27 13:09:58 PDT 2008
Update of /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/tos/platform/msp430_crl_base
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv7023
Modified Files:
DMA_M.nc
Log Message:
added many fine-control calls added by stephen linder to this module,
mainly in support of new dma-based sd driver.
Index: DMA_M.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/contrib/handhelds/tos/platform/msp430_crl_base/DMA_M.nc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** DMA_M.nc 7 Sep 2006 18:36:07 -0000 1.3
--- DMA_M.nc 27 Mar 2008 20:09:55 -0000 1.4
***************
*** 35,46 ****
* Authors: Steven Ayer
* April 2005
*/
includes DMA;
!
module DMA_M {
provides interface DMA[uint8_t id];
}
implementation {
MSP430REG_NORACE(DMACTL0);
MSP430REG_NORACE(DMACTL1);
--- 35,53 ----
* 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);
***************
*** 63,66 ****
--- 70,83 ----
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 {
***************
*** 85,94 ****
command void DMA.ADCbeginConversion[uint8_t id]() {
- uint16_t c;
atomic{
ADC12CTL0 |= ENC + ADC12SC; // start conversion
- c = ADC12MEM0; // start with a read
- c = ADC12MEM1; // start with a read
- c = ADC12MEM2; // start with a read
}
}
--- 102,107 ----
***************
*** 152,162 ****
command void DMA.beginTransfer[uint8_t id]() {
! if(id == 0)
SET_FLAG(DMA0CTL, DMAEN + DMAIE); // enabled and interrupt enabled
! else if(id == 1)
SET_FLAG(DMA1CTL, DMAEN + DMAIE); // enabled and interrupt enabled
! else if(id == 2)
SET_FLAG(DMA2CTL, DMAEN + DMAIE); // enabled and interrupt enabled
!
}
--- 165,180 ----
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);
! }
}
***************
*** 232,236 ****
}
! command void DMA.setDestinationAddressIncrement[uint8_t id](enum addressIncrement ai){
if(id == 0){
SET_FLAG(DMA0CTL, ai << 8);
--- 250,254 ----
}
! command void DMA.setDestinationAddressIncrement[uint8_t id](addressIncrement ai){
if(id == 0){
SET_FLAG(DMA0CTL, ai << 8);
***************
*** 244,248 ****
}
! command void DMA.setSourceAddressIncrement[uint8_t id](enum addressIncrement ai) {
if(id == 0){
SET_FLAG(DMA0CTL, ai << 10);
--- 262,266 ----
}
! command void DMA.setSourceAddressIncrement[uint8_t id](addressIncrement ai) {
if(id == 0){
SET_FLAG(DMA0CTL, ai << 10);
***************
*** 308,337 ****
async default event void DMA.transferComplete[uint8_t id](){}
- /*
- TOSH_SIGNAL(DACDMA_VECTOR) {
- volatile uint16_t v = DMA2CTL;
-
- if(v & DMAIFG) {
- DMA2CTL &= ~DMAIFG;
- signal DMA.transferComplete[2]();
- }
- else{
- v = DMA1CTL;
- if(v & DMAIFG) {
- DMA1CTL &= ~DMAIFG;
- signal DMA.transferComplete[1]();
- }
- else{
- v = DMA0CTL;
- if(v & DMAIFG) {
- DMA0CTL &= ~DMAIFG;
- signal DMA.transferComplete[0]();
- }
- }
- }
- }
- */
TOSH_SIGNAL(DACDMA_VECTOR) {
! volatile int v = DMA0CTL;
if(v & DMAIFG) {
--- 326,331 ----
async default event void DMA.transferComplete[uint8_t id](){}
TOSH_SIGNAL(DACDMA_VECTOR) {
! volatile uint16_t v = DMA0CTL;
if(v & DMAIFG) {
***************
*** 376,378 ****
--- 370,657 ----
}
}
+
+ ///////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // 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();
+ }
+ */
}
More information about the Tinyos-contrib-commits
mailing list