Mercurial > hg > beaglert
diff core/PRU.cpp @ 23:182ae9367104 matrix_gpio
- 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
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Tue, 05 May 2015 17:28:00 +0100 |
parents | c98863e63174 |
children | a9af130097e8 |
line wrap: on
line diff
--- 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