diff --git a/fan-controller/src/modbus/function/mod.rs b/fan-controller/src/modbus/function/mod.rs index 1edfdce..ff2183f 100644 --- a/fan-controller/src/modbus/function/mod.rs +++ b/fan-controller/src/modbus/function/mod.rs @@ -1,5 +1,6 @@ pub(super) mod code; pub(crate) mod read_input_register; +pub(crate) mod write_holding_register; pub(crate) trait Function { const CODE: u8; diff --git a/fan-controller/src/modbus/function/write_holding_register.rs b/fan-controller/src/modbus/function/write_holding_register.rs new file mode 100644 index 0000000..ed5242a --- /dev/null +++ b/fan-controller/src/modbus/function/write_holding_register.rs @@ -0,0 +1,28 @@ +use crate::modbus; + +/// Originally an experiment at a simpler data type to represent a modbus message +pub(crate) struct WriteHoldingRegister([u8; 8]); + +impl WriteHoldingRegister { + pub(crate) fn new(device_address: u8, register_address: u16, value: u16) -> Self { + let register_address = register_address.to_be_bytes(); + let mut data = [ + device_address, + modbus::function::code::WRITE_SINGLE_REGISTER, + register_address[0], + register_address[1], + (value >> 8) as u8, + value as u8, + // CRC set in next step + 0, + 0, + ]; + + let checksum = modbus::CRC.checksum(&data[..6]).to_be_bytes(); + + // They come out reversed (or is us using to_be_bytes reversed?) + data[6] = checksum[1]; + data[7] = checksum[0]; + Self(data) + } +}