From 3b7ee2d47c1d432cfb36747b0f774cd91f2a1a12 Mon Sep 17 00:00:00 2001 From: rincon Date: Mon, 30 Apr 2007 17:24:26 +0000 Subject: [PATCH] Fixed SPI bus crashing issue by adding in a SplitControl interface to shut it down before turning off the radio. The majority of this work and debugging was spawned by Roman Lim. --- tos/chips/cc2420/CC2420CsmaC.nc | 3 + tos/chips/cc2420/CC2420CsmaP.nc | 21 +++- tos/chips/cc2420/CC2420SpiC.nc | 4 +- tos/chips/cc2420/CC2420SpiImplP.nc | 148 ++++++++++++++++++++++------- tos/chips/cc2420/CC2420SpiP.nc | 4 +- 5 files changed, 139 insertions(+), 41 deletions(-) diff --git a/tos/chips/cc2420/CC2420CsmaC.nc b/tos/chips/cc2420/CC2420CsmaC.nc index 5f052a5c..d6d2e57e 100644 --- a/tos/chips/cc2420/CC2420CsmaC.nc +++ b/tos/chips/cc2420/CC2420CsmaC.nc @@ -58,6 +58,9 @@ implementation { components MainC; MainC.SoftwareInit -> CsmaP; + components CC2420SpiP; + CsmaP.SpiSplitControl -> CC2420SpiP; + components CC2420ActiveMessageC; CsmaP.AMPacket -> CC2420ActiveMessageC; diff --git a/tos/chips/cc2420/CC2420CsmaP.nc b/tos/chips/cc2420/CC2420CsmaP.nc index f0382f5a..9c773356 100644 --- a/tos/chips/cc2420/CC2420CsmaP.nc +++ b/tos/chips/cc2420/CC2420CsmaP.nc @@ -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; } diff --git a/tos/chips/cc2420/CC2420SpiC.nc b/tos/chips/cc2420/CC2420SpiC.nc index 97885031..6e4cb217 100644 --- a/tos/chips/cc2420/CC2420SpiC.nc +++ b/tos/chips/cc2420/CC2420SpiC.nc @@ -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 ]; diff --git a/tos/chips/cc2420/CC2420SpiImplP.nc b/tos/chips/cc2420/CC2420SpiImplP.nc index 4bc4540d..f70fba3e 100644 --- a/tos/chips/cc2420/CC2420SpiImplP.nc +++ b/tos/chips/cc2420/CC2420SpiImplP.nc @@ -31,11 +31,14 @@ /** * @author Jonathan Hui + * @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 ) { + } } diff --git a/tos/chips/cc2420/CC2420SpiP.nc b/tos/chips/cc2420/CC2420SpiP.nc index 2b80ae4f..843476ec 100644 --- a/tos/chips/cc2420/CC2420SpiP.nc +++ b/tos/chips/cc2420/CC2420SpiP.nc @@ -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; -- 2.39.2