From afb28f0f97d6e53ed5a88827a86d64bb5c4ea1d2 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 25 Aug 2016 22:16:22 -0700 Subject: [PATCH] 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()`). --- examples/platforms/posix/spi-stubs.c | 9 ++++++++ src/ncp/ncp_spi.cpp | 32 +++++++++++++++++----------- src/ncp/ncp_spi.hpp | 11 +++++----- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/examples/platforms/posix/spi-stubs.c b/examples/platforms/posix/spi-stubs.c index e82cc9fb2..fdc794f44 100644 --- a/examples/platforms/posix/spi-stubs.c +++ b/examples/platforms/posix/spi-stubs.c @@ -39,6 +39,9 @@ ThreadError otPlatSpiSlaveEnable( void *aContext ) { + (void)aCallback; + (void)aContext; + fprintf(stderr, "\nNo SPI support for posix platform."); exit(0); @@ -57,6 +60,12 @@ ThreadError otPlatSpiSlavePrepareTransaction( bool aRequestTransactionFlag ) { + (void)anOutputBuf; + (void)anOutputBufLen; + (void)anInputBuf; + (void)anInputBufLen; + (void)aRequestTransactionFlag; + return kThreadError_NotImplemented; } diff --git a/src/ncp/ncp_spi.cpp b/src/ncp/ncp_spi.cpp index 440c6eeda..29187c2de 100644 --- a/src/ncp/ncp_spi.cpp +++ b/src/ncp/ncp_spi.cpp @@ -86,8 +86,8 @@ static uint16_t spi_header_get_data_len(const uint8_t *header) NcpSpi::NcpSpi(): NcpBase(), - mHandleRxFrame(&HandleRxFrame, this), - mHandleSendDone(&HandleSendDone, this), + mHandleRxFrameTask(&HandleRxFrame, this), + mPrepareTxFrameTask(&PrepareTxFrame, this), mTxFrameBuffer(mTxBuffer, sizeof(mTxBuffer)) { memset(mEmptySendFrame, 0, kSpiHeaderLength); @@ -161,6 +161,7 @@ NcpSpi::SpiTransactionComplete( { rx_accept_len = spi_header_get_accept_len(aMISOBuf); tx_data_len = spi_header_get_data_len(aMISOBuf); + (void)spi_header_get_flag_byte(aMISOBuf); } if (aMOSIBufLen >= kSpiHeaderLength) @@ -175,7 +176,7 @@ NcpSpi::SpiTransactionComplete( && (rx_data_len <= rx_accept_len) ) { mHandlingRxFrame = true; - mHandleRxFrame.Post(); + mHandleRxFrameTask.Post(); } if ( mSending @@ -186,7 +187,7 @@ NcpSpi::SpiTransactionComplete( ) { // Our transmission was successful. mHandlingSendDone = true; - mHandleSendDone.Post(); + mPrepareTxFrameTask.Post(); } } @@ -261,7 +262,7 @@ void NcpSpi::TxFrameBufferHasData(void *aContext, NcpFrameBuffer *aNcpFrameBuffe void NcpSpi::TxFrameBufferHasData(void) { - PrepareNextSpiSendFrame(); + mPrepareTxFrameTask.Post(); } ThreadError NcpSpi::PrepareNextSpiSendFrame(void) @@ -270,8 +271,6 @@ ThreadError NcpSpi::PrepareNextSpiSendFrame(void) uint16_t frameLength; uint16_t readLength; - VerifyOrExit(!mSending, errorCode = kThreadError_Busy); - VerifyOrExit(!mTxFrameBuffer.IsEmpty(), ;); SuccessOrExit(errorCode = mTxFrameBuffer.OutFrameBegin()); @@ -321,16 +320,23 @@ exit: return errorCode; } -void NcpSpi::HandleSendDone(void *aContext) +void NcpSpi::PrepareTxFrame(void *aContext) { - static_cast(aContext)->HandleSendDone(); + static_cast(aContext)->PrepareTxFrame(); } -void NcpSpi::HandleSendDone(void) +void NcpSpi::PrepareTxFrame(void) { - mSending = false; - PrepareNextSpiSendFrame(); - mHandlingSendDone = false; + if (mHandlingSendDone) + { + mSending = false; + PrepareNextSpiSendFrame(); + mHandlingSendDone = false; + } + else if (!mSending) + { + PrepareNextSpiSendFrame(); + } } void NcpSpi::HandleRxFrame(void *aContext) diff --git a/src/ncp/ncp_spi.hpp b/src/ncp/ncp_spi.hpp index 92122feb1..c7533ee88 100644 --- a/src/ncp/ncp_spi.hpp +++ b/src/ncp/ncp_spi.hpp @@ -81,8 +81,8 @@ private: static void HandleRxFrame(void *context); void HandleRxFrame(void); - static void HandleSendDone(void *context); - void HandleSendDone(void); + static void PrepareTxFrame(void *context); + void PrepareTxFrame(void); static void TxFrameBufferHasData(void *aContext, NcpFrameBuffer *aNcpFrameBuffer); void TxFrameBufferHasData(void); @@ -90,12 +90,11 @@ private: ThreadError PrepareNextSpiSendFrame(void); bool mSending; - bool mHandlingRxFrame; - Tasklet mHandleRxFrame; - bool mHandlingSendDone; - Tasklet mHandleSendDone; + + Tasklet mHandleRxFrameTask; + Tasklet mPrepareTxFrameTask; uint8_t mSendFrame[kSpiBufferSize]; uint16_t mSendFrameLen;