]> granicus.if.org Git - esp-idf/blob
5309bbd0b1b80c1cdc86366251c33416e0ec802d
[esp-idf] /
1 /* CAN Network Listen Only Example
2
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4
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.
8 */
9
10 /*
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
19  */
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "freertos/FreeRTOS.h"
23 #include "freertos/task.h"
24 #include "freertos/queue.h"
25 #include "freertos/semphr.h"
26 #include "esp_err.h"
27 #include "esp_log.h"
28 #include "driver/can.h"
29
30 /* --------------------- Definitions and static variables ------------------ */
31 //Example Configuration
32 #define NO_OF_ITERS                     3
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"
37
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
44
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,
53                                               .clkout_divider = 0};
54
55 static SemaphoreHandle_t rx_sem;
56
57 /* --------------------------- Tasks and Functions -------------------------- */
58
59 static void can_receive_task(void *arg)
60 {
61     xSemaphoreTake(rx_sem, portMAX_DELAY);
62     bool start_cmd = false;
63     bool stop_resp = false;
64     uint32_t iterations = 0;
65
66     while (iterations < NO_OF_ITERS) {
67         can_message_t rx_msg;
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");
75             start_cmd = true;
76         } else if (rx_msg.identifier == ID_SLAVE_DATA) {
77             uint32_t data = 0;
78             for (int i = 0; i < rx_msg.data_length_code; i++) {
79                 data |= (rx_msg.data[i] << (i * 8));
80             }
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");
86             stop_resp = true;
87         }
88         if (start_cmd && stop_resp) {
89             //Each iteration is complete after a start command and stop response is received
90             iterations++;
91             start_cmd = 0;
92             stop_resp = 0;
93         }
94     }
95
96     xSemaphoreGive(rx_sem);
97     vTaskDelete(NULL);
98 }
99
100 void app_main()
101 {
102     rx_sem = xSemaphoreCreateBinary();
103     xTaskCreatePinnedToCore(can_receive_task, "CAN_rx", 4096, NULL, RX_TASK_PRIO, NULL, tskNO_AFFINITY);
104
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");
110
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
114
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");
120
121     //Cleanup
122     vSemaphoreDelete(rx_sem);
123 }