- can_ctrl_cmd_t.speed: uint8_t -> uint16_t (bytes 0-1, little-endian) - Remove led_gpio field; add led_r (byte7 bit0) and led_l (byte7 bit7) - byte6 now carries only led_enable (bit0), not the old gpio/enable packed format - Update keepalive thread and can_bus_send_control_cmd() frame assembly accordingly - Update all 6 can_ctrl_cmd_t call sites in event_recorder.c and app_header_init.c - test_can_event() parameter type: uint8_t speed -> uint16_t speed
94 lines
3.9 KiB
C
94 lines
3.9 KiB
C
/*
|
|
* can_bus.h — MCP2515 CAN bus wrapper for KL630 (J15 SPI connector)
|
|
*
|
|
* API mirrors bt_uart.h: both channels carry the same JSON payload.
|
|
* BLE channel: bt_uart_send_json(json)
|
|
* CAN channel: can_bus_send_json(json)
|
|
*
|
|
* The same JSON string {"class":"car","level":1} is transmitted on both
|
|
* channels simultaneously from fire_json_async() in event_recorder.c.
|
|
*
|
|
* MCP2515 is classic CAN (max 8 bytes per frame). Long JSON strings are
|
|
* split into sequential 8-byte frames automatically:
|
|
* Frame N: bytes [N*8 .. N*8+7] of the JSON string (padded with 0x00)
|
|
* The receiver reassembles by concatenating frames until a null byte.
|
|
* If a CAN FD controller is fitted later, switch to single-frame send.
|
|
*/
|
|
|
|
#ifndef CAN_BUS_H
|
|
#define CAN_BUS_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/*
|
|
* can_bus_init — open MCP2515 via SPI and start writer thread.
|
|
* spidev : e.g. "/dev/spidev1.0"
|
|
* can_speed_kbps: 250 (typical) or 125, 500, 1000
|
|
* can_id : 11-bit standard frame ID for outbound frames
|
|
* Returns 0 on success, -1 on error.
|
|
*/
|
|
int can_bus_init(const char *spidev, int can_speed_kbps, uint32_t can_id);
|
|
|
|
/*
|
|
* can_bus_send_json — non-blocking: enqueue a JSON string for CAN transmission.
|
|
* Same signature as bt_uart_send_json(); call both from fire_json_async().
|
|
* Long strings are split into multiple 8-byte CAN frames automatically.
|
|
*/
|
|
void can_bus_send_json(const char *json);
|
|
|
|
/*
|
|
* can_ctrl_cmd_t — parameters for can_bus_send_control_cmd().
|
|
*
|
|
* CAN ID 0x75 DLC=8 little-endian:
|
|
* bytes 0-1 : throttle_limit_command (uint16_t, little-endian)
|
|
* bytes 2-5 : 0x00
|
|
* byte 6 : bit 0 = led_enable (1=on, 0=off)
|
|
* byte 7 : bit 0 = led_r (LED right, 1=on), bit 7 = led_l (LED left, 1=on)
|
|
*
|
|
* keepalive_interval_ms: >0 updates the keepalive period; 0 = no change.
|
|
*/
|
|
typedef struct {
|
|
uint16_t speed; /* bytes 0-1: throttle_limit_command, little-endian */
|
|
uint8_t led_enable; /* bit 48 (byte 6 bit 0): LED enable 1=on, 0=off */
|
|
uint8_t led_r; /* bit 56 (byte 7 bit 0): LED right 1=on, 0=off */
|
|
uint8_t led_l; /* bit 63 (byte 7 bit 7): LED left 1=on, 0=off */
|
|
int keepalive_interval_ms; /* >0 updates keepalive period; 0 = no change */
|
|
} can_ctrl_cmd_t;
|
|
|
|
/*
|
|
* can_bus_send_control_cmd — send one 8-byte CAN control frame immediately
|
|
* and update the keepalive state to maintain the new values.
|
|
*/
|
|
void can_bus_send_control_cmd(const can_ctrl_cmd_t *ctrl);
|
|
|
|
/* can_bus_close — drain queue, join writer thread, close SPI device. */
|
|
void can_bus_close(void);
|
|
|
|
/*
|
|
* can_ecu_status_t — parsed signals from ECU CAN ID 0x50 (throttle_status frame).
|
|
*
|
|
* Frame layout (Intel byte order):
|
|
* frame[0..1] = throttle_status (bits 0-15, uint16)
|
|
* frame[2..3] = throttle_pedal_volt (bits 16-31, uint16)
|
|
* frame[4..5] = led_flash_timer (bits 32-47, uint16)
|
|
* frame[6] bit 0 = can_lose_ecu (bit 48)
|
|
* frame[6] bit 7 = throttle_limit_off (bit 55)
|
|
* frame[7] = heart_beam (bits 56-63, uint8)
|
|
*
|
|
* can_lose_timeout: KL630 self-detected, set to 1 when no ECU frame for >100ms.
|
|
*/
|
|
typedef struct {
|
|
uint16_t throttle_status; /* bits 0-15: current throttle value, 0-8191 */
|
|
uint16_t throttle_pedal_volt; /* bits 16-31: pedal voltage */
|
|
uint16_t led_flash_timer; /* bits 32-47: LED flash timer */
|
|
uint8_t can_lose_ecu; /* bit 48: ECU-reported CAN loss (0/1) */
|
|
uint8_t throttle_limit_off; /* bit 55: throttle limit off flag (0/1) */
|
|
uint8_t heart_beam; /* bits 56-63: heartbeat counter */
|
|
int can_lose_timeout; /* KL630 self-detected: 1 if ECU silent >100ms*/
|
|
} can_ecu_status_t;
|
|
|
|
/* can_bus_get_ecu_status — thread-safe snapshot of latest ECU status. */
|
|
void can_bus_get_ecu_status(can_ecu_status_t *out);
|
|
|
|
#endif /* CAN_BUS_H */
|