X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Fatm128%2Fspi%2FAtm128SpiP.nc;h=1838f7b0d00a48c6a76858b0341c825ebeca97d7;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hp=65edf25eef4bc69e0820c63535bba7065bb63e12;hpb=5613a6ebebf7bcd6f01b8f4df129698788406a8f;p=tinyos-2.x.git
diff --git a/tos/chips/atm128/spi/Atm128SpiP.nc b/tos/chips/atm128/spi/Atm128SpiP.nc
index 65edf25e..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,7 +119,6 @@ implementation {
void stopSpi() {
call Spi.enableSpi(FALSE);
- started = FALSE;
atomic {
call Spi.sleep();
}
@@ -127,13 +126,46 @@ implementation {
}
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
@@ -164,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;
@@ -203,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
@@ -212,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
@@ -256,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;