Navigation Menu

Skip to content

Commit

Permalink
Fixed behaviour when analog is disabled. Now the SPI bus is (mostly) …
Browse files Browse the repository at this point in the history
…left alone and the audio still runs. Closes #7. We could use an improvement to the PRU code that removes any SPI transaction.
  • Loading branch information
giuliomoro committed Jan 17, 2017
1 parent 4479ea0 commit d7f71f0
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 37 deletions.
23 changes: 8 additions & 15 deletions core/PRU.cpp
Expand Up @@ -309,7 +309,12 @@ int PRU::initialise(int pru_num, int frames_per_buffer, int spi_channels, int mu
/* Set up flags */ /* Set up flags */
pru_buffer_comm[PRU_SHOULD_STOP] = 0; pru_buffer_comm[PRU_SHOULD_STOP] = 0;
pru_buffer_comm[PRU_CURRENT_BUFFER] = 0; pru_buffer_comm[PRU_CURRENT_BUFFER] = 0;
pru_buffer_comm[PRU_BUFFER_FRAMES] = context->analogFrames; unsigned int pruFrames;

This comment has been minimized.

Copy link
@giuliomoro

giuliomoro Jan 17, 2017

Author Contributor

@apmcpherson The issue was that by setting

pru_buffer_comm[PRU_BUFFER_FRAMES] = context->analogFrames;

when analog was disabled (and thus context->analogFrames == 0), then the PRU loop would never exit because reg_frame_total would be in turn set to 0 and the condition

     QBNE WRITE_LOOP, reg_frame_current, reg_frame_total

would never be met (given that you get there the first time when reg_frame_current == 2).

if(analog_enabled)
pruFrames = context->analogFrames;
else
pruFrames = context->audioFrames / 2; // PRU assumes 8 "fake" channels when SPI is disabled
pru_buffer_comm[PRU_BUFFER_FRAMES] = pruFrames;
pru_buffer_comm[PRU_SHOULD_SYNC] = 0; pru_buffer_comm[PRU_SHOULD_SYNC] = 0;
pru_buffer_comm[PRU_SYNC_ADDRESS] = 0; pru_buffer_comm[PRU_SYNC_ADDRESS] = 0;
pru_buffer_comm[PRU_SYNC_PIN_MASK] = 0; pru_buffer_comm[PRU_SYNC_PIN_MASK] = 0;
Expand Down Expand Up @@ -531,23 +536,18 @@ int PRU::start(char * const filename)
return 0; return 0;
} }


#ifdef PRU_SIGXCPU_BUG_WORKAROUND
extern bool gProcessAnalog;
#endif /* PRU_SIGXCPU_BUG_WORKAROUND */

// Main loop to read and write data from/to PRU // Main loop to read and write data from/to PRU
void PRU::loop(RT_INTR *pru_interrupt, void *userData) void PRU::loop(RT_INTR *pru_interrupt, void *userData)
{ {
#ifdef BELA_USE_XENOMAI_INTERRUPTS #ifdef BELA_USE_XENOMAI_INTERRUPTS
RTIME irqTimeout = PRU_SAMPLE_INTERVAL_NS * 1024; // Timeout for PRU interrupt: about 10ms, much longer than any expected period RTIME irqTimeout = PRU_SAMPLE_INTERVAL_NS * 1024; // Timeout for PRU interrupt: about 10ms, much longer than any expected period
#else #else
// Polling interval is 1/4 of the period
if(context->analogInChannels != context->analogOutChannels){ if(context->analogInChannels != context->analogOutChannels){
printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n"); printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n");
return; return;
} }
unsigned int analogChannels = context->analogInChannels; // Polling interval is 1/4 of the period
RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (analogChannels / 2) * context->analogFrames / 4; RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (context->audioInChannels) * context->audioFrames / 4;
#endif #endif


uint32_t pru_audio_offset, pru_spi_offset; uint32_t pru_audio_offset, pru_spi_offset;
Expand Down Expand Up @@ -582,13 +582,6 @@ void PRU::loop(RT_INTR *pru_interrupt, void *userData)
uint32_t lastPRUBuffer = 0; uint32_t lastPRUBuffer = 0;
#endif #endif


#ifdef PRU_SIGXCPU_BUG_WORKAROUND
if(gProcessAnalog == false){
context->analogFrames = 0;
context->analogInChannels = 0;
context->analogOutChannels = 0;
}
#endif


while(!gShouldStop) { while(!gShouldStop) {
#ifdef BELA_USE_XENOMAI_INTERRUPTS #ifdef BELA_USE_XENOMAI_INTERRUPTS
Expand Down
11 changes: 0 additions & 11 deletions core/RTAudio.cpp
Expand Up @@ -78,9 +78,6 @@ int gRTAudioVerbose = 0; // Verbosity level for debugging
int gAmplifierMutePin = -1; int gAmplifierMutePin = -1;
int gAmplifierShouldBeginMuted = 0; int gAmplifierShouldBeginMuted = 0;


#ifdef PRU_SIGXCPU_BUG_WORKAROUND
bool gProcessAnalog;
#endif /* PRU_SIGXCPU_BUG_WORKAROUND */


// Context which holds all the audio/sensor data passed to the render routines // Context which holds all the audio/sensor data passed to the render routines
InternalBelaContext gContext; InternalBelaContext gContext;
Expand Down Expand Up @@ -193,14 +190,6 @@ int Bela_initAudio(BelaInitSettings *settings, void *userData)
gContext.audioInChannels = 2; gContext.audioInChannels = 2;
gContext.audioOutChannels = 2; gContext.audioOutChannels = 2;


#ifdef PRU_SIGXCPU_BUG_WORKAROUND
// TODO: see PRU bug mentioned above. We catch here if useAnalog was set to false, store it in gProcessAnalog
// and use this value to decide whether we should process the analogs in PRU::loop, but then we
// set it to true so that the PRU is init'd and the code runs AS IF the analogs were in use.
gProcessAnalog = settings->useAnalog;
settings->useAnalog = true;
#endif /* PRU_SIGXCPU_BUG_WORKAROUND */

if(settings->useAnalog) { if(settings->useAnalog) {
gContext.audioFrames = settings->periodSize; gContext.audioFrames = settings->periodSize;


Expand Down
11 changes: 0 additions & 11 deletions include/Bela.h
Expand Up @@ -736,15 +736,4 @@ int Bela_startAuxiliaryTask(AuxiliaryTask task);
/** @} */ /** @} */
#include <Utilities.h> #include <Utilities.h>


/**\cond HIDDEN_SYMBOLS
// TODO: There is a bug in the PRU code that prevents it from working when SPI is disabled.
// To work around it, we leave the SPI enabled ( as it does not affect the load of the ARM core), but
// we avoid processing the analog channels, to save CPU time. We use global variable gProcessAnalog
// in RTAudio.cpp and PRU.cpp to store the actual value of analog_enabled. To reproduce the bug,
// undefine the line below and run with -N0 (analog disabled)
*/
#define PRU_SIGXCPU_BUG_WORKAROUND
/**
* \endcond
*/
#endif /* BELA_H_ */ #endif /* BELA_H_ */

0 comments on commit d7f71f0

Please sign in to comment.