]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/cc2420/CC2420SpiImplP.nc
Fixed SPI bus crashing issue by adding in a SplitControl interface to shut it down...
[tinyos-2.x.git] / tos / chips / cc2420 / CC2420SpiImplP.nc
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 ) {
+  }
 
 }