X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Fatm128%2Fspi%2FAtm128SpiP.nc;h=1838f7b0d00a48c6a76858b0341c825ebeca97d7;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hp=4187412442816726a8b9c791b2d6e4088c24066d;hpb=1a329382c4f4556fd52d85f4e3f4a67e54911682;p=tinyos-2.x.git diff --git a/tos/chips/atm128/spi/Atm128SpiP.nc b/tos/chips/atm128/spi/Atm128SpiP.nc index 41874124..1838f7b0 100644 --- a/tos/chips/atm128/spi/Atm128SpiP.nc +++ b/tos/chips/atm128/spi/Atm128SpiP.nc @@ -72,10 +72,11 @@ * */ -module Atm128SpiP { +module Atm128SpiP @safe() { provides { interface Init; interface SpiByte; + interface FastSpiByte; interface SpiPacket; interface Resource[uint8_t id]; } @@ -87,9 +88,9 @@ module Atm128SpiP { } } implementation { - uint8_t* txBuffer; - uint8_t* rxBuffer; uint16_t len; + uint8_t* COUNT_NOK(len) txBuffer; + uint8_t* COUNT_NOK(len) rxBuffer; uint16_t pos; enum { @@ -101,7 +102,6 @@ implementation { command error_t Init.init() { return SUCCESS; } - bool started; void startSpi() { call Spi.enableSpi(FALSE); @@ -119,19 +119,53 @@ implementation { void stopSpi() { call Spi.enableSpi(FALSE); - started = FALSE; atomic { call Spi.sleep(); } call McuPowerState.update(); } - + async command uint8_t SpiByte.write( uint8_t tx ) { + /* There is no need to enable the SPI bus and update the power state + here since that must have been done when the resource was granted. + However there seems to be a bug somewhere in the radio driver for + the MicaZ platform so we cannot remove the following two lines + before that problem is resolved. (Miklos Maroti) */ + call Spi.enableSpi(TRUE); + call McuPowerState.update(); + call Spi.write( tx ); while ( !( SPSR & 0x80 ) ); return call Spi.read(); } + inline async command void FastSpiByte.splitWrite(uint8_t data) { + call Spi.write(data); + } + + inline async command uint8_t FastSpiByte.splitRead() { + while( !( SPSR & 0x80 ) ) + ; + return call Spi.read(); + } + + inline async command uint8_t FastSpiByte.splitReadWrite(uint8_t data) { + uint8_t b; + + while( !( SPSR & 0x80 ) ) + ; + b = call Spi.read(); + call Spi.write(data); + + return b; + } + + inline async command uint8_t FastSpiByte.write(uint8_t data) { + call Spi.write(data); + while( !( SPSR & 0x80 ) ) + ; + return call Spi.read(); + } /** * This component sends SPI packets in chunks of size SPI_ATOMIC_SIZE @@ -162,10 +196,12 @@ implementation { error_t sendNextPart() { uint16_t end; uint16_t tmpPos; - uint8_t* tx; - uint8_t* rx; + uint16_t myLen; + uint8_t* COUNT_NOK(myLen) tx; + uint8_t* COUNT_NOK(myLen) rx; atomic { + myLen = len; tx = txBuffer; rx = rxBuffer; tmpPos = pos; @@ -201,6 +237,24 @@ implementation { return SUCCESS; } + + task void zeroTask() { + uint16_t myLen; + uint8_t* COUNT_NOK(myLen) rx; + uint8_t* COUNT_NOK(myLen) tx; + + atomic { + myLen = len; + rx = rxBuffer; + tx = txBuffer; + rxBuffer = NULL; + txBuffer = NULL; + len = 0; + pos = 0; + signal SpiPacket.sendDone(tx, rx, myLen, SUCCESS); + } + } + /** * Send bufLen bytes in writeBuf and receive bufLen bytes * into readBuf. If readBuf is NULL, bytes will be @@ -210,24 +264,32 @@ implementation { * * This command only sets up the state variables and clears the SPI: * sendNextPart() does the real work. - * + * + * If there's a send of zero bytes, short-circuit and just post + * a task to signal the sendDone. This generally occurs due to an + * error in the caler, but signaling an event will hopefully let + * it recover better than returning FAIL. */ - + async command error_t SpiPacket.send(uint8_t* writeBuf, uint8_t* readBuf, uint16_t bufLen) { uint8_t discard; atomic { + len = bufLen; txBuffer = writeBuf; rxBuffer = readBuf; - len = bufLen; pos = 0; } - - discard = call Spi.read(); - - return sendNextPart(); + if (bufLen > 0) { + discard = call Spi.read(); + return sendNextPart(); + } + else { + post zeroTask(); + return SUCCESS; + } } default async event void SpiPacket.sendDone @@ -254,15 +316,15 @@ implementation { sendNextPart(); } else { - uint8_t* rx; - uint8_t* tx; - uint16_t myLen; uint8_t discard; + uint16_t myLen; + uint8_t* COUNT_NOK(myLen) rx; + uint8_t* COUNT_NOK(myLen) tx; atomic { + myLen = len; rx = rxBuffer; tx = txBuffer; - myLen = len; rxBuffer = NULL; txBuffer = NULL; len = 0;