]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Fixed SPI bus crashing issue by adding in a SplitControl interface to shut it down...
authorrincon <rincon>
Mon, 30 Apr 2007 17:24:26 +0000 (17:24 +0000)
committerrincon <rincon>
Mon, 30 Apr 2007 17:24:26 +0000 (17:24 +0000)
tos/chips/cc2420/CC2420CsmaC.nc
tos/chips/cc2420/CC2420CsmaP.nc
tos/chips/cc2420/CC2420SpiC.nc
tos/chips/cc2420/CC2420SpiImplP.nc
tos/chips/cc2420/CC2420SpiP.nc

index 5f052a5c7fc7c270ba4e07891769cd884ab8aa63..d6d2e57ef686a73d5bf5d9489e3c05d1782ce466 100644 (file)
@@ -58,6 +58,9 @@ implementation {
   components MainC;
   MainC.SoftwareInit -> CsmaP;
   
+  components CC2420SpiP;
+  CsmaP.SpiSplitControl -> CC2420SpiP;
+  
   components CC2420ActiveMessageC;
   CsmaP.AMPacket -> CC2420ActiveMessageC;
   
index f0382f5a3795eca06e00c1a554bb4b0776c6087f..9c77335688a825f68fef8a567d0f6bcf691c2df6 100644 (file)
@@ -43,6 +43,7 @@ module CC2420CsmaP {
 
   uses interface Resource;
   uses interface CC2420Power;
+  uses interface SplitControl as SpiSplitControl;
   uses interface StdControl as SubControl;
   uses interface CC2420Transmit;
   uses interface RadioBackoff as SubBackoff;
@@ -95,7 +96,8 @@ implementation {
     }
 
     m_state = S_STARTING;
-    call CC2420Power.startVReg();
+    call SpiSplitControl.start();
+    // Wait for SpiSplitControl.startDone()
     return SUCCESS;
   }
 
@@ -105,12 +107,22 @@ implementation {
     }
 
     m_state = S_STOPPING;
+    call SpiSplitControl.stop();
+    // Wait for SpiSplitControl.stopDone()
+    return SUCCESS;
+  }
+
+  /***************** SpiSplitControl Events ****************/
+  event void SpiSplitControl.startDone(error_t error) {
+    call CC2420Power.startVReg();
+  }
+  
+  event void SpiSplitControl.stopDone(error_t error) {
     call SubControl.stop();
     call CC2420Power.stopVReg();
     post stopDone_task();
-    return SUCCESS;
   }
