
/**
 ******************************************************************************
 *
 * @file        RingBuffer2.c
 * @brief       Ring Buffer routine.
 *
 * @par         Project
 *              MG32
 * @version     V1.01
 * @date        2021/05/31
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/
#include "RingBuffer.h"
#include <string.h>

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/

void RingBuffer_Init(RingBuffer *pBuffer)
{
    pBuffer->head = pBuffer->tail = 0;
    memset(pBuffer->buf, 0, RING_BUFFER_LENGTH);
}

uint16_t RingBuffer_Read(RingBuffer *pBuffer, uint8_t *pData, uint16_t Length)
{
    uint16_t counter = 0;

    while(pBuffer->tail != pBuffer->head && counter < Length)
    {
        pData[counter++] = pBuffer->buf[pBuffer->tail];
        pBuffer->tail = (pBuffer->tail + 1) % RING_BUFFER_LENGTH;
    }
    return counter;
}

uint8_t RingBuffer_Write(RingBuffer *pBuffer, uint8_t *pData, uint16_t Length)
{
    uint16_t counter = 0;
    uint16_t freeSpace = RingBuffer_GetFreeSpace(pBuffer);

    if(freeSpace == 0)
        return RING_BUFFER_FULL;
    else if (freeSpace < Length)
        return RING_BUFFER_NO_SUFFICIENT_SPACE;

    while(counter < Length)
    {
        pBuffer->buf[pBuffer->head] = pData[counter++];
        pBuffer->head = (pBuffer->head + 1) % RING_BUFFER_LENGTH;
    }
    return RING_BUFFER_OK;
}

uint16_t RingBuffer_GetFreeSpace(RingBuffer *pBuffer)
{
    if(pBuffer->tail == pBuffer->head)
    return RING_BUFFER_LENGTH - 1;

    if(pBuffer->head > pBuffer->tail)
        return RING_BUFFER_LENGTH - ((pBuffer->head - pBuffer->tail) + 1);
    else
        return  (pBuffer->tail - pBuffer->head) - 1;
}

uint16_t RingBuffer_GetDataLength(RingBuffer *pBuffer)
{
    return RING_BUFFER_LENGTH - (RingBuffer_GetFreeSpace(pBuffer) + 1);
}


