51 lines
1.7 KiB
C
51 lines
1.7 KiB
C
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
// Simple Modbus RTU master focused on function 0x03 (Read Holding Registers).
|
|
// Transport is byte-stream oriented (USB-serial in this project).
|
|
|
|
typedef struct {
|
|
uint8_t slave_id;
|
|
bool disable_crc;
|
|
} modbus_rtu_master_config_t;
|
|
|
|
typedef struct {
|
|
modbus_rtu_master_config_t cfg;
|
|
|
|
// RX accumulation
|
|
uint8_t rx_buf[256];
|
|
size_t rx_len;
|
|
|
|
// Pending request tracking
|
|
bool awaiting_response;
|
|
uint32_t request_started_ms;
|
|
uint16_t expected_byte_count;
|
|
} modbus_rtu_master_t;
|
|
|
|
void modbus_rtu_master_init(modbus_rtu_master_t *m, modbus_rtu_master_config_t cfg);
|
|
|
|
// Builds a Read Holding Registers (0x03) request.
|
|
// Returns frame length.
|
|
size_t modbus_rtu_build_read_holding(uint8_t *out, size_t out_cap,
|
|
uint8_t slave_id, uint16_t start_addr, uint16_t quantity,
|
|
bool disable_crc);
|
|
|
|
// Feed received bytes into the Modbus parser.
|
|
void modbus_rtu_feed(modbus_rtu_master_t *m, const uint8_t *data, size_t len);
|
|
|
|
// Returns true when a full response for function 0x03 is present in rx_buf.
|
|
// If true, `*out_data_offset` points to first data byte, `*out_word_count` is number of 16-bit registers.
|
|
bool modbus_rtu_try_parse_read_holding_response(modbus_rtu_master_t *m,
|
|
uint8_t expected_slave_id,
|
|
uint16_t expected_quantity,
|
|
size_t *out_data_offset,
|
|
uint16_t *out_word_count);
|
|
|
|
uint16_t modbus_rtu_get_u16_be(const uint8_t *p);
|
|
uint16_t modbus_rtu_crc16(const uint8_t *data, size_t len);
|
|
|
|
float modbus_float_dcba(uint16_t w1, uint16_t w2);
|