-
+    
   /***************** Send Commands ****************/
   command error_t Send.cancel( message_t* p_msg ) {
     return call CC2420Transmit.cancel();
@@ -122,8 +134,9 @@ implementation {
     cc2420_metadata_t* metadata = call CC2420Packet.getMetadata( p_msg );
 
     atomic {
-      if ( m_state != S_STARTED )
+      if ( m_state != S_STARTED ) {
         return FAIL;
+      }
       m_state = S_TRANSMIT;
       m_msg = p_msg;
     }
index 97885031ea37818c6367fde9611aef06e0172145..6e4cb2176e9f14db5b67d71b2d383b381cb47c09 100644 (file)
@@ -38,6 +38,7 @@
 
 generic configuration CC2420SpiC() {
 
+  provides interface SplitControl;
   provides interface Resource;
 
   // commands
@@ -85,7 +86,8 @@ implementation {
   components CC2420SpiP as Spi;
   
   Resource = Spi.Resource[ CLIENT_ID ];
-
+  SplitControl = Spi.SplitControl;
+  
   // commands
   SFLUSHRX = Spi.Strobe[ CC2420_SFLUSHRX ];
   SFLUSHTX = Spi.Strobe[ CC2420_SFLUSHTX ];
index 4bc4540dd54ed8c57e5aa90fe37510facb59b14a..f70fba3ec8525f496717dbeb2eae2ce5fc3533bf 100644 (file)
 
 /**
  * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Roman Lim
  * @version $Revision$ $Date$
  */
 
 module CC2420SpiImplP {
 
+  provides interface SplitControl;
   provides interface Resource[ uint8_t id ];
   provides interface CC2420Fifo as Fifo[ uint8_t id ];
   provides interface CC2420Ram as Ram[ uint16_t id ];
@@ -56,21 +59,55 @@ implementation {
     NO_HOLDER = 0xff,
   };
 
+  enum {
+    S_IDLE,
+    S_GRANTING,
+    S_BUSY,
+  };
+
   norace uint16_t m_addr;
-  bool m_resource_busy = FALSE;
+  
   uint8_t m_requests = 0;
+  
   uint8_t m_holder = NO_HOLDER;
+  
+  uint8_t m_state = S_IDLE;
 
-  default event void Resource.granted[ uint8_t id ]() {
+  bool enabled = FALSE;
+  
+  /***************** Prototypes ****************/
+  task void waitForIdle();
+  
+  /***************** SplitControl Commands ****************/
+  command error_t SplitControl.start() {
+    atomic enabled = TRUE;
+    signal SplitControl.startDone(SUCCESS);
+    return SUCCESS;
   }
-
+  
+  command error_t SplitControl.stop() {
+    atomic {
+      enabled = FALSE;
+      m_requests = 0;
+    }
+    ////call Leds.led1On();
+    post waitForIdle();
+    return SUCCESS;
+  }
+  
+  /***************** Resource Commands *****************/
   async command error_t Resource.request[ uint8_t id ]() {
+    
+    if(!enabled) {
+      return EOFF;
+    }
+    
     atomic {
-      if ( m_resource_busy )
+      if ( m_state != S_IDLE ) {
         m_requests |= 1 << id;
-      else {
+      else {
         m_holder = id;
-        m_resource_busy = TRUE;
+        m_state = S_GRANTING;
         call SpiResource.request();
       }
     }
@@ -79,13 +116,20 @@ implementation {
   
   async command error_t Resource.immediateRequest[ uint8_t id ]() {
     error_t error;
+    
+    if(!enabled) {
+      return EOFF;
+    }
+    
     atomic {
-      if ( m_resource_busy )
+      if ( m_state != S_IDLE ) {
         return EBUSY;
+      }
+      
       error = call SpiResource.immediateRequest();
       if ( error == SUCCESS ) {
         m_holder = id;
-        m_resource_busy = TRUE;
+        m_state = S_BUSY;
       }
     }
     return error;
@@ -94,14 +138,14 @@ implementation {
   async command error_t Resource.release[ uint8_t id ]() {
     uint8_t i;
     atomic {
-      if ( m_holder != id ) {
+      if ( (m_holder != id) || (m_state != S_BUSY)) {
         return FAIL;
       }
-      
+
       m_holder = NO_HOLDER;
       call SpiResource.release();
       if ( !m_requests ) {
-        m_resource_busy = FALSE;
+        m_state = S_IDLE;
       } else {
         for ( i = m_holder + 1; ; i++ ) {
           if ( i >= RESOURCE_COUNT ) {
@@ -112,6 +156,7 @@ implementation {
             m_holder = i;
             m_requests &= ~( 1 << i );
             call SpiResource.request();
+            m_state = S_GRANTING;
             return SUCCESS;
           }
         }
@@ -121,22 +166,18 @@ implementation {
   }
   
   async command uint8_t Resource.isOwner[ uint8_t id ]() {
-    atomic return m_holder == id;
+    atomic return (m_holder == id) & (m_state == S_BUSY);
   }
 
-  event void SpiResource.granted() {
-    uint8_t holder;
-    atomic holder = m_holder;
-    signal Resource.granted[ holder ]();
-  }
 
+  /***************** Fifo Commands ****************/
   async command cc2420_status_t Fifo.beginRead[ uint8_t addr ]( uint8_t* data, 
                                                                 uint8_t len ) {
     
     cc2420_status_t status = 0;
 
     atomic {
-      if(!m_resource_busy) {
+      if(m_state != S_BUSY) {
         return status;
       }
     }
@@ -162,7 +203,7 @@ implementation {
     uint8_t status = 0;
  
     atomic {
-      if(!m_resource_busy) {
+      if(m_state != S_BUSY) {
         return status;
       }
     }
@@ -176,6 +217,7 @@ implementation {
 
   }
 
+  /***************** RAM Commands ****************/
   async command cc2420_status_t Ram.read[ uint16_t addr ]( uint8_t offset,
                                                            uint8_t* data, 
                                                            uint8_t len ) {
@@ -183,7 +225,7 @@ implementation {
     cc2420_status_t status = 0;
 
     atomic {
-      if(!m_resource_busy) {
+      if(m_state != S_BUSY) {
         return status;
       }
     }
@@ -199,13 +241,6 @@ implementation {
 
   }
 
-  async event void SpiPacket.sendDone( uint8_t* tx_buf, uint8_t* rx_buf, 
-                                       uint16_t len, error_t error ) {
-    if ( m_addr & 0x40 )
-      signal Fifo.readDone[ m_addr & ~0x40 ]( rx_buf, len, error );
-    else
-      signal Fifo.writeDone[ m_addr ]( tx_buf, len, error );
-  }
 
   async command cc2420_status_t Ram.write[ uint16_t addr ]( uint8_t offset,
                                                             uint8_t* data, 
@@ -214,7 +249,7 @@ implementation {
     cc2420_status_t status = 0;
 
     atomic {
-      if(!m_resource_busy) {
+      if(m_state != S_BUSY) {
         return status;
       }
     }
@@ -230,12 +265,13 @@ implementation {
 
   }
 
+  /***************** Register Commands ****************/
   async command cc2420_status_t Reg.read[ uint8_t addr ]( uint16_t* data ) {
 
     cc2420_status_t status = 0;
     
     atomic {
-      if(!m_resource_busy) {
+      if(m_state != S_BUSY) {
         return status;
       }
     }
@@ -250,20 +286,20 @@ implementation {
 
   async command cc2420_status_t Reg.write[ uint8_t addr ]( uint16_t data ) {
     atomic {
-      if(!m_resource_busy) {
+      if(m_state != S_BUSY) {
         return 0;
       }
     }
-
     call SpiByte.write( addr );
     call SpiByte.write( data >> 8 );
     return call SpiByte.write( data & 0xff );
-
   }
 
+  
+  /***************** Strobe Commands ****************/
   async command cc2420_status_t Strobe.strobe[ uint8_t addr ]() {
     atomic {
-      if(!m_resource_busy) {
+      if(m_state != S_BUSY) {
         return 0;
       }
     }
@@ -271,7 +307,49 @@ implementation {
     return call SpiByte.write( addr );
   }
 
-  default async event void Fifo.readDone[ uint8_t addr ]( uint8_t* rx_buf, uint8_t rx_len, error_t error ) {}
-  default async event void Fifo.writeDone[ uint8_t addr ]( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {}
+  /***************** SpiResource Events ****************/
+  event void SpiResource.granted() {
+    uint8_t holder;
+    atomic { 
+        holder = m_holder;
+        m_state = S_BUSY;
+    }
+    signal Resource.granted[ holder ]();
+  }
+  
+  /***************** SpiPacket Events ****************/
+  async event void SpiPacket.sendDone( uint8_t* tx_buf, uint8_t* rx_buf, 
+                                       uint16_t len, error_t error ) {
+    if ( m_addr & 0x40 ) {
+      signal Fifo.readDone[ m_addr & ~0x40 ]( rx_buf, len, error );
+    } else {
+      signal Fifo.writeDone[ m_addr ]( tx_buf, len, error );
+    }
+  }
+  
+  
+  /***************** Tasks ****************/
+  task void waitForIdle() {
+    uint8_t currentState;
+    atomic currentState = m_state;
+    
+    if(currentState != S_IDLE) {
+      post waitForIdle();
+    } else {
+      ////call Leds.led1Off();
+      signal SplitControl.stopDone(SUCCESS);
+    }
+  }
+  
+
+  /***************** Defaults ****************/
+  default event void Resource.granted[ uint8_t id ]() {
+  }
+
+  default async event void Fifo.readDone[ uint8_t addr ]( uint8_t* rx_buf, uint8_t rx_len, error_t error ) {
+  }
+  
+  default async event void Fifo.writeDone[ uint8_t addr ]( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {
+  }
 
 }
index 2b80ae4f74f58de108c8396dc93c72461b6fe67e..843476ec1a8e674241206973a326f50160b52f57 100644 (file)
@@ -35,7 +35,8 @@
  */
 
 configuration CC2420SpiP {
-
+  
+  provides interface SplitControl;
   provides interface Resource[ uint8_t id ];
   provides interface CC2420Fifo as Fifo[ uint8_t id ];
   provides interface CC2420Ram as Ram[ uint16_t id ];
@@ -47,6 +48,7 @@ configuration CC2420SpiP {
 implementation {
 
   components CC2420SpiImplP as SpiP;
+  SplitControl = SpiP;
   Resource = SpiP;
   Fifo = SpiP;
   Ram = SpiP;