From 90b160ccfaf2d8f8595919c07c7ea469989e4b0c Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 11 Jun 2018 08:59:25 -0700 Subject: [PATCH] [ncp-spi] improve callback implementation, change code style format (#2734) This commit makes the following changes in `NcpSpi` class: - It adds a new class `SpiFrame` which provides helper methods to parse and update the header fields in the header of an SPI frame. - It simplifies/enhances the `SpiTransactionComplete()` callback implementation by combining the parsing of input/output frame headers with the rx/tx frame processing. - It adds a check for correct pattern bits in a received frame flag byte (frames with incorrect pattern bits are ignored). - Code format is changed to follow the "pretty" style. - Fixes a rare issue with a possible incorrect accept length on the first SPI transaction after NCP reset. --- src/ncp/ncp_spi.cpp | 254 +++++++++++++++++++++----------------------- src/ncp/ncp_spi.hpp | 182 ++++++++++++++++++++++++++----- 2 files changed, 273 insertions(+), 163 deletions(-) diff --git a/src/ncp/ncp_spi.cpp b/src/ncp/ncp_spi.cpp index 9b6a3fa09..7baf7c520 100644 --- a/src/ncp/ncp_spi.cpp +++ b/src/ncp/ncp_spi.cpp @@ -33,8 +33,8 @@ #include "ncp_spi.hpp" #include -#include #include +#include #include "openthread-core-config.h" #include "common/code_utils.hpp" @@ -43,11 +43,6 @@ #include "common/new.hpp" #include "net/ip6.hpp" -#define SPI_RESET_FLAG 0x80 -#define SPI_CRC_FLAG 0x40 -#define SPI_PATTERN_VALUE 0x02 -#define SPI_PATTERN_MASK 0x03 - #if OPENTHREAD_ENABLE_NCP_SPI namespace ot { @@ -59,10 +54,10 @@ static otDEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpSpi), uint64_t); extern "C" void otNcpInit(otInstance *aInstance) { - NcpSpi *ncpSpi = NULL; + NcpSpi * ncpSpi = NULL; Instance *instance = static_cast(aInstance); - ncpSpi = new(&sNcpRaw) NcpSpi(instance); + ncpSpi = new (&sNcpRaw) NcpSpi(instance); if (ncpSpi == NULL || ncpSpi != NcpBase::GetNcpInstance()) { @@ -72,169 +67,154 @@ extern "C" void otNcpInit(otInstance *aInstance) #endif // OPENTHREAD_ENABLE_SPINEL_VENDOR_SUPPORT == 0 -static void spi_header_set_flag_byte(uint8_t *header, uint8_t value) +NcpSpi::NcpSpi(Instance *aInstance) + : NcpBase(aInstance) + , mTxState(kTxStateIdle) + , mHandlingRxFrame(false) + , mResetFlag(true) + , mPrepareTxFrameTask(*aInstance, &NcpSpi::PrepareTxFrame, this) + , mSendFrameLength(0) { - header[0] = value; -} + SpiFrame sendFrame(mSendFrame); + SpiFrame emptyFullAccept(mEmptySendFrameFullAccept); + SpiFrame emptyZeroAccept(mEmptySendFrameZeroAccept); -static void spi_header_set_accept_len(uint8_t *header, uint16_t len) -{ - header[1] = ((len >> 0) & 0xff); - header[2] = ((len >> 8) & 0xff); -} + sendFrame.SetHeaderFlagByte(/* aResetFlag */ true); + sendFrame.SetHeaderAcceptLen(0); + sendFrame.SetHeaderDataLen(0); -static void spi_header_set_data_len(uint8_t *header, uint16_t len) -{ - header[3] = ((len >> 0) & 0xff); - header[4] = ((len >> 8) & 0xff); -} + emptyFullAccept.SetHeaderFlagByte(/* aResetFlag */ true); + emptyFullAccept.SetHeaderAcceptLen(kSpiBufferSize - kSpiHeaderSize); + emptyFullAccept.SetHeaderDataLen(0); -static uint8_t spi_header_get_flag_byte(const uint8_t *header) -{ - return header[0]; -} - -static uint16_t spi_header_get_accept_len(const uint8_t *header) -{ - return ( header[1] + static_cast(header[2] << 8) ); -} - -static uint16_t spi_header_get_data_len(const uint8_t *header) -{ - return ( header[3] + static_cast(header[4] << 8) ); -} - -NcpSpi::NcpSpi(Instance *aInstance) : - NcpBase(aInstance), - mTxState(kTxStateIdle), - mHandlingRxFrame(false), - mResetFlag(true), - mPrepareTxFrameTask(*aInstance, &NcpSpi::PrepareTxFrame, this), - mSendFrameLen(0) -{ - memset(mSendFrame, 0, kSpiHeaderLength); - memset(mEmptySendFrameZeroAccept, 0, kSpiHeaderLength); - memset(mEmptySendFrameFullAccept, 0, kSpiHeaderLength); + emptyZeroAccept.SetHeaderFlagByte(/* aResetFlag */ true); + emptyZeroAccept.SetHeaderAcceptLen(0); + emptyZeroAccept.SetHeaderDataLen(0); mTxFrameBuffer.SetFrameAddedCallback(HandleFrameAddedToTxBuffer, this); - spi_header_set_flag_byte(mSendFrame, SPI_RESET_FLAG | SPI_PATTERN_VALUE); - spi_header_set_flag_byte(mEmptySendFrameZeroAccept, SPI_RESET_FLAG | SPI_PATTERN_VALUE); - spi_header_set_flag_byte(mEmptySendFrameFullAccept, SPI_RESET_FLAG | SPI_PATTERN_VALUE); - - spi_header_set_accept_len(mSendFrame, sizeof(mReceiveFrame) - kSpiHeaderLength); - spi_header_set_accept_len(mEmptySendFrameFullAccept, sizeof(mReceiveFrame) - kSpiHeaderLength); - spi_header_set_accept_len(mEmptySendFrameZeroAccept, 0); - otPlatSpiSlaveEnable(&NcpSpi::SpiTransactionComplete, &NcpSpi::SpiTransactionProcess, this); // We signal an interrupt on this first transaction to // make sure that the host processor knows that our // reset flag was set. - otPlatSpiSlavePrepareTransaction(mEmptySendFrameZeroAccept, kSpiHeaderLength, mEmptyReceiveFrame, kSpiHeaderLength, - true); + otPlatSpiSlavePrepareTransaction(mEmptySendFrameZeroAccept, kSpiHeaderSize, mEmptyReceiveFrame, kSpiHeaderSize, + /* aRequestTras */ true); } -bool NcpSpi::SpiTransactionComplete(void *aContext, uint8_t *aOutputBuf, uint16_t aOutputBufLen, uint8_t *aInputBuf, - uint16_t aInputBufLen, uint16_t aTransactionLength) +bool NcpSpi::SpiTransactionComplete(void * aContext, + uint8_t *aOutputBuf, + uint16_t aOutputLen, + uint8_t *aInputBuf, + uint16_t aInputLen, + uint16_t aTransLen) { - return static_cast(aContext)->SpiTransactionComplete(aOutputBuf, aOutputBufLen, aInputBuf, aInputBufLen, - aTransactionLength); + NcpSpi *ncp = reinterpret_cast(aContext); + + return ncp->SpiTransactionComplete(aOutputBuf, aOutputLen, aInputBuf, aInputLen, aTransLen); } -bool NcpSpi::SpiTransactionComplete(uint8_t *aOutputBuf, uint16_t aOutputBufLen, uint8_t *aInputBuf, - uint16_t aInputBufLen, uint16_t aTransactionLength) +bool NcpSpi::SpiTransactionComplete(uint8_t *aOutputBuf, + uint16_t aOutputLen, + uint8_t *aInputBuf, + uint16_t aInputLen, + uint16_t aTransLen) { - // This may be executed from an interrupt context. - // Must return as quickly as possible. + // This can be executed from an interrupt context, therefore we cannot + // use any of OpenThread APIs here. If further processing is needed, + // returned value `shouldProcess` is set to `true` to indicate to + // platform SPI slave driver to invoke `SpiTransactionProcess()` callback + // which unlike this callback must be called from the same OS context + // that OpenThread APIs/callbacks are executed. - uint16_t rx_data_len = 0; - uint16_t rx_accept_len = 0; - uint16_t tx_data_len = 0; - uint16_t tx_accept_len = 0; - bool shouldProcess = false; + uint16_t transDataLen; + bool shouldProcess = false; + SpiFrame outputFrame(aOutputBuf); + SpiFrame inputFrame(aInputBuf); + SpiFrame sendFrame(mSendFrame); - // TODO: Check `PATTERN` bits of `HDR` and ignore frame if not set. - // Holding off on implementing this so as to not cause immediate - // compatibility problems, even though it is required by the spec. + VerifyOrExit((aTransLen >= kSpiHeaderSize) && (aInputLen >= kSpiHeaderSize) && (aOutputLen >= kSpiHeaderSize)); + VerifyOrExit(inputFrame.IsValid() && outputFrame.IsValid()); - if (aTransactionLength >= kSpiHeaderLength) + transDataLen = aTransLen - kSpiHeaderSize; + + if (!mHandlingRxFrame) { - if (aOutputBufLen >= kSpiHeaderLength) - { - rx_accept_len = spi_header_get_accept_len(aOutputBuf); - tx_data_len = spi_header_get_data_len(aOutputBuf); - (void)spi_header_get_flag_byte(aOutputBuf); - } + uint16_t rxDataLen = inputFrame.GetHeaderDataLen(); - if (aInputBufLen >= kSpiHeaderLength) - { - rx_data_len = spi_header_get_data_len(aInputBuf); - tx_accept_len = spi_header_get_accept_len(aInputBuf); - } + // A new frame is successfully received if input frame + // indicates that there is data and the "data len" is not + // larger than than the "accept len" we provided in the + // exchanged output frame. - if (!mHandlingRxFrame && - (rx_data_len > 0) && - (rx_data_len <= aTransactionLength - kSpiHeaderLength) && - (rx_data_len <= rx_accept_len)) + if ((rxDataLen > 0) && (rxDataLen <= transDataLen) && (rxDataLen <= outputFrame.GetHeaderAcceptLen())) { mHandlingRxFrame = true; - shouldProcess = true; + shouldProcess = true; } + } - if ((mTxState == kTxStateSending) && - (tx_data_len > 0) && - (tx_data_len <= aTransactionLength - kSpiHeaderLength) && - (tx_data_len <= tx_accept_len)) + if (mTxState == kTxStateSending) + { + uint16_t txDataLen = outputFrame.GetHeaderDataLen(); + + // Frame transmission is successful if master indicates + // in the input frame that it could accept the frame + // length that was exchanged, i.e., the "data len" in + // the output frame is smaller than or equal to "accept + // len" in the received input frame from master. + + if ((txDataLen > 0) && (txDataLen <= transDataLen) && (txDataLen <= inputFrame.GetHeaderAcceptLen())) { - mTxState = kTxStateHandlingSendDone; + mTxState = kTxStateHandlingSendDone; shouldProcess = true; } } - if (mResetFlag && (aTransactionLength > 0) && (aOutputBufLen > 0)) +exit: + // Determine the input and output frames to prepare a new transaction. + + if (mResetFlag && (aTransLen > 0) && (aOutputLen > 0)) { - // Clear the reset flag. mResetFlag = false; - spi_header_set_flag_byte(mSendFrame, SPI_PATTERN_VALUE); - spi_header_set_flag_byte(mEmptySendFrameZeroAccept, SPI_PATTERN_VALUE); - spi_header_set_flag_byte(mEmptySendFrameFullAccept, SPI_PATTERN_VALUE); + sendFrame.SetHeaderFlagByte(/*aResetFlag */ false); + SpiFrame(mEmptySendFrameFullAccept).SetHeaderFlagByte(/*aResetFlag */ false); + SpiFrame(mEmptySendFrameZeroAccept).SetHeaderFlagByte(/*aResetFlag */ false); } if (mTxState == kTxStateSending) { aOutputBuf = mSendFrame; - aOutputBufLen = mSendFrameLen; + aOutputLen = mSendFrameLength; } else { - aOutputBuf = (mHandlingRxFrame) ? mEmptySendFrameZeroAccept : mEmptySendFrameFullAccept; - aOutputBufLen = kSpiHeaderLength; + aOutputBuf = mHandlingRxFrame ? mEmptySendFrameZeroAccept : mEmptySendFrameFullAccept; + aOutputLen = kSpiHeaderSize; } if (mHandlingRxFrame) { aInputBuf = mEmptyReceiveFrame; - aInputBufLen = kSpiHeaderLength; - spi_header_set_accept_len(mSendFrame, 0); + aInputLen = kSpiHeaderSize; } else { aInputBuf = mReceiveFrame; - aInputBufLen = sizeof(mReceiveFrame); - spi_header_set_accept_len(mSendFrame, sizeof(mReceiveFrame) - kSpiHeaderLength); + aInputLen = kSpiBufferSize; } - otPlatSpiSlavePrepareTransaction(aOutputBuf, aOutputBufLen, aInputBuf, aInputBufLen, - (mTxState == kTxStateSending)); + sendFrame.SetHeaderAcceptLen(aInputLen - kSpiHeaderSize); + + otPlatSpiSlavePrepareTransaction(aOutputBuf, aOutputLen, aInputBuf, aInputLen, (mTxState == kTxStateSending)); return shouldProcess; } void NcpSpi::SpiTransactionProcess(void *aContext) { - static_cast(aContext)->SpiTransactionProcess(); + reinterpret_cast(aContext)->SpiTransactionProcess(); } void NcpSpi::SpiTransactionProcess(void) @@ -250,8 +230,10 @@ void NcpSpi::SpiTransactionProcess(void) } } -void NcpSpi::HandleFrameAddedToTxBuffer(void *aContext, NcpFrameBuffer::FrameTag aTag, - NcpFrameBuffer::Priority aPriority, NcpFrameBuffer *aNcpFrameBuffer) +void NcpSpi::HandleFrameAddedToTxBuffer(void * aContext, + NcpFrameBuffer::FrameTag aTag, + NcpFrameBuffer::Priority aPriority, + NcpFrameBuffer * aNcpFrameBuffer) { OT_UNUSED_VARIABLE(aNcpFrameBuffer); OT_UNUSED_VARIABLE(aTag); @@ -260,11 +242,12 @@ void NcpSpi::HandleFrameAddedToTxBuffer(void *aContext, NcpFrameBuffer::FrameTag static_cast(aContext)->mPrepareTxFrameTask.Post(); } -otError NcpSpi::PrepareNextSpiSendFrame(void) +void NcpSpi::PrepareNextSpiSendFrame(void) { - otError errorCode = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; uint16_t frameLength; uint16_t readLength; + SpiFrame sendFrame(mSendFrame); VerifyOrExit(!mTxFrameBuffer.IsEmpty()); @@ -273,38 +256,36 @@ otError NcpSpi::PrepareNextSpiSendFrame(void) otPlatWakeHost(); } - SuccessOrExit(errorCode = mTxFrameBuffer.OutFrameBegin()); + SuccessOrExit(error = mTxFrameBuffer.OutFrameBegin()); frameLength = mTxFrameBuffer.OutFrameGetLength(); - assert(frameLength <= sizeof(mSendFrame) - kSpiHeaderLength); - - spi_header_set_data_len(mSendFrame, frameLength); + assert(frameLength <= kSpiBufferSize - kSpiHeaderSize); // The "accept length" in `mSendFrame` is already updated based // on current state of receive. It is changed either from the // `SpiTransactionComplete()` callback or from `HandleRxFrame()`. - readLength = mTxFrameBuffer.OutFrameRead(frameLength, mSendFrame + kSpiHeaderLength); + readLength = mTxFrameBuffer.OutFrameRead(frameLength, sendFrame.GetData()); assert(readLength == frameLength); - mSendFrameLen = frameLength + kSpiHeaderLength; + sendFrame.SetHeaderDataLen(frameLength); + mSendFrameLength = frameLength + kSpiHeaderSize; mTxState = kTxStateSending; // Prepare new transaction by using `mSendFrame` as the output - // buffer while keeping the input buffer unchanged. + // frame while keeping the input frame unchanged. - errorCode = otPlatSpiSlavePrepareTransaction(mSendFrame, mSendFrameLen, NULL, 0, true); + error = otPlatSpiSlavePrepareTransaction(mSendFrame, mSendFrameLength, NULL, 0, /* aRequestTrans */ true); - if (errorCode == OT_ERROR_BUSY) + if (error == OT_ERROR_BUSY) { - // Being busy is OK. We will get the transaction - // set up properly when the current transaction - // is completed. - errorCode = OT_ERROR_NONE; + // Being busy is OK. We will get the transaction set up + // properly when the current transaction is completed. + error = OT_ERROR_NONE; } - if (errorCode != OT_ERROR_NONE) + if (error != OT_ERROR_NONE) { mTxState = kTxStateIdle; mPrepareTxFrameTask.Post(); @@ -314,7 +295,7 @@ otError NcpSpi::PrepareNextSpiSendFrame(void) mTxFrameBuffer.OutFrameRemove(); exit: - return errorCode; + return; } void NcpSpi::PrepareTxFrame(Tasklet &aTasklet) @@ -347,8 +328,11 @@ void NcpSpi::PrepareTxFrame(void) void NcpSpi::HandleRxFrame(void) { + SpiFrame recvFrame(mReceiveFrame); + SpiFrame sendFrame(mSendFrame); + // Pass the received frame to base class to process. - HandleReceive(mReceiveFrame + kSpiHeaderLength, spi_header_get_data_len(mReceiveFrame)); + HandleReceive(recvFrame.GetData(), recvFrame.GetHeaderDataLen()); // The order of operations below is important. We should clear // the `mHandlingRxFrame` before checking `mTxState` and possibly @@ -371,10 +355,10 @@ void NcpSpi::HandleRxFrame(void) if (mTxState != kTxStateSending) { - spi_header_set_accept_len(mSendFrame, sizeof(mReceiveFrame) - kSpiHeaderLength); + sendFrame.SetHeaderAcceptLen(kSpiBufferSize - kSpiHeaderSize); - otPlatSpiSlavePrepareTransaction(mEmptySendFrameFullAccept, kSpiHeaderLength, mReceiveFrame, - sizeof(mReceiveFrame), false); + otPlatSpiSlavePrepareTransaction(mEmptySendFrameFullAccept, kSpiHeaderSize, mReceiveFrame, kSpiBufferSize, + /* aRequestTrans */ false); // No need to check the error status. Getting `OT_ERROR_BUSY` // is OK as everything will be set up properly from callback when @@ -382,7 +366,7 @@ void NcpSpi::HandleRxFrame(void) } } -} // namespace Ncp -} // namespace ot +} // namespace Ncp +} // namespace ot #endif // OPENTHREAD_ENABLE_NCP_SPI diff --git a/src/ncp/ncp_spi.hpp b/src/ncp/ncp_spi.hpp index 588e9ce9c..486544609 100644 --- a/src/ncp/ncp_spi.hpp +++ b/src/ncp/ncp_spi.hpp @@ -40,6 +40,121 @@ namespace ot { namespace Ncp { +/** + * This class defines a SPI frame. + * + */ +class SpiFrame +{ +public: + enum + { + kHeaderSize = 5, ///< SPI header size (in bytes). + }; + + /** + * This constructor initializes an `SpiFrame` instance. + * + * @param[in] aBuffer Pointer to buffer containing the frame. + * + */ + SpiFrame(uint8_t *aBuffer) : mBuffer(aBuffer) { } + + /** + * This method gets a pointer to data portion in the SPI frame skipping the header. + * + * @returns A pointer to data in the SPI frame. + * + */ + uint8_t *GetData(void) { return mBuffer + kHeaderSize; } + + /** + * This method indicates whether or not the frame is valid. + * + * In a valid frame the flag byte should contain the pattern bits. + * + * @returns TRUE if the frame is valid, FALSE otherwise. + * + */ + bool IsValid(void) const + { + return ((mBuffer[kIndexFlagByte] & kFlagPatternMask) == kFlagPattern); + } + + /** + * This method sets the "flag byte" field in the SPI frame header. + * + * @param[in] aResetFalg The status of reset flag (TRUE to set the flag, FALSE to clear flag). + * + */ + void SetHeaderFlagByte(bool aResetFlag) + { + mBuffer[kIndexFlagByte] = kFlagPattern | (aResetFlag ? kFlagReset : 0); + } + + /** + * This method sets the "accept len" field in the SPI frame header. + * + * "accept len" specifies number of bytes the sender of the SPI frame can receive. + * + * @param[in] aAcceptLen The accept length in bytes. + * + */ + void SetHeaderAcceptLen(uint16_t aAcceptLen) + { + Encoding::LittleEndian::WriteUint16(aAcceptLen, mBuffer + kIndexAcceptLen); + } + + /** + * This method gets the "accept len" field in the SPI frame header. + * + * @returns The accept length in bytes. + * + */ + uint16_t GetHeaderAcceptLen(void) const + { + return Encoding::LittleEndian::ReadUint16(mBuffer + kIndexAcceptLen); + } + + /** + * This method sets the "data len" field in the SPI frame header. + * + * "Data len" specifies number of data bytes in the transmitted SPI frame. + * + * @param[in] aDataLen The data length in bytes. + * + */ + void SetHeaderDataLen(uint16_t aDataLen) + { + Encoding::LittleEndian::WriteUint16(aDataLen, mBuffer + kIndexDataLen); + } + + /** + * This method gets the "data len" field in the SPI frame header. + * + * @returns The data length in bytes. + * + */ + uint16_t GetHeaderDataLen(void) const + { + return Encoding::LittleEndian::ReadUint16(mBuffer + kIndexDataLen); + } + +private: + enum + { + kIndexFlagByte = 0, // flag byte (uint8_t). + kIndexAcceptLen = 1, // accept len (uint16_t little-endian encoding). + kIndexDataLen = 3, // data len (uint16_t little-endian encoding). + + kFlagReset = (1 << 7), // Flag byte RESET bit. + kFlagPattern = 0x02, // Flag byte PATTERN bits. + kFlagPatternMask = 0x03, // Flag byte PATTERN mask. + }; + + uint8_t *mBuffer; +}; + class NcpSpi : public NcpBase { public: @@ -58,55 +173,66 @@ private: * SPI tx and rx buffer size (should fit a max length frame + SPI header). * */ - kSpiBufferSize = OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE, + kSpiBufferSize = OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE, /** - * Size of SPI header in bytes. + * Size of the SPI header (in bytes). * */ - kSpiHeaderLength = 5, + kSpiHeaderSize = SpiFrame::kHeaderSize, }; enum TxState { - kTxStateIdle, // No frame to send. - kTxStateSending, // A frame is ready to be sent. - kTxStateHandlingSendDone // The frame was sent successfully, waiting to prepare the next one (if any). + kTxStateIdle, // No frame to send. + kTxStateSending, // A frame is ready to be sent. + kTxStateHandlingSendDone // The frame was sent successfully, waiting to prepare the next one (if any). }; - static bool SpiTransactionComplete(void *aContext, uint8_t *aOutputBuf, uint16_t aOutputBufLen, uint8_t *aInputBuf, - uint16_t aInputBufLen, uint16_t aTransactionLength); - bool SpiTransactionComplete(uint8_t *aOutputBuf, uint16_t aOutputBufLen, uint8_t *aInputBuf, uint16_t aInputBufLen, - uint16_t aTransactionLength); + typedef uint8_t LargeFrameBuffer[kSpiBufferSize]; + typedef uint8_t EmptyFrameBuffer[kSpiHeaderSize]; + + static bool SpiTransactionComplete(void * aContext, + uint8_t *aOutputBuf, + uint16_t aOutputLen, + uint8_t *aInputBuf, + uint16_t aInputLen, + uint16_t aTransLen); + bool SpiTransactionComplete(uint8_t *aOutputBuf, + uint16_t aOutputLen, + uint8_t *aInputBuf, + uint16_t aInputLen, + uint16_t aTransLen); static void SpiTransactionProcess(void *aContext); - void SpiTransactionProcess(void); + void SpiTransactionProcess(void); - static void HandleFrameAddedToTxBuffer(void *aContext, NcpFrameBuffer::FrameTag aFrameTag, - NcpFrameBuffer::Priority aPriority, NcpFrameBuffer *aNcpFrameBuffer); + static void HandleFrameAddedToTxBuffer(void * aContext, + NcpFrameBuffer::FrameTag aFrameTag, + NcpFrameBuffer::Priority aPriority, + NcpFrameBuffer * aNcpFrameBuffer); static void PrepareTxFrame(Tasklet &aTasklet); - void PrepareTxFrame(void); - void HandleRxFrame(void); - - otError PrepareNextSpiSendFrame(void); + void PrepareTxFrame(void); + void HandleRxFrame(void); + void PrepareNextSpiSendFrame(void); volatile TxState mTxState; - volatile bool mHandlingRxFrame; - volatile bool mResetFlag; + volatile bool mHandlingRxFrame; + volatile bool mResetFlag; Tasklet mPrepareTxFrameTask; - uint16_t mSendFrameLen; - uint8_t mSendFrame[kSpiBufferSize]; - uint8_t mReceiveFrame[kSpiBufferSize]; + uint16_t mSendFrameLength; + LargeFrameBuffer mSendFrame; + EmptyFrameBuffer mEmptySendFrameFullAccept; + EmptyFrameBuffer mEmptySendFrameZeroAccept; - uint8_t mEmptySendFrameZeroAccept[kSpiHeaderLength]; - uint8_t mEmptySendFrameFullAccept[kSpiHeaderLength]; - uint8_t mEmptyReceiveFrame[kSpiHeaderLength]; + LargeFrameBuffer mReceiveFrame; + EmptyFrameBuffer mEmptyReceiveFrame; }; -} // namespace Ncp -} // namespace ot +} // namespace Ncp +} // namespace ot -#endif // NCP_SPI_HPP_ +#endif // NCP_SPI_HPP_