1 /* CAN Network Listen Only Example
3 This example code is in the Public Domain (or CC0 licensed, at your option.)
5 Unless required by applicable law or agreed to in writing, this
6 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7 CONDITIONS OF ANY KIND, either express or implied.
11 * The following example demonstrates a Listen Only node in a CAN network. The
12 * Listen Only node will not take part in any CAN bus activity (no acknowledgments
13 * and no error frames). This example will execute multiple iterations, with each
14 * iteration the Listen Only node will do the following:
15 * 1) Listen for ping and ping response
16 * 2) Listen for start command
17 * 3) Listen for data messages
18 * 4) Listen for stop and stop response
22 #include "freertos/FreeRTOS.h"
23 #include "freertos/task.h"
24 #include "freertos/queue.h"
25 #include "freertos/semphr.h"
28 #include "driver/can.h"
30 /* --------------------- Definitions and static variables ------------------ */
31 //Example Configuration
33 #define RX_TASK_PRIO 9
34 #define TX_GPIO_NUM 21
35 #define RX_GPIO_NUM 22
36 #define EXAMPLE_TAG "CAN Listen Only"
38 #define ID_MASTER_STOP_CMD 0x0A0
39 #define ID_MASTER_START_CMD 0x0A1
40 #define ID_MASTER_PING 0x0A2
41 #define ID_SLAVE_STOP_RESP 0x0B0
42 #define ID_SLAVE_DATA 0x0B1
43 #define ID_SLAVE_PING_RESP 0x0B2
45 static const can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL();
46 static const can_timing_config_t t_config = CAN_TIMING_CONFIG_25KBITS();
47 //Set TX queue length to 0 due to listen only mode
48 static const can_general_config_t g_config = {.mode = CAN_MODE_LISTEN_ONLY,
49 .tx_io = TX_GPIO_NUM, .rx_io = RX_GPIO_NUM,
50 .clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED,
51 .tx_queue_len = 0, .rx_queue_len = 5,
52 .alerts_enabled = CAN_ALERT_NONE,
55 static SemaphoreHandle_t rx_sem;
57 /* --------------------------- Tasks and Functions -------------------------- */
59 static void can_receive_task(void *arg)
61 xSemaphoreTake(rx_sem, portMAX_DELAY);
62 bool start_cmd = false;
63 bool stop_resp = false;
64 uint32_t iterations = 0;
66 while (iterations < NO_OF_ITERS) {
68 can_receive(&rx_msg, portMAX_DELAY);
69 if (rx_msg.identifier == ID_MASTER_PING) {
70 ESP_LOGI(EXAMPLE_TAG, "Received master ping");
71 } else if (rx_msg.identifier == ID_SLAVE_PING_RESP) {
72 ESP_LOGI(EXAMPLE_TAG, "Received slave ping response");
73 } else if (rx_msg.identifier == ID_MASTER_START_CMD) {
74 ESP_LOGI(EXAMPLE_TAG, "Received master start command");
76 } else if (rx_msg.identifier == ID_SLAVE_DATA) {
78 for (int i = 0; i < rx_msg.data_length_code; i++) {
79 data |= (rx_msg.data[i] << (i * 8));
81 ESP_LOGI(EXAMPLE_TAG, "Received data value %d", data);
82 } else if (rx_msg.identifier == ID_MASTER_STOP_CMD) {
83 ESP_LOGI(EXAMPLE_TAG, "Received master stop command");
84 } else if (rx_msg.identifier == ID_SLAVE_STOP_RESP) {
85 ESP_LOGI(EXAMPLE_TAG, "Received slave stop response");
88 if (start_cmd && stop_resp) {
89 //Each iteration is complete after a start command and stop response is received
96 xSemaphoreGive(rx_sem);
102 rx_sem = xSemaphoreCreateBinary();
103 xTaskCreatePinnedToCore(can_receive_task, "CAN_rx", 4096, NULL, RX_TASK_PRIO, NULL, tskNO_AFFINITY);
105 //Install and start CAN driver
106 ESP_ERROR_CHECK(can_driver_install(&g_config, &t_config, &f_config));
107 ESP_LOGI(EXAMPLE_TAG, "Driver installed");
108 ESP_ERROR_CHECK(can_start());
109 ESP_LOGI(EXAMPLE_TAG, "Driver started");
111 xSemaphoreGive(rx_sem); //Start RX task
112 vTaskDelay(pdMS_TO_TICKS(100));
113 xSemaphoreTake(rx_sem, portMAX_DELAY); //Wait for RX task to complete
115 //Stop and uninstall CAN driver
116 ESP_ERROR_CHECK(can_stop());
117 ESP_LOGI(EXAMPLE_TAG, "Driver stopped");
118 ESP_ERROR_CHECK(can_driver_uninstall());
119 ESP_LOGI(EXAMPLE_TAG, "Driver uninstalled");
122 vSemaphoreDelete(rx_sem);