CMSIS-DSP: Improve integration of VHT and SDF

pull/19/head
Christophe Favergeon 4 years ago
parent b984d738f4
commit ab6a89a628

@ -30,6 +30,7 @@
#include "RingBuffer.h"
template<typename IN, int inputSize>
class AudioSink: public GenericSink<IN, inputSize>
{

@ -67,43 +67,43 @@ Debug integration
*/
#ifndef RING_DBG_USER_RESERVE_BUFFER
#define RING_DBG_USER_RESERVE_BUFFER(ID)
#define RING_DBG_USER_RESERVE_BUFFER(ID,CONF)
#endif
#ifndef RING_DBG_USER_RELEASE_BUFFER
#define RING_DBG_USER_RELEASE_BUFFER(ID)
#define RING_DBG_USER_RELEASE_BUFFER(ID,CONF)
#endif
#ifndef RING_DBG_USER_WAIT_BUFFER
#define RING_DBG_USER_WAIT_BUFFER(ID)
#define RING_DBG_USER_WAIT_BUFFER(ID,CONF)
#endif
#ifndef RING_DBG_USER_BUFFER_RELEASED
#define RING_DBG_USER_BUFFER_RELEASED(ID)
#define RING_DBG_USER_BUFFER_RELEASED(ID,CONF)
#endif
#ifndef RING_DBG_USER_STATUS
#define RING_DBG_USER_STATUS(SA,SB)
#define RING_DBG_USER_STATUS(SA,SB,CONF)
#endif
#ifndef RING_DBG_INT_RESERVE_BUFFER
#define RING_DBG_INT_RESERVE_BUFFER(ID)
#define RING_DBG_INT_RESERVE_BUFFER(ID,CONF)
#endif
#ifndef RING_DBG_INT_RELEASE_BUFFER
#define RING_DBG_INT_RELEASE_BUFFER(ID)
#define RING_DBG_INT_RELEASE_BUFFER(ID,CONF)
#endif
#ifndef RING_DBG_INT_RELEASE_USER
#define 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)
#define RING_DBG_INT_STATUS(SA,SB,CONF)
#endif
#ifndef RING_DBG_ERROR
#define RING_DBG_ERROR(ERROR)
#define RING_DBG_ERROR(ERROR,CONF)
#endif
/*
@ -127,7 +127,12 @@ Implementation
(RING_TEST(userBufferStatus,ID) || RING_TEST(intBufferStatus,ID))
void ringInit(ring_config_t *config,uint32_t nbBuffers,uint32_t bufferSize,uint8_t *buffer,int timeout)
void ringInit(ring_config_t *config,
uint32_t nbBuffers,
uint32_t bufferSize,
uint8_t *buffer,
int interruptID,
int timeout)
{
config->buffer=buffer;
@ -141,7 +146,7 @@ void ringInit(ring_config_t *config,uint32_t nbBuffers,uint32_t bufferSize,uint8
config->waiting=0;
config->timeout=timeout;
config->interruptID = interruptID;
config->userBufferStatus = 0;
config->intBufferStatus = 0;
@ -165,7 +170,7 @@ uint8_t *ringGetBufferAddress(ring_config_t *config,int id)
int ringInterruptReserveBuffer(ring_config_t *config)
{
RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus);
RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus,config);
if (config->error)
{
return(-1);
@ -176,14 +181,14 @@ int ringInterruptReserveBuffer(ring_config_t *config)
{
/* If buffer is already used then kErrorOverflowUnderflow*/
config->error=kErrorOverflowUnderflow;
RING_DBG_ERROR(config->error);
RING_DBG_ERROR(config->error,config);
return(-1);
}
else
{
RING_DBG_INT_RESERVE_BUFFER(config->interruptBufferIDStop);
RING_DBG_INT_RESERVE_BUFFER(config->interruptBufferIDStop,config);
RING_SET(intBufferStatus,interruptBufferIDStop);
RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus);
RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus,config);
int id=config->interruptBufferIDStop;
RING_INC(interruptBufferIDStop);
return(id);
@ -192,21 +197,21 @@ int ringInterruptReserveBuffer(ring_config_t *config)
void ringInterruptReleaseBuffer(ring_config_t *config,void *threadId)
{
RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus);
RING_DBG_INT_STATUS(userBufferStatus,intBufferStatus,config);
if (config->error)
{
return;
}
if (config->interruptBufferIDStart != config->interruptBufferIDStop)
{
RING_DBG_INT_RELEASE_BUFFER(config->interruptBufferIDStart);
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();
RING_DBG_INT_RELEASE_USER(config);
RING_RELEASE_BUFFER(threadId);
}
}
@ -217,7 +222,7 @@ void ringInterruptReleaseBuffer(ring_config_t *config,void *threadId)
int ringUserReserveBuffer(ring_config_t *config)
{
RING_BEGINCRITICALSECTION();
RING_DBG_USER_STATUS(userBufferStatus,intBufferStatus);
RING_DBG_USER_STATUS(userBufferStatus,intBufferStatus,config);
if (config->error)
{
RING_ENDCRITICALSECTION();
@ -227,23 +232,23 @@ int ringUserReserveBuffer(ring_config_t *config)
if (RING_BUSY(userBufferIDStop))
{
config->waiting=1;
RING_DBG_USER_WAIT_BUFFER(config->userBufferIDStop);
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);
RING_DBG_USER_BUFFER_RELEASED(config->userBufferIDStop,config);
if (RING_HASWAITERROR(err))
{
RING_DBG_ERROR(err);
RING_DBG_ERROR(err,config);
config->error=kTimeout;
return(-1);
}
}
RING_DBG_USER_RESERVE_BUFFER(config->userBufferIDStop);
RING_DBG_USER_RESERVE_BUFFER(config->userBufferIDStop,config);
RING_SET(userBufferStatus,userBufferIDStop);
int id=config->userBufferIDStop;
RING_INC(userBufferIDStop);
@ -256,7 +261,7 @@ int ringUserReserveBuffer(ring_config_t *config)
void ringUserReleaseBuffer(ring_config_t *config)
{
RING_BEGINCRITICALSECTION();
RING_DBG_USER_STATUS(userBufferStatus,intBufferStatus);
RING_DBG_USER_STATUS(userBufferStatus,intBufferStatus,config);
if (config->error)
{
RING_ENDCRITICALSECTION();
@ -264,7 +269,7 @@ void ringUserReleaseBuffer(ring_config_t *config)
}
if (config->userBufferIDStart != config->userBufferIDStop)
{
RING_DBG_USER_RELEASE_BUFFER(config->userBufferIDStart);
RING_DBG_USER_RELEASE_BUFFER(config->userBufferIDStart,config);
RING_CLEAR(userBufferStatus,userBufferIDStart);
RING_INC(userBufferIDStart);
}

@ -56,6 +56,7 @@ typedef struct {
int32_t waiting;
int timeout;
ring_error_t error;
int interruptID;
} ring_config_t;
@ -65,6 +66,7 @@ typedef struct {
* @param[in] nbBuffers number of buffers (max 32)
* @param[in] bufferSize size of each buffer in bytes
* @param[in] buffer array for the buffer storage (bufferSize*nbBuffers)
* @param[in] interruptID interrupt ID
* @param[in] timeout timeout (meaning is RTOS dependent)
* @return Nothing
*/
@ -72,6 +74,7 @@ typedef struct {
uint32_t nbBuffers,
uint32_t bufferSize,
uint8_t *buffer,
int interruptID,
int timeout);

@ -31,28 +31,25 @@
#include "RingBuffer.h"
/* Memory to use for the ring buffer.
ALIGNED in case it may be used directly by the HW
Each subbuffer must also be 4 bytes aligned.
The sizes should be defined in a RingConfig.h header.
*/
__ALIGNED(16) uint8_t ringBufferRX[RING_BUFSIZE*RING_NBBUFS];
__ALIGNED(16) uint8_t ringBufferTX[RING_BUFSIZE*RING_NBBUFS];
extern int32_t AudioDrv_Setup(void);
int initRingAndAudio(ring_config_t *ringConfigRX,ring_config_t *ringConfigTX, int timeOut)
int initRingAndAudio(ring_config_t *ringConfigRX,
uint8_t *rxBuffer,
int rxInterruptID,
ring_config_t *ringConfigTX,
uint8_t *txBuffer,
int txInterruptID,
int timeOut)
{
/* Initialization of the ring buffer data structure */
if (ringConfigRX != NULL)
{
ringInit(ringConfigRX,RING_NBBUFS,RING_BUFSIZE,ringBufferRX,timeOut);
ringInit(ringConfigRX,RING_NBBUFS,RING_BUFSIZE,rxBuffer,rxInterruptID,timeOut);
}
if (ringConfigTX != NULL)
{
ringInit(ringConfigTX,RING_NBBUFS,RING_BUFSIZE,ringBufferTX,timeOut);
ringInit(ringConfigTX,RING_NBBUFS,RING_BUFSIZE,txBuffer,txInterruptID,timeOut);
}
/* Initialization of the audio HW and reservation of first buffer from the

@ -37,7 +37,20 @@ extern "C"
{
#endif
int initRingAndAudio(ring_config_t *ringConfigRX,ring_config_t *ringConfigTX, int timeOut);
extern int32_t AudioDrv_Setup(void);
extern ring_config_t ringConfigRX;
extern ring_config_t ringConfigTX;
extern uint8_t* AudioRXBuffer();
extern uint8_t* AudioTXBuffer();
int initRingAndAudio(ring_config_t *ringConfigRX,
uint8_t *rxBuffer,
int rxInterruptID,
ring_config_t *ringConfigTX,
uint8_t *txBuffer,
int txInterruptID,
int timeOut);
#ifdef __cplusplus
}

@ -19,30 +19,30 @@
#include "RingInit.h"
#define AudioIn_IRQn ((IRQn_Type)ARM_VSI0_IRQn) /* Audio Input Interrupt number */
extern osThreadId_t gAudioThreadID;
// Number of bytes read by DMA
#define AUDIO_BLOCK_NUM (4)
#define AUDIO_BLOCK_SIZE RING_BUFSIZE
// Number of DMA blocks
#define AUDIO_DMA_NB_BLOCKS (RING_BUFSIZE >> 2)
#define AUDIO_DMA_NB_BLOCKS RING_NBBUFS
extern int32_t AudioDrv_Setup(void);
#if RX_ENABLED
extern ring_config_t ringConfigRX;
#ifdef __FVP_PY
__attribute__((section(".ARM.__at_0x90000000")))
#endif
__ALIGNED(16) static uint8_t audio_bufferRX[RING_BUFSIZE];
#if SDF_VHT_TX_RX_ORDERING
__ALIGNED(16) static uint8_t dmaRX[AUDIO_BLOCK_SIZE];
int rxCount=0;
#endif
__ALIGNED(16) static uint8_t audio_bufferRX[AUDIO_DMA_NB_BLOCKS*AUDIO_BLOCK_SIZE];
static uint8_t *reservedBufRX=NULL;
#endif
#if TX_ENABLED
@ -51,32 +51,50 @@ extern ring_config_t ringConfigTX;
#ifdef __FVP_PY
__attribute__((section(".ARM.__at_0x9FFF0000")))
#endif
__ALIGNED(16) static uint8_t audio_bufferTX[RING_BUFSIZE];
#if SDF_VHT_TX_RX_ORDERING
__ALIGNED(16) static uint8_t dmaTX[AUDIO_BLOCK_SIZE];
int txCount=0;
#endif
__ALIGNED(16) static uint8_t audio_bufferTX[AUDIO_DMA_NB_BLOCKS*AUDIO_BLOCK_SIZE];
static uint8_t *reservedBufTX=NULL;
#endif
uint8_t* AudioRXBuffer()
{
return(audio_bufferRX);
}
uint8_t* AudioTXBuffer()
{
return(audio_bufferTX);
}
static void AudioEvent (uint32_t event) {
#if RX_ENABLED
if (event & AUDIO_DRV_EVENT_RX_DATA)
{
if (reservedBufRX != NULL)
{
memcpy(reservedBufRX,audio_bufferRX,RING_BUFSIZE);
#if SDF_VHT_TX_RX_ORDERING
memcpy(reservedBufRX,dmaRX,RING_BUFSIZE);
(void)AudioDrv_Control(AUDIO_DRV_CONTROL_RX_DISABLE);
(void)AudioDrv_Control(AUDIO_DRV_CONTROL_TX_ENABLE);
#endif
ringInterruptReleaseBuffer(&ringConfigRX,(void *)gAudioThreadID);
int reservedRX=ringInterruptReserveBuffer(&ringConfigRX);
reservedBufRX=ringGetBufferAddress(&ringConfigRX,reservedRX);
}
}
#endif
#if TX_ENABLED
if (event & AUDIO_DRV_EVENT_TX_DATA)
{
if (reservedBufTX != NULL)
{
memcpy(audio_bufferTX,reservedBufTX,RING_BUFSIZE);
}
#if SDF_VHT_TX_RX_ORDERING
memcpy(dmaTX,reservedBufTX,RING_BUFSIZE);
(void)AudioDrv_Control(AUDIO_DRV_CONTROL_TX_DISABLE);
(void)AudioDrv_Control(AUDIO_DRV_CONTROL_RX_ENABLE);
#endif
ringInterruptReleaseBuffer(&ringConfigTX,(void *)gAudioThreadID);
int reservedTX=ringInterruptReserveBuffer(&ringConfigTX);
reservedBufTX=ringGetBufferAddress(&ringConfigTX,reservedTX);
@ -108,18 +126,26 @@ int32_t AudioDrv_Setup(void) {
int reservedRX=ringInterruptReserveBuffer(&ringConfigRX);
reservedBufRX=ringGetBufferAddress(&ringConfigRX,reservedRX);
#if SDF_VHT_TX_RX_ORDERING
ret = AudioDrv_SetBuf(AUDIO_DRV_INTERFACE_RX,
audio_bufferRX, AUDIO_BLOCK_NUM, AUDIO_DMA_NB_BLOCKS);
dmaRX, 1,AUDIO_BLOCK_SIZE);
#else
ret = AudioDrv_SetBuf(AUDIO_DRV_INTERFACE_RX,
audio_bufferRX, AUDIO_DMA_NB_BLOCKS,AUDIO_BLOCK_SIZE);
#endif
if (ret != 0) {
return ret;
}
#if !SDF_VHT_TX_RX_ORDERING
ret = AudioDrv_Control(AUDIO_DRV_CONTROL_RX_ENABLE);
if (ret != 0) {
return ret;
}
#endif
#endif /* RX_ENABLED */
#if TX_ENABLED
ret = AudioDrv_Configure(AUDIO_DRV_INTERFACE_TX,
AUDIO_NBCHANNELS, /* single channel */
@ -132,15 +158,24 @@ int32_t AudioDrv_Setup(void) {
/* Work because user process not started yet
*/
/* dataflow must be one packet ahead of the TX */
/* dataflow must be 1 packet ahead of the TX interrupt*/
ringUserReserveBuffer(&ringConfigTX);
ringUserReleaseBuffer(&ringConfigTX);
ringUserReserveBuffer(&ringConfigTX);
ringUserReleaseBuffer(&ringConfigTX);
int reservedTX=ringInterruptReserveBuffer(&ringConfigTX);
reservedBufTX=ringGetBufferAddress(&ringConfigTX,reservedTX);
#if SDF_VHT_TX_RX_ORDERING
ret = AudioDrv_SetBuf(AUDIO_DRV_INTERFACE_TX,
audio_bufferTX, AUDIO_BLOCK_NUM, AUDIO_DMA_NB_BLOCKS);
dmaTX, 1 ,AUDIO_BLOCK_SIZE);
#else
ret = AudioDrv_SetBuf(AUDIO_DRV_INTERFACE_TX,
audio_bufferTX, AUDIO_DMA_NB_BLOCKS,AUDIO_BLOCK_SIZE);
#endif
if (ret != 0) {
return ret;
}
@ -150,8 +185,7 @@ int32_t AudioDrv_Setup(void) {
return ret;
}
#endif
#endif /* TX_ENABLED */
return 0;

@ -10,10 +10,10 @@
#define AUDIO_SAMPLINGFREQUENCY 16000
#endif
// <o>Number of samples <100-3000>
// <o>Number of samples <256=> 256 <512=> 512 <1024=> 1024 <2048=> 2048
// <i> Must be consistent with the settings of the Audio source
#ifndef AUDIO_NBSAMPLES
#define AUDIO_NBSAMPLES 1600
#define AUDIO_NBSAMPLES 2048
#endif
// <o>Number of channels <1=> Mono <2=> Stereo
@ -32,12 +32,15 @@
// <q> TX_ENABLED: Enable TX
#define TX_ENABLED 1
// <q> SDF_VHT_TX_RX_ORDERING: Force TX RX ordering
#define SDF_VHT_TX_RX_ORDERING 0
// </h>
// <h>Ring Buffer Configuration
// <o>Number of buffers <2-32>
// <o>Number of buffers <2=> 2 <4=> 4 <8=> 8 <16=> 16 <32=> 32
#ifndef RING_NBBUFS
#define RING_NBBUFS 2
#define RING_NBBUFS 4
#endif
// </h>

@ -44,19 +44,14 @@ Implementation for RTX + Keil MDK Event logger
#include "cmsis_os2.h"
#ifndef AudioIn_IRQn
#define AudioIn_IRQn ((IRQn_Type)0) /* Audio Input Interrupt number */
#endif
#include "SchedEvents.h"
/*
RTX dependent definition
*/
#define RING_BEGINCRITICALSECTION() NVIC_DisableIRQ (AudioIn_IRQn)
#define RING_ENDCRITICALSECTION() NVIC_EnableIRQ (AudioIn_IRQn)
#define RING_BEGINCRITICALSECTION() NVIC_DisableIRQ ((IRQn_Type)config->interruptID);
#define RING_ENDCRITICALSECTION() NVIC_EnableIRQ ((IRQn_Type)config->interruptID);
#define RING_WAIT_BUFFER(TIMEOUT) osThreadFlagsWait(1,osFlagsWaitAny,(TIMEOUT))
#define RING_HASWAITERROR(F) (F < 0)
@ -64,17 +59,17 @@ RTX dependent definition
#define RING_RELEASE_BUFFER(THREADID) osThreadFlagsSet((osThreadId_t)(THREADID),1)
/* Debug trace using Event Recorder */
#define RING_DBG_USER_RESERVE_BUFFER(ID) EventRecord2 (Evt_UsrReserve, (ID), 0)
#define RING_DBG_USER_RELEASE_BUFFER(ID) EventRecord2 (Evt_UsrRelease, (ID), 0)
#define RING_DBG_USER_WAIT_BUFFER(ID) EventRecord2 (Evt_UsrWait, (ID), 0)
#define RING_DBG_USER_BUFFER_RELEASED(ID) EventRecord2 (Evt_UsrFree, (ID), 0)
#define RING_DBG_USER_STATUS(SA,SB) EventRecord2 (Evt_UsrStatus, config->SA,config->SB)
#define RING_DBG_INT_RESERVE_BUFFER(ID) EventRecord2 (Evt_IntReserve, (ID), 0)
#define RING_DBG_INT_RELEASE_BUFFER(ID) EventRecord2 (Evt_IntRelease, (ID), 0)
#define RING_DBG_INT_RELEASE_USER() EventRecord2 (Evt_IntReleaseUser, 0, 0)
#define RING_DBG_INT_STATUS(SA,SB) EventRecord2 (Evt_IntStatus, config->SA,config->SB)
#define RING_DBG_ERROR(ERROR) EventRecord2 (Evt_Error, (ERROR), 0)
#define RING_DBG_USER_RESERVE_BUFFER(ID,CONF) EventRecord2 (Evt_UsrReserve, (ID), (uint32_t)(CONF))
#define RING_DBG_USER_RELEASE_BUFFER(ID,CONF) EventRecord2 (Evt_UsrRelease, (ID), (uint32_t)(CONF))
#define RING_DBG_USER_WAIT_BUFFER(ID,CONF) EventRecord2 (Evt_UsrWait, (ID), (uint32_t)(CONF))
#define RING_DBG_USER_BUFFER_RELEASED(ID,CONF) EventRecord2 (Evt_UsrFree, (ID), (uint32_t)(CONF))
#define RING_DBG_USER_STATUS(SA,SB,CONF) EventRecord4 (Evt_UsrStatus, config->SA,config->SB,(uint32_t)(CONF),0)
#define RING_DBG_INT_RESERVE_BUFFER(ID,CONF) EventRecord2 (Evt_IntReserve, (ID), (uint32_t)(CONF))
#define RING_DBG_INT_RELEASE_BUFFER(ID,CONF) EventRecord2 (Evt_IntRelease, (ID), (uint32_t)(CONF))
#define RING_DBG_INT_RELEASE_USER(CONF) EventRecord2 (Evt_IntReleaseUser, (uint32_t)(CONF), 0)
#define RING_DBG_INT_STATUS(SA,SB,CONF) EventRecord4 (Evt_IntStatus, config->SA,config->SB,(uint32_t)(CONF),0)
#define RING_DBG_ERROR(ERROR,CONF) EventRecord2 (Evt_Error, (ERROR), (uint32_t)(CONF))
#endif

@ -47,19 +47,19 @@
<event id="0x100" level="Op" property="Reserve" value="ID=%d[val1]" info="Reserve buffer" />
<event id="0x101" level="Op" property="Release" value="ID=%d[val1]" info="Release buffer" />
<event id="0x102" level="Op" property="Wait" value="ID=%d[val1]" info="Wait buffer" />
<event id="0x103" level="Op" property="Unblocked" value="ID=%d[val1]" info="Free buffer" />
<event id="0x104" level="Op" property="Status" value="USR=%x[val1] INT=%x[val2]" info="Reservation status" />
<event id="0x100" level="Op" property="Reserve" value="ID=%d[val1] CONF=%x[val2]" info="Reserve buffer" />
<event id="0x101" level="Op" property="Release" value="ID=%d[val1] CONF=%x[val2]" info="Release buffer" />
<event id="0x102" level="Op" property="Wait" value="ID=%d[val1] CONF=%x[val2]" info="Wait buffer" />
<event id="0x103" level="Op" property="Unblocked" value="ID=%d[val1] CONF=%x[val2]" info="Free buffer" />
<event id="0x104" level="Detail" property="Status" value="USR=%x[val1] INT=%x[val2] CONF=%x[val3]" info="Reservation status" />
<event id="0x200" level="Op" property="Reserve" value="ID=%d[val1]" info="Reserve buffer" />
<event id="0x201" level="Op" property="Release" value="ID=%d[val1]" info="Release buffer" />
<event id="0x202" level="Op" property="Release USR" info="Release user" />
<event id="0x203" level="Op" property="Status" value="USR=%x[val1] INT=%x[val2]" info="Reservation status" />
<event id="0x200" level="Op" property="Reserve" value="ID=%d[val1] CONF=%x[val2]" info="Reserve buffer" />
<event id="0x201" level="Op" property="Release" value="ID=%d[val1] CONF=%x[val2]" info="Release buffer" />
<event id="0x202" level="Op" property="Release USR" value="CONF=%x[val1]" info="Release user" />
<event id="0x203" level="Detail" property="Status" value="USR=%x[val1] INT=%x[val2] CONF=%x[val3]" info="Reservation status" />
<event id="0x300" level="Error" property="Error" value="err=%d[val1]" info="Release buffer" />
<event id="0x300" level="Error" property="Error" value="err=%d[val1] CONF=%x[val2]" info="Release buffer" />
</events>

Loading…
Cancel
Save