#ifndef PROTOCOL_H #define PROTOCOL_H #include #include "eis.h" /* Commands: Client -> Firmware (0x1x, 0x2x, 0x3x) */ #define CMD_SET_SWEEP 0x10 #define CMD_SET_RTIA 0x11 #define CMD_SET_RCAL 0x12 #define CMD_START_SWEEP 0x13 #define CMD_GET_CONFIG 0x14 #define CMD_SET_ELECTRODE 0x15 #define CMD_START_LSV 0x20 #define CMD_START_AMP 0x21 #define CMD_STOP_AMP 0x22 #define CMD_GET_TEMP 0x17 #define CMD_START_CL 0x23 #define CMD_START_PH 0x24 #define CMD_START_CLEAN 0x25 #define CMD_OPEN_CAL 0x26 #define CMD_CLEAR_OPEN_CAL 0x27 #define CMD_SET_CELL_K 0x28 #define CMD_GET_CELL_K 0x29 #define CMD_START_REFS 0x30 #define CMD_GET_REFS 0x31 #define CMD_CLEAR_REFS 0x32 #define CMD_SET_CL_FACTOR 0x33 #define CMD_GET_CL_FACTOR 0x34 #define CMD_SET_PH_CAL 0x35 #define CMD_GET_PH_CAL 0x36 /* Session sync commands (0x4x) */ #define CMD_SESSION_CREATE 0x40 #define CMD_SESSION_SWITCH 0x41 #define CMD_SESSION_LIST 0x42 #define CMD_SESSION_RENAME 0x43 #define CMD_HEARTBEAT 0x44 /* Responses: Firmware -> Client (0x0x, 0x2x) */ #define RSP_SWEEP_START 0x01 #define RSP_DATA_POINT 0x02 #define RSP_SWEEP_END 0x03 #define RSP_CONFIG 0x04 #define RSP_LSV_START 0x05 #define RSP_LSV_POINT 0x06 #define RSP_LSV_END 0x07 #define RSP_AMP_START 0x08 #define RSP_AMP_POINT 0x09 #define RSP_AMP_END 0x0A #define RSP_CL_START 0x0B #define RSP_CL_POINT 0x0C #define RSP_CL_RESULT 0x0D #define RSP_CL_END 0x0E #define RSP_PH_RESULT 0x0F #define RSP_TEMP 0x10 #define RSP_CELL_K 0x11 #define RSP_REF_FRAME 0x20 #define RSP_REF_LP_RANGE 0x21 #define RSP_REFS_DONE 0x22 #define RSP_REF_STATUS 0x23 #define RSP_CL_FACTOR 0x24 #define RSP_PH_CAL 0x25 #define RSP_KEEPALIVE 0x50 /* Session sync responses (0x4x) */ #define RSP_SESSION_CREATED 0x40 #define RSP_SESSION_SWITCHED 0x41 #define RSP_SESSION_LIST 0x42 #define RSP_SESSION_RENAMED 0x43 #define RSP_CLIENT_LIST 0x44 /* Session limits */ #define MAX_SESSIONS 8 #define MAX_SESSION_NAME 32 typedef struct { uint8_t type; union { struct { float freq_start, freq_stop; uint16_t ppd; } sweep; uint8_t rtia; uint8_t rcal; uint8_t electrode; struct { float v_start, v_stop, scan_rate; uint8_t lp_rtia; uint16_t num_points; } lsv; struct { float v_hold, interval_ms, duration_s; uint8_t lp_rtia; } amp; struct { float v_cond, t_cond_ms, v_free, v_total, t_dep_ms, t_meas_ms; uint8_t lp_rtia; } cl; struct { float stabilize_s; } ph; struct { float v_mv; float duration_s; } clean; float cell_k; float cl_factor; struct { float slope; float offset; } ph_cal; struct { uint8_t name_len; char name[MAX_SESSION_NAME]; } session_create; struct { uint8_t id; } session_switch; struct { uint8_t id; uint8_t name_len; char name[MAX_SESSION_NAME]; } session_rename; }; } Command; typedef struct { uint8_t id; char name[MAX_SESSION_NAME + 1]; uint8_t active; } Session; int protocol_init(void); int protocol_recv_command(Command *cmd, uint32_t timeout_ms); void protocol_push_command(const Command *cmd); /* 7-bit encode/decode helpers */ void encode_u32(uint32_t val, uint8_t *out); uint32_t decode_u32(const uint8_t *d); float decode_float(const uint8_t *d); uint16_t decode_u16(const uint8_t *d); /* outbound: EIS */ int send_sweep_start(uint32_t num_points, float freq_start, float freq_stop, uint32_t ts_ms, uint16_t meas_id); int send_eis_point(uint16_t index, const EISPoint *pt); int send_sweep_end(void); int send_config(const EISConfig *cfg); /* outbound: LSV */ int send_lsv_start(uint32_t num_points, float v_start, float v_stop, uint32_t ts_ms, uint16_t meas_id); int send_lsv_point(uint16_t index, float v_mv, float i_ua); int send_lsv_end(void); /* outbound: Amperometry */ int send_amp_start(float v_hold, uint32_t ts_ms, uint16_t meas_id); int send_amp_point(uint16_t index, float t_ms, float i_ua); int send_amp_end(void); /* outbound: Chlorine */ int send_cl_start(uint32_t num_points, uint32_t ts_ms, uint16_t meas_id); int send_cl_point(uint16_t index, float t_ms, float i_ua, uint8_t phase); int send_cl_result(float i_free_ua, float i_total_ua); int send_cl_end(void); /* outbound: pH */ int send_ph_result(float v_ocp_mv, float ph, float temp_c, uint32_t ts_ms, uint16_t meas_id); /* outbound: temperature */ int send_temp(float temp_c); /* outbound: cell constant */ int send_cell_k(float k); /* outbound: chlorine factor */ int send_cl_factor(float f); /* outbound: pH calibration */ int send_ph_cal(float slope, float offset); /* outbound: reference collection */ int send_ref_frame(uint8_t mode, uint8_t rtia_idx); int send_ref_lp_range(uint8_t mode, uint8_t low_idx, uint8_t high_idx); int send_refs_done(void); int send_ref_status(uint8_t has_refs); /* keepalive (sent during long blocking ops) */ int send_keepalive(void); /* session management */ const Session *session_get_all(uint8_t *count); uint8_t session_get_current(void); uint8_t session_create(const char *name, uint8_t name_len); int session_switch(uint8_t id); int session_rename(uint8_t id, const char *name, uint8_t name_len); /* session sync responses */ int send_session_created(uint8_t id, const char *name, uint8_t name_len); int send_session_switched(uint8_t id); int send_session_list(void); int send_session_renamed(uint8_t id, const char *name, uint8_t name_len); int send_client_list(uint8_t count); #endif