Mercurial > hg > beaglert
changeset 19:c98863e63174 matrix_gpio
Renamed matrixGpio to digital and matrix to analog
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Thu, 30 Apr 2015 16:58:41 +0100 |
parents | 31503d9de101 |
children | 58eb99dac921 |
files | core/PRU.cpp core/RTAudio.cpp core/RTAudioCommandLine.cpp include/PRU.h include/RTAudio.h include/Utilities.h include/digital_gpio_mapping.h include/matrix_gpio_mapping.h include/render.h projects/analogDigitalDemo/main.cpp projects/analogDigitalDemo/render.cpp projects/matrix_gpio_demo/main.cpp projects/matrix_gpio_demo/render.cpp pru_rtaudio.bin pru_rtaudio.p |
diffstat | 15 files changed, 495 insertions(+), 495 deletions(-) [+] |
line wrap: on
line diff
--- a/core/PRU.cpp Thu Apr 30 16:02:47 2015 +0100 +++ b/core/PRU.cpp Thu Apr 30 16:58:41 2015 +0100 @@ -16,7 +16,7 @@ #include "../include/PRU.h" #include "../include/prussdrv.h" #include "../include/pruss_intc_mapping.h" -#include "../include/matrix_gpio_mapping.h" +#include "../include/digital_gpio_mapping.h" #include "../include/GPIOcontrol.h" #include "../include/render.h" #include "../include/pru_rtaudio_bin.h" @@ -42,8 +42,8 @@ #define PRU_MEM_DAC_OFFSET 0x0 // Offset within PRU0 RAM #define PRU_MEM_DAC_LENGTH 0x2000 // Length of ADC+DAC memory, in bytes #define PRU_MEM_COMM_OFFSET 0x0 // Offset within PRU-SHARED RAM -#define PRU_MEM_MATRIX_GPIO_OFFSET 0x1000 //Offset within PRU-SHARED RAM -#define MEM_MATRIX_GPIO_BUFFER1_OFFSET 0x400 //Start pointer to MATRIX_GPIO_BUFFER1, which is 256 words. +#define PRU_MEM_DIGITAL_OFFSET 0x1000 //Offset within PRU-SHARED RAM +#define MEM_DIGITAL_BUFFER1_OFFSET 0x400 //Start pointer to DIGITAL_BUFFER1, which is 256 words. // 256 is the maximum number of frames allowed #define PRU_SHOULD_STOP 0 #define PRU_CURRENT_BUFFER 1 @@ -56,9 +56,9 @@ #define PRU_FRAME_COUNT 8 #define PRU_USE_SPI 9 #define PRU_SPI_NUM_CHANNELS 10 -#define PRU_USE_GPIO_MATRIX 11 +#define PRU_USE_GPIO_ANALOG 11 -short int matrixGpioPins[NUM_MATRIX_GPIOS]={ +short int digitalPins[NUM_DIGITALS]={ GPIO_NO_BIT_0, GPIO_NO_BIT_1, GPIO_NO_BIT_2, @@ -127,7 +127,7 @@ // viewed on a scope. If include_led is set, // user LED 3 on the BBB is taken over by the PRU // to indicate activity -int PRU::prepareGPIO(int use_spi, int use_matrix_gpio, int include_test_pin, int include_led) +int PRU::prepareGPIO(int use_spi, int use_digital, int include_test_pin, int include_led) { if(use_spi) { // Prepare DAC CS/ pin: output, high to begin @@ -165,25 +165,25 @@ spi_enabled = true; } - if(use_matrix_gpio){ - printf("gNumMatrixGpioChannels: %d;\n",gNumMatrixGpioChannels); - for(int i=0; i<gNumMatrixGpioChannels; i++){ - if(gpio_export(matrixGpioPins[i])) { + if(use_digital){ + printf("gNumDigitalChannels: %d;\n",gNumDigitalChannels); + for(int i=0; i<gNumDigitalChannels; i++){ + if(gpio_export(digitalPins[i])) { if(gRTAudioVerbose) - cout << "Warning: couldn't export matrix GPIO pin " << matrixGpioPins[i] << "\n"; + cout << "Warning: couldn't export digital GPIO pin " << digitalPins[i] << "\n"; } - if(gpio_set_dir(matrixGpioPins[i], OUTPUT_PIN)) { + if(gpio_set_dir(digitalPins[i], OUTPUT_PIN)) { if(gRTAudioVerbose) - cout << "Couldn't set direction on matrix GPIO pin " << matrixGpioPins[i] << "\n"; + cout << "Couldn't set direction on digital GPIO pin " << digitalPins[i] << "\n"; return -1; } - if(gpio_set_value(matrixGpioPins[i], HIGH)) { + if(gpio_set_value(digitalPins[i], HIGH)) { if(gRTAudioVerbose) - cout << "Couldn't set value on matrix GPIO pin " << matrixGpioPins[i] << "\n"; + cout << "Couldn't set value on digital GPIO pin " << digitalPins[i] << "\n"; return -1; } } - matrix_gpio_enabled=true; + digital_enabled=true; } if(include_test_pin) { @@ -255,9 +255,9 @@ gpio_unexport(kPruGPIODACSyncPin); gpio_unexport(kPruGPIOADCSyncPin); } - if(matrix_gpio_enabled){ - for(int i=0; i<gNumMatrixGpioChannels; i++){ - gpio_unexport(matrixGpioPins[i]); + if(digital_enabled){ + for(int i=0; i<gNumDigitalChannels; i++){ + gpio_unexport(digitalPins[i]); } } if(gpio_test_pin_enabled) { @@ -309,7 +309,7 @@ spi_buffer_frames = frames_per_buffer; audio_buffer_frames = spi_buffer_frames * spi_num_channels / 4; - matrix_gpio_buffer_frames = audio_buffer_frames; + digital_buffer_frames = audio_buffer_frames; /* Map PRU memory to pointers */ prussdrv_map_prumem (PRUSS0_SHARED_DATARAM, (void **)&pruMem); @@ -330,12 +330,12 @@ pru_buffer_spi_dac = pru_buffer_spi_adc = 0; } - if(matrix_gpio_enabled) { + if(digital_enabled) { prussdrv_map_prumem (PRUSS0_SHARED_DATARAM, (void **)&pruMem); - pru_buffer_matrix_gpio = (uint32_t *)&pruMem[PRU_MEM_MATRIX_GPIO_OFFSET/sizeof(uint32_t)]; + pru_buffer_digital = (uint32_t *)&pruMem[PRU_MEM_DIGITAL_OFFSET/sizeof(uint32_t)]; } else { - pru_buffer_matrix_gpio = 0; + pru_buffer_digital = 0; } /* Set up flags */ pru_buffer_comm[PRU_SHOULD_STOP] = 0; @@ -360,13 +360,13 @@ pru_buffer_comm[PRU_USE_SPI] = 0; pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = 0; } - if(matrix_gpio_enabled) { - pru_buffer_comm[PRU_USE_GPIO_MATRIX] = 1; - pru_buffer_comm[NUM_MATRIX_GPIOS] = spi_num_channels; + if(digital_enabled) { + pru_buffer_comm[PRU_USE_GPIO_ANALOG] = 1; + pru_buffer_comm[NUM_DIGITALS] = spi_num_channels; } else { - pru_buffer_comm[PRU_USE_GPIO_MATRIX] = 0; - pru_buffer_comm[NUM_MATRIX_GPIOS] = 0; + pru_buffer_comm[PRU_USE_GPIO_ANALOG] = 0; + pru_buffer_comm[NUM_DIGITALS] = 0; } /* Clear ADC and DAC memory */ @@ -432,31 +432,31 @@ // 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 *matrixInBuffer, *matrixOutBuffer; - uint32_t *matrixGpioBuffer0, *matrixGpioBuffer1, *matrixGpioBufferTemp; + float *analogInBuffer, *analogOutBuffer; + uint32_t *digitalBuffer0, *digitalBuffer1, *digitalBufferTemp; audioInBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); audioOutBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); - matrixInBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); - matrixOutBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); - matrixGpioBuffer0 = pru_buffer_matrix_gpio; - matrixGpioBuffer1 = pru_buffer_matrix_gpio+MEM_MATRIX_GPIO_BUFFER1_OFFSET/sizeof(uint32_t); - matrix_gpio_buffer_frames = matrix_gpio_enabled ? audio_buffer_frames : 0; //TODO: find a more elegant solution for when the matrix_gpio is disabled e.g.: - // - embed in the digitalWrite/Read macros a check whether matrix_gpio is enabled + analogInBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * sizeof(float)); + analogOutBuffer = (float *)malloc(spi_num_channels * spi_buffer_frames * 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.: + // - 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 matrixGpioBuffer0 == matrixGpioBuffer1 - printf("matrix_gpio_buffer_frames: %d;\n",matrix_gpio_buffer_frames); - matrixGpioBufferTemp = (uint32_t *)malloc(matrix_gpio_buffer_frames*sizeof(uint32_t)); //temp buffer to hold previous states + // 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 if(audioInBuffer == 0 || audioOutBuffer == 0) { rt_printf("Error: couldn't allocate audio buffers\n"); return; } - if(matrixInBuffer == 0 || matrixOutBuffer == 0) { - rt_printf("Error: couldn't allocate matrix buffers\n"); + if(analogInBuffer == 0 || analogOutBuffer == 0) { + rt_printf("Error: couldn't allocate analog buffers\n"); return; } - if(matrixGpioBufferTemp == 0) { - rt_printf("Error: couldn't allocate matrix GPIO buffers\n"); + if(digitalBufferTemp == 0) { + rt_printf("Error: couldn't allocate digital buffers\n"); return; } @@ -480,37 +480,37 @@ audioInBuffer[n] = (float)pru_buffer_audio_adc[n] / 32768.0; if(spi_enabled) { for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) - matrixInBuffer[n] = (float)pru_buffer_spi_adc[n] / 65536.0; - //use past matrix_gpio values to initialize the array properly: + 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, //- pins previously set as inputs will carry the newly read input value - if(matrix_gpio_enabled){ - for(unsigned int n = 0; n < matrix_gpio_buffer_frames; n++){ - uint16_t inputs=matrixGpioBufferTemp[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs + 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 // printf("inputs: 0x%x\n",inputs); uint16_t outputs=~inputs; //half-word has 1 for outputs and 0 for inputs; - matrixGpioBuffer0[n]=(matrixGpioBufferTemp[n]&(outputs<<16))| //keep output values set in previous matrixGpioBuffer1[n] - (matrixGpioBuffer0[n]&(inputs<<16)) | //inputs from current matrixGpioBuffer0[n]; - (matrixGpioBufferTemp[n]&(inputs)); //keep pin configuration from previous matrixGpioBuffer1[n] -// matrixGpioBuffer0[n]=matrixGpioBufferTemp[n]; //ignores inputs + digitalBuffer0[n]=(digitalBufferTemp[n]&(outputs<<16))| //keep output values set in previous digitalBuffer1[n] + (digitalBuffer0[n]&(inputs<<16)) | //inputs from current digitalBuffer0[n]; + (digitalBufferTemp[n]&(inputs)); //keep pin configuration from previous digitalBuffer1[n] +// digitalBuffer0[n]=digitalBufferTemp[n]; //ignores inputs } } - render(spi_buffer_frames, matrix_gpio_buffer_frames, audio_buffer_frames, audioInBuffer, audioOutBuffer, - matrixInBuffer, matrixOutBuffer, matrixGpioBuffer0); + render(spi_buffer_frames, digital_buffer_frames, audio_buffer_frames, audioInBuffer, audioOutBuffer, + analogInBuffer, analogOutBuffer, digitalBuffer0); for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) { - int out = matrixOutBuffer[n] * 65536.0; + int out = analogOutBuffer[n] * 65536.0; if(out < 0) out = 0; else if(out > 65535) out = 65535; pru_buffer_spi_dac[n] = (uint16_t)out; } - if(matrix_gpio_enabled){ // keep track of past matrix_gpio values - for(unsigned int n = 0; n < matrix_gpio_buffer_frames; n++){ - matrixGpioBufferTemp[n]=matrixGpioBuffer0[n]; + if(digital_enabled){ // keep track of past digital values + for(unsigned int n = 0; n < digital_buffer_frames; n++){ + digitalBufferTemp[n]=digitalBuffer0[n]; } } } else - render(0, 0, audio_buffer_frames, audioInBuffer, audioOutBuffer, 0, 0, 0); // we still pass matrixGpioBuffer, just it is unused + render(0, 0, audio_buffer_frames, audioInBuffer, audioOutBuffer, 0, 0, 0); // we still pass digitalBuffer, just it is unused // Convert float back to short for(unsigned int n = 0; n < 2 * audio_buffer_frames; n++) { int out = audioOutBuffer[n] * 32768.0; @@ -545,37 +545,37 @@ if(spi_enabled) { for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) - matrixInBuffer[n] = (float)pru_buffer_spi_adc[n + spi_buffer_frames * spi_num_channels] / 65536.0; + analogInBuffer[n] = (float)pru_buffer_spi_adc[n + spi_buffer_frames * spi_num_channels] / 65536.0; - //use past matrix_gpio values to initialize the array properly: + //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 - if(matrix_gpio_enabled){ - for(unsigned int n = 0; n < matrix_gpio_buffer_frames; n++){ - uint16_t inputs=matrixGpioBufferTemp[n]&0xffff;//half-word, has 1 for inputs and 0 for outputs + 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 outputs=~inputs; //half-word has 1 for outputs and one for inputs; - matrixGpioBuffer1[n]=(matrixGpioBufferTemp[n]&(outputs<<16))| //keep output values set in previous matrixGpioBuffer1[n] - (matrixGpioBuffer1[n]&(inputs<<16)) | //inputs from current matrixGpioBuffer1[n]; - (matrixGpioBufferTemp[n]&(inputs)); //keep pin configuration from previous matrixGpioBuffer1[n] -// matrixGpioBuffer1[n]=matrixGpioBufferTemp[n]; //ignores inputs + digitalBuffer1[n]=(digitalBufferTemp[n]&(outputs<<16))| //keep output values set in previous digitalBuffer1[n] + (digitalBuffer1[n]&(inputs<<16)) | //inputs from current digitalBuffer1[n]; + (digitalBufferTemp[n]&(inputs)); //keep pin configuration from previous digitalBuffer1[n] +// digitalBuffer1[n]=digitalBufferTemp[n]; //ignores inputs } } - render(spi_buffer_frames, matrix_gpio_buffer_frames, audio_buffer_frames, audioInBuffer, audioOutBuffer, - matrixInBuffer, matrixOutBuffer, matrixGpioBuffer1); + render(spi_buffer_frames, digital_buffer_frames, audio_buffer_frames, audioInBuffer, audioOutBuffer, + analogInBuffer, analogOutBuffer, digitalBuffer1); for(unsigned int n = 0; n < spi_num_channels * spi_buffer_frames; n++) { - int out = matrixOutBuffer[n] * 65536.0; + int out = analogOutBuffer[n] * 65536.0; if(out < 0) out = 0; else if(out > 65535) out = 65535; pru_buffer_spi_dac[n + spi_buffer_frames * spi_num_channels] = (uint16_t)out; } - if(matrix_gpio_enabled){ // keep track of past matrix_gpio values - for(unsigned int n = 0; n < matrix_gpio_buffer_frames; n++){ - matrixGpioBufferTemp[n]=matrixGpioBuffer1[n]; + if(digital_enabled){ // keep track of past digital values + for(unsigned int n = 0; n < digital_buffer_frames; n++){ + digitalBufferTemp[n]=digitalBuffer1[n]; } } } else - render(0, 0, audio_buffer_frames, audioInBuffer, audioOutBuffer, 0, 0, 0); // we still pass matrixGpioBuffer, just it is unused + render(0, 0, audio_buffer_frames, audioInBuffer, audioOutBuffer, 0, 0, 0); // we still pass digitalBuffer, just it is unused // Convert float back to short for(unsigned int n = 0; n < 2 * audio_buffer_frames; n++) { @@ -594,11 +594,11 @@ // Tell PRU to stop pru_buffer_comm[PRU_SHOULD_STOP] = 1; - free(matrixOutBuffer); + free(analogOutBuffer); free(audioInBuffer); free(audioOutBuffer); - free(matrixInBuffer); - free(matrixGpioBufferTemp); + free(analogInBuffer); + free(digitalBufferTemp); } // Wait for an interrupt from the PRU indicate it is finished
--- a/core/RTAudio.cpp Thu Apr 30 16:02:47 2015 +0100 +++ b/core/RTAudio.cpp Thu Apr 30 16:58:41 2015 +0100 @@ -61,21 +61,21 @@ int gAmplifierMutePin = -1; int gAmplifierShouldBeginMuted = 0; -// Number of audio and matrix channels, globally accessible -// At least gNumMatrixChannels and gNumMatrixGpioChannels need to be global to be used -// by the analogRead() and analogWrite() and the digital macros without creating +// Number of audio and analog channels, globally accessible +// At least gNumAnalogChannels and gNumDigitalChannels need to be global to be used +// by the AnalogRead() and AnalogWrite() and the digital macros without creating // extra confusion in their use cases by passing this argument int gNumAudioChannels = 0; -int gNumMatrixChannels = 0; -int gNumMatrixGpioChannels = 0; +int gNumAnalogChannels = 0; +int gNumDigitalChannels = 0; // initAudio() prepares the infrastructure for running PRU-based real-time // audio, but does not actually start the calculations. // periodSize indicates the number of _sensor_ frames per period: the audio period size // is twice this value. In total, the audio latency in frames will be 4*periodSize, // plus any latency inherent in the ADCs and DACs themselves. -// useMatrix indicates whether to enable the ADC and DAC or just use the audio codec. -// numMatrixChannels indicates how many ADC and DAC channels to use. +// useAnalog indicates whether to enable the ADC and DAC or just use the audio codec. +// numAnalogChannels indicates how many ADC and DAC channels to use. // userData is an opaque pointer which will be passed through to the initialise_render() // function for application-specific use // @@ -91,10 +91,10 @@ if(gRTAudioVerbose) { cout << "Starting with period size " << settings->periodSize << "; "; - if(settings->useMatrix) - cout << "matrix enabled\n"; + if(settings->useAnalog) + cout << "analog enabled\n"; else - cout << "matrix disabled\n"; + cout << "analog disabled\n"; cout << "DAC level " << settings->dacLevel << "dB; ADC level " << settings->adcLevel; cout << "dB; headphone level " << settings->headphoneLevel << "dB\n"; if(settings->beginMuted) @@ -122,21 +122,21 @@ } } - // Limit the matrix channels to sane values - if(settings->numMatrixChannels >= 8) - settings->numMatrixChannels = 8; - else if(settings->numMatrixChannels >= 4) - settings->numMatrixChannels = 4; + // Limit the analog channels to sane values + if(settings->numAnalogChannels >= 8) + settings->numAnalogChannels = 8; + else if(settings->numAnalogChannels >= 4) + settings->numAnalogChannels = 4; else - settings->numMatrixChannels = 2; + settings->numAnalogChannels = 2; // Sanity check the combination of channels and period size - if(settings->numMatrixChannels <= 4 && settings->periodSize < 2) { - cout << "Error: " << settings->numMatrixChannels << " channels and period size of " << settings->periodSize << " not supported.\n"; + if(settings->numAnalogChannels <= 4 && settings->periodSize < 2) { + cout << "Error: " << settings->numAnalogChannels << " channels and period size of " << settings->periodSize << " not supported.\n"; return 1; } - if(settings->numMatrixChannels <= 2 && settings->periodSize < 4) { - cout << "Error: " << settings->numMatrixChannels << " channels and period size of " << settings->periodSize << " not supported.\n"; + if(settings->numAnalogChannels <= 2 && settings->periodSize < 4) { + cout << "Error: " << settings->numAnalogChannels << " channels and period size of " << settings->periodSize << " not supported.\n"; return 1; } @@ -144,12 +144,12 @@ gPRU = new PRU(); gAudioCodec = new I2c_Codec(); - gNumMatrixGpioChannels = settings->useMatrixGpio ? settings->numMatrixGpioChannels : 0; //this is called here to make sure prepareGPIO initializes the appropriate GPIO pins - if(gPRU->prepareGPIO(settings->useMatrix, settings->useMatrixGpio, 1, 1)) { + gNumDigitalChannels = settings->useDigital ? settings->numDigitalChannels : 0; //this is called here to make sure prepareGPIO initializes the appropriate GPIO pins + if(gPRU->prepareGPIO(settings->useAnalog, settings->useDigital, 1, 1)) { cout << "Error: unable to prepare GPIO for PRU audio\n"; return 1; } - if(gPRU->initialise(0, settings->periodSize, settings->numMatrixChannels, true)) { + if(gPRU->initialise(0, settings->periodSize, settings->numAnalogChannels, true)) { cout << "Error: unable to initialise PRU\n"; return 1; } @@ -167,23 +167,23 @@ BeagleRT_setADCLevel(settings->adcLevel); BeagleRT_setHeadphoneLevel(settings->headphoneLevel); - // Initialise the rendering environment: pass the number of audio and matrix - // channels, the period size for matrix and audio, and the sample rates + // Initialise the rendering environment: pass the number of audio and analog + // channels, the period size for analog and audio, and the sample rates int audioPeriodSize = settings->periodSize * 2; float audioSampleRate = 44100.0; - float matrixSampleRate = 22050.0; - if(settings->useMatrix) { - audioPeriodSize = settings->periodSize * settings->numMatrixChannels / 4; - matrixSampleRate = audioSampleRate * 4.0 / (float)settings->numMatrixChannels; + float analogSampleRate = 22050.0; + if(settings->useAnalog) { + audioPeriodSize = settings->periodSize * settings->numAnalogChannels / 4; + analogSampleRate = audioSampleRate * 4.0 / (float)settings->numAnalogChannels; } gNumAudioChannels = 2; - gNumMatrixChannels = settings->useMatrix ? settings->numMatrixChannels : 0; - if(!initialise_render(gNumMatrixChannels, gNumMatrixGpioChannels, gNumAudioChannels, - settings->useMatrix ? settings->periodSize : 0, /* matrix period size */ + gNumAnalogChannels = settings->useAnalog ? settings->numAnalogChannels : 0; + if(!initialise_render(gNumAnalogChannels, gNumDigitalChannels, gNumAudioChannels, + settings->useAnalog ? settings->periodSize : 0, /* analog period size */ audioPeriodSize, - matrixSampleRate, audioSampleRate, + analogSampleRate, audioSampleRate, userData)) { cout << "Couldn't initialise audio rendering\n"; return 1;
--- a/core/RTAudioCommandLine.cpp Thu Apr 30 16:02:47 2015 +0100 +++ b/core/RTAudioCommandLine.cpp Thu Apr 30 16:58:41 2015 +0100 @@ -16,10 +16,10 @@ { {"period", 1, NULL, 'p'}, {"verbose", 0, NULL, 'v'}, - {"use-matrix", 1, NULL, 'm'}, - {"use-matrix-gpio", 1, NULL, 'g'}, - {"matrix-channels", 1, NULL, 'C'}, - {"matrix-gpio-channels", 1, NULL, 'G'}, + {"use-analog", 1, NULL, 'm'}, + {"use-analog-gpio", 1, NULL, 'g'}, + {"analog-channels", 1, NULL, 'C'}, + {"analog-gpio-channels", 1, NULL, 'G'}, {"mute-speaker", 1, NULL, 'M'}, {"dac-level", 1, NULL, 'D'}, {"adc-level", 1, NULL, 'A'}, @@ -39,10 +39,10 @@ settings->dacLevel = DEFAULT_DAC_LEVEL; settings->adcLevel = DEFAULT_ADC_LEVEL; settings->headphoneLevel = DEFAULT_HP_LEVEL; - settings->useMatrix = 1; - settings->useMatrixGpio = 1; - settings->numMatrixChannels = 8; - settings->numMatrixGpioChannels = 16; + settings->useAnalog = 1; + settings->useDigital = 1; + settings->numAnalogChannels = 8; + settings->numDigitalChannels = 16; settings->verbose = 0; settings->pruFilename[0]='\0'; settings->codecI2CAddress = CODEC_I2C_ADDRESS; @@ -128,29 +128,29 @@ settings->verbose = 1; break; case 'm': - settings->useMatrix = atoi(optarg); + settings->useAnalog = atoi(optarg); break; case 'g': - settings->useMatrixGpio = atoi(optarg); - settings->numMatrixGpioChannels = 0; + settings->useDigital = atoi(optarg); + settings->numDigitalChannels = 0; break; case 'C': - settings->numMatrixChannels = atoi(optarg); - if(settings->numMatrixChannels >= 8) - settings->numMatrixChannels = 8; - else if(settings->numMatrixChannels >= 4) - settings->numMatrixChannels = 4; + settings->numAnalogChannels = atoi(optarg); + if(settings->numAnalogChannels >= 8) + settings->numAnalogChannels = 8; + else if(settings->numAnalogChannels >= 4) + settings->numAnalogChannels = 4; else - settings->numMatrixChannels = 2; + settings->numAnalogChannels = 2; break; case 'G': - settings->numMatrixGpioChannels = atoi(optarg); - if(settings->numMatrixGpioChannels >= 16) - settings->numMatrixGpioChannels = 16; - else if (settings->numMatrixGpioChannels < 1){ - settings->numMatrixGpioChannels = 0; - settings->useMatrixGpio = 0; //TODO: this actually works only if -G 0 is specified after -g 1. - //No worries, though: disabling numMatrixGpio will only prevent the pins from being exported. + settings->numDigitalChannels = atoi(optarg); + if(settings->numDigitalChannels >= 16) + settings->numDigitalChannels = 16; + else if (settings->numDigitalChannels < 1){ + settings->numDigitalChannels = 0; + settings->useDigital = 0; //TODO: this actually works only if -G 0 is specified after -g 1. + //No worries, though: disabling numDigital will only prevent the pins from being exported. } break; case 'M': @@ -182,15 +182,15 @@ // Call from within your own usage function void BeagleRT_usage() { - std::cerr << " --period [-p] period: Set the hardware period (buffer) size in matrix samples\n"; + std::cerr << " --period [-p] period: Set the hardware period (buffer) size in analog samples\n"; std::cerr << " --dac-level [-D] dBs: Set the DAC output level (0dB max; -63.5dB min)\n"; std::cerr << " --adc-level [-A] dBs: Set the ADC input level (0dB max; -12dB min)\n"; std::cerr << " --hp-level [-H] dBs: Set the headphone output level (0dB max; -63.5dB min)\n"; std::cerr << " --mute-speaker [-M] val: Set whether to mute the speaker initially (default: no)\n"; - std::cerr << " --use-matrix [-m] val: Set whether to use ADC/DAC matrix (default: yes)\n"; - std::cerr << " --use-gpio-matrix [-g] val: Set whether to use GPIO matrix (default: yes)\n"; - std::cerr << " --matrix-channels [-C] val: Set the number of ADC/DAC channels (default: 8)\n"; - std::cerr << " --matrix-gpio-channels [-G] val: Set the number of GPIO channels (default: 16)\n"; + std::cerr << " --use-analog [-m] val: Set whether to use ADC/DAC analog (default: yes)\n"; + 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 << " --verbose [-v]: Enable verbose logging information\n"; }
--- a/include/PRU.h Thu Apr 30 16:02:47 2015 +0100 +++ b/include/PRU.h Thu Apr 30 16:58:41 2015 +0100 @@ -27,7 +27,7 @@ ~PRU(); // Prepare the GPIO pins needed for the PRU - int prepareGPIO(int use_spi, int use_matrix_gpio, int include_test_pin, int include_led); + int prepareGPIO(int use_spi, int use_digital, int include_test_pin, int include_led); // Clean up the GPIO at the end void cleanupGPIO(); @@ -56,7 +56,7 @@ int pru_number; // Which PRU we use bool running; // Whether the PRU is running bool spi_enabled; // Whether SPI ADC and DAC are used - bool matrix_gpio_enabled; // Whether Matrix GPIO is used + bool digital_enabled; // Whether digital is used bool gpio_enabled; // Whether GPIO has been prepared bool led_enabled; // Whether a user LED is enabled bool gpio_test_pin_enabled; // Whether the test pin was also enabled @@ -65,11 +65,11 @@ volatile uint32_t *pru_buffer_comm; uint16_t *pru_buffer_spi_dac; uint16_t *pru_buffer_spi_adc; - uint32_t *pru_buffer_matrix_gpio; + uint32_t *pru_buffer_digital; int16_t *pru_buffer_audio_dac; int16_t *pru_buffer_audio_adc; unsigned int spi_buffer_frames; - unsigned int matrix_gpio_buffer_frames; + unsigned int digital_buffer_frames; unsigned int audio_buffer_frames; int xenomai_gpio_fd; // File descriptor for /dev/mem for fast GPIO
--- a/include/RTAudio.h Thu Apr 30 16:02:47 2015 +0100 +++ b/include/RTAudio.h Thu Apr 30 16:58:41 2015 +0100 @@ -39,15 +39,15 @@ // real-time audio system typedef struct { // These items might be adjusted by the user: - int periodSize; // Number of (matrix) frames per period; audio is twice this + int periodSize; // Number of (analog) frames per period; audio is twice this int beginMuted; // Whether to begin with the speakers muted float dacLevel; // Level for the audio DAC output float adcLevel; // Level for the audio ADC input float headphoneLevel; // Level for the headphone output - int useMatrix; // Whether to use the matrix - int useMatrixGpio; // Whether to use the 16 programmable GPIOs - int numMatrixChannels; // How many channels for the ADC and DAC - int numMatrixGpioChannels; // How many channels for the GPIOs + int useAnalog; // Whether to use the analog + int useDigital; // Whether to use the 16 programmable GPIOs + int numAnalogChannels; // How many channels for the ADC and DAC + int numDigitalChannels; // How many channels for the GPIOs int verbose; // Whether to use verbose logging char pruFilename[MAX_PRU_FILENAME_LENGTH]; //the external .bin file to load. If empty will use PRU code from pru_rtaudio_bin.h // These items are hardware-dependent and should only be changed
--- a/include/Utilities.h Thu Apr 30 16:02:47 2015 +0100 +++ b/include/Utilities.h Thu Apr 30 16:58:41 2015 +0100 @@ -9,18 +9,18 @@ #define UTILITIES_H_ extern int gNumAudioChannels; // How many audio channels are present -extern int gNumMatrixChannels; // How many matrix channels are present +extern int gNumAnalogChannels; // How many analog channels are present -// Macros for accessing the matrix values: usable _only_ within render() +// 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) (matrixIn[(f)*gNumMatrixChannels + (p)]) -// Write an analog output frame at output pin p, frame f, to value v -#define analogWriteFrame(p, f, v) (matrixOut[(f)*gNumMatrixChannels + (p)] = (v)) -#define analogWrite(pin, frame, value) \ +// Read an Analog input from input pin p at frame f +#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) \ (({do {\ - for (int _privateI=(frame); _privateI<numMatrixFrames; _privateI++){ \ - analogWriteFrame(pin,_privateI,value); \ + for (int _privateI=(frame); _privateI<numAnalogFrames; _privateI++){ \ + AnalogWriteFrame(pin,_privateI,value); \ }\ } while (0);}),(void)0)\ @@ -28,19 +28,19 @@ #define clearBit(word,bit) ((word)&~(1<<(bit))) #define getBit(word,bit) (((word)>>(bit))&1) #define changeBit(word,bit,value) ((clearBit((word),(bit))) | ((value)<<(bit))) -//matrixGpio API: -#define setDigitalDirectionFrame(pin,frame,direction) matrixGpio[(frame)]=changeBit(matrixGpio[(frame)],(pin),(direction)) -#define setDigitalDirection(pin,frame,direction) (for(int _privateI=(frame);_privateI<gNumGpioFrames;_privateI++) matrixGpio[_privateI]=changeBit(matrixGpio[(_privateI)],(pin),(direction))),void(0) -#define digitalWriteAll(frame,value) matrixGpio[(frame)]=0xffff0000*(!(!value)); +//digital API: +#define setDigitalDirectionFrame(pin,frame,direction) digital[(frame)]=changeBit(digital[(frame)],(pin),(direction)) +#define setDigitalDirection(pin,frame,direction) (for(int _privateI=(frame);_privateI<gNumGpioFrames;_privateI++) digital[_privateI]=changeBit(digital[(_privateI)],(pin),(direction))),void(0) +#define digitalWriteAll(frame,value) digital[(frame)]=0xffff0000*(!(!value)); //sets the bit in the high word, clears the bit in the low word (just in case the direction was not previously set) -#define digitalWriteFrame(pin, frame, value) matrixGpio[(frame)]=( changeBit(matrixGpio[(frame)], (pin+16), (value)) & (0xffffffff-(1<<(pin))) ) //could have been done with two subsequent assignments +#define digitalWriteFrame(pin, frame, value) digital[(frame)]=( changeBit(digital[(frame)], (pin+16), (value)) & (0xffffffff-(1<<(pin))) ) //could have been done with two subsequent assignments #define digitalWrite(pin, frame, value) \ (({do {\ - for (int _privateI=(frame); _privateI<gNumMatrixGpioFrames; _privateI++) \ + for (int _privateI=(frame); _privateI<gNumDigitalFrames; _privateI++) \ digitalWriteFrame(pin,_privateI,value); \ } while (0);}),(void)0)\ -#define digitalRead(pin, frame) ( getBit(matrixGpio[(frame)], pin+16) ) +#define digitalRead(pin, frame) ( getBit(digital[(frame)], pin+16) ) float map(float x, float in_min, float in_max, float out_min, float out_max); float constrain(float x, float min_val, float max_val);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/digital_gpio_mapping.h Thu Apr 30 16:58:41 2015 +0100 @@ -0,0 +1,72 @@ +#ifndef DIGITAL_MAPPING_H +#define DIGITAL_MAPPING_H + +#define NUM_DIGITALS 16 +extern short int digitalPins[NUM_DIGITALS]; +//GPIO_INPUT and GPIO_OUTPUT values when calling the setDigitalDirection() macro. +//TODO: these are inverted with respect to INPUT_PIN and OUTPUT_PIN defined in GPIOcontrol.h, +//which might lead to unexpected results in case someone uses those in place of these or viceversa +#define GPIO_INPUT 1 +#define GPIO_OUTPUT 0 +#define GPIO_HIGH 1 +#define GPIO_LOW 0 +//mapping GPIO numbers to header pins +//if you want to use different pins/ordering, define here new pins. The ordering here is NOT binding +#define P8_07_GPIO_NO 66 +#define P8_08_GPIO_NO 67 +#define P8_09_GPIO_NO 69 +#define P8_10_GPIO_NO 68 +#define P8_11_GPIO_NO 45 +#define P8_12_GPIO_NO 44 +#define P9_12_GPIO_NO 60 +#define P9_14_GPIO_NO 50 +#define P8_15_GPIO_NO 47 +#define P8_16_GPIO_NO 46 +#define P9_16_GPIO_NO 51 +#define P8_18_GPIO_NO 65 +#define P8_27_GPIO_NO 86 +#define P8_28_GPIO_NO 88 +#define P8_29_GPIO_NO 87 +#define P8_30_GPIO_NO 89 + +//mapping pin headers to bits in the digital word. +//used in the declaration of short int digitalPins[NUM_DIGITALS] below, which is used in PRU::prepareGPIO to export the pins +//if you want to use different pins, declare them above and use them here +//The ordering here is NOT binding, but if you want to use a different ordering, please change it here as well as below and in the PRU, for consistency +#define GPIO_NO_BIT_0 P8_07_GPIO_NO +#define GPIO_NO_BIT_1 P8_08_GPIO_NO +#define GPIO_NO_BIT_2 P8_09_GPIO_NO +#define GPIO_NO_BIT_3 P8_10_GPIO_NO +#define GPIO_NO_BIT_4 P8_11_GPIO_NO +#define GPIO_NO_BIT_5 P8_12_GPIO_NO +#define GPIO_NO_BIT_6 P9_12_GPIO_NO +#define GPIO_NO_BIT_7 P9_14_GPIO_NO +#define GPIO_NO_BIT_8 P8_15_GPIO_NO +#define GPIO_NO_BIT_9 P8_16_GPIO_NO +#define GPIO_NO_BIT_10 P9_16_GPIO_NO +#define GPIO_NO_BIT_11 P8_18_GPIO_NO +#define GPIO_NO_BIT_12 P8_27_GPIO_NO +#define GPIO_NO_BIT_13 P8_28_GPIO_NO +#define GPIO_NO_BIT_14 P8_29_GPIO_NO +#define GPIO_NO_BIT_15 P8_30_GPIO_NO + +//mapping bits in the digital word to pin headers, so that pin header name can be used instead of but number +//The ordering here IS binding. If you want to use different pins/ordering, please do it above as well as here and in the PRU, for consistency +#define P8_07 0 +#define P8_08 1 +#define P8_09 2 +#define P8_10 3 +#define P8_11 4 +#define P8_12 5 +#define P9_12 6 +#define P9_14 7 +#define P8_15 8 +#define P8_16 9 +#define P9_16 10 +#define P8_18 11 +#define P8_27 12 +#define P8_28 13 +#define P8_29 14 +#define P8_30 15 + +#endif
--- a/include/matrix_gpio_mapping.h Thu Apr 30 16:02:47 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -#ifndef MATRIX_GPIO_MAPPING_H -#define MATRIX_GPIO_MAPPING_H - -#define NUM_MATRIX_GPIOS 16 -extern short int matrixGpioPins[NUM_MATRIX_GPIOS]; -//GPIO_INPUT and GPIO_OUTPUT values when calling the setDigitalDirection() macro. -//TODO: these are inverted with respect to INPUT_PIN and OUTPUT_PIN defined in GPIOcontrol.h, -//which might lead to unexpected results in case someone uses those in place of these or viceversa -#define GPIO_INPUT 1 -#define GPIO_OUTPUT 0 -#define GPIO_HIGH 1 -#define GPIO_LOW 0 -//mapping GPIO numbers to header pins -//if you want to use different pins/ordering, define here new pins. The ordering here is NOT binding -#define P8_07_GPIO_NO 66 -#define P8_08_GPIO_NO 67 -#define P8_09_GPIO_NO 69 -#define P8_10_GPIO_NO 68 -#define P8_11_GPIO_NO 45 -#define P8_12_GPIO_NO 44 -#define P9_12_GPIO_NO 60 -#define P9_14_GPIO_NO 50 -#define P8_15_GPIO_NO 47 -#define P8_16_GPIO_NO 46 -#define P9_16_GPIO_NO 51 -#define P8_18_GPIO_NO 65 -#define P8_27_GPIO_NO 86 -#define P8_28_GPIO_NO 88 -#define P8_29_GPIO_NO 87 -#define P8_30_GPIO_NO 89 - -//mapping pin headers to bits in the matrixGpio word. -//used in the declaration of short int matrixGpioPins[NUM_MATRIX_GPIOS] below, which is used in PRU::prepareGPIO to export the pins -//if you want to use different pins, declare them above and use them here -//The ordering here is NOT binding, but if you want to use a different ordering, please change it here as well as below and in the PRU, for consistency -#define GPIO_NO_BIT_0 P8_07_GPIO_NO -#define GPIO_NO_BIT_1 P8_08_GPIO_NO -#define GPIO_NO_BIT_2 P8_09_GPIO_NO -#define GPIO_NO_BIT_3 P8_10_GPIO_NO -#define GPIO_NO_BIT_4 P8_11_GPIO_NO -#define GPIO_NO_BIT_5 P8_12_GPIO_NO -#define GPIO_NO_BIT_6 P9_12_GPIO_NO -#define GPIO_NO_BIT_7 P9_14_GPIO_NO -#define GPIO_NO_BIT_8 P8_15_GPIO_NO -#define GPIO_NO_BIT_9 P8_16_GPIO_NO -#define GPIO_NO_BIT_10 P9_16_GPIO_NO -#define GPIO_NO_BIT_11 P8_18_GPIO_NO -#define GPIO_NO_BIT_12 P8_27_GPIO_NO -#define GPIO_NO_BIT_13 P8_28_GPIO_NO -#define GPIO_NO_BIT_14 P8_29_GPIO_NO -#define GPIO_NO_BIT_15 P8_30_GPIO_NO - -//mapping bits in the matrixGpio word to pin headers, so that pin header name can be used instead of but number -//The ordering here IS binding. If you want to use different pins/ordering, please do it above as well as here and in the PRU, for consistency -#define P8_07 0 -#define P8_08 1 -#define P8_09 2 -#define P8_10 3 -#define P8_11 4 -#define P8_12 5 -#define P9_12 6 -#define P9_14 7 -#define P8_15 8 -#define P8_16 9 -#define P9_16 10 -#define P8_18 11 -#define P8_27 12 -#define P8_28 13 -#define P8_29 14 -#define P8_30 15 - -#endif
--- a/include/render.h Thu Apr 30 16:02:47 2015 +0100 +++ b/include/render.h Thu Apr 30 16:58:41 2015 +0100 @@ -11,7 +11,7 @@ // uint types #include <stdint.h> #include "../include/Utilities.h" -#include "../include/matrix_gpio_mapping.h" +#include "../include/digital_gpio_mapping.h" // Mappings from pin numbers on PCB to actual DAC channels // This gives the DAC and ADC connectors the same effective pinout #define DAC_PIN0 6 @@ -32,19 +32,19 @@ #define ADC_PIN6 6 #define ADC_PIN7 7 -#define MATRIX_MAX 65535.0 +#define ANALOG_MAX 65535.0 extern int gNumAudioChannels; // How many audio channels are present -extern int gNumMatrixChannels; // How many matrix channels are present -extern int gNumMatrixGpioChannels; -bool initialise_render(int numMatrixChannels, int numMatrixGpioChannels, int numAudioChannels, - int numMatrixFramesPerPeriod, +extern int gNumAnalogChannels; // How many analog channels are present +extern int gNumDigitalChannels; +bool initialise_render(int numAnalogChannels, int numDigitalChannels, int numAudioChannels, + int numAnalogFramesPerPeriod, int numAudioFramesPerPeriod, - float matrixSampleRate, float audioSampleRate, + float analogSampleRate, float audioSampleRate, void *userData); -void render(int numMatrixFrames, int numAudioFrames, int numMatrixGpioFrames, float *audioIn, float *audioOut, - float *matrixIn, float *matrixOut, uint32_t *matrixGpio); +void render(int numAnalogFrames, int numAudioFrames, int numDigitalFrames, float *audioIn, float *audioOut, + float *analogIn, float *analogOut, uint32_t *digital); void render_medium_prio(); void render_low_prio();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/analogDigitalDemo/main.cpp Thu Apr 30 16:58:41 2015 +0100 @@ -0,0 +1,107 @@ +/* + * assignment1_crossover + * RTDSP 2015 + * + * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover + * using the BeagleBone Black. + * + * Andrew McPherson and Victor Zappi + * Queen Mary, University of London + */ + +#include <iostream> +#include <cstdlib> +#include <libgen.h> +#include <signal.h> +#include <getopt.h> +#include "../include/RTAudio.h" +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> + +using namespace std; + +// Handle Ctrl-C by requesting that the audio rendering stop +void interrupt_handler(int var) +{ + gShouldStop = true; +} + +// Print usage information +void usage(const char * processName) +{ + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --help [-h]: Print this menu\n"; +} + +int main(int argc, char *argv[]) +{ + RTAudioSettings settings; // Standard audio settings + float frequency = 1000.0; // Frequency of crossover + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"frequency", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + + // Parse command-line arguments + while (1) { + int c; + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) + break; + switch (c) { + case 'h': + usage(basename(argv[0])); + exit(0); + case 'f': + frequency = atof(optarg); + if(frequency < 20.0) + frequency = 20.0; + if(frequency > 5000.0) + frequency = 5000.0; + break; + case '?': + default: + usage(basename(argv[0])); + exit(1); + } + } + + // Initialise the PRU audio device + if(BeagleRT_initAudio(&settings, &frequency) != 0) { + cout << "Error: unable to initialise audio" << endl; + return -1; + } + + // Start the audio device running + if(BeagleRT_startAudio()) { + cout << "Error: unable to start real-time audio" << endl; + return -1; + } + + // Set up interrupt handler to catch Control-C + signal(SIGINT, interrupt_handler); + signal(SIGTERM, interrupt_handler); + + // Run until told to stop + while(!gShouldStop) { + usleep(100000); + } + + // Stop the audio device + BeagleRT_stopAudio(); + + // Clean up any resources allocated for audio + BeagleRT_cleanupAudio(); + + // All done! + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/analogDigitalDemo/render.cpp Thu Apr 30 16:58:41 2015 +0100 @@ -0,0 +1,81 @@ +/* + * + * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover + * using the BeagleBone Black. + * + * Andrew McPherson and Victor Zappi + * Queen Mary, University of London + */ + +#include "../include/render.h" +#include <cmath> +#include <rtdk.h> + +/* TASK: declare any global variables you need here */ + +// initialise_render() is called once before the audio rendering starts. +// Use it to perform any initialisation and allocation which is dependent +// on the period size or sample rate. +// +// userData holds an opaque pointer to a data structure that was passed +// in from the call to initAudio(). +// +// Return true on success; returning false halts the program. +int gNumMatrixGpioFrames=0; +bool initialise_render(int numMatrixChannels, int numMatrixGpioChannels, int numAudioChannels, + int numMatrixFramesPerPeriod, + int numAudioFramesPerPeriod, + float matrixSampleRate, float audioSampleRate, + void *userData) +{ + gNumMatrixChannels=numMatrixChannels; + return true; +} + +// render() is called regularly at the highest priority by the audio engine. +// Input and output are given from the audio hardware and the other +// ADCs and DACs (if available). If only audio is available, numMatrixFrames +// will be 0. + +long int gCountFrames=0; +void render(int numMatrixFrames, int numMatrixGpioFrames, int numAudioFrames, float *audioIn, float *audioOut, + float *matrixIn, float *matrixOut, uint32_t *matrixGpio) +/* + * Hey, expect buffer underruns to happen here, as we are doing lots of printfs + * */ +{ + gNumMatrixGpioFrames=numMatrixGpioFrames; + if(gCountFrames==0){ //this will be executed only on the first call to render(), but the bits will go through this cycle for every subsequent buffer + // that is, P8_29 will pulse at the beginning of each buffer + } + for(int i=1; i<gNumMatrixGpioFrames; i++) + digitalWriteAll(i, GPIO_LOW); //write all channels on the given frame. Initialize them to zero + digitalWrite(0, 4, GPIO_HIGH); // set pin 0 HIGH from the current frame to the end of the buffer + for(int n=0; n<numMatrixFrames; n++) { + for(int c=0; c<gNumMatrixChannels; c++) + analogWriteFrame(c,n,0); //set channel c on frame n to 0, equivalent to matrixOut[n*numMatrixChannels+c]=0; + } + analogWrite(0,3,0.2); //set channel 0 to 0.2 from frame 3 onwards ... + analogWrite(1,3,0.7); //set channel 1 to 0.7 from frame 3 onwards ... + analogWrite(2,6,0.5); //set channel 2 to 0.5 from frame 6 onwards ... + for(int n=0; n<numAudioFrames; n++){ + printf("Digital frame %d: 0x%08x;\n",n,matrixGpio[n]); + } + for(int n=0; n<numMatrixFrames; n++){ + printf("Analog out frame %d :",n); + for(int c=0; c<gNumMatrixChannels; c++) + printf("%.1f ",matrixOut[n*gNumMatrixChannels + c]); + printf("\n"); + } +} +// cleanup_render() is called once at the end, after the audio has stopped. +// Release any resources that were allocated in initialise_render(). + +void cleanup_render() +{ + /* TASK: + * If you allocate any memory, be sure to release it here. + * You may or may not need anything in this function, depending + * on your implementation. + */ +}
--- a/projects/matrix_gpio_demo/main.cpp Thu Apr 30 16:02:47 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * assignment1_crossover - * RTDSP 2015 - * - * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover - * using the BeagleBone Black. - * - * Andrew McPherson and Victor Zappi - * Queen Mary, University of London - */ - -#include <iostream> -#include <cstdlib> -#include <libgen.h> -#include <signal.h> -#include <getopt.h> -#include "../include/RTAudio.h" -#include <unistd.h> -#include <stdlib.h> -#include <fcntl.h> - -using namespace std; - -// Handle Ctrl-C by requesting that the audio rendering stop -void interrupt_handler(int var) -{ - gShouldStop = true; -} - -// Print usage information -void usage(const char * processName) -{ - cerr << "Usage: " << processName << " [options]" << endl; - - BeagleRT_usage(); - - cerr << " --help [-h]: Print this menu\n"; -} - -int main(int argc, char *argv[]) -{ - RTAudioSettings settings; // Standard audio settings - float frequency = 1000.0; // Frequency of crossover - - struct option customOptions[] = - { - {"help", 0, NULL, 'h'}, - {"frequency", 1, NULL, 'f'}, - {NULL, 0, NULL, 0} - }; - - // Set default settings - BeagleRT_defaultSettings(&settings); - - // Parse command-line arguments - while (1) { - int c; - if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) - break; - switch (c) { - case 'h': - usage(basename(argv[0])); - exit(0); - case 'f': - frequency = atof(optarg); - if(frequency < 20.0) - frequency = 20.0; - if(frequency > 5000.0) - frequency = 5000.0; - break; - case '?': - default: - usage(basename(argv[0])); - exit(1); - } - } - - // Initialise the PRU audio device - if(BeagleRT_initAudio(&settings, &frequency) != 0) { - cout << "Error: unable to initialise audio" << endl; - return -1; - } - - // Start the audio device running - if(BeagleRT_startAudio()) { - cout << "Error: unable to start real-time audio" << endl; - return -1; - } - - // Set up interrupt handler to catch Control-C - signal(SIGINT, interrupt_handler); - signal(SIGTERM, interrupt_handler); - - // Run until told to stop - while(!gShouldStop) { - usleep(100000); - } - - // Stop the audio device - BeagleRT_stopAudio(); - - // Clean up any resources allocated for audio - BeagleRT_cleanupAudio(); - - // All done! - return 0; -}
--- a/projects/matrix_gpio_demo/render.cpp Thu Apr 30 16:02:47 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * - * First assignment for ECS732 RTDSP, to implement a 2-way audio crossover - * using the BeagleBone Black. - * - * Andrew McPherson and Victor Zappi - * Queen Mary, University of London - */ - -#include "../include/render.h" -#include <cmath> -#include <rtdk.h> - -/* TASK: declare any global variables you need here */ - -// initialise_render() is called once before the audio rendering starts. -// Use it to perform any initialisation and allocation which is dependent -// on the period size or sample rate. -// -// userData holds an opaque pointer to a data structure that was passed -// in from the call to initAudio(). -// -// Return true on success; returning false halts the program. -int gNumMatrixGpioFrames=0; -bool initialise_render(int numMatrixChannels, int numMatrixGpioChannels, int numAudioChannels, - int numMatrixFramesPerPeriod, - int numAudioFramesPerPeriod, - float matrixSampleRate, float audioSampleRate, - void *userData) -{ - gNumMatrixChannels=numMatrixChannels; - return true; -} - -// render() is called regularly at the highest priority by the audio engine. -// Input and output are given from the audio hardware and the other -// ADCs and DACs (if available). If only audio is available, numMatrixFrames -// will be 0. - -long int gCountFrames=0; -void render(int numMatrixFrames, int numMatrixGpioFrames, int numAudioFrames, float *audioIn, float *audioOut, - float *matrixIn, float *matrixOut, uint32_t *matrixGpio) -/* - * Hey, expect buffer underruns to happen here, as we are doing lots of printfs - * */ -{ - gNumMatrixGpioFrames=numMatrixGpioFrames; - if(gCountFrames==0){ //this will be executed only on the first call to render(), but the bits will go through this cycle for every subsequent buffer - // that is, P8_29 will pulse at the beginning of each buffer - } - for(int i=1; i<gNumMatrixGpioFrames; i++) - digitalWriteAll(i, GPIO_LOW); //write all channels on the given frame. Initialize them to zero - digitalWrite(0, 4, GPIO_HIGH); // set pin 0 HIGH from the current frame to the end of the buffer - for(int n=0; n<numMatrixFrames; n++) { - for(int c=0; c<gNumMatrixChannels; c++) - analogWriteFrame(c,n,0); //set channel c on frame n to 0, equivalent to matrixOut[n*numMatrixChannels+c]=0; - } - analogWrite(0,3,0.2); //set channel 0 to 0.2 from frame 3 onwards ... - analogWrite(1,3,0.7); //set channel 1 to 0.7 from frame 3 onwards ... - analogWrite(2,6,0.5); //set channel 2 to 0.5 from frame 6 onwards ... - for(int n=0; n<numAudioFrames; n++){ - printf("Digital frame %d: 0x%08x;\n",n,matrixGpio[n]); - } - for(int n=0; n<numMatrixFrames; n++){ - printf("Analog out frame %d :",n); - for(int c=0; c<gNumMatrixChannels; c++) - printf("%.1f ",matrixOut[n*gNumMatrixChannels + c]); - printf("\n"); - } -} -// cleanup_render() is called once at the end, after the audio has stopped. -// Release any resources that were allocated in initialise_render(). - -void cleanup_render() -{ - /* TASK: - * If you allocate any memory, be sure to release it here. - * You may or may not need anything in this function, depending - * on your implementation. - */ -}
--- a/pru_rtaudio.p Thu Apr 30 16:02:47 2015 +0100 +++ b/pru_rtaudio.p Thu Apr 30 16:58:41 2015 +0100 @@ -81,7 +81,7 @@ #define COMM_FRAME_COUNT 32 // How many frames have elapse since beginning #define COMM_USE_SPI 36 // Whether or not to use SPI ADC and DAC #define COMM_NUM_CHANNELS 40 // Low 2 bits indicate 8 [0x3], 4 [0x1] or 2 [0x0] channels -#define COMM_USE_MATRIX_GPIO 44 // Whether or not to use MATRIX_GPIO +#define COMM_USE_DIGITAL 44 // Whether or not to use DIGITAL #define MCASP0_BASE 0x48038000 #define MCASP1_BASE 0x4803C000 @@ -181,18 +181,18 @@ #define FLAG_BIT_BUFFER1 0 #define FLAG_BIT_USE_SPI 1 #define FLAG_BIT_MCASP_HWORD 2 // Whether we are on the high word for McASP transmission -#define FLAG_BIT_USE_MATRIX_GPIO 3 -/*#define FLAG_BIT_MATRIX_GPIO_BUFFER 4 //Whether we are using buffer located at - // 0: MEM_MATRIX_GPIO_BASE or -*/ // 1: MEM_MATRIX_GPIO_BASE + 512 +#define FLAG_BIT_USE_DIGITAL 3 +/*#define FLAG_BIT_DIGITAL_BUFFER 4 //Whether we are using buffer located at + // 0: MEM_DIGITAL_BASE or +*/ // 1: MEM_DIGITAL_BASE + 512 // Registers used throughout // r1, r2, r3 are used for temporary storage -#define MEM_MATRIX_GPIO_BASE 0x11000 //Base address for MATRIX_GPIO : Shared RAM + 0x400 -#define MEM_MATRIX_GPIO_BUFFER1_OFFSET 0x400 //Start pointer to MATRIX_GPIO_BUFFER1, which is 256 words after. +#define MEM_DIGITAL_BASE 0x11000 //Base address for DIGITAL : Shared RAM + 0x400 +#define MEM_DIGITAL_BUFFER1_OFFSET 0x400 //Start pointer to DIGITAL_BUFFER1, which is 256 words after. // 256 is the maximum number of frames allowed -#define reg_matrix_gpio_current r6 // Pointer to current storage location of MATRIX_GPIO +#define reg_digital_current r6 // Pointer to current storage location of DIGITAL #define reg_num_channels r9 // Number of SPI ADC/DAC channels to use #define reg_frame_current r10 // Current frame count in SPI ADC/DAC transfer #define reg_frame_total r11 // Total frame count for SPI ADC/DAC @@ -214,7 +214,7 @@ // r27, r28 used in macros #define reg_mcasp_addr r29 // Base address for McASP -// MATRIX_GPIO new code starts here +// DIGITAL new code starts here //0 P8_07 36 0x890/090 66 gpio2[2] //1 P8_08 37 0x894/094 67 gpio2[3] //2 P8_09 39 0x89c/09c 69 gpio2[5] @@ -249,50 +249,50 @@ #define reg_gpio2_setdataout r5 #define reg_gpio1_cleardataout r7 #define reg_gpio1_setdataout r8 -#define reg_matrix_gpio r27 //will first contain matrixGpioOut from render() and matrixGpioIn to render() later +#define reg_digital r27 //will first contain digitalOut from render() and digitalIn to render() later //aliases #define reg_gpio1_datain reg_gpio1_oe #define reg_gpio2_datain reg_gpio2_oe .macro SET_GPIO1_BITS -.mparam gpio_num_bit, matrix_gpio_bit - SET_GPIO_BITS reg_gpio1_oe, reg_gpio1_setdataout, reg_gpio1_cleardataout, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio +.mparam gpio_num_bit, digital_bit + SET_GPIO_BITS reg_gpio1_oe, reg_gpio1_setdataout, reg_gpio1_cleardataout, gpio_num_bit, digital_bit, reg_digital .endm .macro SET_GPIO2_BITS -.mparam gpio_num_bit, matrix_gpio_bit - SET_GPIO_BITS reg_gpio2_oe, reg_gpio2_setdataout, reg_gpio2_cleardataout, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio +.mparam gpio_num_bit, digital_bit + SET_GPIO_BITS reg_gpio2_oe, reg_gpio2_setdataout, reg_gpio2_cleardataout, gpio_num_bit, digital_bit, reg_digital .endm .macro READ_GPIO1_BITS -.mparam gpio_num_bit, matrix_gpio_bit - READ_GPIO_BITS reg_gpio1_datain, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio +.mparam gpio_num_bit, digital_bit + READ_GPIO_BITS reg_gpio1_datain, gpio_num_bit, digital_bit, reg_digital .endm .macro READ_GPIO2_BITS -.mparam gpio_num_bit, matrix_gpio_bit - READ_GPIO_BITS reg_gpio2_datain, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio +.mparam gpio_num_bit, digital_bit + READ_GPIO_BITS reg_gpio2_datain, gpio_num_bit, digital_bit, reg_digital .endm .macro READ_GPIO_BITS -.mparam gpio_data, gpio_num_bit, matrix_gpio_bit, matrix_gpio - QBBC DONE, matrix_gpio, matrix_gpio_bit //if the pin is set as an output, nothing to do here +.mparam gpio_data, gpio_num_bit, digital_bit, digital + QBBC DONE, digital, digital_bit //if the pin is set as an output, nothing to do here SET r30.t14 QBBC CLEAR, gpio_data, gpio_num_bit - SET matrix_gpio, matrix_gpio_bit+16 + SET digital, digital_bit+16 QBA DONE CLEAR: - CLR matrix_gpio, matrix_gpio_bit+16 + CLR digital, digital_bit+16 QBA DONE DONE: CLR r30.t14 .endm .macro SET_GPIO_BITS -.mparam gpio_oe, gpio_setdataout, gpio_cleardataout, gpio_num_bit, matrix_gpio_bit, matrix_gpio //sets the bits in GPIO_OE, GPIO_SETDATAOUT and GPIO_CLEARDATAOUT +.mparam gpio_oe, gpio_setdataout, gpio_cleardataout, gpio_num_bit, digital_bit, digital //sets the bits in GPIO_OE, GPIO_SETDATAOUT and GPIO_CLEARDATAOUT //Remember that the GPIO_OE Output data enable register behaves as follows for each bit: //0 = The corresponding GPIO pin is configured as an output. //1 = The corresponding GPIO pin is configured as an input. - QBBS SETINPUT, matrix_gpio, matrix_gpio_bit + QBBS SETINPUT, digital, digital_bit CLR gpio_oe, gpio_num_bit //if it is an output, configure pin as output - QBBC CLEARDATAOUT, matrix_gpio, matrix_gpio_bit+16 // check the output value. If it is 0, branch + QBBC CLEARDATAOUT, digital, digital_bit+16 // check the output value. If it is 0, branch SET gpio_setdataout, gpio_num_bit //if it is 1, set output to high QBA DONE CLEARDATAOUT: @@ -306,25 +306,25 @@ .macro PROCESS_GPIO1_BITS //- sets appropriate bits for output in reg_gpio1_oe, reg_gpio1_cleardataout, reg_gpio1_data -//- sets appropriate bits in reg_matrix_gpio to reflect the input values -.mparam gpio_num_bit, matrix_gpio_bit -// params to SET_GPIO_BITS gpio_oe, gpio_setdataout, gpio_cleardataout, gpio_num_bit, matrix_gpio_bit, matrix_gpio //sets the bits in GPIO_OE, GPIO_SETDATAOUT and GPIO_CLEARDATAOUT - SET_GPIO_BITS reg_gpio1_oe, reg_gpio1_setdataout, reg_gpio1_cleardataout, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio - READ_GPIO_BITS reg_gpio1_oe, reg_gpio1_datain, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio +//- sets appropriate bits in reg_digital to reflect the input values +.mparam gpio_num_bit, digital_bit +// params to SET_GPIO_BITS gpio_oe, gpio_setdataout, gpio_cleardataout, gpio_num_bit, digital_bit, digital //sets the bits in GPIO_OE, GPIO_SETDATAOUT and GPIO_CLEARDATAOUT + SET_GPIO_BITS reg_gpio1_oe, reg_gpio1_setdataout, reg_gpio1_cleardataout, gpio_num_bit, digital_bit, reg_digital + READ_GPIO_BITS reg_gpio1_oe, reg_gpio1_datain, gpio_num_bit, digital_bit, reg_digital .endm .macro PROCESS_GPIO2_BITS //- sets appropriate bits for output in reg_gpio2_oe, reg_gpio2_cleardataout, reg_gpio2_data -//- sets appropriate bits in reg_matrix_gpio to reflect the input values -.mparam gpio_num_bit, matrix_gpio_bit - SET_GPIO_BITS reg_gpio2_oe, reg_gpio2_setdataout, reg_gpio2_cleardataout, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio - READ_GPIO_BITS reg_gpio2_oe, reg_gpio2_datain, gpio_num_bit, matrix_gpio_bit, reg_matrix_gpio +//- sets appropriate bits in reg_digital to reflect the input values +.mparam gpio_num_bit, digital_bit + SET_GPIO_BITS reg_gpio2_oe, reg_gpio2_setdataout, reg_gpio2_cleardataout, gpio_num_bit, digital_bit, reg_digital + READ_GPIO_BITS reg_gpio2_oe, reg_gpio2_datain, gpio_num_bit, digital_bit, reg_digital .endm QBA START // when first starting, go to START, skipping this section. -MATRIX_GPIO: -//reg_matrix_gpio is now the input word passed in render(), one word per frame +DIGITAL: +//reg_digital is now the input word passed in render(), one word per frame //[31:16]: data(1=high, 0=low), [15:0]: direction (0=output, 1=input) ) //Preparing the gpio_oe, gpio_cleardataout and gpio_setdataout for each module @@ -336,7 +336,7 @@ //process oe and datain and prepare dataout for GPIO1 LDI reg_gpio1_setdataout, 0 LDI reg_gpio1_cleardataout, 0 -//map GPIO_MATRIX to gpio1 pins, affects reg_gpio1_oe, reg_gpio1_cleardataout, reg_gpio1_data, reg_matrix_gpio +//map GPIO_ANALOG to gpio1 pins, affects reg_gpio1_oe, reg_gpio1_cleardataout, reg_gpio1_data, reg_digital SET_GPIO1_BITS 13, 4 SET_GPIO1_BITS 12, 5 SET_GPIO1_BITS 28, 6 @@ -359,7 +359,7 @@ //process oe and datain and prepare dataout for GPIO2 LDI reg_gpio2_setdataout, 0 LDI reg_gpio2_cleardataout, 0 -//map GPIO_MATRIX to gpio2 pins, affects reg_gpio2_oe, reg_gpio2_cleardataout, reg_gpio2_data, reg_matrix_gpio +//map GPIO_ANALOG to gpio2 pins, affects reg_gpio2_oe, reg_gpio2_cleardataout, reg_gpio2_data, reg_digital SET_GPIO2_BITS 2, 0 SET_GPIO2_BITS 3, 1 SET_GPIO2_BITS 5, 2 @@ -415,7 +415,7 @@ //regardless of whether the order is gpio1-gpio2 or gpio2-gpio1 JMP r28.w0 // go back to ADC_WRITE_GPIO -// MATRIX_GPIO new code ends here +// DIGITAL new code ends here // Bring CS line low to write to DAC @@ -503,24 +503,24 @@ ADC_CS_UNASSERT .endm -// Complete ADC write+read with chip select and also performs IO for matrix_gpio +// Complete ADC write+read with chip select and also performs IO for digital .macro ADC_WRITE_GPIO .mparam in, out, do_gpio ADC_CS_ASSERT ADC_TX in - QBBC GPIO_DONE, reg_flags, FLAG_BIT_USE_MATRIX_GPIO //skip if MATRIX_GPIO is disabled - AND r27, do_gpio, 0x3 // only do a MATRIX_GPIO every 2 SPI I/O + QBBC GPIO_DONE, reg_flags, FLAG_BIT_USE_DIGITAL //skip if DIGITAL is disabled + AND r27, do_gpio, 0x3 // only do a DIGITAL every 2 SPI I/O QBNE GPIO_DONE, r27, 0 //from here to GPIO_DONE takes 1.8us, while usually ADC_WAIT_FOR_FINISH only waits for 1.14us. -//TODO: it would be better to split the MATRIX_GPIO stuff in two parts: +//TODO: it would be better to split the DIGITAL stuff in two parts: //- one taking place during DAC_WRITE which sets the GPIO_OE //- and the other during ADC_WRITE which actually reads DATAIN and writes CLEAR/SET DATAOUT - //reg_matrix_gpio is actually r27, so do not use r27 from here to ... - LBBO reg_matrix_gpio, reg_matrix_gpio_current, 0, 4 - JAL r28.w0, MATRIX_GPIO - SBBO reg_matrix_gpio, reg_matrix_gpio_current, 0, 4 + //reg_digital is actually r27, so do not use r27 from here to ... + LBBO reg_digital, reg_digital_current, 0, 4 + JAL r28.w0, DIGITAL + SBBO reg_digital, reg_digital_current, 0, 4 //..here you can start using r27 again - ADD reg_matrix_gpio_current, reg_matrix_gpio_current, 4 //increment pointer + ADD reg_digital_current, reg_digital_current, 4 //increment pointer GPIO_DONE: ADC_WAIT_FOR_FINISH ADC_RX out @@ -599,12 +599,12 @@ // Default number of channels in case SPI disabled LDI reg_num_channels, 8 - // Find out whether we should use MATRIX_GPIO - LBBO r2, reg_comm_addr, COMM_USE_MATRIX_GPIO, 4 - QBEQ MATRIX_GPIO_FLAG_CHECK_DONE, r2, 0 - SET reg_flags, reg_flags, FLAG_BIT_USE_MATRIX_GPIO -// SET reg_flags, reg_flags, FLAG_BIT_MATRIX_GPIO_BUFFER //set the flag, so that in WRITE_ONE_BUFFER we will start from buffer0 -MATRIX_GPIO_FLAG_CHECK_DONE: + // Find out whether we should use DIGITAL + LBBO r2, reg_comm_addr, COMM_USE_DIGITAL, 4 + QBEQ DIGITAL_FLAG_CHECK_DONE, r2, 0 + SET reg_flags, reg_flags, FLAG_BIT_USE_DIGITAL +// SET reg_flags, reg_flags, FLAG_BIT_DIGITAL_BUFFER //set the flag, so that in WRITE_ONE_BUFFER we will start from buffer0 +DIGITAL_FLAG_CHECK_DONE: // Find out whether we should use SPI ADC and DAC LBBO r2, reg_comm_addr, COMM_USE_SPI, 4 QBEQ SPI_FLAG_CHECK_DONE, r2, 0 @@ -795,15 +795,15 @@ LSL reg_mcasp_adc_current, reg_mcasp_adc_current, 1 ADC reg_mcasp_adc_current, reg_mcasp_adc_current, reg_mcasp_dac_current MOV reg_frame_current, 0 - QBBS MATRIX_GPIO_BASE_CHECK_SET, reg_flags, FLAG_BIT_BUFFER1 //check which buffer we are using for MATRIX_GPIO + QBBS DIGITAL_BASE_CHECK_SET, reg_flags, FLAG_BIT_BUFFER1 //check which buffer we are using for DIGITAL // if we are here, we are using buffer0 MOV r2, 0 //so adjust offset appropriately - QBA MATRIX_GPIO_BASE_CHECK_DONE -MATRIX_GPIO_BASE_CHECK_SET: //if we are here, we are using buffer1 - MOV r2, MEM_MATRIX_GPIO_BUFFER1_OFFSET //so adjust offset appropriately -MATRIX_GPIO_BASE_CHECK_DONE: - MOV reg_matrix_gpio_current, MEM_MATRIX_GPIO_BASE - ADD reg_matrix_gpio_current, reg_matrix_gpio_current, r2 + QBA DIGITAL_BASE_CHECK_DONE +DIGITAL_BASE_CHECK_SET: //if we are here, we are using buffer1 + MOV r2, MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately +DIGITAL_BASE_CHECK_DONE: + MOV reg_digital_current, MEM_DIGITAL_BASE + ADD reg_digital_current, reg_digital_current, r2 CLR r30.t15 WRITE_LOOP: