Created
December 27, 2024 19:38
-
-
Save camprevail/f900b4640cfd6d242b6b0fbdb268c498 to your computer and use it in GitHub Desktop.
Init sdvx amps to a set volume
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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