Skip to content

Instantly share code, notes, and snippets.

@camprevail
Created December 27, 2024 19:38
Show Gist options
  • Save camprevail/f900b4640cfd6d242b6b0fbdb268c498 to your computer and use it in GitHub Desktop.
Save camprevail/f900b4640cfd6d242b6b0fbdb268c498 to your computer and use it in GitHub Desktop.
Init sdvx amps to a set volume
// Pin definitions
#define DATA_PIN 2
#define CLOCK_PIN 3
#define HI(pin) pinMode(pin, INPUT)
#define LO(pin) pinMode(pin, OUTPUT)
enum VOLTAGE: uint32_t {
_12vto15v = 0b11,
_9vto12v = 0b10,
_6vto9v = 0b01,
_4v5to6v = 0b00,
};
// SET VOLUME HERE. 0 IS MAX, 95 IS MIN.
const uint32_t ATTENUATION = 0;
const uint32_t BOARD_VOLTAGE = VOLTAGE::_6vto9v;
/**
* Bits we send to the amps to set the channel volumes. See datasheet
* for the controller on the amps that is receiving this data:
* https://www.renesas.com/in/en/document/dst/m61545afp-datasheet
*
* Give an attenuation from 0 to 95 (don't use negative numbers)
*/
uint32_t get_vol_packet(uint32_t att) {
if(att > 95) {
att = 0xFF; // infinite
}
return
(att << 11) | // left channel
(att << 4) | // right channel
(BOARD_VOLTAGE << 2) | // voltage
(0b11 << 0) // EOF
;
}
/**
* Sends the given packet to the amps. The amp controller is really generous with
* the clock timings allowed, so we just bitbang a low frequency clock signal.
*/
void send_volume_packet(uint32_t packet) {
// We need to send 18 bits of data, synchronized to the clock line we generate
for (int x = 17; x >= 0; x--) {
// Set the data lines low or high depending on the bit we're sending
if (packet & (1UL << x)) {
HI(DATA_PIN);
}
else {
LO(DATA_PIN);
}
// Slight delay between setting the data line and setting the clock line
// to ensure the data is set by the time the clock pulses
delay(1);
// Set the clock high and generate a clock pulse
HI(CLOCK_PIN);
delay(1);
// Reset the data line back to low (except for the final bit, which
// needs to stay high when the clock goes low to signal a latch)
if (x != 0) {
LO(DATA_PIN);
}
delay(1);
// Set the clock low
LO(CLOCK_PIN);
delay(1);
}
// After the final bit, the data line is high after we've already lowered the clock
// so we can signal a latch -- lower it now
LO(DATA_PIN);
}
/**
* Main entrypoint.
*/
void setup() {
// Init the pins
LO(DATA_PIN);
LO(CLOCK_PIN);
// Set the initial states
digitalWrite(DATA_PIN, LOW);
digitalWrite(CLOCK_PIN, LOW);
// Send some packets
for (int x = 0; x < 2; x++) {
delay(200);
send_volume_packet(get_vol_packet(ATTENUATION));
}
// Pull the lines low and call it done
LO(CLOCK_PIN);
LO(CLOCK_PIN);
}
void loop() {
// No-op
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment