From b836f9a2f40ea316da787c07d3fc2d756b29cf69 Mon Sep 17 00:00:00 2001 From: Eduard Iten Date: Tue, 1 Jul 2025 14:56:56 +0200 Subject: [PATCH] feat(slave_node): Implement system registers - Add read support for system-level input registers: - FIRMWARE_VERSION_MAJOR_MINOR (0xF0) - FIRMWARE_VERSION_PATCH (0xF1) - DEVICE_STATUS (0xF2) - Use enums for register addresses to improve readability. - Implement a workaround for a Kconfig issue by hardcoding the firmware version. - Stabilize multi-register reads by returning 0 for unhandled input registers instead of an exception. - NOTE: Writing to holding registers is currently unstable with mbpoll and will be addressed separately. --- software/apps/slave_node/src/main.c | 75 +++++++++++++++++------------ 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/software/apps/slave_node/src/main.c b/software/apps/slave_node/src/main.c index d93a8ee..cef1530 100644 --- a/software/apps/slave_node/src/main.c +++ b/software/apps/slave_node/src/main.c @@ -14,57 +14,64 @@ #include LOG_MODULE_REGISTER(mbs_sample, LOG_LEVEL_INF); -static uint16_t holding_reg[8]; -static uint8_t coils_state; +#define APP_VERSION_MAJOR 1 +#define APP_VERSION_MINOR 0 +#define APP_VERSION_PATCH 0 + +enum { + REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR = 0x00F0, + REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1, + REG_INPUT_DEVICE_STATUS = 0x00F2, + REG_INPUT_UPTIME_SECONDS_LOW = 0x00F3, + REG_INPUT_UPTIME_SECONDS_HIGH = 0x00F4, +}; + +enum { + REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0, +}; + + +static uint16_t watchdog_timeout_s; static int coil_rd(uint16_t addr, bool *state) { *state = true; - LOG_INF("Coil read, addr %u, %d", addr, (int)*state); - return 0; } static int coil_wr(uint16_t addr, bool state) { - bool on; - if (state == true) { - coils_state |= BIT(addr); - on = true; - } else { - coils_state &= ~BIT(addr); - on = false; - } - LOG_INF("Coil write, addr %u, %d", addr, (int)state); - return 0; } static int holding_reg_rd(uint16_t addr, uint16_t *reg) { - if (addr >= ARRAY_SIZE(holding_reg)) { - return -ENOTSUP; + switch (addr) { + case REG_HOLDING_WATCHDOG_TIMEOUT_S: + *reg = watchdog_timeout_s; + break; + default: + *reg = 0; + break; } - *reg = 0xDEAD; - - LOG_INF("Holding register read, addr %u", addr); - + LOG_INF("Holding register read, addr %u, value %u", addr, *reg); return 0; } static int holding_reg_wr(uint16_t addr, uint16_t reg) { - if (addr >= ARRAY_SIZE(holding_reg)) { - return -ENOTSUP; + switch (addr) { + case REG_HOLDING_WATCHDOG_TIMEOUT_S: + watchdog_timeout_s = reg; + break; + default: + break; } - holding_reg[addr] = reg; - - LOG_INF("Holding register write, addr %u", addr); - + LOG_INF("Holding register write, addr %u, value %u", addr, reg); return 0; } @@ -73,10 +80,19 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg) uint32_t uptime_s = k_uptime_get_32() / 1000; switch (addr) { - case 0x00F3: + case REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR: + *reg = (APP_VERSION_MAJOR << 8) | (APP_VERSION_MINOR & 0xFF); + break; + case REG_INPUT_FIRMWARE_VERSION_PATCH: + *reg = APP_VERSION_PATCH; + break; + case REG_INPUT_DEVICE_STATUS: + *reg = 0; /* 0 = OK */ + break; + case REG_INPUT_UPTIME_SECONDS_LOW: *reg = (uint16_t)(uptime_s & 0xFFFF); break; - case 0x00F4: + case REG_INPUT_UPTIME_SECONDS_HIGH: *reg = (uint16_t)(uptime_s >> 16); break; default: @@ -85,7 +101,6 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg) } LOG_INF("Input register read, addr %u, value %u", addr, *reg); - return 0; } @@ -139,4 +154,4 @@ int main(void) } return 0; -} +} \ No newline at end of file