Skip to content

Commit

Permalink
Update machine_can.c
Browse files Browse the repository at this point in the history
  • Loading branch information
IhorNehrutsa committed Mar 3, 2025
1 parent d547be4 commit f88e04f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 51 deletions.
109 changes: 60 additions & 49 deletions ports/esp32/machine_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include "esp_err.h"
#include "esp_log.h"
#include "soc/soc_caps.h"
#include "soc/dport_reg.h"
//#include "soc/dport_reg.h"
#include "soc/clk_tree_defs.h"
#include "soc/twai_periph.h"
#include "hal/twai_types.h"
Expand All @@ -51,6 +51,8 @@

#if MICROPY_PY_MACHINE_CAN

#define debug_printf(...) mp_printf(&mp_plat_print, __VA_ARGS__); mp_printf(&mp_plat_print, " | %d at %s\n", __LINE__, __FILE__);

// Default bitrate: 500kb
#define CAN_TASK_PRIORITY (ESP_TASK_PRIO_MIN + 1)
#define CAN_TASK_STACK_SIZE (1024)
Expand All @@ -60,16 +62,6 @@
#define CAN_DEFAULT_BS2 (4)
#define CAN_MAX_DATA_FRAME (8)

// INTERNAL Deinitialize can
void can_deinit(const esp32_can_obj_t *self) {
check_esp_err(twai_stop_v2(self->handle));
check_esp_err(twai_driver_uninstall_v2(self->handle));
if (self->irq_handler != NULL) {
vTaskDelete(self->irq_handler);
}
self->config->initialized = false;
}

// #define TWAI_TIMING_CONFIG_20KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}

