]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Mark Hays repair the SPI code, unit testing demonstrates SPI0 w/ and w/out DMA works...
authorrincon <rincon>
Thu, 8 Nov 2007 21:34:42 +0000 (21:34 +0000)
committerrincon <rincon>
Thu, 8 Nov 2007 21:34:42 +0000 (21:34 +0000)
tos/chips/msp430/dma/HplMsp430DmaXP.nc
tos/chips/msp430/dma/Msp430Dma.h
tos/chips/msp430/usart/Msp430Spi0C.nc
tos/chips/msp430/usart/Msp430Spi1C.nc
tos/chips/msp430/usart/Msp430SpiDma0P.nc
tos/chips/msp430/usart/Msp430SpiDma1P.nc
tos/chips/msp430/usart/Msp430SpiDmaP.nc

index aced3ed30f55739cc085ac7c8114dc8259ead020..1c3cc2185dec5fc78a0bf904bda1d08d52aba875 100644 (file)
@@ -54,6 +54,7 @@
  * @author Ben Greenstein <ben@cs.ucla.edu>
  * @author Jonathan Hui <jhui@archrock.com>
  * @author Joe Polastre <info@moteiv.com>
+ * @author Mark Hays
  * @version $Revision$ $Date$
  */
 
@@ -105,69 +106,79 @@ implementation {
 
   async command void DMA.setSingleMode() {
     DMAxCTL &= ~( DMADT0 | DMADT1 | DMADT2 );
+    DMAxCTL |= DMA_SINGLE_TRANSFER;
   }
 
   async command void DMA.setBlockMode() {
     DMAxCTL &= ~( DMADT0 | DMADT1 | DMADT2 );
-    DMAxCTL |= DMADT0;
+    DMAxCTL |= DMA_BLOCK_TRANSFER;
   }
 
   async command void DMA.setBurstMode() {
     DMAxCTL &= ~( DMADT0 | DMADT1 | DMADT2 );
-    DMAxCTL |= DMADT1;
+    DMAxCTL |= DMA_BURST_BLOCK_TRANSFER;
   }
 
   async command void DMA.setRepeatedSingleMode() {
     DMAxCTL &= ~( DMADT0 | DMADT1 | DMADT2 );
-    DMAxCTL |= DMADT2;
+    DMAxCTL |= DMA_REPEATED_SINGLE_TRANSFER;
   }
 
   async command void DMA.setRepeatedBlockMode() {
     DMAxCTL &= ~( DMADT0 | DMADT1 | DMADT2 );
-    DMAxCTL |= ( DMADT2 | DMADT0 );
+    DMAxCTL |= DMA_REPEATED_BLOCK_TRANSFER;
   }
 
   async command void DMA.setRepeatedBurstMode() {
     DMAxCTL &= ~( DMADT0 | DMADT1 | DMADT2 );
-    DMAxCTL |= ( DMADT2 | DMADT1 );
+    DMAxCTL |= DMA_REPEATED_BURST_BLOCK_TRANSFER;
   }
 
   async command void DMA.setSrcNoIncrement() {
     DMAxCTL &= ~( DMASRCINCR0 | DMASRCINCR1 );
+    DMAxCTL |= DMA_ADDRESS_UNCHANGED;
   }
 
   async command void DMA.setSrcDecrement() {
-    DMAxCTL |= DMASRCINCR1;
+    DMAxCTL &= ~( DMASRCINCR0 | DMASRCINCR1 );
+    DMAxCTL |= DMA_ADDRESS_DECREMENTED;
   }
 
   async command void DMA.setSrcIncrement() {
-    DMAxCTL |= ( DMASRCINCR0 | DMASRCINCR1 );
+    DMAxCTL &= ~( DMASRCINCR0 | DMASRCINCR1 );
+    DMAxCTL |= DMA_ADDRESS_INCREMENTED;
   }
 
   async command void DMA.setDstNoIncrement() {
     DMAxCTL &= ~( DMADSTINCR0 | DMADSTINCR1 );
+    DMAxCTL |= DMA_ADDRESS_UNCHANGED;
   }          
 
   async command void DMA.setDstDecrement() {
-    DMAxCTL |= DMADSTINCR1;
+    DMAxCTL &= ~( DMADSTINCR0 | DMADSTINCR1 );
+    DMAxCTL |= DMA_ADDRESS_DECREMENTED;
   }
 
   async command void DMA.setDstIncrement() {
-    DMAxCTL |= ( DMADSTINCR0 | DMADSTINCR1 );
+    DMAxCTL &= ~( DMADSTINCR0 | DMADSTINCR1 );
+    DMAxCTL |= DMA_ADDRESS_INCREMENTED;
   }
 
   async command void DMA.setWordToWord() {
     DMAxCTL &= ~(DMASRCBYTE | DMADSTBYTE);
     DMAxCTL |= DMASWDW;
   }
+
   async command void DMA.setByteToWord() {
     DMAxCTL &= ~(DMASRCBYTE | DMADSTBYTE);
     DMAxCTL |= DMASBDW;
   }
+
   async command void DMA.setWordToByte() {
     DMAxCTL &= ~(DMASRCBYTE | DMADSTBYTE);
     DMAxCTL |= DMASWDB;
   }
+
   async command void DMA.setByteToByte() {
     DMAxCTL &= ~(DMASRCBYTE | DMADSTBYTE);
     DMAxCTL |= DMASBDB;
@@ -190,11 +201,11 @@ implementation {
   }
 
   async command void DMA.enableInterrupt() {
-    DMAxCTL  |= DMAIE;
+    DMAxCTL |= DMAIE;
   }
 
   async command void DMA.disableInterrupt() {
-    DMAxCTL  &= ~DMAIE;
+    DMAxCTL &= ~DMAIE;
   }
 
   async command bool DMA.interruptPending() {
@@ -235,7 +246,7 @@ implementation {
     DMAxSA = (uint16_t)src;
     DMAxDA = (uint16_t)dest;
     DMAxSZ = size;
-    DMACTL0 = ( DMACTL0 & ~DMAxTSEL_mask ) | ( t << DMAxTSEL_shift );
+    call DMA.setTrigger((dma_trigger_t) t);
     DMAxCTL = s;
   }
 
@@ -268,7 +279,5 @@ implementation {
     DMAxDA = 0;
     DMAxSZ = 0;
   }
-
-
 }
 
index 51c3bbde15d9f7c09e9025d15d002c8457257708..0a496ed39aaebead97703f35882b63c36149456f 100644 (file)
 /**
  * @author Ben Greenstein <ben@cs.ucla.edu>
  * @author Jonathan Hui <jhui@archrock.com>
+ * @author Mark Hays
  * $Revision$ $Date$
  */
 
 #ifndef MSP430DMA_H
 #define MSP430DMA_H
 
+// General stuff
 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
+  DMA_CHANNEL_IN_USE    = 1
 };
 
-// HPL constants
-
+////////////////////////////////////////
+// Per-channel fields in DMACTL0
 enum {
   DMA0TSEL_SHIFT = 0,
   DMA1TSEL_SHIFT = 4,
@@ -84,27 +88,20 @@ enum {
   DMA1TSEL_MASK  = ( 0xf0 ),
   DMA2TSEL_MASK  = ( 0xf00 ),
 };
-enum {
-  DMASRCINCR_SHIFT = (8),
-  DMADSTINCR_SHIFT = (10),
-  DMAINCR_MASK = (0x3)
-};
-enum {
-  DMADT_SHIFT = (12),
-  DMADT_MASK = (0x3)
-};
+
+// Per-field (channel) in DMACTL0
 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_URXIFG0 =         0x3, // RX on USART0 (UART/SPI)
+  DMA_TRIGGER_UTXIFG0 =         0x4, // TX on USART0 (UART/SPI)
   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_URXIFG1 =         0x9, // RX on USART1 (UART/SPI)
+  DMA_TRIGGER_UTXIFG1 =         0xa, // TX on USART1 (UART/SPI)
   DMA_TRIGGER_MULT =            0xb, // Hardware Multiplier Ready
   DMA_TRIGGER_DMAxIFG =         0xe, // DMA0IFG triggers DMA channel 1
                                      // DMA1IFG triggers DMA channel 2
@@ -112,57 +109,76 @@ typedef enum {
   DMA_TRIGGER_DMAE0 =           0xf  // External Trigger DMAE0
 } dma_trigger_t;
 
+typedef struct dma_channel_trigger_s {
+  unsigned int trigger : 4; 
+  unsigned int reserved : 12;
+} __attribute__ ((packed)) dma_channel_trigger_t;
+
+////////////////////////////////////////
+// Bits in DMACTL1
 enum {
   DISABLE_NMI = 0,
-  ENABLE_NMI = 1
+  ENABLE_NMI  = 1,
 };
 
 enum {
   NOT_ROUND_ROBIN = 0,
-  ROUND_ROBIN = 1,
+  ROUND_ROBIN     = 1,
 };
 
 enum {
   NOT_ON_FETCH = 0,
-  ON_FETCH = 1
+  ON_FETCH     = 1,
 };
 
-typedef enum {
-  DMA_EDGE_SENSITIVE = 0x0,
-  DMA_LEVEL_SENSITIVE = 0x1
-} dma_level_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;
+
+////////////////////////////////////////
+// Stuff in DMAxCTL
+
+// DMADTx
+enum {
+  DMADT_SHIFT = 12,
+  DMADT_MASK  = 0x7,
+};
 
 typedef enum {
-  DMA_WORD = 0x0,
-  DMA_BYTE = 0x1
-} dma_byte_t;
+  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;
+
+// DMA{SRC,DST}INCRx
+enum {
+  DMASRCINCR_SHIFT = 8,
+  DMADSTINCR_SHIFT = 10,
+  DMAINCR_MASK     = 0x3,
+};
 
 typedef enum {
-  DMA_ADDRESS_UNCHANGED = 0x0,
+  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;
+  DMA_WORD = 0x0,
+  DMA_BYTE = 0x1
+} dma_byte_t;
 
-typedef struct dma_channel_trigger_s {
-  unsigned int trigger : 4; 
-  unsigned int reserved : 12;
-} __attribute__ ((packed)) dma_channel_trigger_t;
+// DMALEVEL
+typedef enum {
+  DMA_EDGE_SENSITIVE  = 0x0,
+  DMA_LEVEL_SENSITIVE = 0x1
+} dma_level_t;
 
 typedef struct dma_channel_state_s {
   unsigned int request : 1;
@@ -180,3 +196,4 @@ typedef struct dma_channel_state_s {
 } __attribute__ ((packed)) dma_channel_state_t;
 
 #endif
+
index 9143b5d414ba430d3eb81fd41f1d91cca587b747..cf22622359f00aefc48e20c8e68e2c78a356ac2a 100644 (file)
@@ -36,6 +36,7 @@
  * place of Msp430SpiNoDma0P.
  *
  * @author Jonathan Hui <jhui@archedrock.com>
+ * @author Mark Hays
  * @version $Revision$ $Date$
  */
 
@@ -56,7 +57,13 @@ implementation {
     CLIENT_ID = unique( MSP430_SPIO_BUS ),
   };
 
+#ifdef ENABLE_SPI0_DMA
+#warning "Enabling SPI DMA on USART0"
+  components Msp430SpiDma0P as SpiP;
+#else
   components Msp430SpiNoDma0P as SpiP;
+#endif
+
   Resource = SpiP.Resource[ CLIENT_ID ];
   SpiByte = SpiP.SpiByte;
   SpiPacket = SpiP.SpiPacket[ CLIENT_ID ];
index 1c777d9c9c6b50c1b6dcc2a9e34761476d7f6711..61363f331b0e69ebd083a618c1f54636f20c4c94 100644 (file)
@@ -36,6 +36,7 @@
  * place of Msp430SpiNoDma0P.
  *
  * @author Jonathan Hui <jhui@archedrock.com>
+ * @author Mark Hays
  * @version $Revision$ $Date$
  */
 
@@ -56,7 +57,13 @@ implementation {
     CLIENT_ID = unique( MSP430_SPI1_BUS ),
   };
 
+#ifdef ENABLE_SPI1_DMA
+#warning "Enabling SPI DMA on USART1"
+  components Msp430SpiDma1P as SpiP;
+#else
   components Msp430SpiNoDma1P as SpiP;
+#endif
+
   Resource = SpiP.Resource[ CLIENT_ID ];
   SpiByte = SpiP.SpiByte;
   SpiPacket = SpiP.SpiPacket[ CLIENT_ID ];
index 005201d0ba780b65198a35b914eeb63ab15b0929..c1c24d243c19cb24564a4260f62728c36a35994d 100644 (file)
@@ -31,6 +31,7 @@
 
 /**
  * @author Jonathan Hui <jhui@archedrock.com>
+ * @author Mark Hays
  * @version $Revision$ $Date$
  */
 
@@ -49,7 +50,15 @@ configuration Msp430SpiDma0P {
 
 implementation {
 
-  components new Msp430SpiDmaP() as SpiP;
+#include "Msp430Dma.h"
+
+  components new Msp430SpiDmaP(IFG1_,
+                              U0TXBUF_,
+                              UTXIFG0,
+                              (uint16_t) DMA_TRIGGER_UTXIFG0,
+                              U0RXBUF_,
+                              URXIFG0,
+                              (uint16_t) DMA_TRIGGER_URXIFG0) as SpiP;
   Resource = SpiP.Resource;
   ResourceConfigure = SpiP.ResourceConfigure;
   Msp430SpiConfigure = SpiP.Msp430SpiConfigure;
index dfbd278090fbc8301f784b1f371bb43a79f3a682..5a051b46c5975dab0c3685a27593e5c862bc0ab3 100644 (file)
 
 /**
  * @author Jonathan Hui <jhui@archedrock.com>
+ * @author Mark Hays
  * @version $Revision$ $Date$
  */
 
 configuration Msp430SpiDma1P {
 
   provides interface Resource[ uint8_t id ];
-  provides interface ResourceControl [uint8_t id];
+  provides interface ResourceConfigure[uint8_t id];
   provides interface SpiByte;
   provides interface SpiPacket[ uint8_t id ];
 
@@ -49,9 +50,17 @@ configuration Msp430SpiDma1P {
 
 implementation {
 
-  components new Msp430SpiDmaP() as SpiP;
+#include "Msp430Dma.h"
+
+  components new Msp430SpiDmaP(IFG2_,
+                              U1TXBUF_,
+                              UTXIFG1,
+                              (uint16_t) DMA_TRIGGER_UTXIFG1,
+                              U1RXBUF_,
+                              URXIFG1,
+                              (uint16_t) DMA_TRIGGER_URXIFG1) as SpiP;
   Resource = SpiP.Resource;
-  ResourceControl = SpiP.ResourceControl;
+  ResourceConfigure = SpiP.ResourceConfigure;
   Msp430SpiConfigure = SpiP.Msp430SpiConfigure;
   SpiByte = SpiP.SpiByte;
   SpiPacket = SpiP.SpiPacket;
index c72a054487e03a4b215969c7e9cffd09891cf8ed..cf7fc336ec21bf2e4bc1c631c9dc84b772b43e09 100644 (file)
 
 /**
  * @author Jonathan Hui <jhui@archedrock.com>
+ * @author Mark Hays
  * @version $Revision$ $Date$
  */
 
 
-generic module Msp430SpiDmaP() {
+generic module Msp430SpiDmaP( uint16_t IFG_addr,
+                             uint16_t TXBUF_addr,
+                             uint8_t  TXIFG,
+                             uint16_t TXTRIG,
+                             uint16_t RXBUF_addr,
+                             uint8_t  RXIFG,
+                             uint16_t RXTRIG ) {
 
   provides interface Resource[ uint8_t id ];
   provides interface ResourceConfigure[ uint8_t id ];
@@ -54,7 +61,7 @@ generic module Msp430SpiDmaP() {
 
 implementation {
 
-  MSP430REG_NORACE( IFG1 );
+#define IFG (*(volatile uint8_t*)IFG_addr)
 
   uint8_t* m_tx_buf;
   uint8_t* m_rx_buf;
@@ -115,8 +122,6 @@ implementation {
                                                      uint8_t* rx_buf,
                                                      uint16_t len ) {
 
-    uint16_t ctrl;
-
     atomic {
       m_client = id;
       m_tx_buf = tx_buf;
@@ -124,23 +129,43 @@ implementation {
       m_len = len;
     }
 
-    if ( rx_buf ) {
-      ctrl = 0xcd4;
-    }
-    else {
-      ctrl = 0x0d4;
-      rx_buf = &m_dump;
-    }
-
     if ( len ) {
-      IFG1 &= ~( UTXIFG0 | URXIFG0 );
-      call DmaChannel1.setupTransferRaw( ctrl, DMA_TRIGGER_USARTRX,
-                                        (uint16_t*)U0RXBUF_, rx_buf, len );
-      call DmaChannel2.setupTransferRaw( 0x3d4, DMA_TRIGGER_USARTTX,
-                                        tx_buf, (uint16_t*)U0TXBUF_, len );
-      IFG1 |= UTXIFG0;
-    }
-    else {
+      // clear the interrupt flags
+      IFG &= ~( TXIFG | RXIFG );
+
+      // set up the RX xfer
+      call DmaChannel1.setupTransfer(DMA_SINGLE_TRANSFER,
+                                    RXTRIG,
+                                    DMA_EDGE_SENSITIVE,
+                                    (void *) RXBUF_addr,
+                                    rx_buf ? rx_buf : &m_dump,
+                                    len,
+                                    DMA_BYTE,
+                                    DMA_BYTE,
+                                    DMA_ADDRESS_UNCHANGED,
+                                    rx_buf ?
+                                      DMA_ADDRESS_INCREMENTED :
+                                      DMA_ADDRESS_UNCHANGED);
+      // this doesn't start a transfer; it simply enables the channel
+      call DmaChannel1.startTransfer();
+
+      // set up the TX xfer
+      call DmaChannel2.setupTransfer(DMA_SINGLE_TRANSFER,
+                                    TXTRIG,
+                                    DMA_EDGE_SENSITIVE,
+                                    tx_buf,
+                                    (void *) TXBUF_addr,
+                                    len,
+                                    DMA_BYTE,
+                                    DMA_BYTE,
+                                    DMA_ADDRESS_INCREMENTED,
+                                    DMA_ADDRESS_UNCHANGED);
+      // this doesn't start a transfer; it simply enables the channel
+      call DmaChannel2.startTransfer();
+
+      // pong the tx flag to get things rolling
+      IFG |= TXIFG;
+    } else {
       post signalDone_task();
     }