Files

120 lines
3.8 KiB
C

/*
* can_schema.h
*
* Created on: Sep 16, 2025
* Author: herli
*/
#ifndef INC_CAN_SCHEMA_H_
#define INC_CAN_SCHEMA_H_
#ifndef CAN_SCHEMA_H
#define CAN_SCHEMA_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
typedef enum {
CAN_DIR_RX = 0, // incoming from bus -> decode into RAM
CAN_DIR_TX = 1 // outgoing to bus -> encode from RAM
} CanDirection;
typedef enum {
CAN_ENDIAN_INTEL = 0, // DBC "Intel" (little-endian bit numbering): bit 0 = LSB of byte 0
CAN_ENDIAN_MOTOROLA = 1 // DBC "Motorola" (big-endian bit numbering)
} CanEndian;
typedef enum {
CAN_SYM_UX = 0, // unsigned raw
CAN_SYM_SX = 1, // signed two's complement raw
CAN_SYM_FLOAT = 2 // (kept for future use)
} CanRawType;
typedef enum {
NOMINAL = 0,
INVERTED = 1
} CanInversion;
/* Shared scale (optional): if a symbol sets factor==0 && offset==0 and scale!=NULL,
* the effective factor/offset comes from this struct. If symbol.factor/offset is non-zero,
* it overrides the scale.
*/
typedef struct CanScaleDef {
const char *unit; // informational, may be NULL
float factor;
float offset;
} CanScaleDef;
typedef enum {
CAN_STORE_FLOAT = 0, // ptr -> float (uses factor/offset)
CAN_STORE_U32, // ptr -> uint32_t (raw integer)
CAN_STORE_S32, // ptr -> int32_t (raw integer)
CAN_STORE_U16, // ptr -> uint16_t (raw integer)
CAN_STORE_S16, // ptr -> int16_t (raw integer)
CAN_STORE_U8, // ptr -> uint8_t (raw integer)
CAN_STORE_S8 // ptr -> int8_t (raw integer)
} CanStorage;
struct CanMessageDef; // fwd
// User-provided TX function that actually hands frames to HAL
typedef bool (*CanTxFn)(uint16_t id, const uint8_t data[8], uint8_t dlc);
// Optional per-message RX handler (called AFTER any symbol decode)
typedef void (*CanRxHandler)(
const struct CanMessageDef *msg,
const uint8_t in_data[8],
CanTxFn tx
);
typedef struct {
const char *name;
uint8_t start_bit, bit_len;
CanEndian endian;
CanRawType raw_type; // UX / SX (bit interpretation)
float factor, offset;
void *ptr;
const CanScaleDef *scale;
CanStorage storage; // NEW: how to read/write *ptr
CanInversion inverted;
} CanSymbolDef;
typedef struct CanMessageDef {
uint16_t can_id; // 11-bit standard ID
CanDirection dir; // RX or TX
uint8_t dlc; // 0..8
const char *name; // message name
const CanSymbolDef *symbols; // array of symbols (NULL if template-only)
uint8_t symbol_count; // number of symbols
// Optional template payload (used for TX): copied first, then symbols packed on top.
const uint8_t *tx_template; // 0..8 bytes in flash (NULL if none)
uint8_t send_on_boot; // if 1 and TX, manager will send at init
// Optional RX handler (for custom behaviors like address-based replies)
CanRxHandler rx_handler;
} CanMessageDef;
typedef struct {
uint16_t addr; // request address
void *ptr; // pointer to physical value (usually float*)
CanRawType raw_type; // how to quantize (unsigned/signed)
const CanScaleDef *scale; // scaling used for inverse transform
CanStorage storage; // NEW: how to read ptr (FLOAT/U16/U32/…)
} CanAddressEntry;
/* Registry access (implemented in can_db.c) */
const CanMessageDef* can_db_find(uint16_t can_id, CanDirection dir);
const CanMessageDef* can_db_all(size_t *count);
/* Bit-pack engine (implemented in can_encode.c) */
void can_encode_message(const CanMessageDef *msg, uint8_t out_data[8]);
void can_decode_message(const CanMessageDef *msg, const uint8_t in_data[8]);
#endif /* CAN_SCHEMA_H */
#endif /* INC_CAN_SCHEMA_H_ */