// static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
Expand All @@ -85,9 +77,22 @@ esp32_can_config_t can_config = {

static esp32_can_obj_t esp32_can_obj = {
{&machine_can_type},
.config = &can_config
.config = &can_config,
.handle = NULL,
};

// INTERNAL Deinitialize can
void can_deinit(const esp32_can_obj_t *self) {
if (self->handle) {
check_esp_err(twai_stop_v2(self->handle));
check_esp_err(twai_driver_uninstall_v2(self->handle));
}
if (self->irq_handler != NULL) {
vTaskDelete(self->irq_handler);
}
self->config->initialized = false;
}

static void esp32_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
esp32_can_obj_t *self = MP_OBJ_TO_PTR(self_in);

Expand All @@ -107,7 +112,7 @@ static void esp32_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_
mode = MP_QSTR_UNKNOWN;
break;
}
mp_printf(print, "CAN(tx=%u, rx=%u, bitrate=%ukb, mode=%q, loopback=%u, extframe=%u)",
mp_printf(print, "CAN(tx=%u, rx=%u, bitrate=%u, mode=%q, loopback=%u, extframe=%u)",
self->config->general.tx_io,
self->config->general.rx_io,
self->config->bitrate,
Expand All @@ -124,11 +129,11 @@ static void esp32_can_irq_task(void *self_in) {
esp32_can_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint32_t alerts;

twai_reconfigure_alerts_v2(self->handle, TWAI_ALERT_ALL,
check_esp_err(twai_reconfigure_alerts_v2(self->handle, TWAI_ALERT_ALL,
// TWAI_ALERT_RX_DATA | TWAI_ALERT_RX_QUEUE_FULL | TWAI_ALERT_BUS_OFF | TWAI_ALERT_ERR_PASS |
// TWAI_ALERT_ABOVE_ERR_WARN | TWAI_ALERT_TX_FAILED | TWAI_ALERT_TX_SUCCESS | TWAI_ALERT_BUS_RECOVERED,
NULL
);
));

while (1) {
check_esp_err(twai_read_alerts_v2(self->handle, &alerts, portMAX_DELAY));
Expand All @@ -151,22 +156,22 @@ static void esp32_can_irq_task(void *self_in) {
self->bus_recovery_success = 1;
}

if (self->rxcallback != mp_const_none) {
if (self->rx_callback != mp_const_none) {
if (alerts & TWAI_ALERT_RX_DATA) {
check_esp_err(twai_get_status_info_v2(self->handle, &self->status));
uint32_t msgs_to_rx = self->status.msgs_to_rx;

if (msgs_to_rx == 1) {
// first message in queue
mp_sched_schedule(self->rxcallback, MP_OBJ_NEW_SMALL_INT(0));
mp_sched_schedule(self->rx_callback, MP_OBJ_NEW_SMALL_INT(0));
} else if (msgs_to_rx >= self->config->general.rx_queue_len) {
// queue is full
mp_sched_schedule(self->rxcallback, MP_OBJ_NEW_SMALL_INT(1));
mp_sched_schedule(self->rx_callback, MP_OBJ_NEW_SMALL_INT(1));
}
}
if (alerts & TWAI_ALERT_RX_QUEUE_FULL) {
// queue overflow
mp_sched_schedule(self->rxcallback, MP_OBJ_NEW_SMALL_INT(2));
mp_sched_schedule(self->rx_callback, MP_OBJ_NEW_SMALL_INT(2));
}
}
}
Expand Down Expand Up @@ -235,72 +240,73 @@ static mp_obj_t esp32_can_init_helper(esp32_can_obj_t *self, size_t n_args, cons
.triple_sampling = false
};
break;
#if 1 // #ifdef TWAI_TIMING_CONFIG_1KBITS
#ifdef TWAI_TIMING_CONFIG_1KBITS
case 1000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_1KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_5KBITS
#ifdef TWAI_TIMING_CONFIG_5KBITS
case 5000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_5KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_10KBITS
#ifdef TWAI_TIMING_CONFIG_10KBITS
case 10000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_10KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_12_5KBITS
#ifdef TWAI_TIMING_CONFIG_12_5KBITS
case 12500:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_12_5KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_16KBITS
#ifdef TWAI_TIMING_CONFIG_16KBITS
case 16000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_16KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_20KBITS
#ifdef TWAI_TIMING_CONFIG_20KBITS
case 20000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_20KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_25KBITS
#ifdef TWAI_TIMING_CONFIG_25KBITS
case 25000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_25KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_50KBITS
#ifdef TWAI_TIMING_CONFIG_50KBITS
case 50000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_50KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_100KBITS
#ifdef TWAI_TIMING_CONFIG_100KBITS
case 100000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_100KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_125KBITS
#ifdef TWAI_TIMING_CONFIG_125KBITS
case 125000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_125KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_250KBITS
#ifdef TWAI_TIMING_CONFIG_250KBITS
case 250000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_250KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_500KBITS
#ifdef TWAI_TIMING_CONFIG_500KBITS
case 500000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_500KBITS();
debug_printf("A");
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_800KBITS
#ifdef TWAI_TIMING_CONFIG_800KBITS
case 800000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_800KBITS();
break;
#endif
#if 1 // #ifdef TWAI_TIMING_CONFIG_1MBITS
#ifdef TWAI_TIMING_CONFIG_1MBITS
case 1000000:
self->config->timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_1MBITS();
break;
Expand All @@ -317,7 +323,7 @@ static mp_obj_t esp32_can_init_helper(esp32_can_obj_t *self, size_t n_args, cons
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("failed to create can irq task handler"));
}
self->config->initialized = true;

debug_printf("B");
return mp_const_none;
}

Expand All @@ -332,7 +338,7 @@ static mp_obj_t esp32_can_make_new(const mp_obj_type_t *type, size_t n_args, siz

// work out port
mp_uint_t can_idx = mp_obj_get_int(args[0]);
if (can_idx > SOC_TWAI_CONTROLLER_NUM) {
if (can_idx > SOC_TWAI_CONTROLLER_NUM - 1) {
mp_raise_msg_varg(&mp_type_ValueError, "out of CAN controllers:%d", SOC_TWAI_CONTROLLER_NUM);
}

Expand All @@ -344,7 +350,7 @@ static mp_obj_t esp32_can_make_new(const mp_obj_type_t *type, size_t n_args, siz
// this can only be done if the hardware is in init mode
can_deinit(self);
}
self->rxcallback = mp_const_none;
self->rx_callback = mp_const_none;
self->irq_handler = NULL;
self->rx_state = RX_STATE_FIFO_EMPTY;

Expand All @@ -365,7 +371,6 @@ static mp_obj_t esp32_can_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t
mp_raise_msg(&mp_type_RuntimeError, "Device is already initialized");
return mp_const_none;
}

return esp32_can_init_helper(self, n_args - 1, pos_args + 1, kw_args);
}
static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_can_init_obj, 4, esp32_can_init);
Expand Down Expand Up @@ -611,7 +616,7 @@ static mp_obj_t esp32_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t
// Return the result
return ret_obj;
}
static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_can_recv_obj, 0, esp32_can_recv);
static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_can_recv_obj, 1, esp32_can_recv);

