Files
ch32v20x-examples/EVT/EXAM/BLE/BLE_USB/APP/RingMem.c
T
2023-09-06 10:08:11 +08:00

338 lines
6.7 KiB
C

/********************************** (C) COPYRIGHT *******************************
* File Name : RingMem.C
* Author : WCH
* Version : V1.4
* Date : 2019/12/20
* Description :
* NOTE : If use interrupts, you need to pay attention to the switch interrupt
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "RingMem.h"
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* PUBLIC FUNCTIONS
*/
RingMemProtection_t RingMemProtection;
/*********************************************************************
* @fn RingMemInit
*
* @brief 初始化
*
* @param none
*
* @return none
*/
void RingMemInit( RingMemParm_t *Parm, uint8_t *StartAddr, uint32_t MaxLen, RingMemProtection_t Protection )
{
Parm->pData = StartAddr;
Parm->pWrite = StartAddr;
Parm->pRead = StartAddr;
Parm->RemanentLen = MaxLen;
Parm->CurrentLen = 0;
Parm->pEnd = StartAddr + MaxLen;
Parm->MaxLen = MaxLen;
RingMemProtection = Protection;
}
/*********************************************************************
* @fn RingMemWrite
*
* @brief 往里写
*
* @param none
*
* @return none
*/
uint8_t RingMemWrite( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
{
uint32_t i,edgelen;
if(RingMemProtection)
{
RingMemProtection(ENABLE);
}
if( len > Parm->RemanentLen )
return !SUCCESS;
edgelen = Parm->pEnd - Parm->pWrite; //Calculate the length of the remaining to the boundary
if( len > edgelen )
{
for(i=0; i<edgelen; i++)
{
*Parm->pWrite++ = *pData++;
}
Parm->pWrite = Parm->pData;
for(i=0; i<(len-edgelen); i++)
{
*Parm->pWrite++ = *pData++;
}
}
else
{
for(i=0; i<len; i++)
{
*Parm->pWrite++ = *pData++;
}
}
Parm->RemanentLen -= len;
Parm->CurrentLen += len;
if(RingMemProtection)
{
RingMemProtection(DISABLE);
}
return SUCCESS;
}
/*********************************************************************
* @fn RingMemRead
*
* @brief 往外读
*
* @param none
*
* @return none
*/
uint8_t RingMemRead( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
{
uint32_t i,edgelen;
if(RingMemProtection)
{
RingMemProtection(ENABLE);
}
if( len > Parm->CurrentLen ) //Not enough reading length
return !SUCCESS;
edgelen = Parm->pEnd - Parm->pRead; //Calculate the length of the remaining to the boundarythe length of the remaining to the boundary
if( len > edgelen )
{
for(i=0; i<edgelen; i++)
{
*pData++ = *Parm->pRead++;
}
Parm->pRead = Parm->pData;
for(i=0; i<(len-edgelen); i++)
{
*pData++ = *Parm->pRead++;
}
}
else
{
for(i=0; i<len; i++)
{
*pData++ = *Parm->pRead++;
}
}
Parm->RemanentLen += len;
Parm->CurrentLen -= len;
if(RingMemProtection)
{
RingMemProtection(DISABLE);
}
return SUCCESS;
}
/*********************************************************************
* @fn RingMemCopy
*
* @brief Don't delete it after reading
*
* @param none
*
* @return none
*/
uint8_t RingMemCopy( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
{
uint32_t i,edgelen;
if(RingMemProtection)
{
RingMemProtection(ENABLE);
}
uint8_t volatile *pRead = Parm->pRead;
if( len > Parm->CurrentLen ) //The length that can be copied is not enough
return !SUCCESS;
edgelen = Parm->pEnd - Parm->pRead; //Calculate the length of the remaining to the boundary
if( len > edgelen )
{
for(i=0; i<edgelen; i++)
{
*pData++ = *pRead++;
}
pRead = Parm->pData;
for(i=0; i<(len-edgelen); i++)
{
*pData++ = *pRead++;
}
}
else
{
for(i=0; i<len; i++)
{
*pData++ = *pRead++;
}
}
if(RingMemProtection)
{
RingMemProtection(DISABLE);
}
return SUCCESS;
}
/*********************************************************************
* @fn RingMemDelete
*
* @brief Delete directly
*
* @param none
*
* @return none
*/
uint8_t RingMemDelete( RingMemParm_t *Parm, uint32_t len )
{
uint32_t edgelen;
if(RingMemProtection)
{
RingMemProtection(ENABLE);
}
if( len > Parm->CurrentLen ) //Can delete not enough length
return !SUCCESS;
edgelen = Parm->pEnd - Parm->pRead; //Calculate the length of the remaining to the boundary
if( len > edgelen )
{
Parm->pRead+=edgelen;
Parm->pRead = Parm->pData;
Parm->pRead+=(len-edgelen);
}
else
{
Parm->pRead+=len;
}
Parm->RemanentLen += len;
Parm->CurrentLen -= len;
if(RingMemProtection)
{
RingMemProtection(DISABLE);
}
return SUCCESS;
}
/*********************************************************************
* @fn RingAddInStart
*
* @brief 向缓冲区开始处添加数据
*
* @param none
*
* @return none
*/
uint8_t RingAddInStart( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
{
uint32_t i,edgelen;
if(RingMemProtection)
{
RingMemProtection(ENABLE);
}
if( len > Parm->RemanentLen )
return !SUCCESS;
edgelen = Parm->pRead - Parm->pData; //Calculate the length of the remaining to the boundary
if( len > edgelen )
{
for(i=0; i<edgelen; i++)
{
*Parm->pRead-- = *pData++;
}
Parm->pRead = Parm->pData + Parm->MaxLen;
for(i=0; i<(len-edgelen); i++)
{
*Parm->pRead-- = *pData++;
}
}
else
{
for(i=0; i<len; i++)
{
*Parm->pRead-- = *pData++;
}
}
Parm->RemanentLen -= len;
Parm->CurrentLen += len;
if(RingMemProtection)
{
RingMemProtection(DISABLE);
}
return SUCCESS;
}
/*********************************************************************
* @fn RingCopyOneData
*
* @brief Back the first data on the basis of the first address
*
* @param none
*
* @return none
*/
uint8_t RingReturnSingleData( RingMemParm_t *Parm, uint32_t Num )
{
uint32_t edgelen;
if( Parm->RemanentLen < Parm->MaxLen )
{
edgelen = Parm->pEnd - Parm->pRead;
if( Num >= edgelen )
{
return Parm->pData[Num - edgelen];
}
else
{
return Parm->pRead[Num];
}
}
else
return 0;
}
/*********************************************************************
*********************************************************************/