178 lines
4.6 KiB
C
178 lines
4.6 KiB
C
|
/*
|
||
|
* @brief Common ring buffer support functions
|
||
|
*
|
||
|
* @note
|
||
|
* Copyright(C) NXP Semiconductors, 2012
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* @par
|
||
|
* Software that is described herein is for illustrative purposes only
|
||
|
* which provides customers with programming information regarding the
|
||
|
* LPC products. This software is supplied "AS IS" without any warranties of
|
||
|
* any kind, and NXP Semiconductors and its licensor disclaim any and
|
||
|
* all warranties, express or implied, including all implied warranties of
|
||
|
* merchantability, fitness for a particular purpose and non-infringement of
|
||
|
* intellectual property rights. NXP Semiconductors assumes no responsibility
|
||
|
* or liability for the use of the software, conveys no license or rights under any
|
||
|
* patent, copyright, mask work right, or any other intellectual property rights in
|
||
|
* or to any products. NXP Semiconductors reserves the right to make changes
|
||
|
* in the software without notification. NXP Semiconductors also makes no
|
||
|
* representation or warranty that such application will be suitable for the
|
||
|
* specified use without further testing or modification.
|
||
|
*
|
||
|
* @par
|
||
|
* Permission to use, copy, modify, and distribute this software and its
|
||
|
* documentation is hereby granted, under NXP Semiconductors' and its
|
||
|
* licensor's relevant copyrights in the software, without fee, provided that it
|
||
|
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||
|
* copyright, permission, and disclaimer notice must appear in all copies of
|
||
|
* this code.
|
||
|
*/
|
||
|
|
||
|
#include "ring_buffer.h"
|
||
|
|
||
|
|
||
|
|
||
|
int32_t RingBuf_Init(ring_buffer_t* pRB, uint8_t* buffer, uint32_t size )
|
||
|
{
|
||
|
pRB->pBuf = (uint8_t*)buffer;
|
||
|
pRB->size = size;
|
||
|
pRB->rNdx = 0;
|
||
|
pRB->wNdx = 0;
|
||
|
pRB->cnt = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Deinit(ring_buffer_t* pRB )
|
||
|
{
|
||
|
pRB = pRB;;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_GetFreeBytes(ring_buffer_t* pRB )
|
||
|
{
|
||
|
return pRB->size - pRB->cnt;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_GetUsedBytes(ring_buffer_t* pRB)
|
||
|
{
|
||
|
return pRB->cnt;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Write(ring_buffer_t* pRB, const uint8_t* data, uint32_t dataBytes)
|
||
|
{
|
||
|
uint32_t writeToEnd, bytesToCopy;
|
||
|
INIT_CRITICAL();
|
||
|
ENTER_CRITICAL();
|
||
|
/* Calculate the maximum amount we can copy */
|
||
|
writeToEnd = pRB->size - pRB->wNdx;
|
||
|
bytesToCopy = MIN(dataBytes, pRB->size - pRB->cnt);
|
||
|
|
||
|
if (bytesToCopy != 0)
|
||
|
{
|
||
|
/* Copy as much as we can until we fall off the end of the buffer */
|
||
|
memcpy(&pRB->pBuf[pRB->wNdx], data, MIN(bytesToCopy, writeToEnd));
|
||
|
|
||
|
/* Check if we have more to copy to the front of the buffer */
|
||
|
if (writeToEnd < bytesToCopy)
|
||
|
{
|
||
|
memcpy(pRB->pBuf, data + writeToEnd, bytesToCopy - writeToEnd);
|
||
|
}
|
||
|
|
||
|
/* Update the wNdx */
|
||
|
|
||
|
pRB->wNdx = (pRB->wNdx + bytesToCopy) % pRB->size;
|
||
|
pRB->cnt += dataBytes;
|
||
|
}
|
||
|
LEAVE_CRITICAL();
|
||
|
return bytesToCopy;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Write1Byte(ring_buffer_t* pRB, const uint8_t *pcData)
|
||
|
{
|
||
|
uint32_t ret = 0;
|
||
|
INIT_CRITICAL();
|
||
|
ENTER_CRITICAL();
|
||
|
if (pRB->cnt < pRB->size)
|
||
|
{
|
||
|
pRB->pBuf[pRB->wNdx] = pcData[0];
|
||
|
pRB->wNdx = (pRB->wNdx + 1) % pRB->size;
|
||
|
pRB->cnt++;
|
||
|
ret = 1;
|
||
|
}
|
||
|
LEAVE_CRITICAL();
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int32_t _prvRingBuf_Read(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes, uint32_t isToFree)
|
||
|
{
|
||
|
uint32_t readToEnd, bytesToCopy;
|
||
|
INIT_CRITICAL();
|
||
|
ENTER_CRITICAL();
|
||
|
readToEnd = pRB->size - pRB->rNdx;
|
||
|
bytesToCopy = MIN(dataBytes, pRB->cnt);
|
||
|
if (bytesToCopy != 0)
|
||
|
{
|
||
|
memcpy(data, &pRB->pBuf[pRB->rNdx], MIN(bytesToCopy, readToEnd));
|
||
|
|
||
|
if (readToEnd < bytesToCopy)
|
||
|
memcpy(data + readToEnd, &pRB->pBuf[0], bytesToCopy - readToEnd);
|
||
|
|
||
|
if (isToFree)
|
||
|
{
|
||
|
pRB->rNdx = (pRB->rNdx + bytesToCopy) % pRB->size;
|
||
|
pRB->cnt -= bytesToCopy;
|
||
|
}
|
||
|
}
|
||
|
LEAVE_CRITICAL();
|
||
|
|
||
|
return bytesToCopy;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Read(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes)
|
||
|
{
|
||
|
return _prvRingBuf_Read(pRB, data, dataBytes, 1);
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Copy(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes)
|
||
|
{
|
||
|
return _prvRingBuf_Read(pRB, data, dataBytes, 0);
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Read1Byte(ring_buffer_t* pRB, uint8_t *pData)
|
||
|
{
|
||
|
uint32_t ret = 0;
|
||
|
INIT_CRITICAL();
|
||
|
ENTER_CRITICAL();
|
||
|
if (pRB->cnt != 0)
|
||
|
{
|
||
|
pData[0] = pRB->pBuf[pRB->rNdx];
|
||
|
pRB->rNdx = (pRB->rNdx + 1) % pRB->size;
|
||
|
pRB->cnt--;
|
||
|
ret = 1;
|
||
|
}
|
||
|
LEAVE_CRITICAL();
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Peek(ring_buffer_t* pRB, uint8_t **ppData)
|
||
|
{
|
||
|
uint32_t readToEnd = pRB->size - pRB->rNdx;
|
||
|
uint32_t contiguousBytes;
|
||
|
*ppData = &(pRB->pBuf[pRB->rNdx]);
|
||
|
contiguousBytes = MIN(readToEnd, (readToEnd + pRB->wNdx) % pRB->size);
|
||
|
return contiguousBytes;
|
||
|
}
|
||
|
|
||
|
int32_t RingBuf_Free(ring_buffer_t* pRB, uint32_t bytesToFree)
|
||
|
{
|
||
|
INIT_CRITICAL();
|
||
|
ENTER_CRITICAL();
|
||
|
pRB->rNdx = (pRB->rNdx + bytesToFree) % pRB->size;
|
||
|
pRB->cnt -= bytesToFree;
|
||
|
LEAVE_CRITICAL();
|
||
|
return bytesToFree;
|
||
|
}
|
||
|
|
||
|
|