[READ-ONLY] Mirror of https://github.com/SantaClaas/embedded-fan-control.

Give the relay module a bus of its own master

It cannot join the fans'. They run 8E1, it answers 8N1 and only 8N1, and its parity is not settable at any baud rate — the one thing about it that cannot be reconciled. So UART1, on GP8 and GP9 with GP7 arbitrating a second transceiver. Those pins are not a preference: UART1's other transmit pins here are GP4, which arbitrates the fans' bus, and GP20, which drives a status LED. GP0 and GP1 are free and left alone, being where a debug probe's UART bridge conventionally goes. Home Assistant sees a switch. Its state topic carries what the module confirmed rather than what it was asked for, which is the rule the fans already follow, and the contact is read back on boot for the reason their speeds are: the device holds its state while the controller restarts, so what it is doing now is the state to start from. A module that cannot be reached leaves the switch unknown instead of showing an assumption, and a write that is never acknowledged clears what the firmware thinks it knows, so the next command attempts the write rather than skipping it as already satisfied. The modbus client gains the two coil functions. A single coil write is confirmed by the device sending the request back byte for byte, which is exactly how a written holding register is acknowledged, so it is the same transaction with nothing masked off — the mask the fan needs for the four set point bits it ignores became a parameter rather than a second copy of the function. The read asks for eight coils although the board has one, because a one relay variant of an eight relay design answers only the eight wide read its manual prints and stays silent at any other. That is the same fact the serial tool was taught two days ago, and it is in `docs/relay.md` because the hardware said so. Nothing guards the second client. The fans' sits behind a mutex and a once lock because four tasks reach for it; one task talks to this bus, so it holds the client outright. Copying the pattern would have been copying a solution to a problem this bus does not have. Verified by compiling — this crate has no test harness and none of it has run on hardware yet, the module not being wired. The discovery payload is 3445 bytes against a 4096 byte send buffer, which the compile time assertion in main.rs checks and which the switch left about 600 bytes of. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>


+697 -75
14 changed files