NcpSpi: Ensure spi tx frame preparation and callbacks happen from the same tasklet. (#455)

This commit changes the `NcpSpi` class implementation such that SPI
tx frame preparation always happens from the same task `mPrepareTxFrameTask`
This ensures that the callbacks to base class `Ncp` are also invoked from the
the same task (and not from the the task calling `OutboundFrameEnd()`).
This commit is contained in:
Abtin Keshavarzian
2016-08-25 22:16:22 -07:00
committed by Jonathan Hui
parent e1771f6cc4
commit afb28f0f97
3 changed files with 33 additions and 19 deletions
+9
View File
@@ -39,6 +39,9 @@ ThreadError otPlatSpiSlaveEnable(
void *aContext void *aContext
) )
{ {
(void)aCallback;
(void)aContext;
fprintf(stderr, "\nNo SPI support for posix platform."); fprintf(stderr, "\nNo SPI support for posix platform.");
exit(0); exit(0);
@@ -57,6 +60,12 @@ ThreadError otPlatSpiSlavePrepareTransaction(
bool aRequestTransactionFlag bool aRequestTransactionFlag
) )
{ {
(void)anOutputBuf;
(void)anOutputBufLen;
(void)anInputBuf;
(void)anInputBufLen;
(void)aRequestTransactionFlag;
return kThreadError_NotImplemented; return kThreadError_NotImplemented;
} }
+19 -13
View File
@@ -86,8 +86,8 @@ static uint16_t spi_header_get_data_len(const uint8_t *header)
NcpSpi::NcpSpi(): NcpSpi::NcpSpi():
NcpBase(), NcpBase(),
mHandleRxFrame(&HandleRxFrame, this), mHandleRxFrameTask(&HandleRxFrame, this),
mHandleSendDone(&HandleSendDone, this), mPrepareTxFrameTask(&PrepareTxFrame, this),
mTxFrameBuffer(mTxBuffer, sizeof(mTxBuffer)) mTxFrameBuffer(mTxBuffer, sizeof(mTxBuffer))
{ {
memset(mEmptySendFrame, 0, kSpiHeaderLength); memset(mEmptySendFrame, 0, kSpiHeaderLength);
@@ -161,6 +161,7 @@ NcpSpi::SpiTransactionComplete(
{ {
rx_accept_len = spi_header_get_accept_len(aMISOBuf); rx_accept_len = spi_header_get_accept_len(aMISOBuf);
tx_data_len = spi_header_get_data_len(aMISOBuf); tx_data_len = spi_header_get_data_len(aMISOBuf);
(void)spi_header_get_flag_byte(aMISOBuf);
} }
if (aMOSIBufLen >= kSpiHeaderLength) if (aMOSIBufLen >= kSpiHeaderLength)
@@ -175,7 +176,7 @@ NcpSpi::SpiTransactionComplete(
&& (rx_data_len <= rx_accept_len) && (rx_data_len <= rx_accept_len)
) { ) {
mHandlingRxFrame = true; mHandlingRxFrame = true;
mHandleRxFrame.Post(); mHandleRxFrameTask.Post();
} }
if ( mSending if ( mSending
@@ -186,7 +187,7 @@ NcpSpi::SpiTransactionComplete(
) { ) {
// Our transmission was successful. // Our transmission was successful.
mHandlingSendDone = true; mHandlingSendDone = true;
mHandleSendDone.Post(); mPrepareTxFrameTask.Post();
} }
} }
@@ -261,7 +262,7 @@ void NcpSpi::TxFrameBufferHasData(void *aContext, NcpFrameBuffer *aNcpFrameBuffe
void NcpSpi::TxFrameBufferHasData(void) void NcpSpi::TxFrameBufferHasData(void)
{ {
PrepareNextSpiSendFrame(); mPrepareTxFrameTask.Post();
} }
ThreadError NcpSpi::PrepareNextSpiSendFrame(void) ThreadError NcpSpi::PrepareNextSpiSendFrame(void)
@@ -270,8 +271,6 @@ ThreadError NcpSpi::PrepareNextSpiSendFrame(void)
uint16_t frameLength; uint16_t frameLength;
uint16_t readLength; uint16_t readLength;
VerifyOrExit(!mSending, errorCode = kThreadError_Busy);
VerifyOrExit(!mTxFrameBuffer.IsEmpty(), ;); VerifyOrExit(!mTxFrameBuffer.IsEmpty(), ;);
SuccessOrExit(errorCode = mTxFrameBuffer.OutFrameBegin()); SuccessOrExit(errorCode = mTxFrameBuffer.OutFrameBegin());
@@ -321,16 +320,23 @@ exit:
return errorCode; return errorCode;
} }
void NcpSpi::HandleSendDone(void *aContext) void NcpSpi::PrepareTxFrame(void *aContext)
{ {
static_cast<NcpSpi*>(aContext)->HandleSendDone(); static_cast<NcpSpi*>(aContext)->PrepareTxFrame();
} }
void NcpSpi::HandleSendDone(void) void NcpSpi::PrepareTxFrame(void)
{ {
mSending = false; if (mHandlingSendDone)
PrepareNextSpiSendFrame(); {
mHandlingSendDone = false; mSending = false;
PrepareNextSpiSendFrame();
mHandlingSendDone = false;
}
else if (!mSending)
{
PrepareNextSpiSendFrame();
}
} }
void NcpSpi::HandleRxFrame(void *aContext) void NcpSpi::HandleRxFrame(void *aContext)
+5 -6
View File
@@ -81,8 +81,8 @@ private:
static void HandleRxFrame(void *context); static void HandleRxFrame(void *context);
void HandleRxFrame(void); void HandleRxFrame(void);
static void HandleSendDone(void *context); static void PrepareTxFrame(void *context);
void HandleSendDone(void); void PrepareTxFrame(void);
static void TxFrameBufferHasData(void *aContext, NcpFrameBuffer *aNcpFrameBuffer); static void TxFrameBufferHasData(void *aContext, NcpFrameBuffer *aNcpFrameBuffer);
void TxFrameBufferHasData(void); void TxFrameBufferHasData(void);
@@ -90,12 +90,11 @@ private:
ThreadError PrepareNextSpiSendFrame(void); ThreadError PrepareNextSpiSendFrame(void);
bool mSending; bool mSending;
bool mHandlingRxFrame; bool mHandlingRxFrame;
Tasklet mHandleRxFrame;
bool mHandlingSendDone; bool mHandlingSendDone;
Tasklet mHandleSendDone;
Tasklet mHandleRxFrameTask;
Tasklet mPrepareTxFrameTask;
uint8_t mSendFrame[kSpiBufferSize]; uint8_t mSendFrame[kSpiBufferSize];
uint16_t mSendFrameLen; uint16_t mSendFrameLen;