- can_bus.h: add can_ctrl_cmd_t struct (speed/led_gpio/led_enable/keepalive_interval_ms) - can_bus.c: rename s_keepalive_cmd->s_keepalive_speed; add s_keepalive_led_gpio/ led_enable/interval_ms; keepalive thread supports LED blink (toggle when led_enable=1) and dynamic interval; remove #define CAN_KEEPALIVE_INTERVAL_MS - event_recorder: fire_collision_warning sends SPEED_LIMIT_STOP/NORMAL via CAN - event_recorder: fire_alert sends SPEED_LIMIT_ALERT/NORMAL via CAN - event_recorder/app_header_init: update callers to use can_ctrl_cmd_t struct Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
68 lines
2.6 KiB
C
68 lines
2.6 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 Intel byte order:
|
|
* frame[0] = speed (bits 0-7, byte 0: throttle_limit_command)
|
|
* frame[6] = (led_gpio & 1) | ((led_enable & 1) << 6)
|
|
* bit 48 = led_gpio (byte 6 bit 0): LED GPIO 1=high 0=low
|
|
* bit 54 = led_enable (byte 6 bit 6): LED 1=enable 0=disable
|
|
* frame[1..5], frame[7] = 0x00
|
|
*
|
|
* keepalive_interval_ms: >0 updates the keepalive period; 0 = no change.
|
|
*/
|
|
typedef struct {
|
|
uint8_t speed; /* byte 0: throttle_limit_command, 0-255 */
|
|
uint8_t led_gpio; /* bit 48 (byte 6 bit 0): LED GPIO 1=high, 0=low */
|
|
uint8_t led_enable; /* bit 54 (byte 6 bit 6): 1=enable, 0=disable */
|
|
int keepalive_interval_ms; /* >0 updates interval, 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);
|
|
|
|
#endif /* CAN_BUS_H */
|