thetechnobear btw: I also noticed when Ive been working on something for a while (or perhaps its just when IDE is running for a long time?) , I start getting the following messages in the console of the IDE
That's new to me, so https://github.com/BelaPlatform/Bela/issues/550
thetechnobear the reason:
Im developing a patch where the outputs are driving a VCA and an oscillator, so every time I stop the patch to do some work on it, I have to remember to go turn the VCA input down, to avoid getting a high pitched output from my speakers (since Salt take the vca level to 10v and also pitch of oscillator to +10v)
(same issue with trig out)
makes total sense. The default behaviour is now to set the DAC and GPIO outs to 0, to avoid exactly this kind of issue. Previous behaviour was to keep the latest value, or, in case of ARM crash, cycling through the latest buffer, both somehow unwanted. However, on Salt the analog front-end will invert the output values, yielding the result you observe.
This commit ensure that the digital outs send out a zero when ARM stops (again, handling it both from ARM in case of a graceful stop and from the PRU in case of an ungraceful one).
This one instead writes zeros to the analog outs (no way to handle this from ARM).
In both cases, the approach on the PRU is to replace the value in memory with zeros as soon as the old value has been read, so that if ARM stops responding, the PRU will not cycle through the latest buffer. Additionally, the PRU writes 0 to all DAC channels when it gracefully stops. For GPIO, this is done by ARM.
A hotfix to change this behaviour should be:
- for DAC, set the "data" in the in DAC_WRITE_ALL_ZEROS
to 0xffff
at https://github.com/BelaPlatform/Bela/blob/master/pru/pru_rtaudio.p#L531
diff --git a/pru/pru_rtaudio.p b/pru/pru_rtaudio.p
index 43dc5a89..de575d71 100644
--- a/pru/pru_rtaudio.p
+++ b/pru/pru_rtaudio.p
@@ -528,7 +528,7 @@ SKIP_CS_UNASSERT:
//command 0x3: write and update DAC channel n
//address 0xf: write to all channels
//data: 0
- MOV tempreg, ((0x3 << AD5668_COMMAND_OFFSET) | (0xf << AD5668_ADDRESS_OFFSET) )
+ MOV tempreg, ((0x3 << AD5668_COMMAND_OFFSET) | (0xf << AD5668_ADDRESS_OFFSET) | (0xffff << AD5668_DATA_OFFSET) )
DAC_WRITE tempreg
.endm
additionally, store back in memory 65535 instead of 0 at https://github.com/BelaPlatform/Bela/blob/master/pru/pru_rtaudio.p#L1061:
@@ -1058,7 +1058,7 @@ SPI_DAC_LOAD_DONE:
MCASP_DAC_LOW_WORD:
// Load next 2 Audio DAC samples and store zero in their place
LBCO reg_mcasp_dac_data, C_MCASP_MEM, reg_mcasp_dac_current, 4
- MOV r2, 0
+ MOV r2, 0xffff
SBCO r2, C_MCASP_MEM, reg_mcasp_dac_current, 4
ADD reg_mcasp_dac_current, reg_mcasp_dac_current, 4
For digitals, it's a bit more convoluted:
store back in memory 1s instead of 0 at https://github.com/BelaPlatform/Bela/blob/master/pru/pru_rtaudio.p#L638 . The high word of R27 is where the digital values are, and we need to set the ones that are outputs (that is the ones whose corresponding bit in the low-word is set to 0
) to 1.
@@ -635,7 +635,9 @@ DO_GPIO:
// this way, if the ARM program crashes, the PRU will write 0s to the outputs
LSL r28, r27, 16
// high word now contains bitmask with 0s where outputs are
- AND r27.w2, r28.w2, r27.w2 // mask them out
+ NOT r28.w2, r28.w2
+ // now it contains 1s where outputs are
+ OR r27.w2, r28.w2, r27.w2 // set the outputs to 1
SBBO r27, reg_digital_current, 0, 4
//..here you can start using r27 again
ADD reg_digital_current, reg_digital_current, 4 //increment pointer
Additionally, set this on the ARM side.
--- a/core/PRU.cpp
+++ b/core/PRU.cpp
@@ -366,15 +366,28 @@ void PRU::cleanupGPIO()
}
if(digital_enabled){
for(unsigned int i = 0; i < context->digitalChannels; i++){
+ int outputValue = 0;
if(belaHw == BelaHw_Salt) {
if(gDigitalPins[i] == saltSwitch1Gpio)
continue; // leave alone this pin as it is used by bela_button.service
+ if(0 == gDigitalPins[i] || 5 == gDigitalPins[i] || 12 == gDigitalPins[i] || 13 == gDigitalPins[i])
+ {
+ // set the digital outputs to 1, so that, after the analog inverting stage, the CV out is 0V
+ // when the patch is stopped
+ outputValue = 1;
+ }
+ }
+ int ret = 0;
+ // if the pin has to be 0, try to unexport the pin
+ if(0 == outputValue)
+ {
+ ret = gpio_unexport(gDigitalPins[i]);
}
- if(gpio_unexport(gDigitalPins[i]))
+ if(ret || outputValue)
{
- // if unexport fails, we at least turn off the outputs
+ // if unexport fails (or didn't happen), set the desired output value
gpio_set_dir(gDigitalPins[i], OUTPUT_PIN);
- gpio_set_value(gDigitalPins[i], 0);
+ gpio_set_value(gDigitalPins[i], outputValue);
}
}
}
I haven't tested any of these, but give it a try. We can then make the changes on the PRU side to be conditional to Salt (they are already conditional on ARM).