Changeset - 9785a2ea3aa8
[Not reviewed]
default
0 4 2
Ethan Zonca - 17 months ago 2024-01-05 22:34:56
ez@ethanzonca.com
Add support for canbus
6 files changed with 102 insertions and 20 deletions:
0 comments (0 inline, 0 general)
main/CMakeLists.txt
Show inline comments
 
idf_component_register(SRCS "main.c" "wifi.c" "usb_cdc.c"
 
idf_component_register(SRCS "main.c" "wifi.c" "usb_cdc.c" "can.c"
 
                       INCLUDE_DIRS .)
main/can.c
Show inline comments
 
new file 100644
 
//
 
// can
 
//
 

	
 
#include "can.h"
 
#include "esp_log.h"
 
#include "driver/twai.h"
 

	
 
// EMZ FIXME
 
#define TX_GPIO_NUM 5
 
#define RX_GPIO_NUM 6
 
#define RX_TASK_PRIO 3
 

	
 

	
 
// Private variables
 
static const char *TAG = "canbus";
 

	
 

	
 
// static QueueHandle_t tx_task_queue;
 
// static QueueHandle_t rx_task_queue;
 

	
 

	
 
// Task for receiving CAN messages
 
static void twai_receive_task(void *arg)
 
{
 
    while (1) {
 
        twai_message_t rx_msg;
 
        twai_receive(&rx_msg, portMAX_DELAY);
 
        if (rx_msg.identifier == 0xdead) {
 
            ESP_LOGI(TAG, "Received data ");
 
        }
 

	
 
    }
 
    vTaskDelete(NULL);
 
}
 

	
 

	
 
// Initialize the CAN bus
 
void can_init(void)
 
{
 
    // CAN bus configuration
 
    twai_timing_config_t t_config = TWAI_TIMING_CONFIG_125KBITS();
 
    twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
 
    twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NORMAL);
 
	
 
    // Move canbus irq to free up the default level 1 IRQ it will take up (processor panics if we don't do this)
 
    g_config.intr_flags = ESP_INTR_FLAG_LOWMED;
 

	
 
    // Install TWAI driver
 
    ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config));
 
    ESP_LOGI(TAG, "Driver installed");
 
    ESP_ERROR_CHECK(twai_start());
 
    ESP_LOGI(TAG, "Driver started");
 

	
 
    // rx_task_queue = xQueueCreate(1, sizeof(rx_task_action_t));
 
    // tx_task_queue = xQueueCreate(1, sizeof(tx_task_action_t));
 
    xTaskCreatePinnedToCore(twai_receive_task, "TWAI_rx", 4096, NULL, RX_TASK_PRIO, NULL, tskNO_AFFINITY);
 
}
 

	
 

	
 
// Send message on the CAN bus
 
void can_send(uint32_t id, uint8_t* data, uint8_t len, uint32_t timeout)
 
{
 
    // Gross
 
    twai_message_t msg = { .identifier = id, .data_length_code = len, .ss = 1, .data = {data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]} };
 
    twai_transmit(&msg, timeout);
 
}
 
\ No newline at end of file
main/can.h
Show inline comments
 
new file 100644
 
#ifndef _CAN_H
 
#define _CAN_H
 

	
 
void can_init(void);
 

	
 
#endif
 
\ No newline at end of file
main/main.c
Show inline comments
 
//
 
// Protofusion ESP32S3 Template
 
//
 

	
 
#include <stdint.h>
 
#include "freertos/FreeRTOS.h"
 
#include "freertos/task.h"
 
#include "freertos/event_groups.h"
 

	
 
#include "esp_system.h"
 
#include "esp_event.h"
 
#include "esp_log.h"
 
#include "nvs_flash.h"
 

	
 
// User defines from menuconfig
 
#include "sdkconfig.h"
 

	
 
#include "wifi.h"
 
#include "usb_cdc.h"
 
#include "can.h"
 

	
 

	
 
// Private variables
 
static const char *TAG = "main";
 

	
 

	
 
// Application entry point
 
void app_main(void)
 
{
 
    // Initialize usb-cdc interface
 
    usb_cdc_init();
 

	
 

	
 
    // Initialize NVS
 
    esp_err_t ret = nvs_flash_init();
 
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
 
      ESP_ERROR_CHECK(nvs_flash_erase());
 
      ret = nvs_flash_init();
 
    }
 
    ESP_ERROR_CHECK(ret);
 

	
 

	
 
    // Connect to wifi
 
    wifi_init();
 

	
 

	
 
    // Initialize canbus
 
    can_init();
 

	
 
}
main/usb_cdc.c
Show inline comments
 
//
 
// usb-cdc
 
//
 

	
 
#include "usb_cdc.h"
 

	
 
#include "tinyusb.h"
 
#include "tusb_cdc_acm.h"
 
#include "sdkconfig.h"
 
#include "esp_log.h"
 

	
 

	
 
// Private variables
 
static const char *TAG = "main";
 
static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1];
 

	
 

	
 
// ------------------------ USB CDC ----------------------------------------
 
static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1];
 

	
 
void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event)
 
// Callback for received data
 
