# HG changeset patch # User Giulio Moro # Date 1430843280 -3600 # Node ID 182ae9367104a21788c4615053ccbd40eedfaad7 # Parent fbfeb5895efdbe2fbee15f7c512bb91a68cd9a38 - persistency: the last frame of each digital and analogOut buffers is used to initialize all the frames in the next buffer. This means that once a value is set, the pin will hold the value until you change it - AnalogXyz macros have been renamed to analogXyz - the short option -P has been removed. The long option --pru-file has to be used instead diff -r fbfeb5895efd -r 182ae9367104 .cproject --- a/.cproject Sun May 03 01:10:17 2015 +0100 +++ b/.cproject Tue May 05 17:28:00 2015 +0100 @@ -5,12 +5,12 @@ - + @@ -26,32 +26,32 @@ - - - - @@ -92,7 +92,7 @@ - + @@ -103,12 +103,12 @@ - + @@ -157,7 +157,6 @@ @@ -178,7 +177,7 @@ - + diff -r fbfeb5895efd -r 182ae9367104 .settings/org.eclipse.cdt.core.prefs --- a/.settings/org.eclipse.cdt.core.prefs Sun May 03 01:10:17 2015 +0100 +++ b/.settings/org.eclipse.cdt.core.prefs Tue May 05 17:28:00 2015 +0100 @@ -1,3 +1,17 @@ eclipse.preferences.version=1 +environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/LD_LIBRARY_PATH/delimiter=\: +environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/LD_LIBRARY_PATH/operation=append +environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/LD_LIBRARY_PATH/value=/usr/lib64/openmpi/lib\:/import/teaching/ECS732/arm-gcc/x86_64-linux-gnu/arm-linux-gnueabihf/lib\:/import/teaching/ECS732/arm-gcc/lib/x86_64-linux-gnu\:/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib +environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/PATH/delimiter=\: +environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/PATH/operation=append +environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/PATH/value=/usr/bin\:/bin\:/usr/sbin\:/sbin\:/usr/local/linaro/arm-linux-gnueabihf/bin environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/append=true environment/project/cdt.managedbuild.config.gnu.exe.debug.528876549/appendContributed=true +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/LD_LIBRARY_PATH/delimiter=\: +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/LD_LIBRARY_PATH/operation=append +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/LD_LIBRARY_PATH/value=/usr/lib64/openmpi/lib\:/import/teaching/ECS732/arm-gcc/x86_64-linux-gnu/arm-linux-gnueabihf/lib\:/import/teaching/ECS732/arm-gcc/lib/x86_64-linux-gnu\:/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/PATH/delimiter=\: +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/PATH/operation=append +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/PATH/value=/usr/bin\:/bin\:/usr/sbin\:/sbin\:/usr/local/linaro/arm-linux-gnueabihf/bin +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/append=true +environment/project/cdt.managedbuild.config.gnu.exe.release.1521194538/appendContributed=true diff -r fbfeb5895efd -r 182ae9367104 core/PRU.cpp --- a/core/PRU.cpp Sun May 03 01:10:17 2015 +0100 +++ b/core/PRU.cpp Tue May 05 17:28:00 2015 +0100 @@ -432,33 +432,34 @@ // Polling interval is 1/4 of the period RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (spi_num_channels / 2) * spi_buffer_frames / 4; float *audioInBuffer, *audioOutBuffer; - float *analogInBuffer, *analogOutBuffer; - uint32_t *digitalBuffer0, *digitalBuffer1, *digitalBufferTemp; + float *analogInBuffer, *analogOutBuffer, *lastAnalogOutFrame; + uint32_t *digitalBuffer0, *digitalBuffer1, *lastDigitalBuffer; audioInBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); audioOutBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); analogInBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); analogOutBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); + lastAnalogOutFrame = (float *)malloc(spi_num_channels * sizeof(float)); digitalBuffer0 = pru_buffer_digital; digitalBuffer1 = pru_buffer_digital+MEM_DIGITAL_BUFFER1_OFFSET/sizeof(uint32_t); - digital_buffer_frames = digital_enabled ? audio_buffer_frames : 0; //TODO: find a more elegant solution for when the digital is disabled e.g.: + digital_buffer_frames = digital_enabled ? audio_buffer_frames : 0; //TODO: find a more elegant solution for when the digital is disabled e.g.: // - embed in the digitalWrite/Read macros a check whether digital is enabled // - allocate some memory in ARM just to allow render() to run regardless. // in this case it can be digitalBuffer0 == digitalBuffer1 printf("digital_buffer_frames: %d;\n",digital_buffer_frames); - digitalBufferTemp = (uint32_t *)malloc(digital_buffer_frames*sizeof(uint32_t)); //temp buffer to hold previous states + lastDigitalBuffer = (uint32_t *)malloc(digital_buffer_frames*sizeof(uint32_t)); //temp buffer to hold previous states if(audioInBuffer == 0 || audioOutBuffer == 0) { rt_printf("Error: couldn't allocate audio buffers\n"); return; } - if(analogInBuffer == 0 || analogOutBuffer == 0) { + if(analogInBuffer == 0 || analogOutBuffer == 0 || lastAnalogOutFrame == 0) { rt_printf("Error: couldn't allocate analog buffers\n"); return; } - if(digitalBufferTemp == 0) { + if(lastDigitalBuffer == 0) { rt_printf("Error: couldn't allocate digital buffers\n"); return; - } + } while(!gShouldStop) { // Wait for PRU to move to buffer 1 @@ -481,22 +482,33 @@ if(spi_enabled) { for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) analogInBuffer[n] = (float)pru_buffer_spi_adc[n] / 65536.0; - //use past digital values to initialize the array properly: - //- pins previously set as outputs will keep their previously set output value, + //initialize the output buffer with the values that were in the last frame of the previous output + for(int n = 0; n < spi_num_channels; n++){ + for(unsigned int j = 0; j < spi_buffer_frames; j++){ + analogOutBuffer[j*spi_buffer_frames + n] = lastAnalogOutFrame[n]; + } + } + //use past digital values to initialize the array properly. + //For each frame: + //- pins previously set as outputs will keep the output value they had in the last frame of the previous buffer, //- pins previously set as inputs will carry the newly read input value if(digital_enabled){ for(unsigned int n = 0; n < digital_buffer_frames; n++){ - uint16_t inputs=digitalBufferTemp[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs + uint16_t inputs=lastDigitalBuffer[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs // printf("inputs: 0x%x\n",inputs); uint16_t outputs=~inputs; //half-word has 1 for outputs and 0 for inputs; - digitalBuffer0[n]=(digitalBufferTemp[n]&(outputs<<16))| //keep output values set in previous digitalBuffer1[n] + digitalBuffer0[n]=(lastDigitalBuffer[digital_buffer_frames-1]&(outputs<<16))| //keep output values set in the last frame of the previous buffer (digitalBuffer0[n]&(inputs<<16)) | //inputs from current digitalBuffer0[n]; - (digitalBufferTemp[n]&(inputs)); //keep pin configuration from previous digitalBuffer1[n] + (lastDigitalBuffer[n]&(inputs)); //keep pin configuration from previous digitalBuffer1[n] // digitalBuffer0[n]=digitalBufferTemp[n]; //ignores inputs } } render(spi_buffer_frames, digital_buffer_frames, audio_buffer_frames, audioInBuffer, audioOutBuffer, analogInBuffer, analogOutBuffer, digitalBuffer0); + //remember the content of the lastAnalogOutFrame + for(int n = 0; n < spi_num_channels; n++){ + lastAnalogOutFrame[n] = analogOutBuffer[spi_buffer_frames*(spi_buffer_frames-1) + n]; + } for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) { int out = analogOutBuffer[n] * 65536.0; if(out < 0) out = 0; @@ -505,7 +517,7 @@ } if(digital_enabled){ // keep track of past digital values for(unsigned int n = 0; n < digital_buffer_frames; n++){ - digitalBufferTemp[n]=digitalBuffer0[n]; + lastDigitalBuffer[n]=digitalBuffer0[n]; } } } @@ -544,24 +556,33 @@ audioInBuffer[n] = (float)pru_buffer_audio_adc[n + audio_buffer_frames * 2] / 32768.0; if(spi_enabled) { - for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) + //convert input values TODO: move to PRU + for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++){ analogInBuffer[n] = (float)pru_buffer_spi_adc[n + spi_buffer_frames * spi_num_channels] / 65536.0; - - //use past digital values to initialize the array properly: - //- pins previously set as outputs will keep their previously set output value, - //- pins previously set as inputs will carry the newly read input value + } + //initialize the output buffer with the values that were in the last frame of the previous output + for(int n = 0; n < spi_num_channels; n++){ + for(unsigned int j = 0; j < spi_buffer_frames; j++){ + analogOutBuffer[j*spi_buffer_frames + n] = lastAnalogOutFrame[n]; + } + } if(digital_enabled){ - for(unsigned int n = 0; n < digital_buffer_frames; n++){ - uint16_t inputs=digitalBufferTemp[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs + for(unsigned int n = 0; n < digital_buffer_frames; n++){ + uint16_t inputs=lastDigitalBuffer[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs uint16_t outputs=~inputs; //half-word has 1 for outputs and one for inputs; - digitalBuffer1[n]=(digitalBufferTemp[n]&(outputs<<16))| //keep output values set in previous digitalBuffer1[n] + digitalBuffer1[n]=(lastDigitalBuffer[digital_buffer_frames-1]&(outputs<<16))| //keep output values set in the last frame of the previous buffer (digitalBuffer1[n]&(inputs<<16)) | //inputs from current digitalBuffer1[n]; - (digitalBufferTemp[n]&(inputs)); //keep pin configuration from previous digitalBuffer1[n] + (lastDigitalBuffer[n]&(inputs)); //keep pin configuration from previous digitalBuffer1[n] // digitalBuffer1[n]=digitalBufferTemp[n]; //ignores inputs } } render(spi_buffer_frames, digital_buffer_frames, audio_buffer_frames, audioInBuffer, audioOutBuffer, analogInBuffer, analogOutBuffer, digitalBuffer1); + //remember the content of the lastAnalogOutFrame + for(int n = 0; n < spi_num_channels; n++){ + lastAnalogOutFrame[n] = analogOutBuffer[spi_buffer_frames*(spi_buffer_frames-1) + n]; + } + for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) { int out = analogOutBuffer[n] * 65536.0; if(out < 0) out = 0; @@ -570,7 +591,7 @@ } if(digital_enabled){ // keep track of past digital values for(unsigned int n = 0; n < digital_buffer_frames; n++){ - digitalBufferTemp[n]=digitalBuffer1[n]; + lastDigitalBuffer[n]=digitalBuffer1[n]; } } } @@ -598,7 +619,8 @@ free(audioInBuffer); free(audioOutBuffer); free(analogInBuffer); - free(digitalBufferTemp); + free(lastAnalogOutFrame); + free(lastDigitalBuffer); } // Wait for an interrupt from the PRU indicate it is finished diff -r fbfeb5895efd -r 182ae9367104 core/RTAudioCommandLine.cpp --- a/core/RTAudioCommandLine.cpp Sun May 03 01:10:17 2015 +0100 +++ b/core/RTAudioCommandLine.cpp Tue May 05 17:28:00 2015 +0100 @@ -10,6 +10,9 @@ #include #include #include "../include/RTAudio.h" +#ifndef OPT_PRU_FILE +#define OPT_PRU_FILE -1 +#endif // Default command-line options for RTAudio struct option gDefaultLongOptions[] = @@ -17,18 +20,17 @@ {"period", 1, NULL, 'p'}, {"verbose", 0, NULL, 'v'}, {"use-analog", 1, NULL, 'm'}, - {"use-analog-gpio", 1, NULL, 'g'}, + {"use-digital-gpio", 1, NULL, 'g'}, {"analog-channels", 1, NULL, 'C'}, - {"analog-gpio-channels", 1, NULL, 'G'}, + {"digital-gpio-channels", 1, NULL, 'G'}, {"mute-speaker", 1, NULL, 'M'}, {"dac-level", 1, NULL, 'D'}, {"adc-level", 1, NULL, 'A'}, {"hp-level", 1, NULL, 'H'}, - {"pru-file",1,NULL,'P'}, + {"pru-file",1,NULL,OPT_PRU_FILE}, {NULL, 0, NULL, 0} }; - -const char gDefaultShortOptions[] = "p:vm:M:C:D:A:H:P:g:G:"; +const char gDefaultShortOptions[] = "p:vm:M:C:D:A:H:g:G:"; // This function sets the default settings for the RTAudioSettings structure void BeagleRT_defaultSettings(RTAudioSettings *settings) @@ -165,7 +167,7 @@ case 'H': settings->headphoneLevel = atof(optarg); break; - case 'P': + case OPT_PRU_FILE: if(strlen(optarg)pruFilename, optarg); else @@ -191,7 +193,7 @@ std::cerr << " --use-gpio-analog [-g] val: Set whether to use GPIO analog (default: yes)\n"; std::cerr << " --analog-channels [-C] val: Set the number of ADC/DAC channels (default: 8)\n"; std::cerr << " --analog-gpio-channels [-G] val: Set the number of GPIO channels (default: 16)\n"; - std::cerr << " --pru-file [-P] val: Set an optional external file to use for the PRU binary code\n"; + std::cerr << " --pru-file val: Set an optional external file to use for the PRU binary code\n"; std::cerr << " --verbose [-v]: Enable verbose logging information\n"; } diff -r fbfeb5895efd -r 182ae9367104 include/Utilities.h --- a/include/Utilities.h Sun May 03 01:10:17 2015 +0100 +++ b/include/Utilities.h Tue May 05 17:28:00 2015 +0100 @@ -14,13 +14,13 @@ // Macros for accessing the analog values: usable _only_ within render() // Read an Analog input from input pin p at frame f -#define AnalogRead(p, f) (analogIn[(f)*gNumAnalogChannels + (p)]) +#define analogRead(p, f) (analogIn[(f)*gNumAnalogChannels + (p)]) // Write an Analog output frame at output pin p, frame f, to value v -#define AnalogWriteFrame(p, f, v) (analogOut[(f)*gNumAnalogChannels + (p)] = (v)) -#define AnalogWrite(pin, frame, value) \ +#define analogWriteFrame(p, f, v) (analogOut[(f)*gNumAnalogChannels + (p)] = (v)) +#define analogWrite(pin, frame, value) \ (({do {\ for (int _privateI=(frame); _privateI