Befaco / muxlicer

Befaco Muxlicer information
12 stars 4 forks source link

refresh_mux too slow for changing mux address lines #7

Open eeweegh opened 2 years ago

eeweegh commented 2 years ago

Had some email exchange about this with Befaco support, so thought I'd share the code here. refresh_mux() uses multiple digitalWrite() calls to enable/disable the switches, and to change the address lines for the selected step. You can easily see that if you look at the output with a scope, as (before the final setting of the address lines) the values briefly jump around as A0, A1 and A2 are individually changed. In all honesty, never heard the jump when driving oscillator pitch, so this might be an academical exercise, depending on your angle.

The code below assumes a few things (which are hardware defined anyway), but gets away with some of the spikes, by avoiding digitalWrite() and going straight to the pin registers. Unfortunately, A2 is on a separate register, so a change in address in the high-test bit is still visible. That would require a hardware change.

void refresh_mux (byte myAddress) {
   // this depends on A0,A1,A2 being on digital pins 6, 7, 8
   // aka PD6, PD7 and PB0

   // not time critical
   digitalWrite(enable_mux, LOW);

   {
      // block interrupts, as digitalWrite does
      byte sreg = SREG;
      cli();

      byte address12 = (PORTD & B00111111) | ((myAddress & B00000011) << 6);
      byte address3  = (PORTB & B11111110) | ((myAddress & B00000100) >> 2);

      PORTD = address12;
      PORTB = address3;

      SREG = sreg;
   }

   // not time critical
   digitalWrite(enable_mux, HIGH);
}

BEFORE

image

AFTER

image