#ifndef CAN_DRIVER_H #define CAN_DRIVER_H #include #include #define CAN_NUM_MOTORS 2u #define CAN_NODE_LEFT 0u #define CAN_NODE_RIGHT 1u #define CAN_ID_VEL_CMD_BASE 0x100u #define CAN_ID_ENABLE_CMD_BASE 0x110u #define CAN_ID_FEEDBACK_BASE 0x200u #define CAN_FILTER_STDID 0x200u #define CAN_FILTER_MASK 0x7E0u #define CAN_PRESCALER 6u #define CAN_TX_RATE_HZ 100u #define CAN_NODE_TIMEOUT_MS 100u #define CAN_WDOG_RESTART_MS 200u typedef struct { int16_t velocity_rpm; int16_t torque_x100; } can_cmd_t; typedef struct { int16_t velocity_rpm; int16_t current_ma; int16_t position_x100; int8_t temperature_c; uint8_t fault; uint32_t last_rx_ms; } can_feedback_t; typedef struct { uint32_t tx_count; uint32_t rx_count; uint16_t err_count; uint8_t bus_off; uint8_t _pad; } can_stats_t; typedef enum { CAN_ERR_NOMINAL = 0u, CAN_ERR_WARNING = 1u, CAN_ERR_ERROR_PASSIVE = 2u, CAN_ERR_BUS_OFF = 3u, } can_error_state_t; typedef struct { uint32_t restart_count; uint32_t busoff_count; uint16_t errpassive_count; uint16_t errwarn_count; can_error_state_t error_state; uint8_t tec; uint8_t rec; uint8_t busoff_pending; uint32_t busoff_ms; } can_wdog_t; void can_driver_init(void); void can_driver_send_cmd(uint8_t node_id, const can_cmd_t *cmd); void can_driver_send_enable(uint8_t node_id, bool enable); bool can_driver_get_feedback(uint8_t node_id, can_feedback_t *out); bool can_driver_is_alive(uint8_t node_id, uint32_t now_ms); void can_driver_get_stats(can_stats_t *out); void can_driver_process(void); can_error_state_t can_driver_watchdog_tick(uint32_t now_ms); void can_driver_get_wdog(can_wdog_t *out); #ifdef TEST_HOST void can_driver_inject_esr(uint32_t esr_val); #endif typedef void (*can_ext_frame_cb_t)(uint32_t ext_id, const uint8_t *data, uint8_t len); typedef void (*can_std_frame_cb_t)(uint16_t std_id, const uint8_t *data, uint8_t len); void can_driver_set_ext_cb(can_ext_frame_cb_t cb); void can_driver_set_std_cb(can_std_frame_cb_t cb); void can_driver_send_ext(uint32_t ext_id, const uint8_t *data, uint8_t len); void can_driver_send_std(uint16_t std_id, const uint8_t *data, uint8_t len); #endif /* CAN_DRIVER_H */