// Clear filters setting
static mp_obj_t esp32_can_clearfilter(mp_obj_t self_in) {
Expand Down Expand Up @@ -712,38 +717,44 @@ static mp_obj_t esp32_can_set_filters(size_t n_args, const mp_obj_t *pos_args, m
self->config->filter.acceptance_mask |= mask;
}
// Apply filter
check_esp_err(twai_stop_v2(self->handle));
check_esp_err(twai_driver_uninstall_v2(self->handle));
if (self->handle) {
check_esp_err(twai_stop_v2(self->handle));
check_esp_err(twai_driver_uninstall_v2(self->handle));
}
check_esp_err(twai_driver_install_v2(
&self->config->general,
&self->config->timing,
&self->config->filter,
&self->handle
));
check_esp_err(twai_start_v2(self->handle));

return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_can_set_filters_obj, 1, esp32_can_set_filters);

// rxcallback(callable)
// rx_callback(callable)
// static mp_obj_t esp32_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in) {
// esp32_can_obj_t *self = MP_OBJ_TO_PTR(self_in);
// CAN.irq_recv(callback, hard=False)
//static mp_obj_t esp32_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
//static mp_obj_t esp32_can_irq_recv(mp_obj_t self_in, mp_obj_t callback_in) {
static mp_obj_t esp32_can_irq_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
esp32_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
mp_obj_t callback_in = NULL;
//static mp_obj_t esp32_can_irq_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static mp_obj_t esp32_can_irq_recv(mp_obj_t self_in, mp_obj_t callback_in) {
//esp32_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
esp32_can_obj_t *self = MP_OBJ_TO_PTR(self_in);
// mp_obj_t callback_in = NULL;
if (callback_in == mp_const_none) {
// disable callback
self->rxcallback = mp_const_none;
self->rx_callback = mp_const_none;
} else if (mp_obj_is_callable(callback_in)) {
// set up interrupt
self->rxcallback = callback_in;
self->rx_callback = callback_in;
}

return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_can_irq_recv_obj, 3, esp32_can_irq_recv);
static MP_DEFINE_CONST_FUN_OBJ_2(esp32_can_irq_recv_obj, esp32_can_irq_recv);
//static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_can_irq_recv_obj, 3, esp32_can_irq_recv);
//static MP_DEFINE_CONST_FUN_OBJ_2(esp32_hw_can_rxcallback_obj, esp32_hw_can_rxcallback);

// CAN.irq_send(callback, hard=False)
static mp_obj_t esp32_can_irq_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
Expand Down
3 changes: 2 additions & 1 deletion ports/esp32/machine_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ typedef struct {
typedef struct {
mp_obj_base_t base;
esp32_can_config_t *config;
mp_obj_t rxcallback;
mp_obj_t rx_callback;
mp_obj_t tx_callback;
TaskHandle_t irq_handler;
byte rx_state;
bool extframe : 1;
Expand Down
2 changes: 1 addition & 1 deletion ports/esp32/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
#define MICROPY_STACK_CHECK_MARGIN (1024)
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL+1)
#define MICROPY_WARNINGS (1)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
#define MICROPY_STREAMS_POSIX_API (1)
Expand Down

0 comments on commit f88e04f

Please sign in to comment.