| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /* ----------------------------------------------------------------------
- * Project: CMSIS DSP Library
- * Title: RingBuffer.cpp
- * Description: Implementation of the Ring buffer.
- *
- * $Date: 30 July 2021
- * $Revision: V1.10.0
- *
- * Target Processor: Cortex-M and Cortex-A cores
- * -------------------------------------------------------------------- */
- /*
- * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the License); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- RTOS dependent definitions must be in RingPrivate.h.
- Without a RingPrivate.h, this code cannot work.
- */
- #include "RingPrivate.h"
- #include "RingBuffer.h"
- /*
- RTOS Integration
- */
- #ifndef RING_BEGINCRITICALSECTION
- #define RING_BEGINCRITICALSECTION()
- #endif
- #ifndef RING_ENDCRITICALSECTION
- #define RING_ENDCRITICALSECTION()
- #endif
- #ifndef RING_WAIT_BUFFER
- #define RING_WAIT_BUFFER(ID) 0
- #endif
- #ifndef RING_RELEASE_BUFFER
- #define RING_RELEASE_BUFFER(THREADID)
- #endif
- #ifndef RING_HASWAITERROR
- #define RING_HASWAITERROR(ERR) 0
- #endif
- /*
- Debug integration
- */
- #ifndef RING_DBG_USER_RESERVE_BUFFER
- #define RING_DBG_USER_RESERVE_BUFFER(ID,CONF)
- #endif
- #ifndef RING_DBG_USER_RELEASE_BUFFER
- #define RING_DBG_USER_RELEASE_BUFFER(ID,CONF)
- #endif
- #ifndef RING_DBG_USER_WAIT_BUFFER
- #define RING_DBG_USER_WAIT_BUFFER(ID,CONF)
- #endif
- #ifndef RING_DBG_USER_BUFFER_RELEASED
- #define RING_DBG_USER_BUFFER_RELEASED(ID,CONF)
- #endif
- #ifndef RING_DBG_USER_STATUS
- #define RING_DBG_USER_STATUS(SA,SB,CONF)
- #endif
- #ifndef RING_DBG_INT_RESERVE_BUFFER
- #define RING_DBG_INT_RESERVE_BUFFER(ID,CONF)
- #endif
- #ifndef RING_DBG_INT_RELEASE_BUFFER
- #define RING_DBG_INT_RELEASE_BUFFER(ID,CONF)
- #endif
- #ifndef RING_DBG_INT_RELEASE_USER
- #define RING_DBG_INT_RELEASE_USER(CONF)
- #endif
- #ifndef RING_DBG_INT_STATUS
- #define RING_DBG_INT_STATUS(SA,SB,CONF)
- #endif
- #ifndef RING_DBG_ERROR
- #define RING_DBG_ERROR(ERROR,CONF)
- #endif
- /*
- Implementation
- */
- #define RING_SET(FIELD,BIT) (config->FIELD) |= (1 << (config->BIT))
- #define RING_CLEAR(FIELD,BIT) (config->FIELD) &= ~(1 << (config->BIT))
- #define RING_TEST(FIELD,BIT) (((config->FIELD) & (1 << (config->BIT))) != 0)
- #define RING_INC(ID) \
- config->ID++; \
- if (config->ID == config->nbBuffers)\
- { \
- config->ID=0; \
- }
- #define RING_BUSY(ID) \
- (RING_TEST(userBufferStatus,ID) || RING_TEST(intBufferStatus,ID))
- void ringInit(ring_config_t *config,
- uint32_t nbBuffers,
- uint32_t bufferSize,
- uint8_t *buffer,
- int interruptID,
- int timeout)
- {
-
- config->buffer=buffer;
- config->nbBuffers = nbBuffers;
- config->bufferSize = bufferSize;
- config->interruptBufferIDStart = 0;
- config->interruptBufferIDStop = 0;
- config->userBufferIDStart = 0;
- config->userBufferIDStop = 0;
- config->error=kNoError;
- config->waiting=0;
- config->timeout=timeout;
- config->interruptID = interruptID;
- config->userBufferStatus = 0;
- config->intBufferStatus = 0;
-
- }
- void ringClean(ring_config_t *config)
- {
- }
- uint8_t *ringGetBufferAddress(ring_config_t *config,int id)
- {
- if (id < 0)
- {
- return(NULL);
- }
- else
- {
- return(&config->buffer[id*config->bufferSize]);
- }
- }
- int ringInterruptReserveBuffer(ring_config_t *config)
- {
- RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus,config);
- if (config->error)
- {
- return(-1);
- }
- /* Try to reserve a buffer */
- if (RING_BUSY(interruptBufferIDStop))
- {
- /* If buffer is already used then kErrorOverflowUnderflow*/
- config->error=kErrorOverflowUnderflow;
- RING_DBG_ERROR(config->error,config);
- return(-1);
- }
- else
- {
- RING_DBG_INT_RESERVE_BUFFER(config->interruptBufferIDStop,config);
- RING_SET(intBufferStatus,interruptBufferIDStop);
- RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus,config);
- int id=config->interruptBufferIDStop;
- RING_INC(interruptBufferIDStop);
- return(id);
- }
- }
- void ringInterruptReleaseBuffer(ring_config_t *config,void *threadId)
- {
- RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus,config);
- if (config->error)
- {
- return;
- }
- if (config->interruptBufferIDStart != config->interruptBufferIDStop)
- {
- RING_DBG_INT_RELEASE_BUFFER(config->interruptBufferIDStart,config);
- RING_CLEAR(intBufferStatus,interruptBufferIDStart);
- /* Send release message in case the thread may be waiting */
- if (config->interruptBufferIDStart == config->userBufferIDStop)
- {
- if (config->waiting)
- {
- RING_DBG_INT_RELEASE_USER(config);
- RING_RELEASE_BUFFER(threadId);
- }
- }
- RING_INC(interruptBufferIDStart);
- }
- }
- int ringUserReserveBuffer(ring_config_t *config)
- {
- RING_BEGINCRITICALSECTION();
- RING_DBG_USER_STATUS(userBufferStatus,intBufferStatus,config);
- if (config->error)
- {
- RING_ENDCRITICALSECTION();
- return(-1);
- }
- /* If buffer is busy we wait*/
- if (RING_BUSY(userBufferIDStop))
- {
- config->waiting=1;
- RING_DBG_USER_WAIT_BUFFER(config->userBufferIDStop,config);
- RING_ENDCRITICALSECTION();
- int err = RING_WAIT_BUFFER(config->timeout);
- RING_BEGINCRITICALSECTION();
- RING_DBG_USER_BUFFER_RELEASED(config->userBufferIDStop,config);
- if (RING_HASWAITERROR(err))
- {
- RING_DBG_ERROR(err,config);
- config->error=kTimeout;
- return(-1);
- }
-
- }
-
- RING_DBG_USER_RESERVE_BUFFER(config->userBufferIDStop,config);
- RING_SET(userBufferStatus,userBufferIDStop);
- int id=config->userBufferIDStop;
- RING_INC(userBufferIDStop);
- RING_ENDCRITICALSECTION();
-
- return(id);
- }
- void ringUserReleaseBuffer(ring_config_t *config)
- {
- RING_BEGINCRITICALSECTION();
- RING_DBG_USER_STATUS(userBufferStatus,intBufferStatus,config);
- if (config->error)
- {
- RING_ENDCRITICALSECTION();
- return;
- }
- if (config->userBufferIDStart != config->userBufferIDStop)
- {
- RING_DBG_USER_RELEASE_BUFFER(config->userBufferIDStart,config);
- RING_CLEAR(userBufferStatus,userBufferIDStart);
- RING_INC(userBufferIDStart);
- }
-
- RING_ENDCRITICALSECTION();
- }
|