// variables for each LED
bool lfo_mod_active_state;
bool lfo_mod_single_state;
bool lfo_mod_sine_state;
bool lfo_mod_square_state;
bool lfo_mod_pulse_state;
bool lfo_mod_pulse_duty_state;
bool lfo_mod_triangle_state;
bool lfo_mod_saw_state;
bool lfo_mod_samphold_state;
bool vfoA_single_state;
bool *shiftreg_output_led_ref[] =
{
&lfo_mod_active_state,
&lfo_mod_single_state,
&lfo_mod_sine_state,
&lfo_mod_square_state,
&lfo_mod_pulse_state,
&lfo_mod_pulse_duty_state,
&lfo_mod_triangle_state,
&lfo_mod_saw_state,
&lfo_mod_samphold_state,
&vfoA_single_state,
};
#define NUM_LEDS 10
// how long to let shift register signals settle when clocking data bits in
#define SHIFTREG_DELAY_MICROSECONDS 5
#define LED_PIN 13 // teensy 13
#define SHIFTREG_CLOCK_PIN LED_PIN // teensy 13
#define AUDIO_VOLUME_PIN A1 // teensy 15
#define SHIFTREG_DATA_PIN AUDIO_VOLUME_PIN // teensy 15
#define SHIFTREG_LOW_OUTPUT_ENABLE_PIN 22 // teensy 22
// display the current state of all LEDs
void write_leds_thru_shiftreg(void)
{
AudioNoInterrupts();
// constant enable the shift register output enable (turn off PWM while writing)
analogWrite(SHIFTREG_LOW_OUTPUT_ENABLE_PIN, 0);
// write each LED state sequentially into the shift register
for (int led_index = 0; led_index < NUM_LEDS; led_index++)
{
// set the shift register data
digitalWrite(SHIFTREG_DATA_PIN, *shiftreg_output_led_ref[led_index]);
// delay long enough for the data to settle (spec says 125ns)
// (knowing that values less than delayMicroseconds(3) are not guaranteed to work consistently)
delayMicroseconds(SHIFTREG_DELAY_MICROSECONDS);
// activate the shift register clock (which will also temporarily light the on-board LED)
digitalWrite(SHIFTREG_CLOCK_PIN, HIGH);
// delay long enough for the data to be consistently clocked into the shift register (spec says 100ns)
// (knowing that values less than delayMicroseconds(3) are not guaranteed to work consistently)
delayMicroseconds(SHIFTREG_DELAY_MICROSECONDS);
// deactivate the shift register clock
digitalWrite(SHIFTREG_CLOCK_PIN, LOW);
// delay long enough for the data to be consistently clocked into the shift register (spec says 100ns)
// (knowing that values less than delayMicroseconds(3) are not guaranteed to work consistently)
delayMicroseconds(SHIFTREG_DELAY_MICROSECONDS);
}
// need to toggle the shift register clock two extra times (once to account for the 1-bit delay induced by
// connecting the shift-clock & data-clock together, & a second time to bypass one unused output in the
// shift register chain - of course, Murphy would have it that the unused output is at the beginning of
// the chain, so it affects *every* update - if it were at the end of the chain, it could be ignored !!)
// set the shift register data LOW for the extra bits & leave it inactive
digitalWrite(SHIFTREG_DATA_PIN, LOW);
// delay long enough for the data to settle (spec says 125nsec)
// (knowing that values less than delayMicroseconds(3) are not guaranteed to work consistently)
delayMicroseconds(SHIFTREG_DELAY_MICROSECONDS);
// activate the shift register clock (which will also temporarily light the on-board LED)
digitalWrite(SHIFTREG_CLOCK_PIN, HIGH);
// delay long enough for the data to be consistently clocked into the shift register (spec says 100ns)
// (knowing that values less than delayMicroseconds(3) are not guaranteed to work consistently)
delayMicroseconds(SHIFTREG_DELAY_MICROSECONDS);
// deactivate the shift register clock
digitalWrite(SHIFTREG_CLOCK_PIN, LOW);
// delay long enough for the data to be consistently clocked into the shift register (spec says 100ns)
// (knowing that values less than delayMicroseconds(3) are not guaranteed to work consistently)
delayMicroseconds(SHIFTREG_DELAY_MICROSECONDS);
// activate the shift register clock (which will also temporarily light the on-board LED)
digitalWrite(SHIFTREG_CLOCK_PIN, HIGH);
// delay long enough for the data to be consistently clocked into the shift register (spec says 100ns)
// (knowing that values less than delayMicroseconds(3) are not guaranteed to work consistently)
delayMicroseconds(SHIFTREG_DELAY_MICROSECONDS);
// deactivate the shift register clock
digitalWrite(SHIFTREG_CLOCK_PIN, LOW);
// re-activate the shift register output enable PWM
analogWrite(SHIFTREG_LOW_OUTPUT_ENABLE_PIN, (255 - led_intensity));
AudioInterrupts();
} // write_leds_thru_shiftreg()