#include "gas167.h" #if EEPROM_M95M02 #include "package.h" extern int modbus[]; extern int Desk; extern void ump_log_rs(void); static const uint16_t gas167_info[GAS167_INFO_WORDS] = { 0x4741U, 0x5331U, GAS167_PROFILE_VERSION, 167U, GAS167_REG_BASE, GAS167_REG_COUNT, GAS167_CAPABILITIES, 1U }; int gas167_contains(uint16_t address) { return (uint16_t)(address - GAS167_REG_BASE) < GAS167_REG_COUNT || (uint16_t)(address - GAS167_INFO_BASE) < GAS167_INFO_WORDS; } static unsigned gas167_write(uint16_t offset, uint16_t value) { /* Match the existing native Modbus write policy. These status words * cannot be overwritten and an invalid timeout cannot bypass protection. */ if (Desk == dsk_LOAD && (offset == 0x7CU || offset == 0x7DU)) return 2; if (Desk == dsk_LOAD && offset == 0x52U && (value == 0U || value > 60000U)) return 3; /* C28x int is one register word; reads always expose the raw uint16_t. */ modbus[offset] = (int)value; if (offset == 127U) ump_log_rs(); return 0; } unsigned gas167_prepare(unsigned function, uint16_t address, uint16_t value, int can, uint16_t *reply, unsigned *error) { uint16_t offset; unsigned i, available; int info; if (!reply || !error) return 0; *error = 0; info = (uint16_t)(address - GAS167_INFO_BASE) < GAS167_INFO_WORDS; offset = (uint16_t)(address - (info ? GAS167_INFO_BASE : GAS167_REG_BASE)); available = info ? GAS167_INFO_WORDS : GAS167_REG_COUNT; if (function != 3U && function != 6U) *error = 1; else if (offset >= available) *error = 2; else if (function == 6U) { *error = info ? 2U : gas167_write(offset, value); } else if (!value || value > GAS167_MAX_WORDS || (can && (value & 1U))) { *error = 3; } else if (value > available - offset) { *error = 2; } else { /* Validate the entire block before reading. A block cannot cross a * region boundary, wrap at 0xFFFF, or leak the hidden parameter word. */ for (i = 0; i < value; ++i) reply[i] = info ? gas167_info[offset+i] : (uint16_t)modbus[offset+i]; return value; } reply[0] = address; reply[1] = value; return 2; } #endif