71 lines
3.0 KiB
C
71 lines
3.0 KiB
C
/* Portable continuous recorder. All addresses/counts are 16-bit WORDS,
|
|
* including on C28x (CHAR_BIT=16). No heap, UART, HAL or global state. */
|
|
#ifndef GAS_LOGGER_H
|
|
#define GAS_LOGGER_H
|
|
#include <stdint.h>
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
#define GL_MAGIC 0x474CU
|
|
#define GL_VERSION 1U
|
|
#define GL_HEADER_WORDS 5U /* time_ms:u32, sequence:u32, event:u16, values... */
|
|
#define GL_DATA_OFFSET 0x100U
|
|
#define GL_MAX_CHANNELS 64U
|
|
#define GL_COMMAND 18U
|
|
#define GL_RELEASE_LO 19U
|
|
#define GL_RELEASE_HI 20U
|
|
#define GL_START 1U
|
|
#define GL_SNAPSHOT 2U
|
|
#define GL_RELEASE 3U
|
|
typedef enum { GL_OK=0, GL_ADDRESS, GL_ARGUMENT, GL_BUSY, GL_EMPTY,
|
|
GL_STALE, GL_SOURCE_ERROR } gl_result;
|
|
typedef struct {
|
|
uint16_t gas, modbus, can;
|
|
} gl_channel;
|
|
typedef struct {
|
|
uint16_t base, channels, capacity;
|
|
uint32_t schema_id;
|
|
const gl_channel *map;
|
|
} gl_config;
|
|
/* enter returns the previous IRQ state; leave MUST restore it, not enable
|
|
* IRQs unconditionally. source executes under this lock: bounded RAM reads
|
|
* only, never I/O/waits. Cache remote CAN values before sampling. */
|
|
typedef struct {
|
|
void *user;
|
|
uint32_t (*enter)(void *user);
|
|
void (*leave)(void *user, uint32_t state);
|
|
int (*source)(void *user, uint16_t gas, uint16_t *value);
|
|
} gl_port;
|
|
typedef struct {
|
|
gl_config config;
|
|
gl_port port;
|
|
uint16_t *banks[2];
|
|
uint16_t active, count, next, recording, pinned, snap_count, snap_next;
|
|
uint32_t generation, release_generation, sequence, missed, source_errors;
|
|
} gas_logger;
|
|
/* Each distinct bank must have >=capacity*(channels+5) uint16_t elements.
|
|
* All callbacks and a nonoverlapping register map are required. */
|
|
gl_result gl_init(gas_logger *log, const gl_config *config, const gl_port *port,
|
|
uint16_t *bank0, uint16_t *bank1, uint32_t bank_words);
|
|
/* Called by the project timer/event hook. A failed source discards the whole
|
|
* sample. Sequence/time remain uint32, wrapping modulo 2^32. */
|
|
gl_result gl_capture(gas_logger *log, uint32_t time_ms, uint16_t event);
|
|
/* Snapshot swaps banks, pins the old one, and NEVER stops acquisition.
|
|
* Another snapshot while pinned returns BUSY and increments missed. */
|
|
gl_result gl_snapshot(gas_logger *log);
|
|
/* Atomic, all-or-nothing block read. Snapshot records are chronological;
|
|
* reads past snap_count are rejected, not zero-filled. */
|
|
gl_result gl_read(gas_logger *log, uint16_t address, uint16_t *out, uint16_t count);
|
|
/* No STOP/reset command. START is idempotent. RELEASE requires the generation
|
|
* staged in base+19/20. One controlling client per device. */
|
|
gl_result gl_write(gas_logger *log, uint16_t address, uint16_t value);
|
|
/* Register aliases for FC03/06 and ProtoCAN GAS. Transports keep their own
|
|
* framing/CRC; addresses are zero-based and words preserve their values. */
|
|
gl_result gl_modbus_read(gas_logger *log, uint16_t address, uint16_t *out, uint16_t count);
|
|
gl_result gl_modbus_write(gas_logger *log, uint16_t address, uint16_t value);
|
|
gl_result gl_can_read(gas_logger *log, uint16_t address, uint16_t *out, uint16_t count);
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|