fix(adar): F-4.1 lower broadcast writes to per-device unicast loop

The `broadcast=1` path on adarWrite() emitted the 0x08 broadcast opcode
but setChipSelect() only asserts one device's CS line, so only the single
selected chip ever saw the frame. The opcode path has also never been
validated on silicon. Until a HIL test confirms multi-CS semantics, route
broadcast=1 through a unicast loop over all devices so caller intent
(all four take the write) is preserved and the dead opcode path becomes
unreachable. Logs a DIAG_WARN on entry for visibility.
This commit is contained in:
Jason
2026-04-20 15:27:00 +05:45
parent 902f88a8df
commit 356acea314
@@ -811,14 +811,25 @@ void ADAR1000Manager::setChipSelect(uint8_t deviceIndex, bool state) {
} }
void ADAR1000Manager::adarWrite(uint8_t deviceIndex, uint32_t mem_addr, uint8_t data, uint8_t broadcast) { void ADAR1000Manager::adarWrite(uint8_t deviceIndex, uint32_t mem_addr, uint8_t data, uint8_t broadcast) {
uint8_t instruction[3]; // Audit F-4.1: the broadcast SPI opcode path (`instruction[0] = 0x08`)
// has never been exercised on silicon and is structurally questionable —
if (broadcast) { // setChipSelect() only toggles ONE device's CS line, so even if a caller
instruction[0] = 0x08; // opts into the broadcast opcode today, only the single selected chip
} else { // actually sees the frame. Until a HIL test confirms multi-CS semantics,
instruction[0] = ((devices_[deviceIndex]->dev_addr & 0x03) << 5); // route every broadcast write through a per-device unicast loop. This
// preserves caller intent (all four devices take the write) and makes
// the dead opcode-0x08 path unreachable at runtime.
if (broadcast == BROADCAST_ON) {
DIAG_WARN("BF", "adarWrite: broadcast=1 lowered to per-device unicast (addr=0x%03lX data=0x%02X)",
(unsigned long)mem_addr, data);
for (uint8_t d = 0; d < devices_.size(); ++d) {
adarWrite(d, mem_addr, data, BROADCAST_OFF);
}
return;
} }
uint8_t instruction[3];
instruction[0] = ((devices_[deviceIndex]->dev_addr & 0x03) << 5);
instruction[0] |= (0x1F00 & mem_addr) >> 8; instruction[0] |= (0x1F00 & mem_addr) >> 8;
instruction[1] = (0xFF & mem_addr); instruction[1] = (0xFF & mem_addr);
instruction[2] = data; instruction[2] = data;