static void __cdc_rx_callback(int itf, cdcacm_event_t *event)
 
{
 
    /* initialization */
 
    size_t rx_size = 0;
 

	
 
    /* read */
 
    esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size);
 
    if (ret == ESP_OK) {
 
        ESP_LOGI(TAG, "Data from channel %d:", itf);
 
        ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_INFO);
 
    } else {
 
        ESP_LOGE(TAG, "Read error");
 
    }
 

	
 
    /* write back */
 
    tinyusb_cdcacm_write_queue(itf, buf, rx_size);
 
    tinyusb_cdcacm_write_flush(itf, 0);
 
}
 

	
 
void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event)
 

	
 
// Callback for line state changed
 
void __cdc_line_state_changed_callback(int itf, cdcacm_event_t *event)
 
{
 
    int dtr = event->line_state_changed_data.dtr;
 
    int rts = event->line_state_changed_data.rts;
 
    ESP_LOGI(TAG, "Line state changed on channel %d: DTR:%d, RTS:%d", itf, dtr, rts);
 
}
 

	
 

	
 
// Initialize usb-cdc
 
void usb_cdc_init(void)
 
{
 
    ESP_LOGI(TAG, "USB initialization");
 
    const tinyusb_config_t tusb_cfg = {
 
        .device_descriptor = NULL,
 
        .string_descriptor = NULL,
 
        .external_phy = false,
 
        .configuration_descriptor = NULL,
 
    };
 

	
 
    ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
 

	
 
    tinyusb_config_cdcacm_t acm_cfg = {
 
        .usb_dev = TINYUSB_USBDEV_0,
 
        .cdc_port = TINYUSB_CDC_ACM_0,
 
        .rx_unread_buf_sz = 64,
 
        .callback_rx = &tinyusb_cdc_rx_callback, // the first way to register a callback
 
        .callback_rx = &__cdc_rx_callback, // the first way to register a callback
 
        .callback_rx_wanted_char = NULL,
 
        .callback_line_state_changed = NULL,
 
        .callback_line_coding_changed = NULL
 
    };
 

	
 
    ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg));
 
    /* the second way to register a callback */
 
    ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback(
 
                        TINYUSB_CDC_ACM_0,
 
                        CDC_EVENT_LINE_STATE_CHANGED,
 
                        &tinyusb_cdc_line_state_changed_callback));
 
                        &__cdc_line_state_changed_callback));
 

	
 
#if (CONFIG_TINYUSB_CDC_COUNT > 1)
 
    acm_cfg.cdc_port = TINYUSB_CDC_ACM_1;
 
    ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg));
 
    ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback(
 
                        TINYUSB_CDC_ACM_1,
 
                        CDC_EVENT_LINE_STATE_CHANGED,
 
                        &tinyusb_cdc_line_state_changed_callback));
 
#endif
 

	
 
    ESP_LOGI(TAG, "USB initialization DONE");
 
}
 
\ No newline at end of file
main/wifi.c
Show inline comments
 
//
 
// wifi
 
//
 

	
 
#include "wifi.h"
 
#include "esp_wifi.h"
 
#include "esp_event.h"
 
#include "esp_log.h"
 
#include "lwip/err.h"
 
#include "lwip/sys.h"
 

	
 

	
 
// Private variables
 

	
 
// FreeRTOS event group to signal when we are connected
 
static EventGroupHandle_t s_wifi_event_group;
 

	
 
static const char *TAG = "wifi station";
 
static int s_retry_num = 0;
 

	
 

	
 
static void __event_handler(void* arg, esp_event_base_t event_base,
 
                                int32_t event_id, void* event_data)
 
// Handler for wifi events
 
static void __event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
 
{
 
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
 
        esp_wifi_connect();
 
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
 
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
 
    }
 
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) 
 
    {
 
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) 
 
        {
 
            esp_wifi_connect();
 
            s_retry_num++;
 
            ESP_LOGI(TAG, "retry to connect to the AP");
 
        } else {
 
        } 
 
        else 
 
        {
 
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
 
        }
 
        ESP_LOGI(TAG,"connect to the AP fail");
 
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
 
    } 
 
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) 
 
    {
 
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
 
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
 
        s_retry_num = 0;
 
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
 
    }
 
}
 

	
 

	
 
// Initialize wifi and connect to network
 
void wifi_init(void)
 
{
 
    s_wifi_event_group = xEventGroupCreate();
 

	
 
    ESP_ERROR_CHECK(esp_netif_init());
 

	
 
    ESP_ERROR_CHECK(esp_event_loop_create_default());
 
    esp_netif_create_default_wifi_sta();
 

	
 
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
 
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
 

	
 
    esp_event_handler_instance_t instance_any_id;
 
    esp_event_handler_instance_t instance_got_ip;
 
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
 
                                                        ESP_EVENT_ANY_ID,
 
                                                        &__event_handler,
 
                                                        NULL,
 
                                                        &instance_any_id));
 
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
 
                                                        IP_EVENT_STA_GOT_IP,
 
                                                        &__event_handler,
 
                                                        NULL,
 
                                                        &instance_got_ip));
0 comments (0 inline, 0 general)