uses interface Resource;
uses interface CC2420Power;
+ uses interface SplitControl as SpiSplitControl;
uses interface StdControl as SubControl;
uses interface CC2420Transmit;
uses interface RadioBackoff as SubBackoff;
}
m_state = S_STARTING;
- call CC2420Power.startVReg();
+ call SpiSplitControl.start();
+ // Wait for SpiSplitControl.startDone()
return SUCCESS;
}
}
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();
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;
}
/**
* @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 ];
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();
}
}
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;
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 ) {
m_holder = i;
m_requests &= ~( 1 << i );
call SpiResource.request();
+ m_state = S_GRANTING;
return SUCCESS;
}
}
}
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;
}
}
uint8_t status = 0;
atomic {
- if(!m_resource_busy) {
+ if(m_state != S_BUSY) {
return status;
}
}
}
+ /***************** RAM Commands ****************/
async command cc2420_status_t Ram.read[ uint16_t addr ]( uint8_t offset,
uint8_t* data,
uint8_t len ) {
cc2420_status_t status = 0;
atomic {
- if(!m_resource_busy) {
+ if(m_state != S_BUSY) {
return status;
}
}
}
- 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,
cc2420_status_t status = 0;
atomic {
- if(!m_resource_busy) {
+ if(m_state != S_BUSY) {
return status;
}
}
}
+ /***************** 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;
}
}
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;
}
}
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 ) {
+ }
}