mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[efr32] revert uart.c to commit 4c06b47c34 (#4030)
Fixes NCP often entering a uninitialized:fault state during reset. Readded otSysEventSignalPending to efr32mg12 uart.c
This commit is contained in:
committed by
Jonathan Hui
parent
66cd36b638
commit
e0fdc20f47
@@ -41,23 +41,17 @@
|
||||
|
||||
#include "em_core.h"
|
||||
#include "uartdrv.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hal-config.h"
|
||||
|
||||
enum
|
||||
{
|
||||
kReceiveFifoSize = 128,
|
||||
kDmaBlockSize = 64
|
||||
};
|
||||
|
||||
#define USART_PORT USART0
|
||||
#define USART_PORT_RX_IRQn USART0_RX_IRQn
|
||||
|
||||
#define USART_INIT \
|
||||
{ \
|
||||
USART_PORT, /* USART port */ \
|
||||
USART0, /* USART port */ \
|
||||
115200, /* Baud rate */ \
|
||||
BSP_SERIAL_APP_TX_LOC, /* USART Tx pin location number */ \
|
||||
BSP_SERIAL_APP_RX_LOC, /* USART Rx pin location number */ \
|
||||
@@ -79,107 +73,39 @@ enum
|
||||
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS, sUartRxQueue);
|
||||
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS, sUartTxQueue);
|
||||
|
||||
static CORE_DECLARE_NVIC_MASK(sRxNvicMask);
|
||||
static UARTDRV_HandleData_t sUartHandleData;
|
||||
static UARTDRV_Handle_t sUartHandle = &sUartHandleData;
|
||||
static const uint8_t * sTransmitBuffer;
|
||||
static volatile uint16_t sTransmitLength;
|
||||
static volatile bool sReceiveDeferred;
|
||||
static uint8_t sReceiveBuffer[2];
|
||||
static const uint8_t * sTransmitBuffer = NULL;
|
||||
static volatile uint16_t sTransmitLength = 0;
|
||||
|
||||
// Using unwrapped indexes allows buffer full and buffer empty conditions to be easily distinguished.
|
||||
// These values will eventually wrap themselves (due to an integer overflow). They should always be wrapped
|
||||
// using %kReceiveFifoSize at the point of use, except if testing for a buffer empty condition (mReadEnd == mReadStart).
|
||||
// kReceiveFifoSize must therefore also be specified to a length of a power of 2.
|
||||
typedef struct ReceiveFifo_t
|
||||
{
|
||||
// The data buffer
|
||||
uint8_t mBuffer[kReceiveFifoSize];
|
||||
// The offset of the first item to be read from the list (unwrapped)
|
||||
uint16_t mReadStart;
|
||||
// The offset of the last item to be read plus one (unwrapped)
|
||||
volatile uint16_t mReadEnd;
|
||||
// The offset of first unused item (unwrapped)
|
||||
volatile uint16_t mWrite;
|
||||
// The offset of the first item written to the list.
|
||||
volatile uint16_t mHead;
|
||||
// The offset of the next item to be written to the list.
|
||||
volatile uint16_t mTail;
|
||||
} ReceiveFifo_t;
|
||||
|
||||
static ReceiveFifo_t sReceiveFifo;
|
||||
|
||||
static bool enqueueNextReceive(void);
|
||||
|
||||
static void updateReceiveProgress(uint8_t *aData, UARTDRV_Count_t aCount)
|
||||
{
|
||||
assert(aData != NULL);
|
||||
|
||||
const uint16_t blockStartWrapped = aData - sReceiveFifo.mBuffer;
|
||||
const uint16_t readEndWrapped = sReceiveFifo.mReadEnd % kReceiveFifoSize;
|
||||
|
||||
// Check readEndWrapped is within range of the current block. Required when mReadEnd was set to the end of
|
||||
// the buffer on a previous call and readEndWrapped now wraps to 0.
|
||||
if (readEndWrapped >= blockStartWrapped && readEndWrapped < blockStartWrapped + kDmaBlockSize)
|
||||
{
|
||||
sReceiveFifo.mReadEnd += blockStartWrapped + aCount - readEndWrapped;
|
||||
}
|
||||
}
|
||||
static void processReceive(void);
|
||||
|
||||
static void receiveDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
|
||||
{
|
||||
updateReceiveProgress(aData, aCount);
|
||||
|
||||
if (!enqueueNextReceive())
|
||||
// We can only write if incrementing mTail doesn't equal mHead
|
||||
if (sReceiveFifo.mHead != (sReceiveFifo.mTail + 1) % kReceiveFifoSize)
|
||||
{
|
||||
// A failure to enqueue the next receive is due to no free blocks remaining in the buffer. Defer enqueueing
|
||||
// the next receive operation to processReceive() (running in the main execution context) where the
|
||||
// contents of the buffer shall firstly be emptied. In the mean time, flow control RTS will be deasserted.
|
||||
assert(sReceiveDeferred == false);
|
||||
sReceiveDeferred = true;
|
||||
sReceiveFifo.mBuffer[sReceiveFifo.mTail] = aData[0];
|
||||
sReceiveFifo.mTail = (sReceiveFifo.mTail + 1) % kReceiveFifoSize;
|
||||
}
|
||||
|
||||
UARTDRV_Receive(aHandle, aData, 1, receiveDone);
|
||||
otSysEventSignalPending();
|
||||
}
|
||||
|
||||
static inline bool isBufferEmpty(uint16_t unwrappedReadStart, uint16_t unwrappedReadEnd)
|
||||
{
|
||||
return (unwrappedReadStart == unwrappedReadEnd);
|
||||
}
|
||||
|
||||
static bool enqueueNextReceive(void)
|
||||
{
|
||||
bool result;
|
||||
const uint16_t wrappedWrite = sReceiveFifo.mWrite % kReceiveFifoSize;
|
||||
const uint16_t wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
|
||||
Ecode_t status;
|
||||
|
||||
if (isBufferEmpty(sReceiveFifo.mReadStart, sReceiveFifo.mReadEnd))
|
||||
{
|
||||
// Buffer is completely empty
|
||||
result = true;
|
||||
}
|
||||
else if (wrappedReadStart == wrappedWrite)
|
||||
{
|
||||
// Buffer is completely full because it isn't empty and wrappedReadStart == wrappedWrite
|
||||
result = false;
|
||||
}
|
||||
else if (wrappedReadStart > wrappedWrite)
|
||||
{
|
||||
// Read wrappedReadStart is ahead of wrappedWrite: the next block may or may not be fully vacant
|
||||
result = (wrappedReadStart - wrappedWrite >= kDmaBlockSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read wrappedReadStart is behind wrappedWrite, so therefore there is at least one block free
|
||||
result = true;
|
||||
}
|
||||
|
||||
otEXPECT(result);
|
||||
|
||||
status = UARTDRV_Receive(sUartHandle, sReceiveFifo.mBuffer + wrappedWrite, kDmaBlockSize, receiveDone);
|
||||
otEXPECT_ACTION(ECODE_OK == status, result = false);
|
||||
|
||||
sReceiveFifo.mWrite += kDmaBlockSize;
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
|
||||
{
|
||||
sTransmitLength = 0;
|
||||
@@ -188,69 +114,26 @@ static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aDa
|
||||
|
||||
static void processReceive(void)
|
||||
{
|
||||
uint16_t readEnd;
|
||||
uint8_t * buffer;
|
||||
UARTDRV_Count_t itemsReceived;
|
||||
UARTDRV_Count_t itemsRemaining;
|
||||
uint16_t wrappedReadStart;
|
||||
uint16_t wrappedReadEnd;
|
||||
uint16_t readLength;
|
||||
CORE_DECLARE_NVIC_STATE;
|
||||
// Copy tail to prevent multiple reads
|
||||
uint16_t tail = sReceiveFifo.mTail;
|
||||
|
||||
CORE_ENTER_NVIC(&sRxNvicMask);
|
||||
|
||||
UARTDRV_GetReceiveStatus(sUartHandle, &buffer, &itemsReceived, &itemsRemaining);
|
||||
if (buffer != NULL)
|
||||
// If the data wraps around, process the first part
|
||||
if (sReceiveFifo.mHead > tail)
|
||||
{
|
||||
// Only update the receive progress if a current receive is in progress (buffer not NULL)
|
||||
updateReceiveProgress(buffer, itemsReceived);
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, kReceiveFifoSize - sReceiveFifo.mHead);
|
||||
|
||||
// Reset the buffer mHead back to zero.
|
||||
sReceiveFifo.mHead = 0;
|
||||
}
|
||||
|
||||
readEnd = sReceiveFifo.mReadEnd;
|
||||
|
||||
CORE_EXIT_NVIC();
|
||||
|
||||
wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
|
||||
wrappedReadEnd = readEnd % kReceiveFifoSize;
|
||||
|
||||
if (!isBufferEmpty(sReceiveFifo.mReadStart, readEnd))
|
||||
// For any data remaining, process it
|
||||
if (sReceiveFifo.mHead != tail)
|
||||
{
|
||||
if (wrappedReadStart >= wrappedReadEnd)
|
||||
{
|
||||
// The buffer isn't empty, and wrappedReadStart >= wrappedReadEnd. Firstly, data needs to be read
|
||||
// from wrappedReadStart to the end of the buffer. Subsequently, data can then be read from the start
|
||||
// of the buffer to wrappedReadEnd.
|
||||
readLength = kReceiveFifoSize - wrappedReadStart;
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + wrappedReadStart, readLength);
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, tail - sReceiveFifo.mHead);
|
||||
|
||||
// Move the read start index by the amount of data read
|
||||
sReceiveFifo.mReadStart += readLength;
|
||||
}
|
||||
|
||||
// mReadStart may have been modified above, so recalculate wrappedReadStart
|
||||
wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
|
||||
|
||||
if (!isBufferEmpty(sReceiveFifo.mReadStart, readEnd))
|
||||
{
|
||||
// There is still data in the buffer (i.e. wrappedReadStart < wrappedReadEnd)
|
||||
readLength = wrappedReadEnd - wrappedReadStart;
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + wrappedReadStart, readLength);
|
||||
|
||||
// All data has been read
|
||||
sReceiveFifo.mReadStart = readEnd;
|
||||
}
|
||||
// Set mHead to the local tail we have cached
|
||||
sReceiveFifo.mHead = tail;
|
||||
}
|
||||
|
||||
CORE_ENTER_NVIC(&sRxNvicMask);
|
||||
|
||||
// The buffer has been emptied, but it may have since filled up again just before entering this critical section.
|
||||
// Attempt to enqueue any receive operations that previously failed to enqueue due to a full buffer.
|
||||
if (sReceiveDeferred)
|
||||
{
|
||||
sReceiveDeferred = !enqueueNextReceive();
|
||||
}
|
||||
|
||||
CORE_EXIT_NVIC();
|
||||
}
|
||||
|
||||
otError otPlatUartFlush(void)
|
||||
@@ -269,33 +152,19 @@ static void processTransmit(void)
|
||||
|
||||
otError otPlatUartEnable(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
UARTDRV_Init_t uartInit = USART_INIT;
|
||||
bool enqueuedReceive;
|
||||
|
||||
memset(&sRxNvicMask, 0, sizeof(sRxNvicMask));
|
||||
CORE_NvicMaskSetIRQ(LDMA_IRQn, &sRxNvicMask);
|
||||
CORE_NvicMaskSetIRQ(USART_PORT_RX_IRQn, &sRxNvicMask);
|
||||
sReceiveFifo.mHead = 0;
|
||||
sReceiveFifo.mTail = 0;
|
||||
|
||||
sReceiveFifo.mReadStart = 0;
|
||||
sReceiveFifo.mReadEnd = 0;
|
||||
sReceiveFifo.mWrite = 0;
|
||||
sTransmitLength = 0;
|
||||
sTransmitBuffer = NULL;
|
||||
UARTDRV_Init(sUartHandle, &uartInit);
|
||||
|
||||
otEXPECT_ACTION(ECODE_OK == UARTDRV_Init(sUartHandle, &uartInit), error = OT_ERROR_FAILED);
|
||||
for (uint8_t i = 0; i < sizeof(sReceiveBuffer); i++)
|
||||
{
|
||||
UARTDRV_Receive(sUartHandle, &sReceiveBuffer[i], sizeof(sReceiveBuffer[i]), receiveDone);
|
||||
}
|
||||
|
||||
CORE_DECLARE_NVIC_STATE;
|
||||
CORE_ENTER_NVIC(&sRxNvicMask);
|
||||
|
||||
enqueuedReceive = enqueueNextReceive();
|
||||
|
||||
CORE_EXIT_NVIC();
|
||||
|
||||
otEXPECT_ACTION(enqueuedReceive, error = OT_ERROR_FAILED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatUartDisable(void)
|
||||
@@ -306,15 +175,14 @@ otError otPlatUartDisable(void)
|
||||
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ecode_t status;
|
||||
|
||||
otEXPECT_ACTION(sTransmitBuffer == NULL, error = OT_ERROR_BUSY);
|
||||
|
||||
sTransmitBuffer = aBuf;
|
||||
sTransmitLength = aBufLength;
|
||||
|
||||
status = UARTDRV_Transmit(sUartHandle, (uint8_t *)sTransmitBuffer, sTransmitLength, transmitDone);
|
||||
otEXPECT_ACTION(ECODE_OK == status, error = OT_ERROR_FAILED);
|
||||
UARTDRV_Transmit(sUartHandle, (uint8_t *)sTransmitBuffer, sTransmitLength, transmitDone);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -40,15 +40,12 @@
|
||||
|
||||
#include "em_core.h"
|
||||
#include "uartdrv.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hal-config.h"
|
||||
|
||||
enum
|
||||
{
|
||||
kReceiveFifoSize = 128,
|
||||
kDmaBlockSize = 64
|
||||
};
|
||||
|
||||
#define USART_PORT USART0
|
||||
@@ -79,103 +76,36 @@ enum
|
||||
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS, sUartRxQueue);
|
||||
DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS, sUartTxQueue);
|
||||
|
||||
static CORE_DECLARE_NVIC_MASK(sRxNvicMask);
|
||||
static UARTDRV_HandleData_t sUartHandleData;
|
||||
static UARTDRV_Handle_t sUartHandle = &sUartHandleData;
|
||||
static const uint8_t * sTransmitBuffer;
|
||||
static volatile uint16_t sTransmitLength;
|
||||
static volatile bool sReceiveDeferred;
|
||||
static uint8_t sReceiveBuffer[2];
|
||||
static const uint8_t * sTransmitBuffer = NULL;
|
||||
static volatile uint16_t sTransmitLength = 0;
|
||||
|
||||
// Using unwrapped indexes allows buffer full and buffer empty conditions to be easily distinguished.
|
||||
// These values will eventually wrap themselves (due to an integer overflow). They should always be wrapped
|
||||
// using %kReceiveFifoSize at the point of use, except if testing for a buffer empty condition (mReadEnd == mReadStart).
|
||||
// kReceiveFifoSize must therefore also be specified to a length of a power of 2.
|
||||
typedef struct ReceiveFifo_t
|
||||
{
|
||||
// The data buffer
|
||||
uint8_t mBuffer[kReceiveFifoSize];
|
||||
// The offset of the first item to be read from the list (unwrapped)
|
||||
uint16_t mReadStart;
|
||||
// The offset of the last item to be read plus one (unwrapped)
|
||||
volatile uint16_t mReadEnd;
|
||||
// The offset of first unused item (unwrapped)
|
||||
volatile uint16_t mWrite;
|
||||
// The offset of the first item written to the list.
|
||||
volatile uint16_t mHead;
|
||||
// The offset of the next item to be written to the list.
|
||||
volatile uint16_t mTail;
|
||||
} ReceiveFifo_t;
|
||||
|
||||
static ReceiveFifo_t sReceiveFifo;
|
||||
|
||||
static bool enqueueNextReceive(void);
|
||||
|
||||
static void updateReceiveProgress(uint8_t *aData, UARTDRV_Count_t aCount)
|
||||
{
|
||||
assert(aData != NULL);
|
||||
|
||||
const uint16_t blockStartWrapped = aData - sReceiveFifo.mBuffer;
|
||||
const uint16_t readEndWrapped = sReceiveFifo.mReadEnd % kReceiveFifoSize;
|
||||
|
||||
// Check readEndWrapped is within range of the current block. Required when mReadEnd was set to the end of
|
||||
// the buffer on a previous call and readEndWrapped now wraps to 0.
|
||||
if (readEndWrapped >= blockStartWrapped && readEndWrapped < blockStartWrapped + kDmaBlockSize)
|
||||
{
|
||||
sReceiveFifo.mReadEnd += blockStartWrapped + aCount - readEndWrapped;
|
||||
}
|
||||
}
|
||||
static void processReceive(void);
|
||||
|
||||
static void receiveDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
|
||||
{
|
||||
updateReceiveProgress(aData, aCount);
|
||||
|
||||
if (!enqueueNextReceive())
|
||||
// We can only write if incrementing mTail doesn't equal mHead
|
||||
if (sReceiveFifo.mHead != (sReceiveFifo.mTail + 1) % kReceiveFifoSize)
|
||||
{
|
||||
// A failure to enqueue the next receive is due to no free blocks remaining in the buffer. Defer enqueueing
|
||||
// the next receive operation to processReceive() (running in the main execution context) where the
|
||||
// contents of the buffer shall firstly be emptied. In the mean time, flow control RTS will be deasserted.
|
||||
assert(sReceiveDeferred == false);
|
||||
sReceiveDeferred = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool isBufferEmpty(uint16_t unwrappedReadStart, uint16_t unwrappedReadEnd)
|
||||
{
|
||||
return (unwrappedReadStart == unwrappedReadEnd);
|
||||
}
|
||||
|
||||
static bool enqueueNextReceive(void)
|
||||
{
|
||||
bool result;
|
||||
const uint16_t wrappedWrite = sReceiveFifo.mWrite % kReceiveFifoSize;
|
||||
const uint16_t wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
|
||||
Ecode_t status;
|
||||
|
||||
if (isBufferEmpty(sReceiveFifo.mReadStart, sReceiveFifo.mReadEnd))
|
||||
{
|
||||
// Buffer is completely empty
|
||||
result = true;
|
||||
}
|
||||
else if (wrappedReadStart == wrappedWrite)
|
||||
{
|
||||
// Buffer is completely full because it isn't empty and wrappedReadStart == wrappedWrite
|
||||
result = false;
|
||||
}
|
||||
else if (wrappedReadStart > wrappedWrite)
|
||||
{
|
||||
// Read wrappedReadStart is ahead of wrappedWrite: the next block may or may not be fully vacant
|
||||
result = (wrappedReadStart - wrappedWrite >= kDmaBlockSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read wrappedReadStart is behind wrappedWrite, so therefore there is at least one block free
|
||||
result = true;
|
||||
sReceiveFifo.mBuffer[sReceiveFifo.mTail] = aData[0];
|
||||
sReceiveFifo.mTail = (sReceiveFifo.mTail + 1) % kReceiveFifoSize;
|
||||
}
|
||||
|
||||
otEXPECT(result);
|
||||
|
||||
status = UARTDRV_Receive(sUartHandle, sReceiveFifo.mBuffer + wrappedWrite, kDmaBlockSize, receiveDone);
|
||||
otEXPECT_ACTION(ECODE_OK == status, result = false);
|
||||
|
||||
sReceiveFifo.mWrite += kDmaBlockSize;
|
||||
exit:
|
||||
return result;
|
||||
UARTDRV_Receive(aHandle, aData, 1, receiveDone);
|
||||
}
|
||||
|
||||
static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aData, UARTDRV_Count_t aCount)
|
||||
@@ -185,69 +115,26 @@ static void transmitDone(UARTDRV_Handle_t aHandle, Ecode_t aStatus, uint8_t *aDa
|
||||
|
||||
static void processReceive(void)
|
||||
{
|
||||
uint16_t readEnd;
|
||||
uint8_t * buffer;
|
||||
UARTDRV_Count_t itemsReceived;
|
||||
UARTDRV_Count_t itemsRemaining;
|
||||
uint16_t wrappedReadStart;
|
||||
uint16_t wrappedReadEnd;
|
||||
uint16_t readLength;
|
||||
CORE_DECLARE_NVIC_STATE;
|
||||
// Copy tail to prevent multiple reads
|
||||
uint16_t tail = sReceiveFifo.mTail;
|
||||
|
||||
CORE_ENTER_NVIC(&sRxNvicMask);
|
||||
|
||||
UARTDRV_GetReceiveStatus(sUartHandle, &buffer, &itemsReceived, &itemsRemaining);
|
||||
if (buffer != NULL)
|
||||
// If the data wraps around, process the first part
|
||||
if (sReceiveFifo.mHead > tail)
|
||||
{
|
||||
// Only update the receive progress if a current receive is in progress (buffer not NULL)
|
||||
updateReceiveProgress(buffer, itemsReceived);
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, kReceiveFifoSize - sReceiveFifo.mHead);
|
||||
|
||||
// Reset the buffer mHead back to zero.
|
||||
sReceiveFifo.mHead = 0;
|
||||
}
|
||||
|
||||
readEnd = sReceiveFifo.mReadEnd;
|
||||
|
||||
CORE_EXIT_NVIC();
|
||||
|
||||
wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
|
||||
wrappedReadEnd = readEnd % kReceiveFifoSize;
|
||||
|
||||
if (!isBufferEmpty(sReceiveFifo.mReadStart, readEnd))
|
||||
// For any data remaining, process it
|
||||
if (sReceiveFifo.mHead != tail)
|
||||
{
|
||||
if (wrappedReadStart >= wrappedReadEnd)
|
||||
{
|
||||
// The buffer isn't empty, and wrappedReadStart >= wrappedReadEnd. Firstly, data needs to be read
|
||||
// from wrappedReadStart to the end of the buffer. Subsequently, data can then be read from the start
|
||||
// of the buffer to wrappedReadEnd.
|
||||
readLength = kReceiveFifoSize - wrappedReadStart;
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + wrappedReadStart, readLength);
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + sReceiveFifo.mHead, tail - sReceiveFifo.mHead);
|
||||
|
||||
// Move the read start index by the amount of data read
|
||||
sReceiveFifo.mReadStart += readLength;
|
||||
}
|
||||
|
||||
// mReadStart may have been modified above, so recalculate wrappedReadStart
|
||||
wrappedReadStart = sReceiveFifo.mReadStart % kReceiveFifoSize;
|
||||
|
||||
if (!isBufferEmpty(sReceiveFifo.mReadStart, readEnd))
|
||||
{
|
||||
// There is still data in the buffer (i.e. wrappedReadStart < wrappedReadEnd)
|
||||
readLength = wrappedReadEnd - wrappedReadStart;
|
||||
otPlatUartReceived(sReceiveFifo.mBuffer + wrappedReadStart, readLength);
|
||||
|
||||
// All data has been read
|
||||
sReceiveFifo.mReadStart = readEnd;
|
||||
}
|
||||
// Set mHead to the local tail we have cached
|
||||
sReceiveFifo.mHead = tail;
|
||||
}
|
||||
|
||||
CORE_ENTER_NVIC(&sRxNvicMask);
|
||||
|
||||
// The buffer has been emptied, but it may have since filled up again just before entering this critical section.
|
||||
// Attempt to enqueue any receive operations that previously failed to enqueue due to a full buffer.
|
||||
if (sReceiveDeferred)
|
||||
{
|
||||
sReceiveDeferred = !enqueueNextReceive();
|
||||
}
|
||||
|
||||
CORE_EXIT_NVIC();
|
||||
}
|
||||
|
||||
otError otPlatUartFlush(void)
|
||||
@@ -266,33 +153,19 @@ static void processTransmit(void)
|
||||
|
||||
otError otPlatUartEnable(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
UARTDRV_Init_t uartInit = USART_INIT;
|
||||
bool enqueuedReceive;
|
||||
|
||||
memset(&sRxNvicMask, 0, sizeof(sRxNvicMask));
|
||||
CORE_NvicMaskSetIRQ(LDMA_IRQn, &sRxNvicMask);
|
||||
CORE_NvicMaskSetIRQ(USART_PORT_RX_IRQn, &sRxNvicMask);
|
||||
sReceiveFifo.mHead = 0;
|
||||
sReceiveFifo.mTail = 0;
|
||||
|
||||
sReceiveFifo.mReadStart = 0;
|
||||
sReceiveFifo.mReadEnd = 0;
|
||||
sReceiveFifo.mWrite = 0;
|
||||
sTransmitLength = 0;
|
||||
sTransmitBuffer = NULL;
|
||||
UARTDRV_Init(sUartHandle, &uartInit);
|
||||
|
||||
otEXPECT_ACTION(ECODE_OK == UARTDRV_Init(sUartHandle, &uartInit), error = OT_ERROR_FAILED);
|
||||
for (uint8_t i = 0; i < sizeof(sReceiveBuffer); i++)
|
||||
{
|
||||
UARTDRV_Receive(sUartHandle, &sReceiveBuffer[i], sizeof(sReceiveBuffer[i]), receiveDone);
|
||||
}
|
||||
|
||||
CORE_DECLARE_NVIC_STATE;
|
||||
CORE_ENTER_NVIC(&sRxNvicMask);
|
||||
|
||||
enqueuedReceive = enqueueNextReceive();
|
||||
|
||||
CORE_EXIT_NVIC();
|
||||
|
||||
otEXPECT_ACTION(enqueuedReceive, error = OT_ERROR_FAILED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatUartDisable(void)
|
||||
@@ -303,15 +176,14 @@ otError otPlatUartDisable(void)
|
||||
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ecode_t status;
|
||||
|
||||
otEXPECT_ACTION(sTransmitBuffer == NULL, error = OT_ERROR_BUSY);
|
||||
|
||||
sTransmitBuffer = aBuf;
|
||||
sTransmitLength = aBufLength;
|
||||
|
||||
status = UARTDRV_Transmit(sUartHandle, (uint8_t *)sTransmitBuffer, sTransmitLength, transmitDone);
|
||||
otEXPECT_ACTION(ECODE_OK == status, error = OT_ERROR_FAILED);
|
||||
UARTDRV_Transmit(sUartHandle, (uint8_t *)sTransmitBuffer, sTransmitLength, transmitDone);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user