11#if PC_ENABLE_BUS_CAPTURE
14#include "driver/twai.h"
16size_t can_to_socketcan(
const CanFrame *f, uint8_t *out,
size_t cap)
18 if (!f || !out || cap < PC_SOCKETCAN_FRAME_LEN)
26 id |= PC_CAN_EFF_FLAG;
30 id |= PC_CAN_RTR_FLAG;
33 out[0] = (uint8_t)(
id >> 24);
34 out[1] = (uint8_t)(
id >> 16);
35 out[2] = (uint8_t)(
id >> 8);
45 out[8 + i] = (i < dlc && !f->
rtr) ? f->
data[i] : 0;
47 return PC_SOCKETCAN_FRAME_LEN;
59 bus_capture_sink_fn sink =
nullptr;
64bool timing_for(uint32_t bitrate, twai_timing_config_t *t)
69 twai_timing_config_t c = TWAI_TIMING_CONFIG_1MBITS();
74 twai_timing_config_t c = TWAI_TIMING_CONFIG_500KBITS();
79 twai_timing_config_t c = TWAI_TIMING_CONFIG_250KBITS();
84 twai_timing_config_t c = TWAI_TIMING_CONFIG_125KBITS();
94bool bus_capture_begin(
int tx_pin,
int rx_pin, uint32_t bitrate, bus_capture_sink_fn sink)
100 twai_timing_config_t timing;
101 if (!timing_for(bitrate, &timing))
105 twai_general_config_t gen =
106 TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)tx_pin, (gpio_num_t)rx_pin, TWAI_MODE_LISTEN_ONLY);
107 twai_filter_config_t filt = TWAI_FILTER_CONFIG_ACCEPT_ALL();
108 if (twai_driver_install(&gen, &timing, &filt) != ESP_OK)
112 if (twai_start() != ESP_OK)
114 twai_driver_uninstall();
118 s_bus.running =
true;
122void bus_capture_poll(
void)
124 if (!s_bus.running || !s_bus.sink)
129 while (twai_receive(&m, 0) == ESP_OK)
138 f.
data[i] = (i < f.
dlc) ? m.data[i] : 0;
144void bus_capture_end(
void)
151 twai_driver_uninstall();
152 s_bus.running =
false;
153 s_bus.sink =
nullptr;
158bool bus_capture_begin(
int,
int, uint32_t, bus_capture_sink_fn)
162void bus_capture_poll(
void)
166void bus_capture_end(
void)
Wired field-bus listen-only capture (PC_ENABLE_BUS_CAPTURE) - passive CAN sniffing.
#define PC_CAN_MAX_DLC
classic CAN carries at most 8 data octets.
#define PC_CAN_STD_ID_MASK
11-bit standard identifier.
#define PC_CAN_EXT_ID_MASK
29-bit extended identifier.
uint8_t data[PC_CAN_MAX_DLC]