/* UMP logger v2 (PM35), independent of PM67 and SET protocol v2. * Octets use 16-bit storage: C28x has CHAR_BIT=16 and no uint8_t. * All lengths below count wire octets or register words, never sizeof bytes. */ #ifndef UMP_PROTOCOL_H #define UMP_PROTOCOL_H #include #include #ifdef __cplusplus extern "C" { #endif #define UMP_BASE 0x1000U #define UMP_DATA 0x1010U #define UMP_LIVE 0x1100U #define UMP_MARKER 0x1F00U #define UMP_MAX_WORDS 124U #define UMP_RTU_CAPACITY 253U typedef uint16_t ump_octet; /* Called under caller's snapshot lock. write returns 1 on success, 0 otherwise. */ typedef struct { void *context; uint16_t (*read)(void *context, uint16_t address); int (*write)(void *context, uint16_t address, uint16_t value); } ump_backend; /* Returns Modbus exception 0/1/2/3. CAN has stricter whole-block reads. */ unsigned ump_validate(unsigned function, uint16_t address, uint16_t value, int can); /* reply capacity is >=124 words. Errors and writes return address/value echo. */ unsigned ump_prepare(const ump_backend *backend, unsigned function, uint16_t address, uint16_t value, int can, uint16_t *reply, unsigned *error); uint16_t ump_crc(const ump_octet *data, size_t count); /* Mode 1..16; kind 0=request, 1=normal telemetry, 2=logger reply; invalid ->0. */ uint32_t ump_can_id(unsigned mode, unsigned kind); /* Returns 0 for non-service frames, malformed size, or zero token. */ unsigned ump_can_request(const ump_backend *backend, const ump_octet *request, size_t size, uint16_t *reply, unsigned *token, unsigned *error); /* count must be an even number 2..124; index counts pairs. Returns 8 or 0. */ unsigned ump_can_fragment(const uint16_t *words, unsigned count, unsigned index, unsigned token, unsigned error, ump_octet *reply); /* Complete RTU frame only, after UART framing. Ignores bad CRC/foreign address. * Caller provides >=253 octets; no writes occur on insufficient capacity. * Device address 1..247; no broadcasts or legacy padding in this extension. */ size_t ump_rtu(const ump_backend *backend, unsigned device, const ump_octet *request, size_t size, ump_octet *reply, size_t capacity); /* Response for an already CRC-checked/framed request (legacy UART receiver). */ size_t ump_rtu_response(const ump_backend *backend, unsigned device, unsigned function, uint16_t address, uint16_t value, ump_octet *reply, size_t capacity); /* Serialize a captured reply after releasing the snapshot lock. Returns 0 on * invalid count/capacity; error replies need no words. */ size_t ump_rtu_encode(unsigned device, unsigned function, unsigned error, const uint16_t *words, unsigned count, ump_octet *reply, size_t capacity); #ifdef __cplusplus } #endif #endif