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.
This commit is contained in:
parent
032ddf2cc0
commit
e6dc9f9136
|
|
@ -14,57 +14,66 @@
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(mbs_sample, LOG_LEVEL_INF);
|
LOG_MODULE_REGISTER(mbs_sample, LOG_LEVEL_INF);
|
||||||
|
|
||||||
static uint16_t holding_reg[8];
|
#define APP_VERSION_MAJOR 1
|
||||||
static uint8_t coils_state;
|
#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)
|
static int coil_rd(uint16_t addr, bool *state)
|
||||||
{
|
{
|
||||||
*state = true;
|
*state = true;
|
||||||
|
|
||||||
LOG_INF("Coil read, addr %u, %d", addr, (int)*state);
|
LOG_INF("Coil read, addr %u, %d", addr, (int)*state);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coil_wr(uint16_t addr, bool state)
|
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);
|
LOG_INF("Coil write, addr %u, %d", addr, (int)state);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int holding_reg_rd(uint16_t addr, uint16_t *reg)
|
static int holding_reg_rd(uint16_t addr, uint16_t *reg)
|
||||||
{
|
{
|
||||||
if (addr >= ARRAY_SIZE(holding_reg)) {
|
switch (addr) {
|
||||||
return -ENOTSUP;
|
case REG_HOLDING_WATCHDOG_TIMEOUT_S:
|
||||||
|
*reg = watchdog_timeout_s;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*reg = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*reg = 0xDEAD;
|
LOG_INF("Holding register read, addr %u, value %u", addr, *reg);
|
||||||
|
|
||||||
LOG_INF("Holding register read, addr %u", addr);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int holding_reg_wr(uint16_t addr, uint16_t reg)
|
static int holding_reg_wr(uint16_t addr, uint16_t reg)
|
||||||
{
|
{
|
||||||
if (addr >= ARRAY_SIZE(holding_reg)) {
|
switch (addr) {
|
||||||
return -ENOTSUP;
|
case REG_HOLDING_WATCHDOG_TIMEOUT_S:
|
||||||
|
watchdog_timeout_s = reg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Do nothing for unsupported registers */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
holding_reg[addr] = reg;
|
LOG_INF("Holding register write, addr %u, value %u", addr, reg);
|
||||||
|
|
||||||
LOG_INF("Holding register write, addr %u", addr);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,10 +82,19 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg)
|
||||||
uint32_t uptime_s = k_uptime_get_32() / 1000;
|
uint32_t uptime_s = k_uptime_get_32() / 1000;
|
||||||
|
|
||||||
switch (addr) {
|
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);
|
*reg = (uint16_t)(uptime_s & 0xFFFF);
|
||||||
break;
|
break;
|
||||||
case 0x00F4:
|
case REG_INPUT_UPTIME_SECONDS_HIGH:
|
||||||
*reg = (uint16_t)(uptime_s >> 16);
|
*reg = (uint16_t)(uptime_s >> 16);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -85,7 +103,6 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INF("Input register read, addr %u, value %u", addr, *reg);
|
LOG_INF("Input register read, addr %u, value %u", addr, *reg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,4 +156,4 @@ int main(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue