From 96b8646059a776ec29f736c7379cd30795f9b5fa Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 26 Sep 2019 22:29:04 +0200 Subject: [PATCH 01/62] first commit --- ports/esp32/Makefile | 2 + ports/esp32/machine_can.c | 133 +++++++++++++++++++++++++++++++++++++ ports/esp32/machine_can.h | 94 ++++++++++++++++++++++++++ ports/esp32/modmachine.c | 3 + ports/esp32/modmachine.h | 1 + ports/esp32/mpconfigport.h | 1 + 6 files changed, 234 insertions(+) create mode 100644 ports/esp32/machine_can.c create mode 100644 ports/esp32/machine_can.h diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 919a047eb6a87..ef4d598d639b4 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -161,6 +161,7 @@ INC_ESPCOMP += -I$(ESPCOMP)/app_update/include INC_ESPCOMP += -I$(ESPCOMP)/pthread/include INC_ESPCOMP += -I$(ESPCOMP)/smartconfig_ack/include INC_ESPCOMP += -I$(ESPCOMP)/sdmmc/include +#INC_ESPCOMP += -I$(ESPCOMP)/can/include ifeq ($(ESPIDF_CURHASH),$(ESPIDF_SUPHASH_V4)) INC_ESPCOMP += -I$(ESPCOMP)/esp_common/include @@ -266,6 +267,7 @@ SRC_C = \ machine_i2c.c \ machine_pwm.c \ machine_uart.c \ + machine_can.c \ modmachine.c \ modnetwork.c \ network_lan.c \ diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c new file mode 100644 index 0000000000000..5652079b5c2a3 --- /dev/null +++ b/ports/esp32/machine_can.c @@ -0,0 +1,133 @@ +/* The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" + +#include "soc/dport_reg.h" //FIXME: check if path is found. full path is ESPIDF/components/soc/esp32/include/soc/dport_reg.h + +#include "driver/can.h" +#include "machine_can.h" + +#if MICROPY_HW_ENABLE_CAN + +STATIC const mp_obj_type_t machine_hw_can_type; +STATIC machine_hw_can_obj_t machine_hw_can_obj; + +bool can_init(machine_hw_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, CAN_speed_t baudrate, uint32_t mode) { + + can_driver_install( + CAN_GENERAL_CONFIG_DEFAULT(rx, rx, mode), + CAN_TIMING_CONFIG_1MBITS(), + CAN_FILTER_CONFIG_ACCEPT_ALL() + ); + + double __tq; //Time quantum + + //enable module + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN); + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST); + + //configure TX pin + gpio_set_level(tx, 1); + gpio_set_direction(tx,GPIO_MODE_OUTPUT); + gpio_matrix_out(tx,CAN_TX_IDX,0,0); + gpio_pad_select_gpio(tx); + + //configure RX pin + gpio_set_direction(rx,GPIO_MODE_INPUT); + gpio_matrix_in(rx,CAN_RX_IDX,0); + gpio_pad_select_gpio(rx); + + //set to PELICAN mode #FIXME: ability to change the mode to LOOPBACK + MODULE_CAN->CDR.B.CAN_M = 0x1; + + //synchronization jump width is the same for all baud rates + MODULE_CAN->BTR0.B.SJW = 0x1; + + //TSEG2 is the same for all baud rates + MODULE_CAN->BTR1.B.TSEG2 = 0x1; + + //select time quantum and set TSEG1 + switch(baudrate){ + case CAN_SPEED_1000KBPS: + MODULE_CAN->BTR1.B.TSEG1 = 0x4; + __tq = 0.125; + break; + + case CAN_SPEED_800KBPS: + MODULE_CAN->BTR1.B.TSEG1 =0x6; + __tq = 0.125; + break; + default: + MODULE_CAN->BTR1.B.TSEG1 = 0xc; + __tq = ((float)1000/baudrate) / 16; + } + + //set baud rate prescaler FIXME: APB_CLK_FREQ in soc/soc.h + MODULE_CAN->BTR0.B.BRP=(uint8_t)round((((APB_CLK_FREQ * __tq) / 2) - 1)/1000000)-1; + + /* Set sampling + * 1 -> triple; the bus is sampled three times; recommended for low/medium speed buses (class A and B) where filtering spikes on the bus line is beneficial + * 0 -> single; the bus is sampled once; recommended for high speed buses (SAE class C)*/ + MODULE_CAN->BTR1.B.SAM =0x1; + + //enable all interrupts + MODULE_CAN->IER.U = 0xff; + + //no acceptance filtering, as we want to fetch all messages + MODULE_CAN->MBX_CTRL.ACC.CODE[0] = 0; + MODULE_CAN->MBX_CTRL.ACC.CODE[1] = 0; + MODULE_CAN->MBX_CTRL.ACC.CODE[2] = 0; + MODULE_CAN->MBX_CTRL.ACC.CODE[3] = 0; + MODULE_CAN->MBX_CTRL.ACC.MASK[0] = 0xff; + MODULE_CAN->MBX_CTRL.ACC.MASK[1] = 0xff; + MODULE_CAN->MBX_CTRL.ACC.MASK[2] = 0xff; + MODULE_CAN->MBX_CTRL.ACC.MASK[3] = 0xff; + + //set to normal mode + MODULE_CAN->OCR.B.OCMODE=__CAN_OC_NOM; + + //clear error counters + MODULE_CAN->TXERR.U = 0; + MODULE_CAN->RXERR.U = 0; + (void)MODULE_CAN->ECC; + + //clear interrupt flags + (void)MODULE_CAN->IR.U; + + //install CAN ISR + esp_intr_alloc(ETS_CAN_INTR_SOURCE,0,CAN_isr,NULL,NULL); + + //Showtime. Release Reset Mode. + MODULE_CAN->MOD.B.RM = 0; + + return 0; +} + +int can_deinit(machine_hw_can_obj_t *self){ + return can_driver_uninstall(); +} + +#endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h new file mode 100644 index 0000000000000..1793133a1da82 --- /dev/null +++ b/ports/esp32/machine_can.h @@ -0,0 +1,94 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_ESP32_CAN_H +#define MICROPY_INCLUDED_ESP32_CAN_H + +#if MICROPY_HW_ENABLE_CAN + +typedef enum { + CAN_SPEED_100KBPS=100, /**< \brief CAN Node runs at 100kBit/s. */ + CAN_SPEED_125KBPS=125, /**< \brief CAN Node runs at 125kBit/s. */ + CAN_SPEED_250KBPS=250, /**< \brief CAN Node runs at 250kBit/s. */ + CAN_SPEED_500KBPS=500, /**< \brief CAN Node runs at 500kBit/s. */ + CAN_SPEED_800KBPS=800, /**< \brief CAN Node runs at 800kBit/s. */ + CAN_SPEED_1000KBPS=1000 /**< \brief CAN Node runs at 1000kBit/s. */ +}CAN_speed_t; + +enum { + CAN_STATE_STOPPED, + CAN_STATE_ERROR_ACTIVE, + CAN_STATE_ERROR_WARNING, + CAN_STATE_ERROR_PASSIVE, + CAN_STATE_BUS_OFF, +}; + +typedef enum _rx_state_t { + RX_STATE_FIFO_EMPTY = 0, + RX_STATE_MESSAGE_PENDING, + RX_STATE_FIFO_FULL, + RX_STATE_FIFO_OVERFLOW, +} rx_state_t; + + + +/** \brief CAN configuration structure */ +typedef struct { + CAN_speed_t speed; /**< \brief CAN speed. */ + gpio_num_t tx_pin_id; /**< \brief TX pin. */ + gpio_num_t rx_pin_id; /**< \brief RX pin. */ + QueueHandle_t rx_queue; /**< \brief Handler to FreeRTOS RX queue. */ +}CAN_device_t; + +typedef struct _machine_hw_can_obj_t { + mp_obj_base_t base; + mp_obj_t rxcallback0; + mp_obj_t rxcallback1; + mp_uint_t can_id : 8; + bool is_enabled : 1; + bool extframe : 1; + byte rx_state0; + byte rx_state1; + uint16_t num_error_warning; + uint16_t num_error_passive; + uint16_t num_bus_off; + CAN_HandleTypeDef can; +} esp32_can_obj_t; + +extern const mp_obj_type_t machine_can_type; + +//void can_init0(void); #TODO: +//void can_deinit_all(void); #TODO: +bool can_init(machine_hw_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, CAN_speed_t baudrate, uint32_t mode); +void can_deinit(machine_hw_can_obj_t *self); + +void can_clearfilter(pyb_can_obj_t *self, uint32_t f, uint8_t bank); +int can_receive(CAN_HandleTypeDef *can, int fifo, CanRxMsgTypeDef *msg, uint8_t *data, uint32_t timeout_ms); +HAL_StatusTypeDef CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout); +void pyb_can_handle_callback(pyb_can_obj_t *self, uint fifo_id, mp_obj_t callback, mp_obj_t irq_reason); + +#endif // MICROPY_HW_ENABLE_CAN + +#endif // MICROPY_INCLUDED_ESP32_CAN_H diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 0c803d0960d18..b8ba1745c4a6d 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -258,6 +258,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, + #if MICROPY_HW_ENABLE_CAN + { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&machine_can_type) }, + #endif // Reset reasons { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) }, diff --git a/ports/esp32/modmachine.h b/ports/esp32/modmachine.h index ca1776d8bf721..9e52deb99d04c 100644 --- a/ports/esp32/modmachine.h +++ b/ports/esp32/modmachine.h @@ -18,6 +18,7 @@ extern const mp_obj_type_t machine_dac_type; extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_hw_spi_type; extern const mp_obj_type_t machine_uart_type; +extern const mp_obj_type_t machine_can_type; extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_sdcard_type; diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 1c0d8700facda..66d3b5b1270fa 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -150,6 +150,7 @@ #define MICROPY_PY_MACHINE_SPI_LSB (1) #define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hw_spi_make_new #define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_ENABLE_CAN (1) #define MICROPY_HW_SOFTSPI_MIN_DELAY (0) #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (ets_get_cpu_frequency() * 1000000 / 200) // roughly #define MICROPY_PY_USSL (1) From 4b06c23d083647726f84deaa8875c4d0ab3b8c61 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sat, 28 Sep 2019 18:26:39 +0200 Subject: [PATCH 02/62] Enabled module --- ports/esp32/Makefile | 2 +- ports/esp32/machine_can.c | 129 ++++++++++---------------------------- ports/esp32/machine_can.h | 60 +++++------------- ports/esp32/modmachine.c | 4 +- 4 files changed, 52 insertions(+), 143 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index ef4d598d639b4..a79daf79a034f 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -161,7 +161,7 @@ INC_ESPCOMP += -I$(ESPCOMP)/app_update/include INC_ESPCOMP += -I$(ESPCOMP)/pthread/include INC_ESPCOMP += -I$(ESPCOMP)/smartconfig_ack/include INC_ESPCOMP += -I$(ESPCOMP)/sdmmc/include -#INC_ESPCOMP += -I$(ESPCOMP)/can/include +INC_ESPCOMP += -I$(ESPCOMP)/can/include ifeq ($(ESPIDF_CURHASH),$(ESPIDF_SUPHASH_V4)) INC_ESPCOMP += -I$(ESPCOMP)/esp_common/include diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 5652079b5c2a3..467d7b4e5a85a 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -21,113 +21,52 @@ * THE SOFTWARE. */ +#include "py/obj.h" #include "py/runtime.h" #include "py/mphal.h" #include "py/mperrno.h" +#include +//Headers of ESP-IDF library #include "soc/dport_reg.h" //FIXME: check if path is found. full path is ESPIDF/components/soc/esp32/include/soc/dport_reg.h - #include "driver/can.h" +#include "esp_err.h" +#include "esp_log.h" + #include "machine_can.h" #if MICROPY_HW_ENABLE_CAN -STATIC const mp_obj_type_t machine_hw_can_type; -STATIC machine_hw_can_obj_t machine_hw_can_obj; - -bool can_init(machine_hw_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, CAN_speed_t baudrate, uint32_t mode) { - - can_driver_install( - CAN_GENERAL_CONFIG_DEFAULT(rx, rx, mode), - CAN_TIMING_CONFIG_1MBITS(), - CAN_FILTER_CONFIG_ACCEPT_ALL() - ); - - double __tq; //Time quantum - - //enable module - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST); - - //configure TX pin - gpio_set_level(tx, 1); - gpio_set_direction(tx,GPIO_MODE_OUTPUT); - gpio_matrix_out(tx,CAN_TX_IDX,0,0); - gpio_pad_select_gpio(tx); - - //configure RX pin - gpio_set_direction(rx,GPIO_MODE_INPUT); - gpio_matrix_in(rx,CAN_RX_IDX,0); - gpio_pad_select_gpio(rx); - - //set to PELICAN mode #FIXME: ability to change the mode to LOOPBACK - MODULE_CAN->CDR.B.CAN_M = 0x1; - - //synchronization jump width is the same for all baud rates - MODULE_CAN->BTR0.B.SJW = 0x1; - - //TSEG2 is the same for all baud rates - MODULE_CAN->BTR1.B.TSEG2 = 0x1; - - //select time quantum and set TSEG1 - switch(baudrate){ - case CAN_SPEED_1000KBPS: - MODULE_CAN->BTR1.B.TSEG1 = 0x4; - __tq = 0.125; - break; - - case CAN_SPEED_800KBPS: - MODULE_CAN->BTR1.B.TSEG1 =0x6; - __tq = 0.125; - break; - default: - MODULE_CAN->BTR1.B.TSEG1 = 0xc; - __tq = ((float)1000/baudrate) / 16; - } - - //set baud rate prescaler FIXME: APB_CLK_FREQ in soc/soc.h - MODULE_CAN->BTR0.B.BRP=(uint8_t)round((((APB_CLK_FREQ * __tq) / 2) - 1)/1000000)-1; - - /* Set sampling - * 1 -> triple; the bus is sampled three times; recommended for low/medium speed buses (class A and B) where filtering spikes on the bus line is beneficial - * 0 -> single; the bus is sampled once; recommended for high speed buses (SAE class C)*/ - MODULE_CAN->BTR1.B.SAM =0x1; - - //enable all interrupts - MODULE_CAN->IER.U = 0xff; - - //no acceptance filtering, as we want to fetch all messages - MODULE_CAN->MBX_CTRL.ACC.CODE[0] = 0; - MODULE_CAN->MBX_CTRL.ACC.CODE[1] = 0; - MODULE_CAN->MBX_CTRL.ACC.CODE[2] = 0; - MODULE_CAN->MBX_CTRL.ACC.CODE[3] = 0; - MODULE_CAN->MBX_CTRL.ACC.MASK[0] = 0xff; - MODULE_CAN->MBX_CTRL.ACC.MASK[1] = 0xff; - MODULE_CAN->MBX_CTRL.ACC.MASK[2] = 0xff; - MODULE_CAN->MBX_CTRL.ACC.MASK[3] = 0xff; - - //set to normal mode - MODULE_CAN->OCR.B.OCMODE=__CAN_OC_NOM; - - //clear error counters - MODULE_CAN->TXERR.U = 0; - MODULE_CAN->RXERR.U = 0; - (void)MODULE_CAN->ECC; - - //clear interrupt flags - (void)MODULE_CAN->IR.U; - - //install CAN ISR - esp_intr_alloc(ETS_CAN_INTR_SOURCE,0,CAN_isr,NULL,NULL); - - //Showtime. Release Reset Mode. - MODULE_CAN->MOD.B.RM = 0; - - return 0; +const mp_obj_type_t machine_can_type; + +void can_init(machine_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, uint32_t baudrate, uint32_t mode) { + static const can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); + static const can_timing_config_t t_config = CAN_TIMING_CONFIG_25KBITS(); + //Set TX queue length to 0 due to listen only mode + can_general_config_t g_config = {.mode = mode, + .tx_io = tx, .rx_io = rx, + .clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED, + .tx_queue_len = 0, .rx_queue_len = 5, + .alerts_enabled = CAN_ALERT_NONE, + .clkout_divider = 0}; + ESP_ERROR_CHECK(can_driver_install(&g_config, &t_config, &f_config)); + ESP_LOGI("CAN", "Driver installed"); + ESP_ERROR_CHECK(can_start()); + ESP_LOGI("CAN", "Driver started"); } -int can_deinit(machine_hw_can_obj_t *self){ - return can_driver_uninstall(); +/*void machine_can_trasmit(machine_hw_can_obj_t *self, uint32_t address, size_t length, mp_machine_can_buf_t *data) +{ + can_message_t tx_msg = {.data_length_code = length, .identifier = address, .flags = CAN_MSG_FLAG_SELF}; + for (uint8_t i=0; i Date: Sun, 29 Sep 2019 12:07:47 +0200 Subject: [PATCH 03/62] Stable basic code for module loading in Python --- ports/esp32/machine_can.c | 26 ++++++++++++------ ports/esp32/machine_can.h | 57 +++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 467d7b4e5a85a..dac51bb1b9459 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -23,6 +23,7 @@ #include "py/obj.h" #include "py/runtime.h" +#include "py/builtin.h" #include "py/mphal.h" #include "py/mperrno.h" #include @@ -35,12 +36,19 @@ #include "machine_can.h" -#if MICROPY_HW_ENABLE_CAN +//#if MICROPY_HW_ENABLE_CAN -const mp_obj_type_t machine_can_type; +const machine_hw_can_obj_t can_default = {.tx=6, .rx=4}; -void can_init(machine_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, uint32_t baudrate, uint32_t mode) { - static const can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); +STATIC const mp_obj_type_t machine_hw_can_type; //FIXME: da popolare + +STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_hw_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "CAN(tx=%u, rx=%u)", self->tx, self->rx); +} + +STATIC mp_obj_t machine_hw_can_init(mp_obj_t self_in) { + /*static const can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); static const can_timing_config_t t_config = CAN_TIMING_CONFIG_25KBITS(); //Set TX queue length to 0 due to listen only mode can_general_config_t g_config = {.mode = mode, @@ -52,9 +60,11 @@ void can_init(machine_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, uint32_t ba ESP_ERROR_CHECK(can_driver_install(&g_config, &t_config, &f_config)); ESP_LOGI("CAN", "Driver installed"); ESP_ERROR_CHECK(can_start()); - ESP_LOGI("CAN", "Driver started"); + ESP_LOGI("CAN", "Driver started");*/ + return mp_const_none; } + /*void machine_can_trasmit(machine_hw_can_obj_t *self, uint32_t address, size_t length, mp_machine_can_buf_t *data) { can_message_t tx_msg = {.data_length_code = length, .identifier = address, .flags = CAN_MSG_FLAG_SELF}; @@ -62,11 +72,11 @@ void can_init(machine_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, uint32_t ba ESP_ERROR_CHECK(can_transmit(&tx_msg, portMAX_DELAY)); }*/ -void machine_can_deinit(machine_can_obj_t *self){ +/*void machine_can_deinit(machine_can_obj_t *self){ ESP_ERROR_CHECK(can_stop()); ESP_LOGI("CAN", "Driver stopped"); ESP_ERROR_CHECK(can_driver_uninstall()); ESP_LOGI("CAN", "Driver uninstalled"); -} +}*/ -#endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file +//#endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 3b20ea5a3929e..5cccb97ba7e97 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -30,37 +30,34 @@ #include "py/obj.h" - -typedef enum _rx_state_t { - RX_STATE_FIFO_EMPTY = 0, - RX_STATE_MESSAGE_PENDING, - RX_STATE_FIFO_FULL, - RX_STATE_FIFO_OVERFLOW, -} rx_state_t; - typedef struct _machine_can_obj_t { mp_obj_base_t base; - mp_obj_t rxcallback; - gpio_num_t tx; - gpio_num_t rx; -} machine_can_obj_t; - -extern const mp_obj_type_t machine_can_type; - -//extern const mp_obj_type_t machine_can_type; -void can_init(machine_can_obj_t *self, gpio_num_t tx, gpio_num_t rx, uint32_t baudrate, uint32_t mode); -void can_deinit(machine_can_obj_t *self); - -//void can_trasmit(uint32_t address, byte data[], uint8_t length); - -//void can_init0(void); #TODO: -//void can_deinit_all(void); #TODO: - - -/*void can_clearfilter(pyb_can_obj_t *self, uint32_t f, uint8_t bank); -int can_receive(CAN_HandleTypeDef *can, int fifo, CanRxMsgTypeDef *msg, uint8_t *data, uint32_t timeout_ms); -HAL_StatusTypeDef CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout); -void pyb_can_handle_callback(pyb_can_obj_t *self, uint fifo_id, mp_obj_t callback, mp_obj_t irq_reason); -*/ + uint8_t tx; + uint8_t rx; +} machine_hw_can_obj_t; + +//Functions signature definition +STATIC mp_obj_t machine_hw_can_init(mp_obj_t self_in); +STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); + +//Python function declarations +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_init_obj, machine_hw_can_init); + +//Python objects list declaration +STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(125) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(250) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(500) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(1000) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); + +//Python object definition +const mp_obj_type_t machine_can_type = { + { &mp_type_type }, + .name = MP_QSTR_CAN, + .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, +}; #endif // MICROPY_INCLUDED_ESP32_CAN_H From 263338c4cdc38895f590b2bd2f5442ba6a8468d8 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 6 Oct 2019 18:52:25 +0200 Subject: [PATCH 04/62] Full initialization and dummy write --- ports/esp32/machine_can.c | 222 +++++++++++++++++++++++++++++++++----- ports/esp32/machine_can.h | 74 +++++++++++-- 2 files changed, 260 insertions(+), 36 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index dac51bb1b9459..6077f4ac48a7b 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -38,30 +38,78 @@ //#if MICROPY_HW_ENABLE_CAN -const machine_hw_can_obj_t can_default = {.tx=6, .rx=4}; +// singleton CAN device object +machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERAL_CONFIG_DEFAULT(2,4,0)), + .filter = &((can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()), + .timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()), + .initialized = false}; + +STATIC const machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; -STATIC const mp_obj_type_t machine_hw_can_type; //FIXME: da popolare -STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - machine_hw_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "CAN(tx=%u, rx=%u)", self->tx, self->rx); + + + +STATIC can_state_t _machine_hw_can_get_state(){ + can_status_info_t status; + ESP_ERROR_CHECK(can_get_status_info(&status)); //FIXME: remove ESP_ERROR_CHECK + return status.state; } -STATIC mp_obj_t machine_hw_can_init(mp_obj_t self_in) { - /*static const can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); - static const can_timing_config_t t_config = CAN_TIMING_CONFIG_25KBITS(); - //Set TX queue length to 0 due to listen only mode - can_general_config_t g_config = {.mode = mode, - .tx_io = tx, .rx_io = rx, - .clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED, - .tx_queue_len = 0, .rx_queue_len = 5, - .alerts_enabled = CAN_ALERT_NONE, - .clkout_divider = 0}; - ESP_ERROR_CHECK(can_driver_install(&g_config, &t_config, &f_config)); - ESP_LOGI("CAN", "Driver installed"); - ESP_ERROR_CHECK(can_start()); - ESP_LOGI("CAN", "Driver started");*/ - return mp_const_none; +STATIC mp_obj_t machine_hw_can_get_rx_waiting_messages(mp_obj_t self_in){ + can_status_info_t status; + ESP_ERROR_CHECK(can_get_status_info(&status)); //FIXME: remove ESP_ERROR_CHECK + return mp_obj_new_int(status.msgs_to_rx); +} + +STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in){ + can_status_info_t status; + ESP_ERROR_CHECK(can_get_status_info(&status)); //FIXME: remove ESP_ERROR_CHECK + return mp_obj_new_int(status.msgs_to_tx); +} + +STATIC mp_obj_t machine_hw_can_write(mp_obj_t self_in, mp_obj_t address) { + int value = mp_obj_get_int(address); + if (value < 0 || value > 255) mp_raise_ValueError("Value out of range"); + + if (_machine_hw_can_get_state()==CAN_STATE_RUNNING){ + //TODO: Check if queue is full + can_message_t tx_msg = {.data_length_code = 2, .identifier = 0x86, .flags = CAN_MSG_FLAG_SELF}; + tx_msg.data[0] = 0x58; + tx_msg.data[1] = 0x86; + ESP_ERROR_CHECK(can_transmit(&tx_msg, 100)); //FIXME: remove ESP_ERROR_CHECK + return machine_hw_can_get_rx_waiting_messages(self_in); + }else{ + ESP_LOGW(DEVICE_NAME, "Unable to send the message"); + return MP_OBJ_NEW_SMALL_INT(-1); + } +} + +STATIC mp_obj_t machine_hw_can_read(mp_obj_t self_in) { + can_message_t rx_message; + switch(can_receive(&rx_message, 1)){ + case ESP_ERR_TIMEOUT: + ESP_LOGW(DEVICE_NAME, "Time-out"); break; + case ESP_ERR_INVALID_ARG: + ESP_LOGE(DEVICE_NAME, "Invalid Args"); break; + case ESP_ERR_INVALID_STATE: + ESP_LOGW(DEVICE_NAME, "Invalid State"); break; + case ESP_OK: + return MP_OBJ_NEW_SMALL_INT(rx_message.identifier); + }; + return MP_OBJ_NEW_SMALL_INT(-1); + +} + +STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->config->initialized){ + mp_printf(print, "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%u)", self->config->general->tx_io, self->config->general->rx_io, + self->config->baudrate, self->config->general->mode); + }else{ + mp_printf(print, "CAN Device is not initialized"); + } + } @@ -72,11 +120,133 @@ STATIC mp_obj_t machine_hw_can_init(mp_obj_t self_in) { ESP_ERROR_CHECK(can_transmit(&tx_msg, portMAX_DELAY)); }*/ -/*void machine_can_deinit(machine_can_obj_t *self){ - ESP_ERROR_CHECK(can_stop()); - ESP_LOGI("CAN", "Driver stopped"); - ESP_ERROR_CHECK(can_driver_uninstall()); - ESP_LOGI("CAN", "Driver uninstalled"); -}*/ +// CAN(...) No argument to get the object +// Any argument will be used to init the device through init function +mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *args){ + const machine_can_obj_t *self = &machine_can_obj; + + if (n_args > 0 || n_kw > 0) { + if (self->config->initialized) { + // The caller is requesting a reconfiguration of the hardware + // this can only be done if the hardware is in init mode + ESP_LOGW(DEVICE_NAME, "Device is going to be reconfigured"); + machine_hw_can_deinit(&self); + } + //TODO: implement callback + /*self->rxcallback0 = mp_const_none; + self->rxcallback1 = mp_const_none; + self->rx_state0 = RX_STATE_FIFO_EMPTY; + self->rx_state1 = RX_STATE_FIFO_EMPTY;*/ + + // start the peripheral + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_hw_can_init_helper(self, n_args, args, &kw_args); + } + return MP_OBJ_FROM_PTR(self); +} + +// init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) +STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + const machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (self->config->initialized){ + ESP_LOGW(DEVICE_NAME, "Device is already initialized"); + return mp_const_false; + } + return machine_hw_can_init_helper(self, n_args - 1, args + 1, kw_args); +} + +// INTERNAL FUNCTION init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) +STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_mode, ARG_tx_queue, ARG_rx_queue}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 4} }, + { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 2} }, + { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 500} }, + { MP_QSTR_mode, MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, + { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, + }; + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + //Check if device was already configured + if (self->config->initialized){ + ESP_LOGE(DEVICE_NAME, "Device is already initialized: unable to re-init"); + return mp_const_none; + } + //Configure device + can_general_config_t g_config = {.mode = args[ARG_mode].u_int, + .tx_io = args[ARG_tx].u_int, + .rx_io = args[ARG_rx].u_int, + .clkout_io = CAN_IO_UNUSED, + .bus_off_io = CAN_IO_UNUSED, + .tx_queue_len = args[ARG_tx_queue].u_int, + .rx_queue_len = args[ARG_rx_queue].u_int, + .alerts_enabled = CAN_ALERT_NONE, + .clkout_divider = 0}; + self->config->general = &g_config; + + switch ((int)args[ARG_baudrate].u_int){ + case CAN_BAUDRATE_25k: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()); + break; + case CAN_BAUDRATE_50k: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_50KBITS()); + break; + case CAN_BAUDRATE_100k: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_100KBITS()); + break; + case CAN_BAUDRATE_125k: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_125KBITS()); + break; + case CAN_BAUDRATE_250k: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_250KBITS()); + break; + case CAN_BAUDRATE_500k: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_500KBITS()); + break; + case CAN_BAUDRATE_800k: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_800KBITS()); + break; + case CAN_BAUDRATE_1M: + self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); + break; + default: + ESP_LOGE(DEVICE_NAME, "Unable to set baudrate"); + self->config->baudrate = 0; + return mp_const_none; + } + self->config->baudrate = args[ARG_baudrate].u_int; + + uint8_t status = can_driver_install(self->config->general, self->config->timing, self->config->filter); + if (status != ESP_OK){ + ESP_LOGE(DEVICE_NAME, "Unable to init the device. ErrCode: %u",status); + }else if (can_start() != ESP_OK){ + ESP_LOGE(DEVICE_NAME, "Unable to start the device. ErrCode: %u",status); + }else{ + self->config->initialized = true; + } + + return mp_const_none; +} + +STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ + const machine_can_obj_t *self = &machine_can_obj; + if (self->config->initialized != true){ + ESP_LOGW(DEVICE_NAME, "Device is not initialized"); + return mp_const_false; + } + if(can_stop()!=ESP_OK){ + ESP_LOGW(DEVICE_NAME, "Unable to stop device"); + } + if (can_driver_uninstall() != ESP_OK){ + ESP_LOGW(DEVICE_NAME, "Unable to uninstall device"); + return mp_const_false; + } + self->config->initialized = false; + return mp_const_true; +} //#endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 5cccb97ba7e97..d2b2d101553db 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -30,26 +30,78 @@ #include "py/obj.h" +#define DEVICE_NAME "CAN" + +#define CAN_BAUDRATE_25k 25 +#define CAN_BAUDRATE_50k 50 +#define CAN_BAUDRATE_100k 100 +#define CAN_BAUDRATE_125k 125 +#define CAN_BAUDRATE_250k 250 +#define CAN_BAUDRATE_500k 500 +#define CAN_BAUDRATE_800k 800 +#define CAN_BAUDRATE_1M 1000 + + +typedef struct _machine_can_config_t { + const can_timing_config_t *timing; + const can_filter_config_t *filter; + const can_general_config_t *general; + uint16_t baudrate; + bool initialized; +} machine_can_config_t; + typedef struct _machine_can_obj_t { mp_obj_base_t base; - uint8_t tx; - uint8_t rx; -} machine_hw_can_obj_t; + machine_can_config_t *config; +} machine_can_obj_t; + +//Internal functions +STATIC can_state_t _machine_hw_can_get_state(); //Functions signature definition -STATIC mp_obj_t machine_hw_can_init(mp_obj_t self_in); +mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); +STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); +STATIC mp_obj_t machine_hw_can_read(mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_write(mp_obj_t self_in, mp_obj_t address) ; +STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_get_rx_waiting_messages(mp_obj_t self_in); //Python function declarations -STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_init_obj, machine_hw_can_init); +MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_write_obj, machine_hw_can_write); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_read_obj, machine_hw_can_read); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deinit); +MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); //Python objects list declaration STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { + //CAN_ATTRIBUTES + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, + //CAN_FUNCTIONS { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(125) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(250) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(500) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(1000) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_write_obj)}, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_hw_can_read_obj)}, + //CAN_MODE + { MP_ROM_QSTR(MP_QSTR_CAN_MODE_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, + { MP_ROM_QSTR(MP_QSTR_CAN_MODE_NO_ACK), MP_ROM_INT(CAN_MODE_NO_ACK) }, + { MP_ROM_QSTR(MP_QSTR_CAN_MODE_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, + //CAN_STATE + { MP_ROM_QSTR(MP_QSTR_CAN_STATE_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, + { MP_ROM_QSTR(MP_QSTR_CAN_STATE_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, + { MP_ROM_QSTR(MP_QSTR_CAN_STATE_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, + { MP_ROM_QSTR(MP_QSTR_CAN_STATE_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, + //CAN_BAUDRATE + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_100k), MP_ROM_INT(CAN_BAUDRATE_100k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(CAN_BAUDRATE_125k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(CAN_BAUDRATE_250k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M) }, }; STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); @@ -57,7 +109,9 @@ STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_tab const mp_obj_type_t machine_can_type = { { &mp_type_type }, .name = MP_QSTR_CAN, - .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, + .print = machine_hw_can_print, // give it a print-function + .make_new = machine_hw_can_make_new, // give it a constructor + .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members }; #endif // MICROPY_INCLUDED_ESP32_CAN_H From 79540e33b7358c3137384a5fbd1baba0b6101dff Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 6 Oct 2019 19:15:39 +0200 Subject: [PATCH 05/62] added function to retrieve information of CAN STATUS --- ports/esp32/machine_can.c | 49 +++++++++++++++++++++++++++++---------- ports/esp32/machine_can.h | 20 ++++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 6077f4ac48a7b..69bdd25996184 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -26,7 +26,7 @@ #include "py/builtin.h" #include "py/mphal.h" #include "py/mperrno.h" -#include +#include "mpconfigport.h" //Headers of ESP-IDF library #include "soc/dport_reg.h" //FIXME: check if path is found. full path is ESPIDF/components/soc/esp32/include/soc/dport_reg.h @@ -46,28 +46,53 @@ machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERA STATIC const machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; - - - +STATIC can_status_info_t _machine_hw_can_get_status(){ + can_status_info_t status; + if(can_get_status_info(&status)!=ESP_OK){ + mp_raise_ValueError("Unable to get CAN status"); + } + return status; +} STATIC can_state_t _machine_hw_can_get_state(){ - can_status_info_t status; - ESP_ERROR_CHECK(can_get_status_info(&status)); //FIXME: remove ESP_ERROR_CHECK - return status.state; + can_status_info_t status = _machine_hw_can_get_status(); + return status.state; } STATIC mp_obj_t machine_hw_can_get_rx_waiting_messages(mp_obj_t self_in){ - can_status_info_t status; - ESP_ERROR_CHECK(can_get_status_info(&status)); //FIXME: remove ESP_ERROR_CHECK - return mp_obj_new_int(status.msgs_to_rx); + can_status_info_t status = _machine_hw_can_get_status(); + return mp_obj_new_int(status.msgs_to_rx); } STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in){ - can_status_info_t status; - ESP_ERROR_CHECK(can_get_status_info(&status)); //FIXME: remove ESP_ERROR_CHECK + can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_int(status.msgs_to_tx); } +//Return status information +STATIC mp_obj_t machine_hw_can_get_tec(mp_obj_t self_in){ + can_status_info_t status = _machine_hw_can_get_status(); + return mp_obj_new_int(status.tx_error_counter); +} + +STATIC mp_obj_t machine_hw_can_get_rec(mp_obj_t self_in){ + can_status_info_t status = _machine_hw_can_get_status(); + return mp_obj_new_int(status.rx_error_counter); +} + +STATIC mp_obj_t machine_hw_can_get_state(mp_obj_t self_in){ + return mp_obj_new_int(_machine_hw_can_get_state()); +} + +STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ + return mp_obj_new_bool(can_clear_transmit_queue()==ESP_OK); +} + +STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ + return mp_obj_new_bool(can_clear_receive_queue()==ESP_OK); +} + + STATIC mp_obj_t machine_hw_can_write(mp_obj_t self_in, mp_obj_t address) { int value = mp_obj_get_int(address); if (value < 0 || value > 255) mp_raise_ValueError("Value out of range"); diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index d2b2d101553db..70018c50acc0c 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -67,13 +67,26 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p STATIC mp_obj_t machine_hw_can_read(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_write(mp_obj_t self_in, mp_obj_t address) ; +STATIC mp_obj_t machine_hw_can_get_tec(mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_get_rec(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_get_rx_waiting_messages(mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_get_state(mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in); + //Python function declarations MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_write_obj, machine_hw_can_write); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_read_obj, machine_hw_can_read); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deinit); MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_tec_obj, machine_hw_can_get_tec); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_rec_obj, machine_hw_can_get_rec); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_tx_waiting_messages_obj, machine_hw_can_get_tx_waiting_messages); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_rx_waiting_messages_obj, machine_hw_can_get_rx_waiting_messages); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_state_obj, machine_hw_can_get_state); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); //Python objects list declaration STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { @@ -84,6 +97,13 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_write_obj)}, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_hw_can_read_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_tec), MP_ROM_PTR(&machine_hw_can_get_tec_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_rec), MP_ROM_PTR(&machine_hw_can_get_rec_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_tx_waiting_messages), MP_ROM_PTR(&machine_hw_can_get_tx_waiting_messages_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_rx_waiting_messages), MP_ROM_PTR(&machine_hw_can_get_rx_waiting_messages_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_state), MP_ROM_PTR(&machine_hw_can_get_state_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, //CAN_MODE { MP_ROM_QSTR(MP_QSTR_CAN_MODE_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, { MP_ROM_QSTR(MP_QSTR_CAN_MODE_NO_ACK), MP_ROM_INT(CAN_MODE_NO_ACK) }, From 5c6a318dcab294468a715979f94b6335647d8b06 Mon Sep 17 00:00:00 2001 From: Salvo Musumeci Date: Sun, 6 Oct 2019 21:09:49 +0200 Subject: [PATCH 06/62] Update quickref.rst Added quick commands for CAN usage --- docs/esp32/quickref.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index dd85b102b2551..846d194a43a5a 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -325,6 +325,22 @@ pins can be used for SCL and SDA. The driver is accessed via the buf = bytearray(10) # create a buffer with 10 bytes i2c.writeto(0x3a, buf) # write the given buffer to the slave +CAN bus +------- + +The CAN driver is based on hardware implementation. +Any available output-capablepins can be used for SCL and SDA. +The driver is accessed via the :ref:`machine.CAN ` class:: + + from machine import CAN + + # construct a CAN bus + bus = CAN(tx=4, rx=2, baudrate=500, mode=CAN.MODE_NO_ACK) + + bus.send([0,1,2,3], 0x86, self_flag=True) #Send a self message + bus.recv() #Read the message sent + + Real time clock (RTC) --------------------- From 83297b4fcf5e153748082b4284968fe98491f01d Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 6 Oct 2019 21:02:59 +0200 Subject: [PATCH 07/62] Function SEND and RECV implemented --- ports/esp32/machine_can.c | 107 +++++++++++++++++++++++++++----------- ports/esp32/machine_can.h | 12 ++--- 2 files changed, 83 insertions(+), 36 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 69bdd25996184..c81a06373a03c 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -46,6 +46,7 @@ machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERA STATIC const machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; +//Return status information STATIC can_status_info_t _machine_hw_can_get_status(){ can_status_info_t status; if(can_get_status_info(&status)!=ESP_OK){ @@ -69,7 +70,6 @@ STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in){ return mp_obj_new_int(status.msgs_to_tx); } -//Return status information STATIC mp_obj_t machine_hw_can_get_tec(mp_obj_t self_in){ can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_int(status.tx_error_counter); @@ -84,67 +84,113 @@ STATIC mp_obj_t machine_hw_can_get_state(mp_obj_t self_in){ return mp_obj_new_int(_machine_hw_can_get_state()); } +//Clear TX Queue STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_transmit_queue()==ESP_OK); } - +//Clear RX Queue STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_receive_queue()==ESP_OK); } - -STATIC mp_obj_t machine_hw_can_write(mp_obj_t self_in, mp_obj_t address) { - int value = mp_obj_get_int(address); - if (value < 0 || value > 255) mp_raise_ValueError("Value out of range"); - +//send([data], id, timeout=0, rtr=False, self_flag=False) +STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_data, ARG_id, ARG_timeout, ARG_rtr, ARG_self }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_self_flag, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args-1, pos_args+1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // populate message + size_t length; + mp_obj_t *items; + mp_obj_get_array(args[ARG_data].u_obj,&length, &items); + if (length>8){ + mp_raise_ValueError("CAN data field too long"); + } + uint8_t flags = (args[ARG_rtr].u_bool==true ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); + if (args[ARG_id].u_int>0x7ff){ + flags += CAN_MSG_FLAG_EXTD; + } + if (args[ARG_self].u_bool){ + flags += CAN_MSG_FLAG_SELF; + } + + can_message_t tx_msg = {.data_length_code = length, + .identifier = args[ARG_id].u_int & 0x1FFFFFFF, + .flags = flags}; + for (uint8_t i=0; iitems; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + can_message_t rx_message; switch(can_receive(&rx_message, 1)){ + case ESP_OK: + items[0] = MP_OBJ_NEW_SMALL_INT(rx_message.identifier); + items[1] = mp_obj_new_bytes(rx_message.data, rx_message.data_length_code); + items[2] = MP_OBJ_NEW_SMALL_INT(rx_message.flags); + return ret_obj; case ESP_ERR_TIMEOUT: - ESP_LOGW(DEVICE_NAME, "Time-out"); break; + mp_raise_ValueError("Timeout"); case ESP_ERR_INVALID_ARG: - ESP_LOGE(DEVICE_NAME, "Invalid Args"); break; + mp_raise_ValueError("Invalid Args"); case ESP_ERR_INVALID_STATE: - ESP_LOGW(DEVICE_NAME, "Invalid State"); break; - case ESP_OK: - return MP_OBJ_NEW_SMALL_INT(rx_message.identifier); + mp_raise_ValueError("Invalid State"); + default: + mp_raise_ValueError(""); }; - return MP_OBJ_NEW_SMALL_INT(-1); - } STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->config->initialized){ + qstr mode; + switch(self->config->general->mode){ + case CAN_MODE_LISTEN_ONLY: mode = MP_QSTR_LISTEN; break; + case CAN_MODE_NO_ACK: mode = MP_QSTR_NO_ACK; break; + case CAN_MODE_NORMAL: mode = MP_QSTR_NORMAL; break; + default: mode = MP_QSTR_UNKNOWN; break; + } mp_printf(print, "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%u)", self->config->general->tx_io, self->config->general->rx_io, - self->config->baudrate, self->config->general->mode); + self->config->baudrate, mode); }else{ mp_printf(print, "CAN Device is not initialized"); } } - -/*void machine_can_trasmit(machine_hw_can_obj_t *self, uint32_t address, size_t length, mp_machine_can_buf_t *data) -{ - can_message_t tx_msg = {.data_length_code = length, .identifier = address, .flags = CAN_MSG_FLAG_SELF}; - for (uint8_t i=0; iconfig->initialized != true){ diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 70018c50acc0c..b3beef0d5203d 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -65,8 +65,8 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); -STATIC mp_obj_t machine_hw_can_read(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_write(mp_obj_t self_in, mp_obj_t address) ; +STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); STATIC mp_obj_t machine_hw_can_get_tec(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_get_rec(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in); @@ -76,10 +76,10 @@ STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in); //Python function declarations -MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_write_obj, machine_hw_can_write); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_read_obj, machine_hw_can_read); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deinit); MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); +MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_send); +MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_tec_obj, machine_hw_can_get_tec); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_rec_obj, machine_hw_can_get_rec); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_tx_waiting_messages_obj, machine_hw_can_get_tx_waiting_messages); @@ -95,8 +95,8 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { //CAN_FUNCTIONS { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_write_obj)}, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_hw_can_read_obj)}, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_get_tec), MP_ROM_PTR(&machine_hw_can_get_tec_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_get_rec), MP_ROM_PTR(&machine_hw_can_get_rec_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_get_tx_waiting_messages), MP_ROM_PTR(&machine_hw_can_get_tx_waiting_messages_obj)}, From e184574e7a8f158335707d14251b7bd49db33fa3 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 6 Oct 2019 21:17:39 +0200 Subject: [PATCH 08/62] improve object print --- ports/esp32/machine_can.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index c81a06373a03c..22fc4de7c10a9 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -183,8 +183,11 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p case CAN_MODE_NORMAL: mode = MP_QSTR_NORMAL; break; default: mode = MP_QSTR_UNKNOWN; break; } - mp_printf(print, "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%u)", self->config->general->tx_io, self->config->general->rx_io, - self->config->baudrate, mode); + mp_printf(print, + "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%q)", + self->config->general->tx_io, + self->config->general->rx_io, + self->config->baudrate, mode); }else{ mp_printf(print, "CAN Device is not initialized"); } From e4abe724f29854420981165c7acf9e0505602c8e Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 6 Oct 2019 21:18:04 +0200 Subject: [PATCH 09/62] remove prefix CAN_ from constants --- ports/esp32/machine_can.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index b3beef0d5203d..46dea4202f3e3 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -105,14 +105,14 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, //CAN_MODE - { MP_ROM_QSTR(MP_QSTR_CAN_MODE_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, - { MP_ROM_QSTR(MP_QSTR_CAN_MODE_NO_ACK), MP_ROM_INT(CAN_MODE_NO_ACK) }, - { MP_ROM_QSTR(MP_QSTR_CAN_MODE_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, + { MP_ROM_QSTR(MP_QSTR_MODE_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, + { MP_ROM_QSTR(MP_QSTR_MODE_NO_ACK), MP_ROM_INT(CAN_MODE_NO_ACK) }, + { MP_ROM_QSTR(MP_QSTR_MODE_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, //CAN_STATE - { MP_ROM_QSTR(MP_QSTR_CAN_STATE_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, - { MP_ROM_QSTR(MP_QSTR_CAN_STATE_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, - { MP_ROM_QSTR(MP_QSTR_CAN_STATE_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, - { MP_ROM_QSTR(MP_QSTR_CAN_STATE_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, + { MP_ROM_QSTR(MP_QSTR_STATE_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, + { MP_ROM_QSTR(MP_QSTR_STATE_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, + { MP_ROM_QSTR(MP_QSTR_STATE_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, + { MP_ROM_QSTR(MP_QSTR_STATE_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, //CAN_BAUDRATE { MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k) }, From 872ce7383709e9a8b320c96dd4d1ed8e315a5e91 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 8 Oct 2019 21:12:45 +0200 Subject: [PATCH 10/62] implementation of hardware filter --- ports/esp32/machine_can.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 22fc4de7c10a9..1631a3a975994 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -29,12 +29,12 @@ #include "mpconfigport.h" //Headers of ESP-IDF library -#include "soc/dport_reg.h" //FIXME: check if path is found. full path is ESPIDF/components/soc/esp32/include/soc/dport_reg.h +#include "soc/dport_reg.h" #include "driver/can.h" #include "esp_err.h" #include "esp_log.h" -#include "machine_can.h" +#include //#if MICROPY_HW_ENABLE_CAN @@ -231,16 +231,19 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ return machine_hw_can_init_helper(self, n_args - 1, args + 1, kw_args); } -// INTERNAL FUNCTION init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) +// INTERNAL FUNCTION init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5, filter_mask = 0xFFFFFFFF, filter_code = 0; single_filter = True) STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_mode, ARG_tx_queue, ARG_rx_queue}; + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_mode, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; static const mp_arg_t allowed_args[] = { - { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 4} }, - { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 2} }, - { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 500} }, - { MP_QSTR_mode, MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, - { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, + { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 4} }, + { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 2} }, + { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 500} }, + { MP_QSTR_mode, MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, + { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, + { MP_QSTR_filter_mask, MP_ARG_INT, {.u_int = 0xFFFFFFFF} }, + { MP_QSTR_filter_code, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_single_filter, MP_ARG_BOOL, {.u_bool = true} }, }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -261,6 +264,12 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t .alerts_enabled = CAN_ALERT_NONE, .clkout_divider = 0}; self->config->general = &g_config; + can_filter_config_t f_config = { + .acceptance_code = args[ARG_filter_code].u_int, + .acceptance_mask = args[ARG_filter_mask].u_int, + .single_filter = args[ARG_single_filter].u_bool + }; + self->config->filter = &f_config; switch ((int)args[ARG_baudrate].u_int){ case CAN_BAUDRATE_25k: From b2e7e23d4baa24cb9abdc1675ce30cd057d0fac1 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 8 Oct 2019 21:13:33 +0200 Subject: [PATCH 11/62] update includePath --- .vscode/c_cpp_properties.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000..5f0824b540e6b --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Mac", + "includePath": [ + "${workspaceFolder}/../esp-idf/components/**", + "${workspaceFolder}/ports/esp32/**", + "${workspaceFolder}/**" + ], + "defines": [], + "macFrameworkPath": [ + "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Frameworks" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "clang-x64" + } + ], + "version": 4 +} \ No newline at end of file From d175e3c04b63d2a7eab88aa60c5f962e67ca189d Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 10 Dec 2019 21:33:15 +0100 Subject: [PATCH 12/62] Changed author --- ports/esp32/machine_can.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 46dea4202f3e3..fa67df93cca41 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2014 Damien P. George + * Copyright (c) 2019 Musumeci Salvatore * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From 11cec6d6964fe02dcf115c69c3aaaa54a9b1a8ba Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 10 Dec 2019 21:52:37 +0100 Subject: [PATCH 13/62] STM32 Harmonization: rename get_state() to state(), add info() and any() functions and remove functions now included in info() --- ports/esp32/machine_can.c | 57 ++++++++++++++++++++++++++++----------- ports/esp32/machine_can.h | 27 +++++++------------ 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 1631a3a975994..081e3b159fb4d 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -38,6 +38,9 @@ //#if MICROPY_HW_ENABLE_CAN +// Internal Functions +STATIC can_state_t _machine_hw_can_get_state(); + // singleton CAN device object machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERAL_CONFIG_DEFAULT(2,4,0)), .filter = &((can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()), @@ -55,33 +58,54 @@ STATIC can_status_info_t _machine_hw_can_get_status(){ return status; } -STATIC can_state_t _machine_hw_can_get_state(){ - can_status_info_t status = _machine_hw_can_get_status(); - return status.state; } -STATIC mp_obj_t machine_hw_can_get_rx_waiting_messages(mp_obj_t self_in){ +// any(fifo) - return `True` if any message waiting on the FIFO, else `False` +STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in){ can_status_info_t status = _machine_hw_can_get_status(); - return mp_obj_new_int(status.msgs_to_rx); + if(mp_obj_new_int(status.msgs_to_rx)>0){ + return mp_const_true; + }else{ + return mp_const_false; + } } -STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in){ +// Get the state of the controller +STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) { can_status_info_t status = _machine_hw_can_get_status(); - return mp_obj_new_int(status.msgs_to_tx); + return mp_obj_new_int(status.state); } -STATIC mp_obj_t machine_hw_can_get_tec(mp_obj_t self_in){ +STATIC can_state_t _machine_hw_can_get_state(){ can_status_info_t status = _machine_hw_can_get_status(); - return mp_obj_new_int(status.tx_error_counter); + return status.state; } -STATIC mp_obj_t machine_hw_can_get_rec(mp_obj_t self_in){ +// Get info about error states and TX/RX buffers +STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { + //machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); //FIXME: Remove it if useless + mp_obj_list_t *list; + if (n_args == 1) { + list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); + } else { + if (!mp_obj_is_type(args[1], &mp_type_list)) { + mp_raise_TypeError(NULL); + } + list = MP_OBJ_TO_PTR(args[1]); + if (list->len < 8) { + mp_raise_ValueError(NULL); + } + } can_status_info_t status = _machine_hw_can_get_status(); - return mp_obj_new_int(status.rx_error_counter); -} - -STATIC mp_obj_t machine_hw_can_get_state(mp_obj_t self_in){ - return mp_obj_new_int(_machine_hw_can_get_state()); + list->items[0] = MP_OBJ_NEW_SMALL_INT(status.tx_error_counter); + list->items[1] = MP_OBJ_NEW_SMALL_INT(status.rx_error_counter); + //list->items[2] = MP_OBJ_NEW_SMALL_INT(self->num_error_warning); //FIXME: + //list->items[3] = MP_OBJ_NEW_SMALL_INT(self->num_error_passive); //FIXME: + //list->items[4] = MP_OBJ_NEW_SMALL_INT(self->num_bus_off); //FIXME: + list->items[5] = MP_OBJ_NEW_SMALL_INT(status.msgs_to_tx); + //list->items[6] = MP_OBJ_NEW_SMALL_INT(can->RF0R >> CAN_RF0R_FMP0_Pos & 3); //FIXME: + //list->items[7] = MP_OBJ_NEW_SMALL_INT(can->RF1R >> CAN_RF1R_FMP1_Pos & 3); //FIXME: + return MP_OBJ_FROM_PTR(list); } //Clear TX Queue @@ -137,7 +161,8 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ case ESP_ERR_INVALID_STATE: ESP_LOGW(DEVICE_NAME, "Device is not initialized"); break; case ESP_ERR_NOT_SUPPORTED: ESP_LOGW(DEVICE_NAME, "Listen Only Mode active"); break; } - return machine_hw_can_get_tx_waiting_messages(pos_args[0]); + + return 0; //machine_hw_can_get_tx_waiting_messages(pos_args[0]); }else{ ESP_LOGW(DEVICE_NAME, "Unable to send the message"); return MP_OBJ_NEW_SMALL_INT(-1); diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index fa67df93cca41..e65830d76a6ad 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -55,9 +55,6 @@ typedef struct _machine_can_obj_t { machine_can_config_t *config; } machine_can_obj_t; -//Internal functions -STATIC can_state_t _machine_hw_can_get_state(); - //Functions signature definition mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); @@ -66,27 +63,23 @@ STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args); +STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in); STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -STATIC mp_obj_t machine_hw_can_get_tec(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_get_rec(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_get_tx_waiting_messages(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_get_rx_waiting_messages(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_get_state(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in); //Python function declarations MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deinit); MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state); MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_send); MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_tec_obj, machine_hw_can_get_tec); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_rec_obj, machine_hw_can_get_rec); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_tx_waiting_messages_obj, machine_hw_can_get_tx_waiting_messages); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_rx_waiting_messages_obj, machine_hw_can_get_rx_waiting_messages); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_get_state_obj, machine_hw_can_get_state); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); +MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_any_obj, machine_hw_can_any); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); //Python objects list declaration STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { @@ -95,13 +88,11 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { //CAN_FUNCTIONS { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj) }, + { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj) }, + { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_get_tec), MP_ROM_PTR(&machine_hw_can_get_tec_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_get_rec), MP_ROM_PTR(&machine_hw_can_get_rec_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_get_tx_waiting_messages), MP_ROM_PTR(&machine_hw_can_get_tx_waiting_messages_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_get_rx_waiting_messages), MP_ROM_PTR(&machine_hw_can_get_rx_waiting_messages_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_get_state), MP_ROM_PTR(&machine_hw_can_get_state_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, //CAN_MODE From 1baa023e8bd60dd201b6709f18faaba82b8b7aba Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 10 Dec 2019 21:54:19 +0100 Subject: [PATCH 14/62] STM32 Harmonization: added restart() signature --- ports/esp32/machine_can.c | 4 ++++ ports/esp32/machine_can.h | 1 + 2 files changed, 5 insertions(+) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 081e3b159fb4d..a8df1cf6190bd 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -58,6 +58,10 @@ STATIC can_status_info_t _machine_hw_can_get_status(){ return status; } +// Force a software restart of the controller, to allow transmission after a bus error +STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ + mp_raise_NotImplementedError(""); //TODO: Implement this function + return self_in; } // any(fifo) - return `True` if any message waiting on the FIFO, else `False` diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index e65830d76a6ad..594c299da12bb 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -78,6 +78,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_send); MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); +MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_any_obj, machine_hw_can_any); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); From 175073d58c97be74b00eb59bd558662eba8b1b49 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 10 Dec 2019 21:54:51 +0100 Subject: [PATCH 15/62] STM32 Harmonization: move private methods in c file --- ports/esp32/machine_can.c | 10 ++++++++++ ports/esp32/machine_can.h | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index a8df1cf6190bd..57d86f412f13a 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -41,6 +41,16 @@ // Internal Functions STATIC can_state_t _machine_hw_can_get_state(); + +//Python object definition +const mp_obj_type_t machine_can_type = { + { &mp_type_type }, + .name = MP_QSTR_CAN, + .print = machine_hw_can_print, // give it a print-function + .make_new = machine_hw_can_make_new, // give it a constructor + .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members +}; + // singleton CAN device object machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERAL_CONFIG_DEFAULT(2,4,0)), .filter = &((can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()), diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 594c299da12bb..3b8499acdfaf8 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -117,13 +117,5 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); -//Python object definition -const mp_obj_type_t machine_can_type = { - { &mp_type_type }, - .name = MP_QSTR_CAN, - .print = machine_hw_can_print, // give it a print-function - .make_new = machine_hw_can_make_new, // give it a constructor - .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members -}; #endif // MICROPY_INCLUDED_ESP32_CAN_H From b8a5c0efe49694758b3e1ff58f2ece7366c0fe35 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 10 Dec 2019 21:55:30 +0100 Subject: [PATCH 16/62] Enabled compiler switch for module --- ports/esp32/machine_can.c | 4 ++-- ports/esp32/machine_can.h | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 57d86f412f13a..5f8bba2dab98e 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -36,7 +36,7 @@ #include -//#if MICROPY_HW_ENABLE_CAN +#if MICROPY_HW_ENABLE_CAN // Internal Functions STATIC can_state_t _machine_hw_can_get_state(); @@ -372,4 +372,4 @@ STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ return mp_const_true; } -//#endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file +#endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 3b8499acdfaf8..7c707c4fdb410 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -30,6 +30,8 @@ #include "py/obj.h" +#if MICROPY_HW_ENABLE_CAN + #define DEVICE_NAME "CAN" #define CAN_BAUDRATE_25k 25 @@ -118,4 +120,6 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); + +#endif // MICROPY_HW_ENABLE_CAN #endif // MICROPY_INCLUDED_ESP32_CAN_H From 195088fc4bf2873119f0daf5df582feb12e3ccaf Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 10 Dec 2019 21:57:03 +0100 Subject: [PATCH 17/62] Code Cleaning: Reordered the function sequence --- ports/esp32/machine_can.h | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 7c707c4fdb410..eb818aa905b5a 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -60,15 +60,20 @@ typedef struct _machine_can_obj_t { //Functions signature definition mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); -STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); -STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +//Micropython Generic API +//FIXME: check init arguments and harmonize with pyBoard as well as the outputs +STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in); +STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args); STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in); STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); + +//ESP32 specific API STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in); STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in); @@ -84,29 +89,33 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_any_obj, machine_hw_can_any); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); + //Python objects list declaration STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { //CAN_ATTRIBUTES { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, - //CAN_FUNCTIONS + //Micropython Generic API { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj) }, { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj) }, { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj) }, { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, + //ESP32 Specific API { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, - //CAN_MODE - { MP_ROM_QSTR(MP_QSTR_MODE_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, - { MP_ROM_QSTR(MP_QSTR_MODE_NO_ACK), MP_ROM_INT(CAN_MODE_NO_ACK) }, - { MP_ROM_QSTR(MP_QSTR_MODE_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, + + //CAN_MODE + { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, + { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK) }, + { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, //CAN_STATE - { MP_ROM_QSTR(MP_QSTR_STATE_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, - { MP_ROM_QSTR(MP_QSTR_STATE_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, - { MP_ROM_QSTR(MP_QSTR_STATE_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, - { MP_ROM_QSTR(MP_QSTR_STATE_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, + { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, + { MP_ROM_QSTR(MP_QSTR_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, + { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, + { MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, //CAN_BAUDRATE { MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k) }, From a03c23bbcba895530f34f21daef4c5c2ac4c1d88 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 10 Dec 2019 22:21:51 +0100 Subject: [PATCH 18/62] STM32 Harmonization: init() returns mp_const_none and raise exceptions instead Error Logs --- ports/esp32/machine_can.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 5f8bba2dab98e..37b222e50c55d 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -265,19 +265,19 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ const machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (self->config->initialized){ ESP_LOGW(DEVICE_NAME, "Device is already initialized"); - return mp_const_false; + return mp_const_none; } return machine_hw_can_init_helper(self, n_args - 1, args + 1, kw_args); } -// INTERNAL FUNCTION init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5, filter_mask = 0xFFFFFFFF, filter_code = 0; single_filter = True) +// INTERNAL FUNCTION init(mode, tx, rx, baudrate, tx_queue = 2, rx_queue = 5, filter_mask = 0xFFFFFFFF, filter_code = 0; single_filter = True) STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_mode, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; + enum { ARG_mode, ARG_tx, ARG_rx, ARG_baudrate, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; static const mp_arg_t allowed_args[] = { + { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 4} }, { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 2} }, { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 500} }, - { MP_QSTR_mode, MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, { MP_QSTR_filter_mask, MP_ARG_INT, {.u_int = 0xFFFFFFFF} }, @@ -287,12 +287,13 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - //Check if device was already configured + // Check if device was already configured if (self->config->initialized){ - ESP_LOGE(DEVICE_NAME, "Device is already initialized: unable to re-init"); + //TODO: check if this condition is redundant compared to init() + nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "CAN device is already initialized")); return mp_const_none; } - //Configure device + // Configure device can_general_config_t g_config = {.mode = args[ARG_mode].u_int, .tx_io = args[ARG_tx].u_int, .rx_io = args[ARG_rx].u_int, @@ -336,7 +337,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); break; default: - ESP_LOGE(DEVICE_NAME, "Unable to set baudrate"); + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Unable to set baudrate")); self->config->baudrate = 0; return mp_const_none; } @@ -344,9 +345,9 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t uint8_t status = can_driver_install(self->config->general, self->config->timing, self->config->filter); if (status != ESP_OK){ - ESP_LOGE(DEVICE_NAME, "Unable to init the device. ErrCode: %u",status); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, "Unable to init the device. ErrCode: %u",status)); }else if (can_start() != ESP_OK){ - ESP_LOGE(DEVICE_NAME, "Unable to start the device. ErrCode: %u",status); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, "Unable to start the device. ErrCode: %u",status)); }else{ self->config->initialized = true; } @@ -359,17 +360,17 @@ STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ const machine_can_obj_t *self = &machine_can_obj; if (self->config->initialized != true){ ESP_LOGW(DEVICE_NAME, "Device is not initialized"); - return mp_const_false; + return mp_const_none; } if(can_stop()!=ESP_OK){ - ESP_LOGW(DEVICE_NAME, "Unable to stop device"); + nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to stop the device")); } if (can_driver_uninstall() != ESP_OK){ - ESP_LOGW(DEVICE_NAME, "Unable to uninstall device"); - return mp_const_false; + nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to uninstall the device")); + return mp_const_none; } self->config->initialized = false; - return mp_const_true; + return mp_const_none; } #endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file From c0c8c8bffbd46a8f8f73dfc64db4c023fd5433ab Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 12 Dec 2019 22:48:40 +0100 Subject: [PATCH 19/62] STM32 Harmonization: Alignment of init function to pyCan. --- ports/esp32/machine_can.c | 82 +++++++++++++++++++++++++++------------ ports/esp32/machine_can.h | 13 +++++++ 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 37b222e50c55d..9ba8762452e53 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -20,8 +20,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include #include "py/obj.h" +#include "py/objarray.h" +#include "py/binary.h" #include "py/runtime.h" #include "py/builtin.h" #include "py/mphal.h" @@ -38,6 +41,12 @@ #if MICROPY_HW_ENABLE_CAN +//Default baudrate: 500kb +#define CAN_DEFAULT_PRESCALER (8) +#define CAN_DEFAULT_SJW (3) +#define CAN_DEFAULT_BS1 (15) +#define CAN_DEFAULT_BS2 (4) + // Internal Functions STATIC can_state_t _machine_hw_can_get_state(); @@ -57,7 +66,7 @@ machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERA .timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()), .initialized = false}; -STATIC const machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; +STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; //Return status information STATIC can_status_info_t _machine_hw_can_get_status(){ @@ -233,36 +242,41 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p } -// CAN(...) No argument to get the object -// Any argument will be used to init the device through init function +// CAN(bus, ...) No argument to get the object +//If no arguments are provided, the initialized object will be returned mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args){ - const machine_can_obj_t *self = &machine_can_obj; - - if (n_args > 0 || n_kw > 0) { + // check arguments + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + if (mp_obj_is_int(args[0])!=true){ + mp_raise_TypeError("bus must be a number"); + } + mp_uint_t can_idx = mp_obj_get_int(args[0]); + if (can_idx > 1) { //TODO: check naming convention + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN(%d) doesn't exist", can_idx)); + } + machine_can_obj_t *self = &machine_can_obj; + if (n_args > 1 || n_kw > 0) { if (self->config->initialized) { // The caller is requesting a reconfiguration of the hardware // this can only be done if the hardware is in init mode ESP_LOGW(DEVICE_NAME, "Device is going to be reconfigured"); machine_hw_can_deinit(&self); } - //TODO: implement callback - /*self->rxcallback0 = mp_const_none; - self->rxcallback1 = mp_const_none; - self->rx_state0 = RX_STATE_FIFO_EMPTY; - self->rx_state1 = RX_STATE_FIFO_EMPTY;*/ + self->rxcallback = mp_const_none; + self->rx_state = RX_STATE_FIFO_EMPTY; // start the peripheral mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - machine_hw_can_init_helper(self, n_args, args, &kw_args); + machine_hw_can_init_helper(self, n_args - 1, args + 1, &kw_args); } return MP_OBJ_FROM_PTR(self); } // init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - const machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); + machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (self->config->initialized){ ESP_LOGW(DEVICE_NAME, "Device is already initialized"); return mp_const_none; @@ -270,20 +284,28 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ return machine_hw_can_init_helper(self, n_args - 1, args + 1, kw_args); } -// INTERNAL FUNCTION init(mode, tx, rx, baudrate, tx_queue = 2, rx_queue = 5, filter_mask = 0xFFFFFFFF, filter_code = 0; single_filter = True) +// init(mode, extframe=False, baudrate=500, *) STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_mode, ARG_tx, ARG_rx, ARG_baudrate, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; + enum { ARG_mode, ARG_extframe, ARG_baudrate, ARG_prescaler, ARG_sjw, ARG_bs1, ARG_bs2, + ARG_auto_restart, ARG_tx_io, ARG_rx_io, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; static const mp_arg_t allowed_args[] = { { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, - { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 4} }, - { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 2} }, - { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 500} }, + { MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_prescaler, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_PRESCALER} }, + { MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_SJW} }, + { MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS1} }, + { MP_QSTR_bs2, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS2} }, + { MP_QSTR_auto_restart, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_tx_io, MP_ARG_INT, {.u_int = 4} }, + { MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2} }, { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, { MP_QSTR_filter_mask, MP_ARG_INT, {.u_int = 0xFFFFFFFF} }, { MP_QSTR_filter_code, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_single_filter, MP_ARG_BOOL, {.u_bool = true} }, }; + //FIXME: auto_restart // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -295,8 +317,8 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t } // Configure device can_general_config_t g_config = {.mode = args[ARG_mode].u_int, - .tx_io = args[ARG_tx].u_int, - .rx_io = args[ARG_rx].u_int, + .tx_io = args[ARG_tx_io].u_int, + .rx_io = args[ARG_rx_io].u_int, .clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED, .tx_queue_len = args[ARG_tx_queue].u_int, @@ -312,6 +334,14 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t self->config->filter = &f_config; switch ((int)args[ARG_baudrate].u_int){ + case 0: + self->config->timing = &((can_timing_config_t){ + .brp = args[ARG_prescaler].u_int, + .sjw = args[ARG_sjw].u_int, + .tseg_1 = args[ARG_bs1].u_int, + .tseg_2 = args[ARG_bs1].u_int, + .triple_sampling = false}); + break; case CAN_BAUDRATE_25k: self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()); break; @@ -345,13 +375,15 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t uint8_t status = can_driver_install(self->config->general, self->config->timing, self->config->filter); if (status != ESP_OK){ - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, "Unable to init the device. ErrCode: %u",status)); - }else if (can_start() != ESP_OK){ - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, "Unable to start the device. ErrCode: %u",status)); + mp_raise_OSError(-status); }else{ - self->config->initialized = true; + status = can_start() + if (status != ESP_OK){ + mp_raise_OSError(-status); + }else{ + self->config->initialized = true; + } } - return mp_const_none; } diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index eb818aa905b5a..e4275d79b24cd 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -55,8 +55,21 @@ typedef struct _machine_can_config_t { typedef struct _machine_can_obj_t { mp_obj_base_t base; machine_can_config_t *config; + mp_obj_t rxcallback; + byte rx_state; + bool extframe : 1; + uint16_t num_error_warning; //FIXME: populate this value somewhere + uint16_t num_error_passive; + uint16_t num_bus_off; } machine_can_obj_t; +typedef enum _rx_state_t { + RX_STATE_FIFO_EMPTY = 0, + RX_STATE_MESSAGE_PENDING, + RX_STATE_FIFO_FULL, + RX_STATE_FIFO_OVERFLOW, +} rx_state_t; + //Functions signature definition mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); From b362179c62847800d7731d245b7a22c9e38285f4 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 12 Dec 2019 22:50:24 +0100 Subject: [PATCH 20/62] STM32 Harmonization: Alignment of send(...) and recv(...) methods to pyBoard signature and return values --- ports/esp32/machine_can.c | 80 +++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 9ba8762452e53..5aae874708bc0 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -177,48 +177,70 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ tx_msg.data[i] = mp_obj_get_int(items[i]); } if (_machine_hw_can_get_state()==CAN_STATE_RUNNING){ - switch(can_transmit(&tx_msg, args[ARG_timeout].u_int)){ - case ESP_ERR_INVALID_ARG: ESP_LOGW(DEVICE_NAME, "Arguments are invalid"); break; - case ESP_ERR_TIMEOUT: //TX Queue is full - case ESP_FAIL: ESP_LOGW(DEVICE_NAME, "Message transmission failed"); break; - case ESP_ERR_INVALID_STATE: ESP_LOGW(DEVICE_NAME, "Device is not initialized"); break; - case ESP_ERR_NOT_SUPPORTED: ESP_LOGW(DEVICE_NAME, "Listen Only Mode active"); break; + int status = can_transmit(&tx_msg, args[ARG_timeout].u_int); + if (status!=ESP_OK){ + mp_raise_OSError(-status); } - - return 0; //machine_hw_can_get_tx_waiting_messages(pos_args[0]); + return mp_const_none; }else{ - ESP_LOGW(DEVICE_NAME, "Unable to send the message"); - return MP_OBJ_NEW_SMALL_INT(-1); + nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to send the message")); } } -// recv(timeout=5000) +// recv(list=None, *, timeout=5000) STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_timeout }; - mp_obj_t ret_obj = mp_obj_new_tuple(3, NULL); - mp_obj_t *items = ((mp_obj_tuple_t*)MP_OBJ_TO_PTR(ret_obj))->items; + enum { ARG_fifo, ARG_list, ARG_timeout }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_list, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, }; + + // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); can_message_t rx_message; - switch(can_receive(&rx_message, 1)){ - case ESP_OK: - items[0] = MP_OBJ_NEW_SMALL_INT(rx_message.identifier); - items[1] = mp_obj_new_bytes(rx_message.data, rx_message.data_length_code); - items[2] = MP_OBJ_NEW_SMALL_INT(rx_message.flags); - return ret_obj; - case ESP_ERR_TIMEOUT: - mp_raise_ValueError("Timeout"); - case ESP_ERR_INVALID_ARG: - mp_raise_ValueError("Invalid Args"); - case ESP_ERR_INVALID_STATE: - mp_raise_ValueError("Invalid State"); - default: - mp_raise_ValueError(""); - }; + int status = can_receive(&rx_message, 1); + if (status != ESP_OK){ + mp_raise_OSError(-status); + } + //TODO: manage callback + // Create the tuple, or get the list, that will hold the return values + // Also populate the fourth element, either a new bytes or reuse existing memoryview + mp_obj_t ret_obj = args[ARG_list].u_obj; + mp_obj_t *items; + if (ret_obj == mp_const_none){ + ret_obj = mp_obj_new_tuple(4, NULL); + items = ((mp_obj_tuple_t*)MP_OBJ_TO_PTR(ret_obj))->items; + items[3] = mp_obj_new_bytes(rx_message.data, rx_message.data_length_code); + } else { + // User should provide a list of length at least 4 to hold the values + if (!mp_obj_is_type(ret_obj, &mp_type_list)) { + mp_raise_TypeError(NULL); + } + mp_obj_list_t *list = MP_OBJ_TO_PTR(ret_obj); + if (list->len < 4) { + mp_raise_ValueError(NULL); + } + items = list->items; + // Fourth element must be a memoryview which we assume points to a + // byte-like array which is large enough, and then we resize it inplace + if (!mp_obj_is_type(items[3], &mp_type_memoryview)) { + mp_raise_TypeError(NULL); + } + mp_obj_array_t *mv = MP_OBJ_TO_PTR(items[3]); + if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) + || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))) { + mp_raise_ValueError(NULL); + } + mv->len = rx_message.data_length_code; + memcpy(mv->items, rx_message.data, rx_message.data_length_code); + + } + items[0] = MP_OBJ_NEW_SMALL_INT(rx_message.identifier); + items[1] = rx_message.flags && CAN_MSG_FLAG_RTR > 0 ? mp_const_true : mp_const_false; + items[2] = 0; //TODO: check if Filter Mailbox Index is available for ESP32 + return ret_obj; } STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { From 02cadd0214771c95d7ea0004f36f89f380f2d297 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 12 Dec 2019 22:58:51 +0100 Subject: [PATCH 21/62] removed auto_restart option since the esp32 framework doesn't have this feature. It could be implemented in the feature if needed --- ports/esp32/machine_can.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 5aae874708bc0..d684a8bce34a4 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -309,7 +309,7 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ // init(mode, extframe=False, baudrate=500, *) STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_extframe, ARG_baudrate, ARG_prescaler, ARG_sjw, ARG_bs1, ARG_bs2, - ARG_auto_restart, ARG_tx_io, ARG_rx_io, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; + ARG_tx_io, ARG_rx_io, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; static const mp_arg_t allowed_args[] = { { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, { MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} }, @@ -318,7 +318,6 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t { MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_SJW} }, { MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS1} }, { MP_QSTR_bs2, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS2} }, - { MP_QSTR_auto_restart, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_tx_io, MP_ARG_INT, {.u_int = 4} }, { MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2} }, { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, @@ -327,7 +326,6 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t { MP_QSTR_filter_code, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_single_filter, MP_ARG_BOOL, {.u_bool = true} }, }; - //FIXME: auto_restart // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -399,7 +397,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t if (status != ESP_OK){ mp_raise_OSError(-status); }else{ - status = can_start() + status = can_start(); if (status != ESP_OK){ mp_raise_OSError(-status); }else{ From 82017a9f9d0035449c875820f1f64cab984822e5 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Fri, 13 Dec 2019 08:03:30 +0100 Subject: [PATCH 22/62] Added signature for RX Callback; currently this method is not implemented --- ports/esp32/machine_can.c | 18 ++++++++++++++++++ ports/esp32/machine_can.h | 4 +++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index d684a8bce34a4..2eecd32048b7f 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -407,6 +407,24 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t return mp_const_none; } +STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in) { + mp_raise_NotImplementedError("IRQ not supported yet"); + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (callback_in == mp_const_none) { + self->rxcallback = mp_const_none; + } else if (self->rxcallback != mp_const_none) { + // Rx call backs has already been initialized + // only the callback function should be changed + self->rxcallback = callback_in; + // TODO: disable interrupt + } else if (mp_obj_is_callable(callback_in)) { + self->rxcallback = callback_in; + // TODO: set interrupt + } + return mp_const_none; +} + //deinit() STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ const machine_can_obj_t *self = &machine_can_obj; diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index e4275d79b24cd..3e05e204f16a6 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -85,6 +85,7 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args); STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in); STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in); //ESP32 specific API STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in); @@ -101,7 +102,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clea MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_any_obj, machine_hw_can_any); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); - +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); //Python objects list declaration STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { @@ -116,6 +117,7 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, + { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj) }, //ESP32 Specific API { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, From a65026af61884096a8412db8167a4ce2b69dcef3 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Fri, 13 Dec 2019 08:32:00 +0100 Subject: [PATCH 23/62] Python Interface has been moved from header to source --- ports/esp32/machine_can.c | 167 ++++++++++++++++++++++++++------------ ports/esp32/machine_can.h | 76 +---------------- 2 files changed, 116 insertions(+), 127 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 2eecd32048b7f..81c957844294c 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -49,16 +49,12 @@ // Internal Functions STATIC can_state_t _machine_hw_can_get_state(); +mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); +STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); + -//Python object definition -const mp_obj_type_t machine_can_type = { - { &mp_type_type }, - .name = MP_QSTR_CAN, - .print = machine_hw_can_print, // give it a print-function - .make_new = machine_hw_can_make_new, // give it a constructor - .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members -}; // singleton CAN device object machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERAL_CONFIG_DEFAULT(2,4,0)), @@ -82,6 +78,7 @@ STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ mp_raise_NotImplementedError(""); //TODO: Implement this function return self_in; } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); // any(fifo) - return `True` if any message waiting on the FIFO, else `False` STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in){ @@ -92,6 +89,7 @@ STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in){ return mp_const_false; } } +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_any_obj, machine_hw_can_any); // Get the state of the controller STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) { @@ -103,6 +101,7 @@ STATIC can_state_t _machine_hw_can_get_state(){ can_status_info_t status = _machine_hw_can_get_status(); return status.state; } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state); // Get info about error states and TX/RX buffers STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { @@ -130,15 +129,20 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { //list->items[7] = MP_OBJ_NEW_SMALL_INT(can->RF1R >> CAN_RF1R_FMP1_Pos & 3); //FIXME: return MP_OBJ_FROM_PTR(list); } +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); //Clear TX Queue STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_transmit_queue()==ESP_OK); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); + //Clear RX Queue STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_receive_queue()==ESP_OK); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); + //send([data], id, timeout=0, rtr=False, self_flag=False) STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -186,6 +190,7 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to send the message")); } } +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_send); // recv(list=None, *, timeout=5000) STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -242,6 +247,27 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ items[2] = 0; //TODO: check if Filter Mailbox Index is available for ESP32 return ret_obj; } +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); + +STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in) { + mp_raise_NotImplementedError("IRQ not supported yet"); + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (callback_in == mp_const_none) { + self->rxcallback = mp_const_none; + } else if (self->rxcallback != mp_const_none) { + // Rx call backs has already been initialized + // only the callback function should be changed + self->rxcallback = callback_in; + // TODO: disable interrupt + } else if (mp_obj_is_callable(callback_in)) { + self->rxcallback = callback_in; + // TODO: set interrupt + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); + STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -264,6 +290,37 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p } + +// init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) +STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (self->config->initialized){ + ESP_LOGW(DEVICE_NAME, "Device is already initialized"); + return mp_const_none; + } + return machine_hw_can_init_helper(self, n_args - 1, args + 1, kw_args); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); + +//deinit() +STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ + const machine_can_obj_t *self = &machine_can_obj; + if (self->config->initialized != true){ + ESP_LOGW(DEVICE_NAME, "Device is not initialized"); + return mp_const_none; + } + if(can_stop()!=ESP_OK){ + nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to stop the device")); + } + if (can_driver_uninstall() != ESP_OK){ + nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to uninstall the device")); + return mp_const_none; + } + self->config->initialized = false; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deinit); + // CAN(bus, ...) No argument to get the object //If no arguments are provided, the initialized object will be returned mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, @@ -296,16 +353,6 @@ mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(self); } -// init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) -STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (self->config->initialized){ - ESP_LOGW(DEVICE_NAME, "Device is already initialized"); - return mp_const_none; - } - return machine_hw_can_init_helper(self, n_args - 1, args + 1, kw_args); -} - // init(mode, extframe=False, baudrate=500, *) STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_extframe, ARG_baudrate, ARG_prescaler, ARG_sjw, ARG_bs1, ARG_bs2, @@ -407,40 +454,56 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t return mp_const_none; } -STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in) { - mp_raise_NotImplementedError("IRQ not supported yet"); - machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (callback_in == mp_const_none) { - self->rxcallback = mp_const_none; - } else if (self->rxcallback != mp_const_none) { - // Rx call backs has already been initialized - // only the callback function should be changed - self->rxcallback = callback_in; - // TODO: disable interrupt - } else if (mp_obj_is_callable(callback_in)) { - self->rxcallback = callback_in; - // TODO: set interrupt - } - return mp_const_none; -} -//deinit() -STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ - const machine_can_obj_t *self = &machine_can_obj; - if (self->config->initialized != true){ - ESP_LOGW(DEVICE_NAME, "Device is not initialized"); - return mp_const_none; - } - if(can_stop()!=ESP_OK){ - nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to stop the device")); - } - if (can_driver_uninstall() != ESP_OK){ - nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to uninstall the device")); - return mp_const_none; - } - self->config->initialized = false; - return mp_const_none; -} +STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { + //CAN_ATTRIBUTES + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, + //Micropython Generic API + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj) }, + { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj) }, + { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj) }, + { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, + /* + { MP_ROM_QSTR(MP_QSTR_initfilterbanks), MP_ROM_PTR(&pyb_can_initfilterbanks_obj) }, + { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&pyb_can_setfilter_obj) }, + { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&pyb_can_clearfilter_obj) }, + */ + { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj) }, + //ESP32 Specific API + { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, + + //CAN_MODE + { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, + { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK) }, + { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, + //CAN_STATE + { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, + { MP_ROM_QSTR(MP_QSTR_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, + { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, + { MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, + //CAN_BAUDRATE + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_100k), MP_ROM_INT(CAN_BAUDRATE_100k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(CAN_BAUDRATE_125k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(CAN_BAUDRATE_250k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k) }, + { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); +//Python object definition +const mp_obj_type_t machine_can_type = { + { &mp_type_type }, + .name = MP_QSTR_CAN, + .print = machine_hw_can_print, // give it a print-function + .make_new = machine_hw_can_make_new, // give it a constructor + .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members +}; #endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 3e05e204f16a6..f1d0a22633a10 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -43,7 +43,6 @@ #define CAN_BAUDRATE_800k 800 #define CAN_BAUDRATE_1M 1000 - typedef struct _machine_can_config_t { const can_timing_config_t *timing; const can_filter_config_t *filter; @@ -70,80 +69,7 @@ typedef enum _rx_state_t { RX_STATE_FIFO_OVERFLOW, } rx_state_t; -//Functions signature definition -mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); -STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); - -//Micropython Generic API -//FIXME: check init arguments and harmonize with pyBoard as well as the outputs -STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); -STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args); -STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in); -STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in); - -//ESP32 specific API -STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in); -STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in); - -//Python function declarations -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deinit); -MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state); -MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_send); -MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); -MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); -MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_any_obj, machine_hw_can_any); -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); -STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); - -//Python objects list declaration -STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { - //CAN_ATTRIBUTES - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, - //Micropython Generic API - { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj) }, - { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj) }, - { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj) }, - { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, - { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, - { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj) }, - //ESP32 Specific API - { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, - - //CAN_MODE - { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, - { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK) }, - { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, - //CAN_STATE - { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, - { MP_ROM_QSTR(MP_QSTR_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, - { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, - { MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, - //CAN_BAUDRATE - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_100k), MP_ROM_INT(CAN_BAUDRATE_100k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(CAN_BAUDRATE_125k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(CAN_BAUDRATE_250k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M) }, -}; -STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); - - +extern const mp_obj_type_t machine_can_type; #endif // MICROPY_HW_ENABLE_CAN #endif // MICROPY_INCLUDED_ESP32_CAN_H From de8c71b6a6466f5e6275613f0bde4594949c4718 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Fri, 13 Dec 2019 08:34:26 +0100 Subject: [PATCH 24/62] Removed redundant function --- ports/esp32/machine_can.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 81c957844294c..da72ded6caeb3 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -48,7 +48,6 @@ #define CAN_DEFAULT_BS2 (4) // Internal Functions -STATIC can_state_t _machine_hw_can_get_state(); mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); @@ -64,7 +63,7 @@ machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERA STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; -//Return status information +//INTERNAL FUNCTION Return status information STATIC can_status_info_t _machine_hw_can_get_status(){ can_status_info_t status; if(can_get_status_info(&status)!=ESP_OK){ @@ -96,11 +95,6 @@ STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) { can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_int(status.state); } - -STATIC can_state_t _machine_hw_can_get_state(){ - can_status_info_t status = _machine_hw_can_get_status(); - return status.state; -} STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state); // Get info about error states and TX/RX buffers @@ -180,7 +174,7 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ for (uint8_t i=0; i Date: Fri, 13 Dec 2019 08:37:00 +0100 Subject: [PATCH 25/62] beautify --- ports/esp32/machine_can.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index da72ded6caeb3..43b045fa869d8 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -31,7 +31,7 @@ #include "py/mperrno.h" #include "mpconfigport.h" -//Headers of ESP-IDF library +// Headers of ESP-IDF library #include "soc/dport_reg.h" #include "driver/can.h" #include "esp_err.h" @@ -41,20 +41,18 @@ #if MICROPY_HW_ENABLE_CAN -//Default baudrate: 500kb +// Default baudrate: 500kb #define CAN_DEFAULT_PRESCALER (8) #define CAN_DEFAULT_SJW (3) #define CAN_DEFAULT_BS1 (15) #define CAN_DEFAULT_BS2 (4) + // Internal Functions mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); - - - // singleton CAN device object machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERAL_CONFIG_DEFAULT(2,4,0)), .filter = &((can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()), @@ -63,7 +61,7 @@ machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERA STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; -//INTERNAL FUNCTION Return status information +// INTERNAL FUNCTION Return status information STATIC can_status_info_t _machine_hw_can_get_status(){ can_status_info_t status; if(can_get_status_info(&status)!=ESP_OK){ @@ -125,20 +123,20 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); -//Clear TX Queue +// Clear TX Queue STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_transmit_queue()==ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); -//Clear RX Queue +// Clear RX Queue STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_receive_queue()==ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); -//send([data], id, timeout=0, rtr=False, self_flag=False) +// send([data], id, timeout=0, rtr=False, self_flag=False) STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_data, ARG_id, ARG_timeout, ARG_rtr, ARG_self }; static const mp_arg_t allowed_args[] = { @@ -296,7 +294,7 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); -//deinit() +// deinit() STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ const machine_can_obj_t *self = &machine_can_obj; if (self->config->initialized != true){ @@ -316,7 +314,7 @@ STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deinit); // CAN(bus, ...) No argument to get the object -//If no arguments are provided, the initialized object will be returned +// If no arguments are provided, the initialized object will be returned mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args){ // check arguments @@ -450,9 +448,9 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { - //CAN_ATTRIBUTES + // CAN_ATTRIBUTES { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, - //Micropython Generic API + // Micropython Generic API { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj) }, @@ -467,20 +465,20 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&pyb_can_clearfilter_obj) }, */ { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj) }, - //ESP32 Specific API + // ESP32 Specific API { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, - //CAN_MODE + // CAN_MODE { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK) }, { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, - //CAN_STATE + // CAN_STATE { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, { MP_ROM_QSTR(MP_QSTR_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, { MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, - //CAN_BAUDRATE + // CAN_BAUDRATE { MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_100k), MP_ROM_INT(CAN_BAUDRATE_100k) }, @@ -492,7 +490,7 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); -//Python object definition +// Python object definition const mp_obj_type_t machine_can_type = { { &mp_type_type }, .name = MP_QSTR_CAN, From bbdfa6f72d3c40d43e83b247937ce63ab15cbeed Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Fri, 13 Dec 2019 09:52:03 +0100 Subject: [PATCH 26/62] STM32 Harmonization: implemented same CAN_MODE --- ports/esp32/machine_can.c | 21 +++++++++++++-------- ports/esp32/machine_can.h | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 43b045fa869d8..ffebfc44fc469 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -136,7 +136,7 @@ STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); -// send([data], id, timeout=0, rtr=False, self_flag=False) +// send([data], id, *) STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_data, ARG_id, ARG_timeout, ARG_rtr, ARG_self }; static const mp_arg_t allowed_args[] = { @@ -144,10 +144,10 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_self_flag, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; // parse args + machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args-1, pos_args+1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -159,15 +159,17 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ mp_raise_ValueError("CAN data field too long"); } uint8_t flags = (args[ARG_rtr].u_bool==true ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); - if (args[ARG_id].u_int>0x7ff){ + uint32_t id = args[ARG_id].u_int; + if (self->extframe){ flags += CAN_MSG_FLAG_EXTD; + id &= 0x1FFFFFFF; } - if (args[ARG_self].u_bool){ + if (self->loopback){ flags += CAN_MSG_FLAG_SELF; + id &= 0x1FF; } - can_message_t tx_msg = {.data_length_code = length, - .identifier = args[ARG_id].u_int & 0x1FFFFFFF, + .identifier = id, .flags = flags}; for (uint8_t i=0; iconfig->general = &g_config; + self->loopback = (args[ARG_mode] && 0x10 > 0) can_filter_config_t f_config = { .acceptance_code = args[ARG_filter_code].u_int, .acceptance_mask = args[ARG_filter_mask].u_int, @@ -471,7 +474,9 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { // CAN_MODE { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, + { MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_NORMAL | 0x10) }, { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK) }, + { MP_ROM_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_ROM_INT(CAN_MODE_NO_ACK | 0x10) }, { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, // CAN_STATE { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index f1d0a22633a10..3e91588682ab0 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -57,6 +57,7 @@ typedef struct _machine_can_obj_t { mp_obj_t rxcallback; byte rx_state; bool extframe : 1; + bool loopback : 1; uint16_t num_error_warning; //FIXME: populate this value somewhere uint16_t num_error_passive; uint16_t num_bus_off; From cf0f92aea56b7bca0622e1a36bd81f1d0ad182b0 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 17 Dec 2019 23:06:55 +0100 Subject: [PATCH 27/62] minor fix --- ports/esp32/machine_can.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index ffebfc44fc469..8eb936508b42e 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -64,8 +64,9 @@ STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_co // INTERNAL FUNCTION Return status information STATIC can_status_info_t _machine_hw_can_get_status(){ can_status_info_t status; - if(can_get_status_info(&status)!=ESP_OK){ - mp_raise_ValueError("Unable to get CAN status"); + uint8_t err_code = can_get_status_info(&status); + if(err_code!=ESP_OK){ + mp_raise_OSError(-err_code); } return status; } @@ -97,7 +98,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state) // Get info about error states and TX/RX buffers STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { - //machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); //FIXME: Remove it if useless mp_obj_list_t *list; if (n_args == 1) { list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); @@ -113,9 +113,9 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { can_status_info_t status = _machine_hw_can_get_status(); list->items[0] = MP_OBJ_NEW_SMALL_INT(status.tx_error_counter); list->items[1] = MP_OBJ_NEW_SMALL_INT(status.rx_error_counter); - //list->items[2] = MP_OBJ_NEW_SMALL_INT(self->num_error_warning); //FIXME: - //list->items[3] = MP_OBJ_NEW_SMALL_INT(self->num_error_passive); //FIXME: - //list->items[4] = MP_OBJ_NEW_SMALL_INT(self->num_bus_off); //FIXME: + list->items[2] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_error_warning + list->items[3] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_error_passive + list->items[4] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_bus_off list->items[5] = MP_OBJ_NEW_SMALL_INT(status.msgs_to_tx); //list->items[6] = MP_OBJ_NEW_SMALL_INT(can->RF0R >> CAN_RF0R_FMP0_Pos & 3); //FIXME: //list->items[7] = MP_OBJ_NEW_SMALL_INT(can->RF1R >> CAN_RF1R_FMP1_Pos & 3); //FIXME: @@ -303,12 +303,13 @@ STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ ESP_LOGW(DEVICE_NAME, "Device is not initialized"); return mp_const_none; } - if(can_stop()!=ESP_OK){ - nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to stop the device")); + uint8_t status = can_stop(); + if(status!=ESP_OK){ + mp_raise_OSError(-status); } - if (can_driver_uninstall() != ESP_OK){ - nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "Unable to uninstall the device")); - return mp_const_none; + status = can_driver_uninstall(); + if (status != ESP_OK){ + mp_raise_OSError(-status); } self->config->initialized = false; return mp_const_none; @@ -429,7 +430,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); break; default: - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Unable to set baudrate")); + mp_raise_ValueError("Unable to set baudrate"); self->config->baudrate = 0; return mp_const_none; } From 9e00b411afb231146162b3ff2a315fc45a5a00df Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 17 Dec 2019 23:51:47 +0100 Subject: [PATCH 28/62] manage flags for loopback and extframe --- ports/esp32/machine_can.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 8eb936508b42e..6f9464a99caec 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -50,7 +50,7 @@ // Internal Functions mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); -STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); +STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); // singleton CAN device object @@ -349,7 +349,7 @@ mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, } // init(mode, extframe=False, baudrate=500, *) -STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_extframe, ARG_baudrate, ARG_prescaler, ARG_sjw, ARG_bs1, ARG_bs2, ARG_tx_io, ARG_rx_io, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; static const mp_arg_t allowed_args[] = { @@ -388,7 +388,8 @@ STATIC mp_obj_t machine_hw_can_init_helper(const machine_can_obj_t *self, size_t .alerts_enabled = CAN_ALERT_NONE, .clkout_divider = 0}; self->config->general = &g_config; - self->loopback = (args[ARG_mode] && 0x10 > 0) + self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); + self->extframe = args[ARG_extframe].u_bool; can_filter_config_t f_config = { .acceptance_code = args[ARG_filter_code].u_int, .acceptance_mask = args[ARG_filter_mask].u_int, From 8e45d1173669cdfe49474b3eb36e63a3e0b71bd7 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 17 Dec 2019 23:52:45 +0100 Subject: [PATCH 29/62] removed unused input variable from any() --- ports/esp32/machine_can.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 6f9464a99caec..255ed7064b380 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -78,16 +78,12 @@ STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); -// any(fifo) - return `True` if any message waiting on the FIFO, else `False` -STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in, mp_obj_t fifo_in){ +// any() - return `True` if any message waiting, else `False` +STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in){ can_status_info_t status = _machine_hw_can_get_status(); - if(mp_obj_new_int(status.msgs_to_rx)>0){ - return mp_const_true; - }else{ - return mp_const_false; - } + return mp_obj_new_bool((status.msgs_to_rx)>0); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_any_obj, machine_hw_can_any); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_any_obj, machine_hw_can_any); // Get the state of the controller STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) { From 215dd81ed29a5473e8b7bb2cc21ccd93549b7a8e Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 17 Dec 2019 23:53:02 +0100 Subject: [PATCH 30/62] bugfix --- ports/esp32/machine_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 255ed7064b380..4f108d589e594 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -184,7 +184,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_sen // recv(list=None, *, timeout=5000) STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_fifo, ARG_list, ARG_timeout }; + enum { ARG_list, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_list, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, From 9d0190851fff92f50afac566d34fcecc7bcf5feb Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 17 Dec 2019 23:53:15 +0100 Subject: [PATCH 31/62] Improved print function --- ports/esp32/machine_can.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 4f108d589e594..69de73a279338 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -270,10 +270,13 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p default: mode = MP_QSTR_UNKNOWN; break; } mp_printf(print, - "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%q)", + "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%q, loopback=%u, extframe=%u)", self->config->general->tx_io, self->config->general->rx_io, - self->config->baudrate, mode); + self->config->baudrate, + mode, + self->loopback, + self->extframe); }else{ mp_printf(print, "CAN Device is not initialized"); } From 7fed70972c8b37914b272f44b9693a11723a2cf0 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Wed, 18 Dec 2019 23:35:00 +0100 Subject: [PATCH 32/62] Implementation of restart function --- ports/esp32/machine_can.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 69de73a279338..493ef0d8656f9 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -73,8 +73,16 @@ STATIC can_status_info_t _machine_hw_can_get_status(){ // Force a software restart of the controller, to allow transmission after a bus error STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ - mp_raise_NotImplementedError(""); //TODO: Implement this function - return self_in; + uint32_t status = can_initiate_recovery(); + if (status != ESP_OK){ + mp_raise_OSError(-status); + } + mp_hal_delay_ms(200); // FIXME: replace it with a smarter solution + status = can_start(); + if (status != ESP_OK){ + mp_raise_OSError(-status); + } + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); From 38b2e6cca5c0838bc4e617341252ecf7489ef279 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Wed, 18 Dec 2019 23:35:39 +0100 Subject: [PATCH 33/62] data type bugfix --- ports/esp32/machine_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 493ef0d8656f9..f8dd96e5a731e 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -310,7 +310,7 @@ STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ ESP_LOGW(DEVICE_NAME, "Device is not initialized"); return mp_const_none; } - uint8_t status = can_stop(); + uint32_t status = can_stop(); if(status!=ESP_OK){ mp_raise_OSError(-status); } @@ -444,7 +444,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg } self->config->baudrate = args[ARG_baudrate].u_int; - uint8_t status = can_driver_install(self->config->general, self->config->timing, self->config->filter); + uint32_t status = can_driver_install(self->config->general, self->config->timing, self->config->filter); if (status != ESP_OK){ mp_raise_OSError(-status); }else{ From bb0ed63be37dc50891bb00c6343ab74a9e42fc1e Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 19 Dec 2019 22:20:52 +0100 Subject: [PATCH 34/62] Added alert function --- ports/esp32/machine_can.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index f8dd96e5a731e..5a7473c8195cc 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -127,6 +127,16 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); +STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in){ + uint32_t alerts; + uint32_t status = can_read_alerts(&alerts, 0); + if (status != ESP_OK){ + mp_raise_OSError(-status); + } + return mp_obj_new_int(alerts); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_alert_obj, machine_hw_can_alert); + // Clear TX Queue STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_transmit_queue()==ESP_OK); @@ -392,7 +402,8 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg .bus_off_io = CAN_IO_UNUSED, .tx_queue_len = args[ARG_tx_queue].u_int, .rx_queue_len = args[ARG_rx_queue].u_int, - .alerts_enabled = CAN_ALERT_NONE, + .alerts_enabled = CAN_ALERT_AND_LOG || CAN_ALERT_BELOW_ERR_WARN || CAN_ALERT_ERR_ACTIVE || CAN_ALERT_BUS_RECOVERED || + CAN_ALERT_ABOVE_ERR_WARN || CAN_ALERT_BUS_ERROR || CAN_ALERT_ERR_PASS || CAN_ALERT_BUS_OFF, .clkout_divider = 0}; self->config->general = &g_config; self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); @@ -481,6 +492,7 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj)}, // CAN_MODE { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, { MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_NORMAL | 0x10) }, @@ -501,6 +513,20 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M) }, + // CAN_ALERT + { MP_ROM_QSTR(MP_QSTR_ALERT_TX_IDLE), MP_ROM_INT(CAN_ALERT_TX_IDLE) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_TX_SUCCESS), MP_ROM_INT(CAN_ALERT_TX_SUCCESS) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_BELOW_ERR_WARN), MP_ROM_INT(CAN_ALERT_BELOW_ERR_WARN) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_ERR_ACTIVE), MP_ROM_INT(CAN_ALERT_ERR_ACTIVE) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_RECOVERY_IN_PROGRESS), MP_ROM_INT(CAN_ALERT_RECOVERY_IN_PROGRESS) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_BUS_RECOVERED), MP_ROM_INT(CAN_ALERT_BUS_RECOVERED) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_ARB_LOST), MP_ROM_INT(CAN_ALERT_ARB_LOST) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_ABOVE_ERR_WARN), MP_ROM_INT(CAN_ALERT_ABOVE_ERR_WARN) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_BUS_ERROR), MP_ROM_INT(CAN_ALERT_BUS_ERROR) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_TX_FAILED), MP_ROM_INT(CAN_ALERT_TX_FAILED) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_RX_QUEUE_FULL), MP_ROM_INT(CAN_ALERT_RX_QUEUE_FULL) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_ERR_PASS), MP_ROM_INT(CAN_ALERT_ERR_PASS) }, + { MP_ROM_QSTR(MP_QSTR_ALERT_BUS_OFF), MP_ROM_INT(CAN_ALERT_BUS_OFF) } }; STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); From a508f4cb33acbf506e56e9abedf42582fcdb7d30 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 19 Dec 2019 23:01:04 +0100 Subject: [PATCH 35/62] Added docs for ESP32 CAN --- docs/library/esp32.CAN.rst | 326 +++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 docs/library/esp32.CAN.rst diff --git a/docs/library/esp32.CAN.rst b/docs/library/esp32.CAN.rst new file mode 100644 index 0000000000000..e17e9f4a5598f --- /dev/null +++ b/docs/library/esp32.CAN.rst @@ -0,0 +1,326 @@ +.. currentmodule:: esp32 +.. _esp32.CAN: + +class CAN -- controller area network communication bus +====================================================== + +CAN implements the standard CAN communications protocol. At +the physical level it consists of 2 lines: RX and TX. Note that +to connect the ESP32 to a CAN bus you must use a CAN transceiver +to convert the CAN logic signals from the ESP32 to the correct +voltage levels on the bus. + +Example usage (works without anything connected):: + + from machine import CAN + can = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=CAN.BAUDRATE_500k) + can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) # set a filter to receive messages with id=123, 124, 125 and 126 + can.send([1,2,3], 123) # send a message with id 123 + can.recv() # receive message + + +Constructors +------------ + +.. class:: machine.CAN(bus, ...) + + Construct a CAN object on the given bus. *bus* can be 0 or 1 (for compatibility with STM32). It will point at the same device + With no additional parameters, the CAN object is created but not + initialised (it has the settings from the last initialisation of + the bus, if any). If extra arguments are given, the bus is initialised. + See :meth:`CAN.init` for parameters of initialisation. + + The physical pins of the CAN bus can be assigned during init. + +Class Methods +------------- +.. classmethod:: CAN.initfilterbanks(nr) TODO: + + Reset and disable all filter banks and assign how many banks should be available for CAN(1). + + STM32F405 has 28 filter banks that are shared between the two available CAN bus controllers. + This function configures how many filter banks should be assigned to each. *nr* is the number of banks + that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2). + At boot, 14 banks are assigned to each controller. + +Methods +------- + +.. method:: CAN.init(mode, extframe=False, baudrate, prescaler, \*, sjw=1, bs1=6, bs2=8, auto_restart=False) + + Initialise the CAN bus with the given parameters: + + - *mode* is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK + - if *extframe* is True then the bus uses extended identifiers in the frames + (29 bits); otherwise it uses standard 11 bit identifiers + - *baudrate* is used to define a standard speed. If it is defined, the *prescaler*, *sjw*, *bs1*, *bs2* + will be ignored. Standard speeds are available as CAN.BAUDRATE_* + - *prescaler* is used to set the duration of 1 time quanta; the time quanta + will be the input clock (PCLK1, see :meth:`pyb.freq()`) divided by the prescaler + - *sjw* is the resynchronisation jump width in units of the time quanta; + it can be 1, 2, 3, 4 + - *bs1* defines the location of the sample point in units of the time quanta; + it can be between 1 and 1024 inclusive + - *bs2* defines the location of the transmit point in units of the time quanta; + it can be between 1 and 16 inclusive + - *tx_io* defines the gpio used for transmission + - *rx_io* defines the gpio used for receiving + - *tx_queue* defines the number of waiting tx messages can be stored + - *rx_queue* defines the number of received messages can be stored + - *auto_restart* sets whether the controller will automatically try and restart + communications after entering the bus-off state; if this is disabled then + :meth:`~CAN.restart()` can be used to leave the bus-off state. + This parameter is currently not implemented and it must be set to False + + +.. method:: CAN.deinit() + + Turn off the CAN bus. + +.. method:: CAN.restart() + + Force a software restart of the CAN controller without resetting its + configuration. + + If the controller enters the bus-off state then it will no longer participate + in bus activity. If the controller is not configured to automatically restart + (see :meth:`~CAN.init()`) then this method can be used to trigger a restart, + and the controller will follow the CAN protocol to leave the bus-off state and + go into the error active state. + +.. method:: CAN.state() + + Return the state of the controller. The return value can be one of: + + - ``CAN.STOPPED`` -- the controller is completely off and reset; + - ``CAN.ERROR_ACTIVE`` -- the controller is on and in the Error Active state + (both TEC and REC are less than 96); + - ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity + (TEC overflowed beyond 255). + - ``CAN.RECOVERING`` -- the controller is under recover from bus-off state; + + +.. method:: CAN.info([list]) + + Get information about the controller's error states and TX and RX buffers. + If *list* is provided then it should be a list object with at least 8 entries, + which will be filled in with the information. Otherwise a new list will be + created and filled in. In both cases the return value of the method is the + populated list. + + The values in the list are: + + - TEC value + - REC value + - number of times the controller enterted the Error Warning state (wrapped + around to 0 after 65535) - CURRENTLY NOT IMPLEMENTED + - number of times the controller enterted the Error Passive state (wrapped + around to 0 after 65535) - CURRENTLY NOT IMPLEMENTED + - number of times the controller enterted the Bus Off state (wrapped + around to 0 after 65535) - CURRENTLY NOT IMPLEMENTED + - number of pending TX messages + - number of pending RX messages + - Reserved + +.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr) TODO: + + Configure a filter bank: + + - *bank* is the filter bank that is to be configured. + - *mode* is the mode the filter should operate in. + - *fifo* is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter. + - *params* is an array of values the defines the filter. The contents of the array depends on the *mode* argument. + + +-----------+---------------------------------------------------------+ + |*mode* |contents of *params* array | + +===========+=========================================================+ + |CAN.LIST16 |Four 16 bit ids that will be accepted | + +-----------+---------------------------------------------------------+ + |CAN.LIST32 |Two 32 bit ids that will be accepted | + +-----------+---------------------------------------------------------+ + |CAN.MASK16 |Two 16 bit id/mask pairs. E.g. (1, 3, 4, 4) | + | | | The first pair, 1 and 3 will accept all ids | + | | | that have bit 0 = 1 and bit 1 = 0. | + | | | The second pair, 4 and 4, will accept all ids | + | | | that have bit 2 = 1. | + +-----------+---------------------------------------------------------+ + |CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.| + +-----------+---------------------------------------------------------+ + + - *rtr* is an array of booleans that states if a filter should accept a + remote transmission request message. If this argument is not given + then it defaults to ``False`` for all entries. The length of the array + depends on the *mode* argument. + + +-----------+----------------------+ + |*mode* |length of *rtr* array | + +===========+======================+ + |CAN.LIST16 |4 | + +-----------+----------------------+ + |CAN.LIST32 |2 | + +-----------+----------------------+ + |CAN.MASK16 |2 | + +-----------+----------------------+ + |CAN.MASK32 |1 | + +-----------+----------------------+ + +.. method:: CAN.clearfilter(bank) TODO: + + Clear and disables a filter bank: + + - *bank* is the filter bank that is to be cleared. + +.. method:: CAN.any(fifo) + + Return ``True`` if any message waiting on the FIFO, else ``False``. + +.. method:: CAN.recv(list=None, \*, timeout=5000) + + Receive data on the bus: + + - *list* is an optional list object to be used as the return value + - *timeout* is the timeout in milliseconds to wait for the receive. + + Return value: A tuple containing four values. + + - The id of the message. + - A boolean that indicates if the message is an RTR message. + - Reserved. + - An array containing the data. + + If *list* is ``None`` then a new tuple will be allocated, as well as a new + bytes object to contain the data (as the fourth element in the tuple). + + If *list* is not ``None`` then it should be a list object with a least four + elements. The fourth element should be a memoryview object which is created + from either a bytearray or an array of type 'B' or 'b', and this array must + have enough room for at least 8 bytes. The list object will then be + populated with the first three return values above, and the memoryview object + will be resized inplace to the size of the data and filled in with that data. + The same list and memoryview objects can be reused in subsequent calls to + this method, providing a way of receiving data without using the heap. + For example:: + + buf = bytearray(8) + lst = [0, 0, 0, memoryview(buf)] + # No heap memory is allocated in the following call + can.recv(0, lst) + +.. method:: CAN.send(data, id, \*, timeout=0, rtr=False) + + Send a message on the bus: + + - *data* is the data to send (an integer to send, or a buffer object). + - *id* is the id of the message to be sent. + - *timeout* is the timeout in milliseconds to wait for the send. + - *rtr* is a boolean that specifies if the message shall be sent as + a remote transmission request. If *rtr* is True then only the length + of *data* is used to fill in the DLC slot of the frame; the actual + bytes in *data* are unused. + + If timeout is 0 the message is placed in a buffer and the method returns + immediately. If all three buffers are in use an exception is thrown. + If timeout is not 0, the method waits until the message is transmitted. + If the message can't be transmitted within the specified time an exception + is thrown. + + Return value: ``None``. + +.. method:: CAN.clear_tx_queue() + + Clear all messages from transmitting queue. + +.. method:: CAN.clear_rx_queue() + + Clear all messages from receiving queue. + +.. method:: CAN.get_alerts() + + Read the alert status word directly from hardware. + + +.. method:: CAN.rxcallback(fifo, fun) TODO: NOT YET IMPLEMENTED + + Register a function to be called when a message is accepted into a empty fifo: + + - *fifo* is the receiving fifo. + - *fun* is the function to be called when the fifo becomes non empty. + + The callback function takes two arguments the first is the can object it self the second is + a integer that indicates the reason for the callback. + + +--------+------------------------------------------------+ + | Reason | | + +========+================================================+ + | 0 | A message has been accepted into a empty FIFO. | + +--------+------------------------------------------------+ + | 1 | The FIFO is full | + +--------+------------------------------------------------+ + | 2 | A message has been lost due to a full FIFO | + +--------+------------------------------------------------+ + + Example use of rxcallback:: + + def cb0(bus, reason): + print('cb0') + if reason == 0: + print('pending') + if reason == 1: + print('full') + if reason == 2: + print('overflow') + + can = CAN(1, CAN.LOOPBACK) + can.rxcallback(0, cb0) + +Constants +--------- + +.. data:: CAN.NORMAL + CAN.LOOPBACK + CAN.SILENT + CAN.SILENT_LOOPBACK + CAN.LISTEN_ONLY + + The mode of the CAN bus used in :meth:`~CAN.init()`. + +.. data:: CAN.BAUDRATE_25k + CAN.BAUDRATE_50k + CAN.BAUDRATE_100k + CAN.BAUDRATE_125k + CAN.BAUDRATE_250k + CAN.BAUDRATE_500k + CAN.BAUDRATE_800k + CAN.BAUDRATE_1M + + The baudrate of the CAN bus used in :meth:`~CAN.init()`. + +.. data:: CAN.STOPPED + CAN.ERROR_ACTIVE + CAN.BUS_OFF + CAN.RECOVERING + + Possible states of the CAN controller returned from :meth:`~CAN.state()`. + +.. data:: CAN.LIST16 TODO: + CAN.MASK16 + CAN.LIST32 + CAN.MASK32 + + The operation mode of a filter used in :meth:`~CAN.setfilter()`. + +.. data:: CAN.ALERT_TX_IDLE + CAN.ALERT_TX_SUCCESS + CAN.ALERT_BELOW_ERR_WARN + CAN.ALERT_ERR_ACTIVE + CAN.ALERT_RECOVERY_IN_PROGRESS + CAN.ALERT_BUS_RECOVERED + CAN.ALERT_ARB_LOST + CAN.ALERT_ABOVE_ERR_WARN + CAN.ALERT_BUS_ERROR + CAN.ALERT_TX_FAILED + CAN.ALERT_RX_QUEUE_FULL + CAN.ALERT_ERR_PASS + CAN.ALERT_BUS_OFF + + Possibile bit position of alert mask returned by :meth:`~CAN.get_alerts()`. From 11cca71e30b1955cdbc8fdaa82777c887bfe836c Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 19 Dec 2019 23:03:24 +0100 Subject: [PATCH 36/62] Removed filter setup from init. --- ports/esp32/machine_can.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 5a7473c8195cc..d8233b7f31ced 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -368,7 +368,7 @@ mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, // init(mode, extframe=False, baudrate=500, *) STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mode, ARG_extframe, ARG_baudrate, ARG_prescaler, ARG_sjw, ARG_bs1, ARG_bs2, - ARG_tx_io, ARG_rx_io, ARG_tx_queue, ARG_rx_queue, ARG_filter_mask, ARG_filter_code, ARG_single_filter}; + ARG_tx_io, ARG_rx_io, ARG_tx_queue, ARG_rx_queue, ARG_auto_restart}; static const mp_arg_t allowed_args[] = { { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, { MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} }, @@ -381,9 +381,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg { MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2} }, { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, - { MP_QSTR_filter_mask, MP_ARG_INT, {.u_int = 0xFFFFFFFF} }, - { MP_QSTR_filter_code, MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_single_filter, MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = true} }, }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -408,11 +406,10 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->general = &g_config; self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); self->extframe = args[ARG_extframe].u_bool; - can_filter_config_t f_config = { - .acceptance_code = args[ARG_filter_code].u_int, - .acceptance_mask = args[ARG_filter_mask].u_int, - .single_filter = args[ARG_single_filter].u_bool - }; + if (args[ARG_auto_restart].u_bool){ + mp_raise_NotImplementedError("Auto-restart not supported"); + } + can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); self->config->filter = &f_config; switch ((int)args[ARG_baudrate].u_int){ From 57efe7979494a6488f1ad0fc2c39492a82f010ed Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 19 Dec 2019 23:08:09 +0100 Subject: [PATCH 37/62] STM32 Harmonization --- ports/esp32/machine_can.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index d8233b7f31ced..c8118de30b408 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -121,8 +121,8 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { list->items[3] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_error_passive list->items[4] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_bus_off list->items[5] = MP_OBJ_NEW_SMALL_INT(status.msgs_to_tx); - //list->items[6] = MP_OBJ_NEW_SMALL_INT(can->RF0R >> CAN_RF0R_FMP0_Pos & 3); //FIXME: - //list->items[7] = MP_OBJ_NEW_SMALL_INT(can->RF1R >> CAN_RF1R_FMP1_Pos & 3); //FIXME: + list->items[6] = MP_OBJ_NEW_SMALL_INT(status.msgs_to_rx); + list->items[7] = mp_const_none; return MP_OBJ_FROM_PTR(list); } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); @@ -252,7 +252,7 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ } items[0] = MP_OBJ_NEW_SMALL_INT(rx_message.identifier); items[1] = rx_message.flags && CAN_MSG_FLAG_RTR > 0 ? mp_const_true : mp_const_false; - items[2] = 0; //TODO: check if Filter Mailbox Index is available for ESP32 + items[2] = 0; return ret_obj; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); @@ -489,7 +489,7 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj)}, // CAN_MODE { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, { MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_NORMAL | 0x10) }, @@ -498,7 +498,7 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, // CAN_STATE { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, - { MP_ROM_QSTR(MP_QSTR_RUNNING), MP_ROM_INT(CAN_STATE_RUNNING) }, + { MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_RUNNING) }, { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, { MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, // CAN_BAUDRATE From 3f04346145e3d730e8b20753be1afd470a9ad4ac Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 19 Dec 2019 23:25:18 +0100 Subject: [PATCH 38/62] Integrated you docs with existing one --- docs/esp32/quickref.rst | 10 ++++++---- docs/library/esp32.rst | 8 ++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 846d194a43a5a..2b8893c45881a 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -328,6 +328,8 @@ pins can be used for SCL and SDA. The driver is accessed via the CAN bus ------- +See :ref:`esp32.CAN ` :: + The CAN driver is based on hardware implementation. Any available output-capablepins can be used for SCL and SDA. The driver is accessed via the :ref:`machine.CAN ` class:: @@ -335,10 +337,10 @@ The driver is accessed via the :ref:`machine.CAN ` class:: from machine import CAN # construct a CAN bus - bus = CAN(tx=4, rx=2, baudrate=500, mode=CAN.MODE_NO_ACK) - - bus.send([0,1,2,3], 0x86, self_flag=True) #Send a self message - bus.recv() #Read the message sent + bus = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=CAN.BAUDRATE_500k) + + bus.send([0,1,2,3], 0x86) #Send the message + bus.recv() #Read the message sent Real time clock (RTC) diff --git a/docs/library/esp32.rst b/docs/library/esp32.rst index a593965ae2740..4cd7efc3949e5 100644 --- a/docs/library/esp32.rst +++ b/docs/library/esp32.rst @@ -109,3 +109,11 @@ Constants esp32.WAKEUP_ANY_HIGH Selects the wake level for pins. + +Classes +------- + +.. toctree:: + :maxdepth: 1 + + esp32.CAN.rst From c346b591af0f7e7eab945cbc5e4d92b9b1bb17ae Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Fri, 20 Dec 2019 18:52:51 +0100 Subject: [PATCH 39/62] Code cleaning --- ports/esp32/machine_can.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index c8118de30b408..d48c68b0093c3 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -117,9 +117,9 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { can_status_info_t status = _machine_hw_can_get_status(); list->items[0] = MP_OBJ_NEW_SMALL_INT(status.tx_error_counter); list->items[1] = MP_OBJ_NEW_SMALL_INT(status.rx_error_counter); - list->items[2] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_error_warning - list->items[3] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_error_passive - list->items[4] = MP_OBJ_NEW_SMALL_INT(0); // TODO: self->num_bus_off + list->items[2] = MP_OBJ_NEW_SMALL_INT(self->num_error_warning); + list->items[3] = MP_OBJ_NEW_SMALL_INT(self->num_error_passive); + list->items[4] = MP_OBJ_NEW_SMALL_INT(self->num_bus_off); list->items[5] = MP_OBJ_NEW_SMALL_INT(status.msgs_to_tx); list->items[6] = MP_OBJ_NEW_SMALL_INT(status.msgs_to_rx); list->items[7] = mp_const_none; @@ -217,7 +217,6 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ if (status != ESP_OK){ mp_raise_OSError(-status); } - //TODO: manage callback // Create the tuple, or get the list, that will hold the return values // Also populate the fourth element, either a new bytes or reuse existing memoryview mp_obj_t ret_obj = args[ARG_list].u_obj; @@ -298,10 +297,8 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p }else{ mp_printf(print, "CAN Device is not initialized"); } - } - // init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); @@ -343,7 +340,7 @@ mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, mp_raise_TypeError("bus must be a number"); } mp_uint_t can_idx = mp_obj_get_int(args[0]); - if (can_idx > 1) { //TODO: check naming convention + if (can_idx > 1) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN(%d) doesn't exist", can_idx)); } machine_can_obj_t *self = &machine_can_obj; @@ -386,11 +383,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // Check if device was already configured - if (self->config->initialized){ - //TODO: check if this condition is redundant compared to init() - nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "CAN device is already initialized")); - return mp_const_none; + return mp_const_none; } // Configure device can_general_config_t g_config = {.mode = args[ARG_mode].u_int & 0x0F, @@ -466,7 +459,6 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg return mp_const_none; } - STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { // CAN_ATTRIBUTES { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, From d13310e850e17c8c3864bb0ef8ee426d55da7b1f Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Fri, 20 Dec 2019 18:53:14 +0100 Subject: [PATCH 40/62] WIP: first implementation of filters --- ports/esp32/machine_can.c | 49 +++++++++++++++++++++++++++++++++++++++ ports/esp32/machine_can.h | 9 ++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index d48c68b0093c3..97ddc7afb5f9f 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -275,6 +275,54 @@ STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in } STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); +// bank: 1 or 2(only for std) +// mode: FILTER_RAW_SINGLE, FILTER_RAW_DUAL or FILTER_ADDR_SINGLE or FILTER_ADDR_DUAL +// params: [id, mask] +// rtr: ignored if FILTER_RAW +STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ + enum { ARG_bank, ARG_mode, ARG_params, ARG_rtr }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bank, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_params, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_bool = false} }, + }; + + // parse args + machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + size_t len; + mp_obj_t *params; + mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); + if(len != 2){ + mp_raise_ValueError("params shall be a 2-values list"); + } + bool single_filter = (args[ARG_mode].u_int==FILTER_ADDR_SINGLE || args[ARG_mode].u_int==FILTER_RAW_SINGLE); + if (args[ARG_bank].u_int<0 || (args[ARG_bank].u_int > (single_filter ? 1 : 2))){ + mp_raise_ValueError("selected bank is not available"); + } + can_filter_config_t *filter = self->config->filter; + if (args[ARG_mode].u_int==FILTER_RAW_DUAL || args[ARG_mode].u_int==FILTER_RAW_DUAL){ + filter->single_filter = single_filter; + filter->acceptance_code = params[0]; + filter->acceptance_mask = params[1]; // FIXME: check if order is right + }else{ + if (self->extframe && !single_filter){ + mp_raise_ValueError("Dual filter for Extd Msg is not supported. Use FILTER_RAW_DUAL") + } + if (filter->single_filter==true & single_filter==false){ + // Switch to dual filter from single filter + filter->single_filter = single_filter; + filter->acceptance_code = 0; + filter->acceptance_mask = 0xFFFFFFFF; + } + + } + +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter);s STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -403,6 +451,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg mp_raise_NotImplementedError("Auto-restart not supported"); } can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); + f_config->single_filter = self->extframe; self->config->filter = &f_config; switch ((int)args[ARG_baudrate].u_int){ diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 3e91588682ab0..704e6daa3f134 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -43,9 +43,16 @@ #define CAN_BAUDRATE_800k 800 #define CAN_BAUDRATE_1M 1000 +typedef enum _filter_mode_t{ + FILTER_RAW_SINGLE = 0, + FILTER_RAW_DUAL, + FILTER_ADDR_SINGLE, + FILTER_ADDR_DUAL +} + typedef struct _machine_can_config_t { const can_timing_config_t *timing; - const can_filter_config_t *filter; + can_filter_config_t *filter; //FIXME: point to this variable for setting const can_general_config_t *general; uint16_t baudrate; bool initialized; From 34053452891f494cb2f4a18533cf55d141db87c8 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Fri, 20 Dec 2019 18:55:45 +0100 Subject: [PATCH 41/62] WIP --- ports/esp32/machine_can.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 97ddc7afb5f9f..913be60994d14 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -71,6 +71,10 @@ STATIC can_status_info_t _machine_hw_can_get_status(){ return status; } +STATIC void _machine_hw_can_set_filter(uint32_t addr, uint32_t mask, uint8_t bank, bool rtr){ + //addr = addr & () +} + // Force a software restart of the controller, to allow transmission after a bus error STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ uint32_t status = can_initiate_recovery(); @@ -318,7 +322,7 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args filter->acceptance_code = 0; filter->acceptance_mask = 0xFFFFFFFF; } - + uint32_t addr = params[0] & (self->extframe ? 0x1FFFFFFF : 0x7FF) } } From c43aef3e0315dce8af951c83e861b1ed7c762822 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sat, 21 Dec 2019 11:41:37 +0100 Subject: [PATCH 42/62] Syntax Correction --- .gitignore | 3 +++ ports/esp32/machine_can.c | 17 ++++++++--------- ports/esp32/machine_can.h | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 50bd30e877e87..a4ef09599ecb6 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ user.props # Generated rst files ###################### genrst/ +docs/_build +.vscode +esp-idf diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 913be60994d14..f2df6e41f20e1 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -106,6 +106,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state) // Get info about error states and TX/RX buffers STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_list_t *list; if (n_args == 1) { list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); @@ -310,23 +311,23 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args can_filter_config_t *filter = self->config->filter; if (args[ARG_mode].u_int==FILTER_RAW_DUAL || args[ARG_mode].u_int==FILTER_RAW_DUAL){ filter->single_filter = single_filter; - filter->acceptance_code = params[0]; - filter->acceptance_mask = params[1]; // FIXME: check if order is right + filter->acceptance_code = mp_obj_get_int(params[0]); + filter->acceptance_mask = mp_obj_get_int(params[1]); // FIXME: check if order is right }else{ if (self->extframe && !single_filter){ - mp_raise_ValueError("Dual filter for Extd Msg is not supported. Use FILTER_RAW_DUAL") + mp_raise_ValueError("Dual filter for Extd Msg is not supported. Use FILTER_RAW_DUAL"); } - if (filter->single_filter==true & single_filter==false){ + if (filter->single_filter==true && single_filter==false){ // Switch to dual filter from single filter filter->single_filter = single_filter; filter->acceptance_code = 0; filter->acceptance_mask = 0xFFFFFFFF; } - uint32_t addr = params[0] & (self->extframe ? 0x1FFFFFFF : 0x7FF) + uint32_t addr = mp_obj_get_int(params[0]) & (self->extframe ? 0x1FFFFFFF : 0x7FF); } } -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter);s +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter); STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -435,8 +436,6 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - return mp_const_none; - } // Configure device can_general_config_t g_config = {.mode = args[ARG_mode].u_int & 0x0F, .tx_io = args[ARG_tx_io].u_int, @@ -455,7 +454,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg mp_raise_NotImplementedError("Auto-restart not supported"); } can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); - f_config->single_filter = self->extframe; + f_config.single_filter = self->extframe; self->config->filter = &f_config; switch ((int)args[ARG_baudrate].u_int){ diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index 704e6daa3f134..b5d1db38fa8e2 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -48,7 +48,7 @@ typedef enum _filter_mode_t{ FILTER_RAW_DUAL, FILTER_ADDR_SINGLE, FILTER_ADDR_DUAL -} +} filter_mode_t; typedef struct _machine_can_config_t { const can_timing_config_t *timing; From 68a3880fe526035ca93646ce482001dce3553341 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 22 Dec 2019 16:56:32 +0100 Subject: [PATCH 43/62] CAN configuration is stored in object struct --- ports/esp32/machine_can.c | 64 +++++++++++++++++++++------------------ ports/esp32/machine_can.h | 6 ++-- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index f2df6e41f20e1..0c77e552ef7d9 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -54,9 +54,9 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); // singleton CAN device object -machine_can_config_t can_config = {.general = &((can_general_config_t)CAN_GENERAL_CONFIG_DEFAULT(2,4,0)), - .filter = &((can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()), - .timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()), +machine_can_config_t can_config = {.general = CAN_GENERAL_CONFIG_DEFAULT(2,4,0), + .filter = CAN_FILTER_CONFIG_ACCEPT_ALL(), + .timing = CAN_TIMING_CONFIG_25KBITS(), .initialized = false}; STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; @@ -333,7 +333,7 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->config->initialized){ qstr mode; - switch(self->config->general->mode){ + switch(self->config->general.mode){ case CAN_MODE_LISTEN_ONLY: mode = MP_QSTR_LISTEN; break; case CAN_MODE_NO_ACK: mode = MP_QSTR_NO_ACK; break; case CAN_MODE_NORMAL: mode = MP_QSTR_NORMAL; break; @@ -341,8 +341,8 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p } mp_printf(print, "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%q, loopback=%u, extframe=%u)", - self->config->general->tx_io, - self->config->general->rx_io, + self->config->general.tx_io, + self->config->general.rx_io, self->config->baudrate, mode, self->loopback, @@ -437,29 +437,29 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // Configure device - can_general_config_t g_config = {.mode = args[ARG_mode].u_int & 0x0F, - .tx_io = args[ARG_tx_io].u_int, - .rx_io = args[ARG_rx_io].u_int, - .clkout_io = CAN_IO_UNUSED, - .bus_off_io = CAN_IO_UNUSED, - .tx_queue_len = args[ARG_tx_queue].u_int, - .rx_queue_len = args[ARG_rx_queue].u_int, - .alerts_enabled = CAN_ALERT_AND_LOG || CAN_ALERT_BELOW_ERR_WARN || CAN_ALERT_ERR_ACTIVE || CAN_ALERT_BUS_RECOVERED || - CAN_ALERT_ABOVE_ERR_WARN || CAN_ALERT_BUS_ERROR || CAN_ALERT_ERR_PASS || CAN_ALERT_BUS_OFF, - .clkout_divider = 0}; - self->config->general = &g_config; + self->config->general.mode = args[ARG_mode].u_int & 0x0F; + self->config->general.tx_io = args[ARG_tx_io].u_int; + self->config->general.rx_io = args[ARG_rx_io].u_int; + self->config->general.clkout_io = CAN_IO_UNUSED; + self->config->general.bus_off_io = CAN_IO_UNUSED; + self->config->general.tx_queue_len = args[ARG_tx_queue].u_int; + self->config->general.rx_queue_len = args[ARG_rx_queue].u_int; + self->config->general.alerts_enabled = CAN_ALERT_AND_LOG || CAN_ALERT_BELOW_ERR_WARN || CAN_ALERT_ERR_ACTIVE || CAN_ALERT_BUS_RECOVERED || + CAN_ALERT_ABOVE_ERR_WARN || CAN_ALERT_BUS_ERROR || CAN_ALERT_ERR_PASS || CAN_ALERT_BUS_OFF; + self->config->general.clkout_divider = 0; self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); self->extframe = args[ARG_extframe].u_bool; if (args[ARG_auto_restart].u_bool){ mp_raise_NotImplementedError("Auto-restart not supported"); } can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); - f_config.single_filter = self->extframe; - self->config->filter = &f_config; - + self->config->filter.single_filter = self->extframe; + self->config->filter.acceptance_code = f_config.acceptance_code; + self->config->filter.acceptance_mask = f_config.acceptance_mask; + can_timing_config_t *timing; switch ((int)args[ARG_baudrate].u_int){ case 0: - self->config->timing = &((can_timing_config_t){ + timing = &((can_timing_config_t){ .brp = args[ARG_prescaler].u_int, .sjw = args[ARG_sjw].u_int, .tseg_1 = args[ARG_bs1].u_int, @@ -467,37 +467,41 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg .triple_sampling = false}); break; case CAN_BAUDRATE_25k: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()); break; case CAN_BAUDRATE_50k: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_50KBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_50KBITS()); break; case CAN_BAUDRATE_100k: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_100KBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_100KBITS()); break; case CAN_BAUDRATE_125k: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_125KBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_125KBITS()); break; case CAN_BAUDRATE_250k: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_250KBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_250KBITS()); break; case CAN_BAUDRATE_500k: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_500KBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_500KBITS()); break; case CAN_BAUDRATE_800k: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_800KBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_800KBITS()); break; case CAN_BAUDRATE_1M: - self->config->timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); break; default: mp_raise_ValueError("Unable to set baudrate"); self->config->baudrate = 0; return mp_const_none; } + self->config->timing = *timing; self->config->baudrate = args[ARG_baudrate].u_int; - uint32_t status = can_driver_install(self->config->general, self->config->timing, self->config->filter); + uint32_t status = can_driver_install( + &self->config->general, + &self->config->timing, + &(can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()); //self->config->filter); if (status != ESP_OK){ mp_raise_OSError(-status); }else{ diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index b5d1db38fa8e2..c4c9cc4c34c48 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -51,9 +51,9 @@ typedef enum _filter_mode_t{ } filter_mode_t; typedef struct _machine_can_config_t { - const can_timing_config_t *timing; - can_filter_config_t *filter; //FIXME: point to this variable for setting - const can_general_config_t *general; + can_timing_config_t timing; + can_filter_config_t filter; + can_general_config_t general; uint16_t baudrate; bool initialized; } machine_can_config_t; From 960435c1fc1ed264a419f8c95937bd17f75c5fe4 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 22 Dec 2019 16:59:27 +0100 Subject: [PATCH 44/62] Bugfixes --- ports/esp32/machine_can.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 0c77e552ef7d9..2cee0bbd01348 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -64,7 +64,7 @@ STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_co // INTERNAL FUNCTION Return status information STATIC can_status_info_t _machine_hw_can_get_status(){ can_status_info_t status; - uint8_t err_code = can_get_status_info(&status); + uint32_t err_code = can_get_status_info(&status); if(err_code!=ESP_OK){ mp_raise_OSError(-err_code); } @@ -182,10 +182,11 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ if (self->extframe){ flags += CAN_MSG_FLAG_EXTD; id &= 0x1FFFFFFF; + }else{ + id &= 0x1FF; } if (self->loopback){ flags += CAN_MSG_FLAG_SELF; - id &= 0x1FF; } can_message_t tx_msg = {.data_length_code = length, .identifier = id, @@ -431,7 +432,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg { MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2} }, { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, - { MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = false} }, }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; From 7b9a9a904f04f74bec3aef7a3111c804aef7c20c Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 22 Dec 2019 17:04:08 +0100 Subject: [PATCH 45/62] WIP: implementation of setfilter() --- ports/esp32/machine_can.c | 71 ++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 2cee0bbd01348..cf5e8046f31a9 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -71,8 +71,29 @@ STATIC can_status_info_t _machine_hw_can_get_status(){ return status; } -STATIC void _machine_hw_can_set_filter(uint32_t addr, uint32_t mask, uint8_t bank, bool rtr){ - //addr = addr & () +//INTERNAL FUNCTION Populates the filter register according to inputs +STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr){ + //Check if bank is allowed + if (bank<0 && bank>((self->extframe && self->config->filter.single_filter) ? 0 : 1)){ + mp_raise_ValueError("CAN filter parameter error"); + } + uint32_t preserve_mask; + if (self->extframe){ + addr = (addr & 0x1FFFFFFF) << 3 | (rtr ? 0x04 : 0); + mask = (mask & 0x1FFFFFFF) << 3 | 0x04; + preserve_mask = 0; + }else{ + addr = ((addr & 0x7FF) | (rtr ? 0x800 : 0)) << (bank==1 ? 16 : 0); + mask = ((mask & 0x7FF) | 0x800) << (bank==1 ? 16 : 0); + preserve_mask = 0xFFFF << (bank==0 ? 16 : 0);; + } + ESP_LOGI(DEVICE_NAME, "Address: %08X",addr); + ESP_LOGI(DEVICE_NAME, "Mask: %08X", mask); + ESP_LOGI(DEVICE_NAME, "Preserve: %08X", preserve_mask); + self->config->filter.acceptance_code &= preserve_mask; + self->config->filter.acceptance_code |= addr; + self->config->filter.acceptance_mask &= preserve_mask; + self->config->filter.acceptance_mask |= mask; } // Force a software restart of the controller, to allow transmission after a bus error @@ -281,7 +302,7 @@ STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in } STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); -// bank: 1 or 2(only for std) +// bank: 0 or 1(only for std) // mode: FILTER_RAW_SINGLE, FILTER_RAW_DUAL or FILTER_ADDR_SINGLE or FILTER_ADDR_DUAL // params: [id, mask] // rtr: ignored if FILTER_RAW @@ -301,32 +322,31 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args size_t len; mp_obj_t *params; - mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); + mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); if(len != 2){ mp_raise_ValueError("params shall be a 2-values list"); } - bool single_filter = (args[ARG_mode].u_int==FILTER_ADDR_SINGLE || args[ARG_mode].u_int==FILTER_RAW_SINGLE); - if (args[ARG_bank].u_int<0 || (args[ARG_bank].u_int > (single_filter ? 1 : 2))){ - mp_raise_ValueError("selected bank is not available"); - } - can_filter_config_t *filter = self->config->filter; - if (args[ARG_mode].u_int==FILTER_RAW_DUAL || args[ARG_mode].u_int==FILTER_RAW_DUAL){ - filter->single_filter = single_filter; - filter->acceptance_code = mp_obj_get_int(params[0]); - filter->acceptance_mask = mp_obj_get_int(params[1]); // FIXME: check if order is right + uint32_t id = mp_obj_get_int(params[0]); + uint32_t mask = mp_obj_get_int(params[1]); // FIXME: Overflow in case 0xFFFFFFFF for mask + if (args[ARG_mode].u_int==FILTER_RAW_SINGLE || args[ARG_mode].u_int==FILTER_RAW_DUAL){ + self->config->filter.single_filter = (args[ARG_mode].u_int==FILTER_RAW_SINGLE); + self->config->filter.acceptance_code = id; + self->config->filter.acceptance_mask = mask; }else{ - if (self->extframe && !single_filter){ - mp_raise_ValueError("Dual filter for Extd Msg is not supported. Use FILTER_RAW_DUAL"); - } - if (filter->single_filter==true && single_filter==false){ - // Switch to dual filter from single filter - filter->single_filter = single_filter; - filter->acceptance_code = 0; - filter->acceptance_mask = 0xFFFFFFFF; - } - uint32_t addr = mp_obj_get_int(params[0]) & (self->extframe ? 0x1FFFFFFF : 0x7FF); + _machine_hw_can_set_filter(self, id, mask, args[ARG_bank].u_int, args[ARG_rtr].u_int); } +ESP_LOGI(DEVICE_NAME, "New Code: %08X",self->config->filter.acceptance_code); +ESP_LOGI(DEVICE_NAME, "New Mask: %08X",self->config->filter.acceptance_mask); + ESP_STATUS_CHECK(can_stop()); + ESP_STATUS_CHECK(can_driver_uninstall()); + ESP_STATUS_CHECK(can_driver_install( + &self->config->general, + &self->config->timing, + &self->config->filter)); + ESP_STATUS_CHECK(can_start()); + ESP_LOGI(DEVICE_NAME, "Restarted"); + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter); @@ -528,6 +548,7 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, + { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_hw_can_setfilter_obj) }, /* { MP_ROM_QSTR(MP_QSTR_initfilterbanks), MP_ROM_PTR(&pyb_can_initfilterbanks_obj) }, { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&pyb_can_setfilter_obj) }, @@ -559,6 +580,10 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k) }, { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M) }, + // CAN_FILTER_MODE + { MP_ROM_QSTR(MP_QSTR_FILTER_RAW_SINGLE), MP_ROM_INT(FILTER_RAW_SINGLE) }, + { MP_ROM_QSTR(MP_QSTR_FILTER_RAW_DUAL), MP_ROM_INT(FILTER_RAW_DUAL) }, + { MP_ROM_QSTR(MP_QSTR_FILTER_ADDRESS), MP_ROM_INT(FILTER_ADDRESS) }, // CAN_ALERT { MP_ROM_QSTR(MP_QSTR_ALERT_TX_IDLE), MP_ROM_INT(CAN_ALERT_TX_IDLE) }, { MP_ROM_QSTR(MP_QSTR_ALERT_TX_SUCCESS), MP_ROM_INT(CAN_ALERT_TX_SUCCESS) }, From 96721c9367ff7acfe368614c606a41d0c7072d1f Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Mon, 23 Dec 2019 09:49:17 +0100 Subject: [PATCH 46/62] Completed setfilter() --- ports/esp32/machine_can.c | 32 ++++++++++++++++++++------------ ports/esp32/machine_can.h | 4 ++-- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index cf5e8046f31a9..272b05126cf72 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -80,16 +80,27 @@ STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, u uint32_t preserve_mask; if (self->extframe){ addr = (addr & 0x1FFFFFFF) << 3 | (rtr ? 0x04 : 0); - mask = (mask & 0x1FFFFFFF) << 3 | 0x04; + mask = (mask & 0x1FFFFFFF) << 3 | 0x03; + preserve_mask = 0; + }else if(self->config->filter.single_filter){ + addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); + mask = ((mask & 0x7FF) << 5); + mask |= 0xFFFFF000; preserve_mask = 0; }else{ - addr = ((addr & 0x7FF) | (rtr ? 0x800 : 0)) << (bank==1 ? 16 : 0); - mask = ((mask & 0x7FF) | 0x800) << (bank==1 ? 16 : 0); - preserve_mask = 0xFFFF << (bank==0 ? 16 : 0);; + addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); + mask = ((mask & 0x7FF) << 5); + preserve_mask = 0xFFFF << (bank==0 ? 16 : 0); + if ((self->config->filter.acceptance_mask & preserve_mask) == (0xFFFF << (bank==0 ? 16 : 0))){ + // Other filter accepts all; it will replaced duplicating current filter + addr = addr | (addr << 16); + mask = mask | (mask << 16); + preserve_mask = 0; + }else{ + addr = addr << (bank==1 ? 16 : 0); + mask = mask << (bank==1 ? 16 : 0); + } } - ESP_LOGI(DEVICE_NAME, "Address: %08X",addr); - ESP_LOGI(DEVICE_NAME, "Mask: %08X", mask); - ESP_LOGI(DEVICE_NAME, "Preserve: %08X", preserve_mask); self->config->filter.acceptance_code &= preserve_mask; self->config->filter.acceptance_code |= addr; self->config->filter.acceptance_mask &= preserve_mask; @@ -333,11 +344,9 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args self->config->filter.acceptance_code = id; self->config->filter.acceptance_mask = mask; }else{ + self->config->filter.single_filter = self->extframe; _machine_hw_can_set_filter(self, id, mask, args[ARG_bank].u_int, args[ARG_rtr].u_int); } - -ESP_LOGI(DEVICE_NAME, "New Code: %08X",self->config->filter.acceptance_code); -ESP_LOGI(DEVICE_NAME, "New Mask: %08X",self->config->filter.acceptance_mask); ESP_STATUS_CHECK(can_stop()); ESP_STATUS_CHECK(can_driver_uninstall()); ESP_STATUS_CHECK(can_driver_install( @@ -345,7 +354,6 @@ ESP_LOGI(DEVICE_NAME, "New Mask: %08X",self->config->filter.acceptance_mask); &self->config->timing, &self->config->filter)); ESP_STATUS_CHECK(can_start()); - ESP_LOGI(DEVICE_NAME, "Restarted"); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter); @@ -522,7 +530,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg uint32_t status = can_driver_install( &self->config->general, &self->config->timing, - &(can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()); //self->config->filter); + &(can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()); if (status != ESP_OK){ mp_raise_OSError(-status); }else{ diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h index c4c9cc4c34c48..a79a23271345a 100644 --- a/ports/esp32/machine_can.h +++ b/ports/esp32/machine_can.h @@ -43,11 +43,11 @@ #define CAN_BAUDRATE_800k 800 #define CAN_BAUDRATE_1M 1000 +#define ESP_STATUS_CHECK(status) if (status != ESP_OK){ mp_raise_OSError(-status);} typedef enum _filter_mode_t{ FILTER_RAW_SINGLE = 0, FILTER_RAW_DUAL, - FILTER_ADDR_SINGLE, - FILTER_ADDR_DUAL + FILTER_ADDRESS } filter_mode_t; typedef struct _machine_can_config_t { From 89208858af0579367bbcbf9871b1f785fe0606e1 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Mon, 23 Dec 2019 09:49:34 +0100 Subject: [PATCH 47/62] added clearfilter() --- ports/esp32/machine_can.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 272b05126cf72..fddba0ccc8778 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -313,6 +313,22 @@ STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in } STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); +STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + self->config->filter.single_filter = self->extframe; + self->config->filter.acceptance_code = 0; + self->config->filter.acceptance_mask = 0xFFFFFFFF; + ESP_STATUS_CHECK(can_stop()); + ESP_STATUS_CHECK(can_driver_uninstall()); + ESP_STATUS_CHECK(can_driver_install( + &self->config->general, + &self->config->timing, + &self->config->filter)); + ESP_STATUS_CHECK(can_start()); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clearfilter_obj, machine_hw_can_clearfilter); + // bank: 0 or 1(only for std) // mode: FILTER_RAW_SINGLE, FILTER_RAW_DUAL or FILTER_ADDR_SINGLE or FILTER_ADDR_DUAL // params: [id, mask] @@ -557,12 +573,8 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_hw_can_setfilter_obj) }, - /* - { MP_ROM_QSTR(MP_QSTR_initfilterbanks), MP_ROM_PTR(&pyb_can_initfilterbanks_obj) }, - { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&pyb_can_setfilter_obj) }, - { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&pyb_can_clearfilter_obj) }, - */ - { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj) }, + { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&machine_hw_can_clearfilter_obj) }, + { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj) }, // ESP32 Specific API { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, From 2c6b6f4f64878a3093ada218e486f2d844ad3c62 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Mon, 23 Dec 2019 09:50:07 +0100 Subject: [PATCH 48/62] Added unittest as example --- examples/esp32_can.py | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 examples/esp32_can.py diff --git a/examples/esp32_can.py b/examples/esp32_can.py new file mode 100644 index 0000000000000..b5c4966a04dbc --- /dev/null +++ b/examples/esp32_can.py @@ -0,0 +1,68 @@ +from machine import CAN +import time + +def sendAndCheck(dev, name, id, expectedLP = True): + dev.clear_tx_queue() + dev.clear_rx_queue() + dev.send([], id) + time.sleep_ms(100) + if dev.any() == expectedLP: + print("{}: OK".format(name)) + if expectedLP: + dev.recv() + else: + print("{}: FAILED".format(name)) + +dev = CAN(0, + extframe=False, + mode=CAN.SILENT_LOOPBACK, + baudrate=CAN.BAUDRATE_500k, + tx_io=18,rx_io=19, auto_restart=False) + +#Test send/receive message +print("Loopback Test: no filter - STD") +sendAndCheck(dev, "No filter", 0x100, True) + +#Set filter1 +print("Loopback Test: one filter - STD") +dev.setfilter(0, CAN.FILTER_ADDRESS, [0x101, 0]) +sendAndCheck(dev, "Passing Message", 0x101, True) +sendAndCheck(dev, "Blocked Message", 0x100, False) + +#Set filter2 +print("Loopback Test: second filter - STD") +dev.setfilter(0, CAN.FILTER_ADDRESS, [0x102, 0]) +sendAndCheck(dev, "Passing Message - Bank 1", 0x102, True) +sendAndCheck(dev, "Passing Message - Bank 0", 0x101, True) +sendAndCheck(dev, "Blocked Message", 0x100, False) + +#Remove filter +print("Loopback Test: clear filter - STD") +dev.clearfilter() +sendAndCheck(dev, "Passing Message - Bank 1", 0x102, True) +sendAndCheck(dev, "Passing Message - Bank 0", 0x101, True) +sendAndCheck(dev, "Passing any Message", 0x100, True) + +#Move to Extended +dev = CAN(0, + extframe=True, + mode=CAN.SILENT_LOOPBACK, + baudrate=CAN.BAUDRATE_500k, + tx_io=18,rx_io=19, auto_restart=False) + +#Test send/receive message +print("Loopback Test: no filter - Extd") +sendAndCheck(dev, "No filter", 0x100, True) + +#Set filter1 +print("Loopback Test: one filter - Extd") +dev.setfilter(0, CAN.FILTER_ADDRESS, [0x101, 0]) +sendAndCheck(dev, "Passing Message", 0x101, True) +sendAndCheck(dev, "Blocked Message", 0x100, False) + +#Remove filter +print("Loopback Test: clear filter - Extd") +dev.clearfilter() +sendAndCheck(dev, "Passing Message - Bank 0", 0x101, True) +sendAndCheck(dev, "Passing any Message", 0x100, True) + From 5432a7d884c2b50d5237376e745d52c6a143c52b Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Mon, 23 Dec 2019 09:58:51 +0100 Subject: [PATCH 49/62] removed machine_can.h --- ports/esp32/machine_can.c | 49 ++++++++++++++++++++++- ports/esp32/machine_can.h | 83 --------------------------------------- 2 files changed, 47 insertions(+), 85 deletions(-) delete mode 100644 ports/esp32/machine_can.h diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index fddba0ccc8778..0ffbf7e88382a 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -37,10 +37,55 @@ #include "esp_err.h" #include "esp_log.h" -#include +#include "modmachine.h" #if MICROPY_HW_ENABLE_CAN +#define DEVICE_NAME "CAN" + +#define CAN_BAUDRATE_25k 25 +#define CAN_BAUDRATE_50k 50 +#define CAN_BAUDRATE_100k 100 +#define CAN_BAUDRATE_125k 125 +#define CAN_BAUDRATE_250k 250 +#define CAN_BAUDRATE_500k 500 +#define CAN_BAUDRATE_800k 800 +#define CAN_BAUDRATE_1M 1000 + +#define ESP_STATUS_CHECK(status) if (status != ESP_OK){ mp_raise_OSError(-status);} +typedef enum _filter_mode_t{ + FILTER_RAW_SINGLE = 0, + FILTER_RAW_DUAL, + FILTER_ADDRESS +} filter_mode_t; + +typedef struct _machine_can_config_t { + can_timing_config_t timing; + can_filter_config_t filter; + can_general_config_t general; + uint16_t baudrate; + bool initialized; +} machine_can_config_t; + +typedef struct _machine_can_obj_t { + mp_obj_base_t base; + machine_can_config_t *config; + mp_obj_t rxcallback; + byte rx_state; + bool extframe : 1; + bool loopback : 1; + uint16_t num_error_warning; //FIXME: populate this value somewhere + uint16_t num_error_passive; + uint16_t num_bus_off; +} machine_can_obj_t; + +typedef enum _rx_state_t { + RX_STATE_FIFO_EMPTY = 0, + RX_STATE_MESSAGE_PENDING, + RX_STATE_FIFO_FULL, + RX_STATE_FIFO_OVERFLOW, +} rx_state_t; + // Default baudrate: 500kb #define CAN_DEFAULT_PRESCALER (8) #define CAN_DEFAULT_SJW (3) @@ -113,7 +158,7 @@ STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ if (status != ESP_OK){ mp_raise_OSError(-status); } - mp_hal_delay_ms(200); // FIXME: replace it with a smarter solution + mp_hal_delay_ms(200); // TODO: replace it with a smarter solution status = can_start(); if (status != ESP_OK){ mp_raise_OSError(-status); diff --git a/ports/esp32/machine_can.h b/ports/esp32/machine_can.h deleted file mode 100644 index a79a23271345a..0000000000000 --- a/ports/esp32/machine_can.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2019 Musumeci Salvatore - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef MICROPY_INCLUDED_ESP32_CAN_H -#define MICROPY_INCLUDED_ESP32_CAN_H - -#include "modmachine.h" - -#include "py/obj.h" - -#if MICROPY_HW_ENABLE_CAN - -#define DEVICE_NAME "CAN" - -#define CAN_BAUDRATE_25k 25 -#define CAN_BAUDRATE_50k 50 -#define CAN_BAUDRATE_100k 100 -#define CAN_BAUDRATE_125k 125 -#define CAN_BAUDRATE_250k 250 -#define CAN_BAUDRATE_500k 500 -#define CAN_BAUDRATE_800k 800 -#define CAN_BAUDRATE_1M 1000 - -#define ESP_STATUS_CHECK(status) if (status != ESP_OK){ mp_raise_OSError(-status);} -typedef enum _filter_mode_t{ - FILTER_RAW_SINGLE = 0, - FILTER_RAW_DUAL, - FILTER_ADDRESS -} filter_mode_t; - -typedef struct _machine_can_config_t { - can_timing_config_t timing; - can_filter_config_t filter; - can_general_config_t general; - uint16_t baudrate; - bool initialized; -} machine_can_config_t; - -typedef struct _machine_can_obj_t { - mp_obj_base_t base; - machine_can_config_t *config; - mp_obj_t rxcallback; - byte rx_state; - bool extframe : 1; - bool loopback : 1; - uint16_t num_error_warning; //FIXME: populate this value somewhere - uint16_t num_error_passive; - uint16_t num_bus_off; -} machine_can_obj_t; - -typedef enum _rx_state_t { - RX_STATE_FIFO_EMPTY = 0, - RX_STATE_MESSAGE_PENDING, - RX_STATE_FIFO_FULL, - RX_STATE_FIFO_OVERFLOW, -} rx_state_t; - -extern const mp_obj_type_t machine_can_type; - -#endif // MICROPY_HW_ENABLE_CAN -#endif // MICROPY_INCLUDED_ESP32_CAN_H From 2616b9e96f30260199379bdda185e024c770b8e9 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Mon, 23 Dec 2019 10:00:58 +0100 Subject: [PATCH 50/62] Bugfix --- ports/esp32/modmachine.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 894ad2f6d9ac7..067e909d5bb65 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -253,7 +253,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_TouchPad), MP_ROM_PTR(&machine_touchpad_type) }, { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) }, { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) }, + #if MICROPY_HW_ENABLE_CAN { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&machine_can_type) }, + #endif { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, From f5ed914023b2f5c66fa4d153fd0456c0c5527173 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Mon, 23 Dec 2019 10:18:52 +0100 Subject: [PATCH 51/62] Docs updated --- docs/library/esp32.CAN.rst | 77 +++++++++++++------------------------- ports/esp32/machine_can.c | 6 ++- 2 files changed, 30 insertions(+), 53 deletions(-) diff --git a/docs/library/esp32.CAN.rst b/docs/library/esp32.CAN.rst index e17e9f4a5598f..0a35accdf630a 100644 --- a/docs/library/esp32.CAN.rst +++ b/docs/library/esp32.CAN.rst @@ -32,17 +32,6 @@ Constructors The physical pins of the CAN bus can be assigned during init. -Class Methods -------------- -.. classmethod:: CAN.initfilterbanks(nr) TODO: - - Reset and disable all filter banks and assign how many banks should be available for CAN(1). - - STM32F405 has 28 filter banks that are shared between the two available CAN bus controllers. - This function configures how many filter banks should be assigned to each. *nr* is the number of banks - that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2). - At boot, 14 banks are assigned to each controller. - Methods ------- @@ -122,53 +111,37 @@ Methods - number of pending RX messages - Reserved -.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr) TODO: +.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr) Configure a filter bank: - - *bank* is the filter bank that is to be configured. + - *bank* is the filter bank that is to be configured (0 for extended, 0 or 1 for standard msg) - *mode* is the mode the filter should operate in. - - *fifo* is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter. - - *params* is an array of values the defines the filter. The contents of the array depends on the *mode* argument. + - *params* is an array of two values that defines the filter. + The first element will be the id to filter and the second element will be the mask to apply. + mask bit implementation considers 1 as a don't care state and 0 as a check state. - +-----------+---------------------------------------------------------+ + +----------------------+----------------------------------------------+ |*mode* |contents of *params* array | - +===========+=========================================================+ - |CAN.LIST16 |Four 16 bit ids that will be accepted | - +-----------+---------------------------------------------------------+ - |CAN.LIST32 |Two 32 bit ids that will be accepted | - +-----------+---------------------------------------------------------+ - |CAN.MASK16 |Two 16 bit id/mask pairs. E.g. (1, 3, 4, 4) | - | | | The first pair, 1 and 3 will accept all ids | - | | | that have bit 0 = 1 and bit 1 = 0. | - | | | The second pair, 4 and 4, will accept all ids | - | | | that have bit 2 = 1. | - +-----------+---------------------------------------------------------+ - |CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.| - +-----------+---------------------------------------------------------+ - - - *rtr* is an array of booleans that states if a filter should accept a - remote transmission request message. If this argument is not given - then it defaults to ``False`` for all entries. The length of the array - depends on the *mode* argument. - - +-----------+----------------------+ - |*mode* |length of *rtr* array | - +===========+======================+ - |CAN.LIST16 |4 | - +-----------+----------------------+ - |CAN.LIST32 |2 | - +-----------+----------------------+ - |CAN.MASK16 |2 | - +-----------+----------------------+ - |CAN.MASK32 |1 | - +-----------+----------------------+ - -.. method:: CAN.clearfilter(bank) TODO: - - Clear and disables a filter bank: - - - *bank* is the filter bank that is to be cleared. + +======================+==============================================+ + |CAN.FILTER_RAW_SINGLE | *params* will be copied in hardware variable | + | | and single_filter_mode will be selected | + | | In this mode, *bank* will be ignored | + +----------------------+----------------------------------------------+ + |CAN.FILTER_RAW_DUAL | *params* will be copied in hardware variable | + | | and single_filter_mode will be cleared | + | | In this mode, *bank* will be ignored | + +----------------------+----------------------------------------------+ + |CAN.FILTER_ADDRESS | *params* will be set in hardware registers | + | | according to *bank* selection | + +----------------------+----------------------------------------------+ + + - *rtr* is bool that states if a filter should accept a remote transmission request message. + If this argument is not given then it defaults to ``False``. + +.. method:: CAN.clearfilter(bank) + + Clear and disables all filters .. method:: CAN.any(fifo) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 0ffbf7e88382a..ac5455aaed451 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -209,6 +209,7 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); +// Get Alert info STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in){ uint32_t alerts; uint32_t status = can_read_alerts(&alerts, 0); @@ -358,6 +359,7 @@ STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in } STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); +// Clear filters setting STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) { machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); self->config->filter.single_filter = self->extframe; @@ -378,6 +380,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clearfilter_obj, machine_hw_can_ // mode: FILTER_RAW_SINGLE, FILTER_RAW_DUAL or FILTER_ADDR_SINGLE or FILTER_ADDR_DUAL // params: [id, mask] // rtr: ignored if FILTER_RAW +// Set CAN HW filter STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ enum { ARG_bank, ARG_mode, ARG_params, ARG_rtr }; static const mp_arg_t allowed_args[] = { @@ -674,4 +677,5 @@ const mp_obj_type_t machine_can_type = { .make_new = machine_hw_can_make_new, // give it a constructor .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members }; -#endif // MICROPY_HW_ENABLE_CAN \ No newline at end of file +#endif // MICROPY_HW_ENABLE_CAN + \ No newline at end of file From ef0ae9f1415d8d470f52f14c7e05a0fe5fa6fe7f Mon Sep 17 00:00:00 2001 From: Salvo Musumeci Date: Mon, 23 Dec 2019 10:23:12 +0100 Subject: [PATCH 52/62] Update Author name --- ports/esp32/machine_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index ac5455aaed451..dcdda0d2f7442 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -1,6 +1,6 @@ /* The MIT License (MIT) * - * Copyright (c) 2019 Damien P. George + * Copyright (c) 2019 Musumeci Salvatore * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -678,4 +678,4 @@ const mp_obj_type_t machine_can_type = { .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members }; #endif // MICROPY_HW_ENABLE_CAN - \ No newline at end of file + From e5a7e9d3b18ebba417c18f76a7ecbd6bbbd5fc70 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Mon, 23 Dec 2019 10:25:52 +0100 Subject: [PATCH 53/62] remove .vscode folder --- .vscode/c_cpp_properties.json | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 5f0824b540e6b..0000000000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "configurations": [ - { - "name": "Mac", - "includePath": [ - "${workspaceFolder}/../esp-idf/components/**", - "${workspaceFolder}/ports/esp32/**", - "${workspaceFolder}/**" - ], - "defines": [], - "macFrameworkPath": [ - "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Frameworks" - ], - "compilerPath": "/usr/bin/clang", - "cStandard": "c11", - "cppStandard": "c++17", - "intelliSenseMode": "clang-x64" - } - ], - "version": 4 -} \ No newline at end of file From 66c8a3227c92a75e8582d4f86f87a6f8c72da6b7 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 9 Jan 2020 22:09:13 +0100 Subject: [PATCH 54/62] Formatting sources --- examples/esp32_can.py | 37 +-- ports/esp32/machine_can.c | 636 +++++++++++++++++++++++--------------- 2 files changed, 399 insertions(+), 274 deletions(-) diff --git a/examples/esp32_can.py b/examples/esp32_can.py index b5c4966a04dbc..495370bb1d5e8 100644 --- a/examples/esp32_can.py +++ b/examples/esp32_can.py @@ -1,7 +1,8 @@ from machine import CAN import time -def sendAndCheck(dev, name, id, expectedLP = True): + +def sendAndCheck(dev, name, id, expectedLP=True): dev.clear_tx_queue() dev.clear_rx_queue() dev.send([], id) @@ -13,56 +14,56 @@ def sendAndCheck(dev, name, id, expectedLP = True): else: print("{}: FAILED".format(name)) + dev = CAN(0, - extframe=False, - mode=CAN.SILENT_LOOPBACK, - baudrate=CAN.BAUDRATE_500k, - tx_io=18,rx_io=19, auto_restart=False) + extframe=False, + mode=CAN.SILENT_LOOPBACK, + baudrate=CAN.BAUDRATE_500k, + tx_io=18, rx_io=19, auto_restart=False) -#Test send/receive message +# Test send/receive message print("Loopback Test: no filter - STD") sendAndCheck(dev, "No filter", 0x100, True) -#Set filter1 +# Set filter1 print("Loopback Test: one filter - STD") dev.setfilter(0, CAN.FILTER_ADDRESS, [0x101, 0]) sendAndCheck(dev, "Passing Message", 0x101, True) sendAndCheck(dev, "Blocked Message", 0x100, False) -#Set filter2 +# Set filter2 print("Loopback Test: second filter - STD") dev.setfilter(0, CAN.FILTER_ADDRESS, [0x102, 0]) sendAndCheck(dev, "Passing Message - Bank 1", 0x102, True) sendAndCheck(dev, "Passing Message - Bank 0", 0x101, True) sendAndCheck(dev, "Blocked Message", 0x100, False) -#Remove filter +# Remove filter print("Loopback Test: clear filter - STD") dev.clearfilter() sendAndCheck(dev, "Passing Message - Bank 1", 0x102, True) sendAndCheck(dev, "Passing Message - Bank 0", 0x101, True) sendAndCheck(dev, "Passing any Message", 0x100, True) -#Move to Extended +# Move to Extended dev = CAN(0, - extframe=True, - mode=CAN.SILENT_LOOPBACK, - baudrate=CAN.BAUDRATE_500k, - tx_io=18,rx_io=19, auto_restart=False) + extframe=True, + mode=CAN.SILENT_LOOPBACK, + baudrate=CAN.BAUDRATE_500k, + tx_io=18, rx_io=19, auto_restart=False) -#Test send/receive message +# Test send/receive message print("Loopback Test: no filter - Extd") sendAndCheck(dev, "No filter", 0x100, True) -#Set filter1 +# Set filter1 print("Loopback Test: one filter - Extd") dev.setfilter(0, CAN.FILTER_ADDRESS, [0x101, 0]) sendAndCheck(dev, "Passing Message", 0x101, True) sendAndCheck(dev, "Blocked Message", 0x100, False) -#Remove filter +# Remove filter print("Loopback Test: clear filter - Extd") dev.clearfilter() sendAndCheck(dev, "Passing Message - Bank 0", 0x101, True) sendAndCheck(dev, "Passing any Message", 0x100, True) - diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index dcdda0d2f7442..7dfc8729c6178 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -52,22 +52,29 @@ #define CAN_BAUDRATE_800k 800 #define CAN_BAUDRATE_1M 1000 -#define ESP_STATUS_CHECK(status) if (status != ESP_OK){ mp_raise_OSError(-status);} -typedef enum _filter_mode_t{ +#define ESP_STATUS_CHECK(status) \ + if (status != ESP_OK) \ + { \ + mp_raise_OSError(-status); \ + } +typedef enum _filter_mode_t +{ FILTER_RAW_SINGLE = 0, FILTER_RAW_DUAL, FILTER_ADDRESS } filter_mode_t; -typedef struct _machine_can_config_t { +typedef struct _machine_can_config_t +{ can_timing_config_t timing; - can_filter_config_t filter; + can_filter_config_t filter; can_general_config_t general; uint16_t baudrate; bool initialized; } machine_can_config_t; -typedef struct _machine_can_obj_t { +typedef struct _machine_can_obj_t +{ mp_obj_base_t base; machine_can_config_t *config; mp_obj_t rxcallback; @@ -79,7 +86,8 @@ typedef struct _machine_can_obj_t { uint16_t num_bus_off; } machine_can_obj_t; -typedef enum _rx_state_t { +typedef enum _rx_state_t +{ RX_STATE_FIFO_EMPTY = 0, RX_STATE_MESSAGE_PENDING, RX_STATE_FIFO_FULL, @@ -87,11 +95,10 @@ typedef enum _rx_state_t { } rx_state_t; // Default baudrate: 500kb -#define CAN_DEFAULT_PRESCALER (8) -#define CAN_DEFAULT_SJW (3) -#define CAN_DEFAULT_BS1 (15) -#define CAN_DEFAULT_BS2 (4) - +#define CAN_DEFAULT_PRESCALER (8) +#define CAN_DEFAULT_SJW (3) +#define CAN_DEFAULT_BS1 (15) +#define CAN_DEFAULT_BS2 (4) // Internal Functions mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); @@ -99,51 +106,63 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); // singleton CAN device object -machine_can_config_t can_config = {.general = CAN_GENERAL_CONFIG_DEFAULT(2,4,0), +machine_can_config_t can_config = {.general = CAN_GENERAL_CONFIG_DEFAULT(2, 4, 0), .filter = CAN_FILTER_CONFIG_ACCEPT_ALL(), .timing = CAN_TIMING_CONFIG_25KBITS(), .initialized = false}; - -STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config=&can_config}; + +STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config = &can_config}; // INTERNAL FUNCTION Return status information -STATIC can_status_info_t _machine_hw_can_get_status(){ +STATIC can_status_info_t _machine_hw_can_get_status() +{ can_status_info_t status; uint32_t err_code = can_get_status_info(&status); - if(err_code!=ESP_OK){ + if (err_code != ESP_OK) + { mp_raise_OSError(-err_code); } return status; } //INTERNAL FUNCTION Populates the filter register according to inputs -STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr){ +STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr) +{ //Check if bank is allowed - if (bank<0 && bank>((self->extframe && self->config->filter.single_filter) ? 0 : 1)){ + if (bank < 0 && bank > ((self->extframe && self->config->filter.single_filter) ? 0 : 1)) + { mp_raise_ValueError("CAN filter parameter error"); } uint32_t preserve_mask; - if (self->extframe){ + if (self->extframe) + { addr = (addr & 0x1FFFFFFF) << 3 | (rtr ? 0x04 : 0); mask = (mask & 0x1FFFFFFF) << 3 | 0x03; preserve_mask = 0; - }else if(self->config->filter.single_filter){ + } + else if (self->config->filter.single_filter) + { addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); - mask = ((mask & 0x7FF) << 5); + mask = ((mask & 0x7FF) << 5); mask |= 0xFFFFF000; preserve_mask = 0; - }else{ + } + else + { addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); - mask = ((mask & 0x7FF) << 5); - preserve_mask = 0xFFFF << (bank==0 ? 16 : 0); - if ((self->config->filter.acceptance_mask & preserve_mask) == (0xFFFF << (bank==0 ? 16 : 0))){ + mask = ((mask & 0x7FF) << 5); + preserve_mask = 0xFFFF << (bank == 0 ? 16 : 0); + if ((self->config->filter.acceptance_mask & preserve_mask) == (0xFFFF << (bank == 0 ? 16 : 0))) + { // Other filter accepts all; it will replaced duplicating current filter addr = addr | (addr << 16); mask = mask | (mask << 16); preserve_mask = 0; - }else{ - addr = addr << (bank==1 ? 16 : 0); - mask = mask << (bank==1 ? 16 : 0); + } + else + { + addr = addr << (bank == 1 ? 16 : 0); + mask = mask << (bank == 1 ? 16 : 0); } } self->config->filter.acceptance_code &= preserve_mask; @@ -153,14 +172,17 @@ STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, u } // Force a software restart of the controller, to allow transmission after a bus error -STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in) +{ uint32_t status = can_initiate_recovery(); - if (status != ESP_OK){ + if (status != ESP_OK) + { mp_raise_OSError(-status); } mp_hal_delay_ms(200); // TODO: replace it with a smarter solution status = can_start(); - if (status != ESP_OK){ + if (status != ESP_OK) + { mp_raise_OSError(-status); } return mp_const_none; @@ -168,31 +190,39 @@ STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); // any() - return `True` if any message waiting, else `False` -STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in) +{ can_status_info_t status = _machine_hw_can_get_status(); - return mp_obj_new_bool((status.msgs_to_rx)>0); + return mp_obj_new_bool((status.msgs_to_rx) > 0); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_any_obj, machine_hw_can_any); // Get the state of the controller -STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) { +STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) +{ can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_int(status.state); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state); // Get info about error states and TX/RX buffers -STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) +{ machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_list_t *list; - if (n_args == 1) { + if (n_args == 1) + { list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); - } else { - if (!mp_obj_is_type(args[1], &mp_type_list)) { + } + else + { + if (!mp_obj_is_type(args[1], &mp_type_list)) + { mp_raise_TypeError(NULL); } list = MP_OBJ_TO_PTR(args[1]); - if (list->len < 8) { + if (list->len < 8) + { mp_raise_ValueError(NULL); } } @@ -210,10 +240,12 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); // Get Alert info -STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in) +{ uint32_t alerts; uint32_t status = can_read_alerts(&alerts, 0); - if (status != ESP_OK){ + if (status != ESP_OK) + { mp_raise_OSError(-status); } return mp_obj_new_int(alerts); @@ -221,75 +253,99 @@ STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in){ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_alert_obj, machine_hw_can_alert); // Clear TX Queue -STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ - return mp_obj_new_bool(can_clear_transmit_queue()==ESP_OK); +STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in) +{ + return mp_obj_new_bool(can_clear_transmit_queue() == ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); // Clear RX Queue -STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ - return mp_obj_new_bool(can_clear_receive_queue()==ESP_OK); +STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in) +{ + return mp_obj_new_bool(can_clear_receive_queue() == ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); - // send([data], id, *) -STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_data, ARG_id, ARG_timeout, ARG_rtr, ARG_self }; +STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) +{ + enum + { + ARG_data, + ARG_id, + ARG_timeout, + ARG_rtr, + ARG_self + }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + {MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0}}, + {MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}}, + {MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false}}, }; - + // parse args machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args-1, pos_args+1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + // populate message size_t length; mp_obj_t *items; - mp_obj_get_array(args[ARG_data].u_obj,&length, &items); - if (length>8){ + mp_obj_get_array(args[ARG_data].u_obj, &length, &items); + if (length > 8) + { mp_raise_ValueError("CAN data field too long"); } - uint8_t flags = (args[ARG_rtr].u_bool==true ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); + uint8_t flags = (args[ARG_rtr].u_bool == true ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); uint32_t id = args[ARG_id].u_int; - if (self->extframe){ + if (self->extframe) + { flags += CAN_MSG_FLAG_EXTD; id &= 0x1FFFFFFF; - }else{ + } + else + { id &= 0x1FF; } - if (self->loopback){ + if (self->loopback) + { flags += CAN_MSG_FLAG_SELF; } - can_message_t tx_msg = {.data_length_code = length, - .identifier = id, + can_message_t tx_msg = {.data_length_code = length, + .identifier = id, .flags = flags}; - for (uint8_t i=0; iitems; + items = ((mp_obj_tuple_t *)MP_OBJ_TO_PTR(ret_obj))->items; items[3] = mp_obj_new_bytes(rx_message.data, rx_message.data_length_code); - } else { + } + else + { // User should provide a list of length at least 4 to hold the values - if (!mp_obj_is_type(ret_obj, &mp_type_list)) { + if (!mp_obj_is_type(ret_obj, &mp_type_list)) + { mp_raise_TypeError(NULL); } mp_obj_list_t *list = MP_OBJ_TO_PTR(ret_obj); - if (list->len < 4) { + if (list->len < 4) + { mp_raise_ValueError(NULL); } items = list->items; // Fourth element must be a memoryview which we assume points to a // byte-like array which is large enough, and then we resize it inplace - if (!mp_obj_is_type(items[3], &mp_type_memoryview)) { + if (!mp_obj_is_type(items[3], &mp_type_memoryview)) + { mp_raise_TypeError(NULL); } mp_obj_array_t *mv = MP_OBJ_TO_PTR(items[3]); - if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) - || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))) { + if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))) + { mp_raise_ValueError(NULL); } mv->len = rx_message.data_length_code; memcpy(mv->items, rx_message.data, rx_message.data_length_code); - } items[0] = MP_OBJ_NEW_SMALL_INT(rx_message.identifier); items[1] = rx_message.flags && CAN_MSG_FLAG_RTR > 0 ? mp_const_true : mp_const_false; @@ -340,18 +402,24 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); -STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in) { +STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in) +{ mp_raise_NotImplementedError("IRQ not supported yet"); - machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (callback_in == mp_const_none) { + if (callback_in == mp_const_none) + { self->rxcallback = mp_const_none; - } else if (self->rxcallback != mp_const_none) { + } + else if (self->rxcallback != mp_const_none) + { // Rx call backs has already been initialized // only the callback function should be changed self->rxcallback = callback_in; // TODO: disable interrupt - } else if (mp_obj_is_callable(callback_in)) { + } + else if (mp_obj_is_callable(callback_in)) + { self->rxcallback = callback_in; // TODO: set interrupt } @@ -360,7 +428,8 @@ STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); // Clear filters setting -STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) { +STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) +{ machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); self->config->filter.single_filter = self->extframe; self->config->filter.acceptance_code = 0; @@ -368,8 +437,8 @@ STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) { ESP_STATUS_CHECK(can_stop()); ESP_STATUS_CHECK(can_driver_uninstall()); ESP_STATUS_CHECK(can_driver_install( - &self->config->general, - &self->config->timing, + &self->config->general, + &self->config->timing, &self->config->filter)); ESP_STATUS_CHECK(can_start()); return mp_const_none; @@ -381,15 +450,22 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clearfilter_obj, machine_hw_can_ // params: [id, mask] // rtr: ignored if FILTER_RAW // Set CAN HW filter -STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ - enum { ARG_bank, ARG_mode, ARG_params, ARG_rtr }; +STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) +{ + enum + { + ARG_bank, + ARG_mode, + ARG_params, + ARG_rtr + }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_bank, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_params, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_bool = false} }, + {MP_QSTR_bank, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0}}, + {MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0}}, + {MP_QSTR_params, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_bool = false}}, }; - + // parse args machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -397,58 +473,77 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args size_t len; mp_obj_t *params; - mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); - if(len != 2){ + mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); + if (len != 2) + { mp_raise_ValueError("params shall be a 2-values list"); } uint32_t id = mp_obj_get_int(params[0]); uint32_t mask = mp_obj_get_int(params[1]); // FIXME: Overflow in case 0xFFFFFFFF for mask - if (args[ARG_mode].u_int==FILTER_RAW_SINGLE || args[ARG_mode].u_int==FILTER_RAW_DUAL){ - self->config->filter.single_filter = (args[ARG_mode].u_int==FILTER_RAW_SINGLE); + if (args[ARG_mode].u_int == FILTER_RAW_SINGLE || args[ARG_mode].u_int == FILTER_RAW_DUAL) + { + self->config->filter.single_filter = (args[ARG_mode].u_int == FILTER_RAW_SINGLE); self->config->filter.acceptance_code = id; self->config->filter.acceptance_mask = mask; - }else{ + } + else + { self->config->filter.single_filter = self->extframe; _machine_hw_can_set_filter(self, id, mask, args[ARG_bank].u_int, args[ARG_rtr].u_int); } - ESP_STATUS_CHECK(can_stop()); + ESP_STATUS_CHECK(can_stop()); ESP_STATUS_CHECK(can_driver_uninstall()); ESP_STATUS_CHECK(can_driver_install( - &self->config->general, - &self->config->timing, + &self->config->general, + &self->config->timing, &self->config->filter)); ESP_STATUS_CHECK(can_start()); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter); -STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { +STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) +{ machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->config->initialized){ + if (self->config->initialized) + { qstr mode; - switch(self->config->general.mode){ - case CAN_MODE_LISTEN_ONLY: mode = MP_QSTR_LISTEN; break; - case CAN_MODE_NO_ACK: mode = MP_QSTR_NO_ACK; break; - case CAN_MODE_NORMAL: mode = MP_QSTR_NORMAL; break; - default: mode = MP_QSTR_UNKNOWN; break; + switch (self->config->general.mode) + { + case CAN_MODE_LISTEN_ONLY: + mode = MP_QSTR_LISTEN; + break; + case CAN_MODE_NO_ACK: + mode = MP_QSTR_NO_ACK; + break; + case CAN_MODE_NORMAL: + mode = MP_QSTR_NORMAL; + break; + default: + mode = MP_QSTR_UNKNOWN; + break; } - mp_printf(print, - "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%q, loopback=%u, extframe=%u)", - self->config->general.tx_io, - self->config->general.rx_io, - self->config->baudrate, - mode, - self->loopback, - self->extframe); - }else{ + mp_printf(print, + "CAN(tx=%u, rx=%u, baudrate=%ukb, mode=%q, loopback=%u, extframe=%u)", + self->config->general.tx_io, + self->config->general.rx_io, + self->config->baudrate, + mode, + self->loopback, + self->extframe); + } + else + { mp_printf(print, "CAN Device is not initialized"); } } // init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) -STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (self->config->initialized){ +STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) +{ + machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (self->config->initialized) + { ESP_LOGW(DEVICE_NAME, "Device is already initialized"); return mp_const_none; } @@ -457,18 +552,22 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); // deinit() -STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ - const machine_can_obj_t *self = &machine_can_obj; - if (self->config->initialized != true){ +STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in) +{ + const machine_can_obj_t *self = &machine_can_obj; + if (self->config->initialized != true) + { ESP_LOGW(DEVICE_NAME, "Device is not initialized"); return mp_const_none; } uint32_t status = can_stop(); - if(status!=ESP_OK){ + if (status != ESP_OK) + { mp_raise_OSError(-status); } status = can_driver_uninstall(); - if (status != ESP_OK){ + if (status != ESP_OK) + { mp_raise_OSError(-status); } self->config->initialized = false; @@ -478,20 +577,25 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deini // CAN(bus, ...) No argument to get the object // If no arguments are provided, the initialized object will be returned -mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args){ +mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *args) +{ // check arguments mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - if (mp_obj_is_int(args[0])!=true){ + if (mp_obj_is_int(args[0]) != true) + { mp_raise_TypeError("bus must be a number"); } mp_uint_t can_idx = mp_obj_get_int(args[0]); - if (can_idx > 1) { + if (can_idx > 1) + { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN(%d) doesn't exist", can_idx)); } - machine_can_obj_t *self = &machine_can_obj; - if (n_args > 1 || n_kw > 0) { - if (self->config->initialized) { + machine_can_obj_t *self = &machine_can_obj; + if (n_args > 1 || n_kw > 0) + { + if (self->config->initialized) + { // The caller is requesting a reconfiguration of the hardware // this can only be done if the hardware is in init mode ESP_LOGW(DEVICE_NAME, "Device is going to be reconfigured"); @@ -509,22 +613,36 @@ mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, } // init(mode, extframe=False, baudrate=500, *) -STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_mode, ARG_extframe, ARG_baudrate, ARG_prescaler, ARG_sjw, ARG_bs1, ARG_bs2, - ARG_tx_io, ARG_rx_io, ARG_tx_queue, ARG_rx_queue, ARG_auto_restart}; +STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) +{ + enum + { + ARG_mode, + ARG_extframe, + ARG_baudrate, + ARG_prescaler, + ARG_sjw, + ARG_bs1, + ARG_bs2, + ARG_tx_io, + ARG_rx_io, + ARG_tx_queue, + ARG_rx_queue, + ARG_auto_restart + }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, - { MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_prescaler, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_PRESCALER} }, - { MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_SJW} }, - { MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS1} }, - { MP_QSTR_bs2, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS2} }, - { MP_QSTR_tx_io, MP_ARG_INT, {.u_int = 4} }, - { MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2} }, - { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, - { MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = false} }, + {MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL}}, + {MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false}}, + {MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}}, + {MP_QSTR_prescaler, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_PRESCALER}}, + {MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_SJW}}, + {MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS1}}, + {MP_QSTR_bs2, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS2}}, + {MP_QSTR_tx_io, MP_ARG_INT, {.u_int = 4}}, + {MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2}}, + {MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0}}, + {MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5}}, + {MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = false}}, }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -537,12 +655,13 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->general.bus_off_io = CAN_IO_UNUSED; self->config->general.tx_queue_len = args[ARG_tx_queue].u_int; self->config->general.rx_queue_len = args[ARG_rx_queue].u_int; - self->config->general.alerts_enabled = CAN_ALERT_AND_LOG || CAN_ALERT_BELOW_ERR_WARN || CAN_ALERT_ERR_ACTIVE || CAN_ALERT_BUS_RECOVERED || - CAN_ALERT_ABOVE_ERR_WARN || CAN_ALERT_BUS_ERROR || CAN_ALERT_ERR_PASS || CAN_ALERT_BUS_OFF; + self->config->general.alerts_enabled = CAN_ALERT_AND_LOG || CAN_ALERT_BELOW_ERR_WARN || CAN_ALERT_ERR_ACTIVE || CAN_ALERT_BUS_RECOVERED || + CAN_ALERT_ABOVE_ERR_WARN || CAN_ALERT_BUS_ERROR || CAN_ALERT_ERR_PASS || CAN_ALERT_BUS_OFF; self->config->general.clkout_divider = 0; - self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); + self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); self->extframe = args[ARG_extframe].u_bool; - if (args[ARG_auto_restart].u_bool){ + if (args[ARG_auto_restart].u_bool) + { mp_raise_NotImplementedError("Auto-restart not supported"); } can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); @@ -550,58 +669,65 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->filter.acceptance_code = f_config.acceptance_code; self->config->filter.acceptance_mask = f_config.acceptance_mask; can_timing_config_t *timing; - switch ((int)args[ARG_baudrate].u_int){ - case 0: - timing = &((can_timing_config_t){ - .brp = args[ARG_prescaler].u_int, - .sjw = args[ARG_sjw].u_int, - .tseg_1 = args[ARG_bs1].u_int, - .tseg_2 = args[ARG_bs1].u_int, - .triple_sampling = false}); - break; - case CAN_BAUDRATE_25k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()); - break; - case CAN_BAUDRATE_50k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_50KBITS()); - break; - case CAN_BAUDRATE_100k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_100KBITS()); - break; - case CAN_BAUDRATE_125k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_125KBITS()); - break; - case CAN_BAUDRATE_250k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_250KBITS()); - break; - case CAN_BAUDRATE_500k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_500KBITS()); - break; - case CAN_BAUDRATE_800k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_800KBITS()); - break; - case CAN_BAUDRATE_1M: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); - break; - default: - mp_raise_ValueError("Unable to set baudrate"); - self->config->baudrate = 0; - return mp_const_none; + switch ((int)args[ARG_baudrate].u_int) + { + case 0: + timing = &((can_timing_config_t){ + .brp = args[ARG_prescaler].u_int, + .sjw = args[ARG_sjw].u_int, + .tseg_1 = args[ARG_bs1].u_int, + .tseg_2 = args[ARG_bs1].u_int, + .triple_sampling = false}); + break; + case CAN_BAUDRATE_25k: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()); + break; + case CAN_BAUDRATE_50k: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_50KBITS()); + break; + case CAN_BAUDRATE_100k: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_100KBITS()); + break; + case CAN_BAUDRATE_125k: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_125KBITS()); + break; + case CAN_BAUDRATE_250k: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_250KBITS()); + break; + case CAN_BAUDRATE_500k: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_500KBITS()); + break; + case CAN_BAUDRATE_800k: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_800KBITS()); + break; + case CAN_BAUDRATE_1M: + timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); + break; + default: + mp_raise_ValueError("Unable to set baudrate"); + self->config->baudrate = 0; + return mp_const_none; } self->config->timing = *timing; self->config->baudrate = args[ARG_baudrate].u_int; - + uint32_t status = can_driver_install( - &self->config->general, - &self->config->timing, - &(can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()); - if (status != ESP_OK){ + &self->config->general, + &self->config->timing, + &(can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()); + if (status != ESP_OK) + { mp_raise_OSError(-status); - }else{ + } + else + { status = can_start(); - if (status != ESP_OK){ + if (status != ESP_OK) + { mp_raise_OSError(-status); - }else{ + } + else + { self->config->initialized = true; } } @@ -610,72 +736,70 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { // CAN_ATTRIBUTES - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, + {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN)}, // Micropython Generic API - { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj) }, - { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj) }, - { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj) }, - { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, - { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, - { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_hw_can_setfilter_obj) }, - { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&machine_hw_can_clearfilter_obj) }, - { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj) }, - // ESP32 Specific API - { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, - - { MP_OBJ_NEW_QSTR(MP_QSTR_get_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj)}, - // CAN_MODE - { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, - { MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_NORMAL | 0x10) }, - { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK) }, - { MP_ROM_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_ROM_INT(CAN_MODE_NO_ACK | 0x10) }, - { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, + {MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj)}, + {MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj)}, + {MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj)}, + {MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj)}, + {MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj)}, + {MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj)}, + {MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, + {MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, + {MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_hw_can_setfilter_obj)}, + {MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&machine_hw_can_clearfilter_obj)}, + {MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj)}, + // ESP32 Specific API + {MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, + + {MP_OBJ_NEW_QSTR(MP_QSTR_get_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj)}, + // CAN_MODE + {MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL)}, + {MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_NORMAL | 0x10)}, + {MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK)}, + {MP_ROM_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_ROM_INT(CAN_MODE_NO_ACK | 0x10)}, + {MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY)}, // CAN_STATE - { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, - { MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_RUNNING) }, - { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, - { MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, + {MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED)}, + {MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_RUNNING)}, + {MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF)}, + {MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING)}, // CAN_BAUDRATE - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_100k), MP_ROM_INT(CAN_BAUDRATE_100k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(CAN_BAUDRATE_125k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(CAN_BAUDRATE_250k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k) }, - { MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M) }, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k)}, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k)}, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_100k), MP_ROM_INT(CAN_BAUDRATE_100k)}, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(CAN_BAUDRATE_125k)}, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(CAN_BAUDRATE_250k)}, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k)}, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k)}, + {MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M)}, // CAN_FILTER_MODE - { MP_ROM_QSTR(MP_QSTR_FILTER_RAW_SINGLE), MP_ROM_INT(FILTER_RAW_SINGLE) }, - { MP_ROM_QSTR(MP_QSTR_FILTER_RAW_DUAL), MP_ROM_INT(FILTER_RAW_DUAL) }, - { MP_ROM_QSTR(MP_QSTR_FILTER_ADDRESS), MP_ROM_INT(FILTER_ADDRESS) }, + {MP_ROM_QSTR(MP_QSTR_FILTER_RAW_SINGLE), MP_ROM_INT(FILTER_RAW_SINGLE)}, + {MP_ROM_QSTR(MP_QSTR_FILTER_RAW_DUAL), MP_ROM_INT(FILTER_RAW_DUAL)}, + {MP_ROM_QSTR(MP_QSTR_FILTER_ADDRESS), MP_ROM_INT(FILTER_ADDRESS)}, // CAN_ALERT - { MP_ROM_QSTR(MP_QSTR_ALERT_TX_IDLE), MP_ROM_INT(CAN_ALERT_TX_IDLE) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_TX_SUCCESS), MP_ROM_INT(CAN_ALERT_TX_SUCCESS) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_BELOW_ERR_WARN), MP_ROM_INT(CAN_ALERT_BELOW_ERR_WARN) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_ERR_ACTIVE), MP_ROM_INT(CAN_ALERT_ERR_ACTIVE) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_RECOVERY_IN_PROGRESS), MP_ROM_INT(CAN_ALERT_RECOVERY_IN_PROGRESS) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_BUS_RECOVERED), MP_ROM_INT(CAN_ALERT_BUS_RECOVERED) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_ARB_LOST), MP_ROM_INT(CAN_ALERT_ARB_LOST) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_ABOVE_ERR_WARN), MP_ROM_INT(CAN_ALERT_ABOVE_ERR_WARN) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_BUS_ERROR), MP_ROM_INT(CAN_ALERT_BUS_ERROR) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_TX_FAILED), MP_ROM_INT(CAN_ALERT_TX_FAILED) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_RX_QUEUE_FULL), MP_ROM_INT(CAN_ALERT_RX_QUEUE_FULL) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_ERR_PASS), MP_ROM_INT(CAN_ALERT_ERR_PASS) }, - { MP_ROM_QSTR(MP_QSTR_ALERT_BUS_OFF), MP_ROM_INT(CAN_ALERT_BUS_OFF) } -}; + {MP_ROM_QSTR(MP_QSTR_ALERT_TX_IDLE), MP_ROM_INT(CAN_ALERT_TX_IDLE)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_TX_SUCCESS), MP_ROM_INT(CAN_ALERT_TX_SUCCESS)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_BELOW_ERR_WARN), MP_ROM_INT(CAN_ALERT_BELOW_ERR_WARN)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_ERR_ACTIVE), MP_ROM_INT(CAN_ALERT_ERR_ACTIVE)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_RECOVERY_IN_PROGRESS), MP_ROM_INT(CAN_ALERT_RECOVERY_IN_PROGRESS)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_BUS_RECOVERED), MP_ROM_INT(CAN_ALERT_BUS_RECOVERED)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_ARB_LOST), MP_ROM_INT(CAN_ALERT_ARB_LOST)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_ABOVE_ERR_WARN), MP_ROM_INT(CAN_ALERT_ABOVE_ERR_WARN)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_BUS_ERROR), MP_ROM_INT(CAN_ALERT_BUS_ERROR)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_TX_FAILED), MP_ROM_INT(CAN_ALERT_TX_FAILED)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_RX_QUEUE_FULL), MP_ROM_INT(CAN_ALERT_RX_QUEUE_FULL)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_ERR_PASS), MP_ROM_INT(CAN_ALERT_ERR_PASS)}, + {MP_ROM_QSTR(MP_QSTR_ALERT_BUS_OFF), MP_ROM_INT(CAN_ALERT_BUS_OFF)}}; STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); // Python object definition const mp_obj_type_t machine_can_type = { - { &mp_type_type }, + {&mp_type_type}, .name = MP_QSTR_CAN, - .print = machine_hw_can_print, // give it a print-function - .make_new = machine_hw_can_make_new, // give it a constructor - .locals_dict = (mp_obj_dict_t*)&machine_can_locals_dict, // and the global members + .print = machine_hw_can_print, // give it a print-function + .make_new = machine_hw_can_make_new, // give it a constructor + .locals_dict = (mp_obj_dict_t *)&machine_can_locals_dict, // and the global members }; #endif // MICROPY_HW_ENABLE_CAN - From c807e7d99cfd64bc7e71c7ea41e35b36079e6c54 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 9 Jan 2020 22:27:47 +0100 Subject: [PATCH 55/62] Removed additional constants and added in documentation --- docs/library/esp32.CAN.rst | 20 +++++++++++++++++++- ports/esp32/machine_can.c | 25 +------------------------ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/docs/library/esp32.CAN.rst b/docs/library/esp32.CAN.rst index 0a35accdf630a..6c3ebe2f8679c 100644 --- a/docs/library/esp32.CAN.rst +++ b/docs/library/esp32.CAN.rst @@ -43,7 +43,7 @@ Methods - if *extframe* is True then the bus uses extended identifiers in the frames (29 bits); otherwise it uses standard 11 bit identifiers - *baudrate* is used to define a standard speed. If it is defined, the *prescaler*, *sjw*, *bs1*, *bs2* - will be ignored. Standard speeds are available as CAN.BAUDRATE_* + will be ignored. Standard speeds are 25, 50, 100, 125, 250, 500, 1000 - *prescaler* is used to set the duration of 1 time quanta; the time quanta will be the input clock (PCLK1, see :meth:`pyb.freq()`) divided by the prescaler - *sjw* is the resynchronisation jump width in units of the time quanta; @@ -210,6 +210,24 @@ Methods .. method:: CAN.get_alerts() Read the alert status word directly from hardware. + In order to save space in the firmware, the constants for the result decoding are not included on the :mod:`machine.CAN` module. Add the ones that you need from the list below to your program. + + The event codes are:: + + from micropython import const + CAN_ALERT_TX_IDLE = const(0x0001) + CAN_ALERT_TX_SUCCESS = const(0x0002) + CAN_ALERT_BELOW_ERR_WARN = const(0x0004) + CAN_ALERT_ERR_ACTIVE = const(0x0008) + CAN_ALERT_RECOVERY_IN_PROGRESS = const(0x0010) + CAN_ALERT_BUS_RECOVERED = const(0x0020) + CAN_ALERT_ARB_LOST = const(0x0040) + CAN_ALERT_ABOVE_ERR_WARN = const(0x0080) + CAN_ALERT_BUS_ERROR = const(0x0100) + CAN_ALERT_TX_FAILED = const(0x0200) + CAN_ALERT_RX_QUEUE_FULL = const(0x0400) + CAN_ALERT_ERR_PASS = const(0x0800) + CAN_ALERT_BUS_OFF = const(0x1000) .. method:: CAN.rxcallback(fifo, fun) TODO: NOT YET IMPLEMENTED diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 7dfc8729c6178..f607e140ea95f 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -752,7 +752,6 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { // ESP32 Specific API {MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, {MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, - {MP_OBJ_NEW_QSTR(MP_QSTR_get_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj)}, // CAN_MODE {MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL)}, @@ -765,33 +764,11 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { {MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_RUNNING)}, {MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF)}, {MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING)}, - // CAN_BAUDRATE - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_25k), MP_ROM_INT(CAN_BAUDRATE_25k)}, - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_50k), MP_ROM_INT(CAN_BAUDRATE_50k)}, - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_100k), MP_ROM_INT(CAN_BAUDRATE_100k)}, - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_125k), MP_ROM_INT(CAN_BAUDRATE_125k)}, - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_250k), MP_ROM_INT(CAN_BAUDRATE_250k)}, - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_500k), MP_ROM_INT(CAN_BAUDRATE_500k)}, - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_800k), MP_ROM_INT(CAN_BAUDRATE_800k)}, - {MP_ROM_QSTR(MP_QSTR_BAUDRATE_1M), MP_ROM_INT(CAN_BAUDRATE_1M)}, // CAN_FILTER_MODE {MP_ROM_QSTR(MP_QSTR_FILTER_RAW_SINGLE), MP_ROM_INT(FILTER_RAW_SINGLE)}, {MP_ROM_QSTR(MP_QSTR_FILTER_RAW_DUAL), MP_ROM_INT(FILTER_RAW_DUAL)}, {MP_ROM_QSTR(MP_QSTR_FILTER_ADDRESS), MP_ROM_INT(FILTER_ADDRESS)}, - // CAN_ALERT - {MP_ROM_QSTR(MP_QSTR_ALERT_TX_IDLE), MP_ROM_INT(CAN_ALERT_TX_IDLE)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_TX_SUCCESS), MP_ROM_INT(CAN_ALERT_TX_SUCCESS)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_BELOW_ERR_WARN), MP_ROM_INT(CAN_ALERT_BELOW_ERR_WARN)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_ERR_ACTIVE), MP_ROM_INT(CAN_ALERT_ERR_ACTIVE)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_RECOVERY_IN_PROGRESS), MP_ROM_INT(CAN_ALERT_RECOVERY_IN_PROGRESS)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_BUS_RECOVERED), MP_ROM_INT(CAN_ALERT_BUS_RECOVERED)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_ARB_LOST), MP_ROM_INT(CAN_ALERT_ARB_LOST)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_ABOVE_ERR_WARN), MP_ROM_INT(CAN_ALERT_ABOVE_ERR_WARN)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_BUS_ERROR), MP_ROM_INT(CAN_ALERT_BUS_ERROR)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_TX_FAILED), MP_ROM_INT(CAN_ALERT_TX_FAILED)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_RX_QUEUE_FULL), MP_ROM_INT(CAN_ALERT_RX_QUEUE_FULL)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_ERR_PASS), MP_ROM_INT(CAN_ALERT_ERR_PASS)}, - {MP_ROM_QSTR(MP_QSTR_ALERT_BUS_OFF), MP_ROM_INT(CAN_ALERT_BUS_OFF)}}; +}; STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); // Python object definition From b07db3a05a45afc9a05584fbafe27a1ec3ce16ea Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 9 Jan 2020 22:39:10 +0100 Subject: [PATCH 56/62] Documentation bugfix --- docs/library/esp32.CAN.rst | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/docs/library/esp32.CAN.rst b/docs/library/esp32.CAN.rst index 6c3ebe2f8679c..7c9152ba801fb 100644 --- a/docs/library/esp32.CAN.rst +++ b/docs/library/esp32.CAN.rst @@ -14,9 +14,9 @@ Example usage (works without anything connected):: from machine import CAN can = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=CAN.BAUDRATE_500k) - can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) # set a filter to receive messages with id=123, 124, 125 and 126 - can.send([1,2,3], 123) # send a message with id 123 - can.recv() # receive message + dev.setfilter(0, CAN.FILTER_ADDRESS, [0x102, 0]) # set a filter to receive messages with id = 0x102 + can.send([1,2,3], 0x102) # send a message with id 123 + can.recv() # receive message Constructors @@ -45,7 +45,7 @@ Methods - *baudrate* is used to define a standard speed. If it is defined, the *prescaler*, *sjw*, *bs1*, *bs2* will be ignored. Standard speeds are 25, 50, 100, 125, 250, 500, 1000 - *prescaler* is used to set the duration of 1 time quanta; the time quanta - will be the input clock (PCLK1, see :meth:`pyb.freq()`) divided by the prescaler + will be the input clock divided by the prescaler - *sjw* is the resynchronisation jump width in units of the time quanta; it can be 1, 2, 3, 4 - *bs1* defines the location of the sample point in units of the time quanta; @@ -293,25 +293,9 @@ Constants Possible states of the CAN controller returned from :meth:`~CAN.state()`. -.. data:: CAN.LIST16 TODO: - CAN.MASK16 - CAN.LIST32 - CAN.MASK32 +.. data:: CAN.FILTER_RAW_SINGLE + CAN.FILTER_RAW_DUAL + CAN.FILTER_ADDRESS The operation mode of a filter used in :meth:`~CAN.setfilter()`. -.. data:: CAN.ALERT_TX_IDLE - CAN.ALERT_TX_SUCCESS - CAN.ALERT_BELOW_ERR_WARN - CAN.ALERT_ERR_ACTIVE - CAN.ALERT_RECOVERY_IN_PROGRESS - CAN.ALERT_BUS_RECOVERED - CAN.ALERT_ARB_LOST - CAN.ALERT_ABOVE_ERR_WARN - CAN.ALERT_BUS_ERROR - CAN.ALERT_TX_FAILED - CAN.ALERT_RX_QUEUE_FULL - CAN.ALERT_ERR_PASS - CAN.ALERT_BUS_OFF - - Possibile bit position of alert mask returned by :meth:`~CAN.get_alerts()`. From c8afef6e86f07f80563bd5d29a34d051258facba Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 9 Jan 2020 22:39:39 +0100 Subject: [PATCH 57/62] removed implemented methods --- docs/library/esp32.CAN.rst | 47 +------------------------------------- ports/esp32/machine_can.c | 28 +---------------------- 2 files changed, 2 insertions(+), 73 deletions(-) diff --git a/docs/library/esp32.CAN.rst b/docs/library/esp32.CAN.rst index 7c9152ba801fb..299e0cc2010f0 100644 --- a/docs/library/esp32.CAN.rst +++ b/docs/library/esp32.CAN.rst @@ -87,7 +87,7 @@ Methods - ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity (TEC overflowed beyond 255). - ``CAN.RECOVERING`` -- the controller is under recover from bus-off state; - + .. method:: CAN.info([list]) @@ -228,41 +228,7 @@ Methods CAN_ALERT_RX_QUEUE_FULL = const(0x0400) CAN_ALERT_ERR_PASS = const(0x0800) CAN_ALERT_BUS_OFF = const(0x1000) - - -.. method:: CAN.rxcallback(fifo, fun) TODO: NOT YET IMPLEMENTED - - Register a function to be called when a message is accepted into a empty fifo: - - - *fifo* is the receiving fifo. - - *fun* is the function to be called when the fifo becomes non empty. - The callback function takes two arguments the first is the can object it self the second is - a integer that indicates the reason for the callback. - - +--------+------------------------------------------------+ - | Reason | | - +========+================================================+ - | 0 | A message has been accepted into a empty FIFO. | - +--------+------------------------------------------------+ - | 1 | The FIFO is full | - +--------+------------------------------------------------+ - | 2 | A message has been lost due to a full FIFO | - +--------+------------------------------------------------+ - - Example use of rxcallback:: - - def cb0(bus, reason): - print('cb0') - if reason == 0: - print('pending') - if reason == 1: - print('full') - if reason == 2: - print('overflow') - - can = CAN(1, CAN.LOOPBACK) - can.rxcallback(0, cb0) Constants --------- @@ -275,17 +241,6 @@ Constants The mode of the CAN bus used in :meth:`~CAN.init()`. -.. data:: CAN.BAUDRATE_25k - CAN.BAUDRATE_50k - CAN.BAUDRATE_100k - CAN.BAUDRATE_125k - CAN.BAUDRATE_250k - CAN.BAUDRATE_500k - CAN.BAUDRATE_800k - CAN.BAUDRATE_1M - - The baudrate of the CAN bus used in :meth:`~CAN.init()`. - .. data:: CAN.STOPPED CAN.ERROR_ACTIVE CAN.BUS_OFF diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index f607e140ea95f..2c674debd3a6b 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -179,7 +179,7 @@ STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in) { mp_raise_OSError(-status); } - mp_hal_delay_ms(200); // TODO: replace it with a smarter solution + mp_hal_delay_ms(200); status = can_start(); if (status != ESP_OK) { @@ -402,31 +402,6 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); -STATIC mp_obj_t machine_hw_can_rxcallback(mp_obj_t self_in, mp_obj_t callback_in) -{ - mp_raise_NotImplementedError("IRQ not supported yet"); - machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (callback_in == mp_const_none) - { - self->rxcallback = mp_const_none; - } - else if (self->rxcallback != mp_const_none) - { - // Rx call backs has already been initialized - // only the callback function should be changed - self->rxcallback = callback_in; - // TODO: disable interrupt - } - else if (mp_obj_is_callable(callback_in)) - { - self->rxcallback = callback_in; - // TODO: set interrupt - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hw_can_rxcallback_obj, machine_hw_can_rxcallback); - // Clear filters setting STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) { @@ -748,7 +723,6 @@ STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { {MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, {MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_hw_can_setfilter_obj)}, {MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&machine_hw_can_clearfilter_obj)}, - {MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_hw_can_rxcallback_obj)}, // ESP32 Specific API {MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, {MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, From b9525138ec4ef1c7203998586567295fdd60c4b0 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 30 Jan 2020 19:01:23 +0100 Subject: [PATCH 58/62] beautify: brackets inline --- ports/esp32/machine_can.c | 227 ++++++++++++-------------------------- 1 file changed, 72 insertions(+), 155 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 2c674debd3a6b..e74636470da93 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -57,15 +57,13 @@ { \ mp_raise_OSError(-status); \ } -typedef enum _filter_mode_t -{ +typedef enum _filter_mode_t{ FILTER_RAW_SINGLE = 0, FILTER_RAW_DUAL, FILTER_ADDRESS } filter_mode_t; -typedef struct _machine_can_config_t -{ +typedef struct _machine_can_config_t{ can_timing_config_t timing; can_filter_config_t filter; can_general_config_t general; @@ -73,8 +71,7 @@ typedef struct _machine_can_config_t bool initialized; } machine_can_config_t; -typedef struct _machine_can_obj_t -{ +typedef struct _machine_can_obj_t{ mp_obj_base_t base; machine_can_config_t *config; mp_obj_t rxcallback; @@ -86,8 +83,7 @@ typedef struct _machine_can_obj_t uint16_t num_bus_off; } machine_can_obj_t; -typedef enum _rx_state_t -{ +typedef enum _rx_state_t{ RX_STATE_FIFO_EMPTY = 0, RX_STATE_MESSAGE_PENDING, RX_STATE_FIFO_FULL, @@ -114,8 +110,7 @@ machine_can_config_t can_config = {.general = CAN_GENERAL_CONFIG_DEFAULT(2, 4, 0 STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config = &can_config}; // INTERNAL FUNCTION Return status information -STATIC can_status_info_t _machine_hw_can_get_status() -{ +STATIC can_status_info_t _machine_hw_can_get_status(){ can_status_info_t status; uint32_t err_code = can_get_status_info(&status); if (err_code != ESP_OK) @@ -126,41 +121,31 @@ STATIC can_status_info_t _machine_hw_can_get_status() } //INTERNAL FUNCTION Populates the filter register according to inputs -STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr) -{ +STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr){ //Check if bank is allowed - if (bank < 0 && bank > ((self->extframe && self->config->filter.single_filter) ? 0 : 1)) - { + if (bank < 0 && bank > ((self->extframe && self->config->filter.single_filter) ? 0 : 1)){ mp_raise_ValueError("CAN filter parameter error"); } uint32_t preserve_mask; - if (self->extframe) - { + if (self->extframe){ addr = (addr & 0x1FFFFFFF) << 3 | (rtr ? 0x04 : 0); mask = (mask & 0x1FFFFFFF) << 3 | 0x03; preserve_mask = 0; - } - else if (self->config->filter.single_filter) - { + }else if (self->config->filter.single_filter){ addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); mask = ((mask & 0x7FF) << 5); mask |= 0xFFFFF000; preserve_mask = 0; - } - else - { + }else{ addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); mask = ((mask & 0x7FF) << 5); preserve_mask = 0xFFFF << (bank == 0 ? 16 : 0); - if ((self->config->filter.acceptance_mask & preserve_mask) == (0xFFFF << (bank == 0 ? 16 : 0))) - { + if ((self->config->filter.acceptance_mask & preserve_mask) == (0xFFFF << (bank == 0 ? 16 : 0))){ // Other filter accepts all; it will replaced duplicating current filter addr = addr | (addr << 16); mask = mask | (mask << 16); preserve_mask = 0; - } - else - { + }else{ addr = addr << (bank == 1 ? 16 : 0); mask = mask << (bank == 1 ? 16 : 0); } @@ -172,17 +157,14 @@ STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, u } // Force a software restart of the controller, to allow transmission after a bus error -STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ uint32_t status = can_initiate_recovery(); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); } mp_hal_delay_ms(200); status = can_start(); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); } return mp_const_none; @@ -190,39 +172,31 @@ STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in) STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); // any() - return `True` if any message waiting, else `False` -STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in){ can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_bool((status.msgs_to_rx) > 0); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_any_obj, machine_hw_can_any); // Get the state of the controller -STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in){ can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_int(status.state); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state); // Get info about error states and TX/RX buffers -STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) -{ +STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args){ machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_list_t *list; - if (n_args == 1) - { + if (n_args == 1){ list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); - } - else - { - if (!mp_obj_is_type(args[1], &mp_type_list)) - { + }else{ + if (!mp_obj_is_type(args[1], &mp_type_list)){ mp_raise_TypeError(NULL); } list = MP_OBJ_TO_PTR(args[1]); - if (list->len < 8) - { + if (list->len < 8){ mp_raise_ValueError(NULL); } } @@ -240,12 +214,10 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); // Get Alert info -STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in){ uint32_t alerts; uint32_t status = can_read_alerts(&alerts, 0); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); } return mp_obj_new_int(alerts); @@ -253,24 +225,20 @@ STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in) STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_alert_obj, machine_hw_can_alert); // Clear TX Queue -STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_transmit_queue() == ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); // Clear RX Queue -STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ return mp_obj_new_bool(can_clear_receive_queue() == ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); // send([data], id, *) -STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) -{ - enum - { +STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ + enum{ ARG_data, ARG_id, ARG_timeout, @@ -293,53 +261,41 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ size_t length; mp_obj_t *items; mp_obj_get_array(args[ARG_data].u_obj, &length, &items); - if (length > 8) - { + if (length > 8){ mp_raise_ValueError("CAN data field too long"); } uint8_t flags = (args[ARG_rtr].u_bool == true ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); uint32_t id = args[ARG_id].u_int; - if (self->extframe) - { + if (self->extframe){ flags += CAN_MSG_FLAG_EXTD; id &= 0x1FFFFFFF; - } - else - { + }else{ id &= 0x1FF; } - if (self->loopback) - { + if (self->loopback){ flags += CAN_MSG_FLAG_SELF; } can_message_t tx_msg = {.data_length_code = length, .identifier = id, .flags = flags}; - for (uint8_t i = 0; i < length; i++) - { + for (uint8_t i = 0; i < length; i++){ tx_msg.data[i] = mp_obj_get_int(items[i]); } - if (_machine_hw_can_get_status().state == CAN_STATE_RUNNING) - { + if (_machine_hw_can_get_status().state == CAN_STATE_RUNNING){ int status = can_transmit(&tx_msg, args[ARG_timeout].u_int); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); } return mp_const_none; - } - else - { + }else{ nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "CAN Device is not ready")); } } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_send); // recv(list=None, *, timeout=5000) -STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) -{ - enum - { +STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ + enum{ ARG_list, ARG_timeout }; @@ -354,42 +310,34 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ can_message_t rx_message; int status = can_receive(&rx_message, 1); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); } // Create the tuple, or get the list, that will hold the return values // Also populate the fourth element, either a new bytes or reuse existing memoryview mp_obj_t ret_obj = args[ARG_list].u_obj; mp_obj_t *items; - if (ret_obj == mp_const_none) - { + if (ret_obj == mp_const_none){ ret_obj = mp_obj_new_tuple(4, NULL); items = ((mp_obj_tuple_t *)MP_OBJ_TO_PTR(ret_obj))->items; items[3] = mp_obj_new_bytes(rx_message.data, rx_message.data_length_code); - } - else - { + }else{ // User should provide a list of length at least 4 to hold the values - if (!mp_obj_is_type(ret_obj, &mp_type_list)) - { + if (!mp_obj_is_type(ret_obj, &mp_type_list)){ mp_raise_TypeError(NULL); } mp_obj_list_t *list = MP_OBJ_TO_PTR(ret_obj); - if (list->len < 4) - { + if (list->len < 4){ mp_raise_ValueError(NULL); } items = list->items; // Fourth element must be a memoryview which we assume points to a // byte-like array which is large enough, and then we resize it inplace - if (!mp_obj_is_type(items[3], &mp_type_memoryview)) - { + if (!mp_obj_is_type(items[3], &mp_type_memoryview)){ mp_raise_TypeError(NULL); } mp_obj_array_t *mv = MP_OBJ_TO_PTR(items[3]); - if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))) - { + if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))){ mp_raise_ValueError(NULL); } mv->len = rx_message.data_length_code; @@ -403,8 +351,7 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); // Clear filters setting -STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in){ machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); self->config->filter.single_filter = self->extframe; self->config->filter.acceptance_code = 0; @@ -425,8 +372,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clearfilter_obj, machine_hw_can_ // params: [id, mask] // rtr: ignored if FILTER_RAW // Set CAN HW filter -STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) -{ +STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ enum { ARG_bank, @@ -449,20 +395,16 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args size_t len; mp_obj_t *params; mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); - if (len != 2) - { + if (len != 2){ mp_raise_ValueError("params shall be a 2-values list"); } uint32_t id = mp_obj_get_int(params[0]); uint32_t mask = mp_obj_get_int(params[1]); // FIXME: Overflow in case 0xFFFFFFFF for mask - if (args[ARG_mode].u_int == FILTER_RAW_SINGLE || args[ARG_mode].u_int == FILTER_RAW_DUAL) - { + if (args[ARG_mode].u_int == FILTER_RAW_SINGLE || args[ARG_mode].u_int == FILTER_RAW_DUAL){ self->config->filter.single_filter = (args[ARG_mode].u_int == FILTER_RAW_SINGLE); self->config->filter.acceptance_code = id; self->config->filter.acceptance_mask = mask; - } - else - { + }else{ self->config->filter.single_filter = self->extframe; _machine_hw_can_set_filter(self, id, mask, args[ARG_bank].u_int, args[ARG_rtr].u_int); } @@ -477,11 +419,9 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter); -STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) -{ +STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind){ machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->config->initialized) - { + if (self->config->initialized){ qstr mode; switch (self->config->general.mode) { @@ -506,19 +446,15 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p mode, self->loopback, self->extframe); - } - else - { + }else{ mp_printf(print, "CAN Device is not initialized"); } } // init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) -STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) -{ +STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args){ machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (self->config->initialized) - { + if (self->config->initialized){ ESP_LOGW(DEVICE_NAME, "Device is already initialized"); return mp_const_none; } @@ -527,22 +463,18 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); // deinit() -STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in) -{ +STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ const machine_can_obj_t *self = &machine_can_obj; - if (self->config->initialized != true) - { + if (self->config->initialized != true){ ESP_LOGW(DEVICE_NAME, "Device is not initialized"); return mp_const_none; } uint32_t status = can_stop(); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); } status = can_driver_uninstall(); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); } self->config->initialized = false; @@ -553,24 +485,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deini // CAN(bus, ...) No argument to get the object // If no arguments are provided, the initialized object will be returned mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args) -{ + size_t n_kw, const mp_obj_t *args){ // check arguments mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - if (mp_obj_is_int(args[0]) != true) - { + if (mp_obj_is_int(args[0]) != true){ mp_raise_TypeError("bus must be a number"); } mp_uint_t can_idx = mp_obj_get_int(args[0]); - if (can_idx > 1) - { + if (can_idx > 1){ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN(%d) doesn't exist", can_idx)); } machine_can_obj_t *self = &machine_can_obj; - if (n_args > 1 || n_kw > 0) - { - if (self->config->initialized) - { + if (n_args > 1 || n_kw > 0){ + if (self->config->initialized){ // The caller is requesting a reconfiguration of the hardware // this can only be done if the hardware is in init mode ESP_LOGW(DEVICE_NAME, "Device is going to be reconfigured"); @@ -588,10 +515,8 @@ mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, } // init(mode, extframe=False, baudrate=500, *) -STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) -{ - enum - { +STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ + enum{ ARG_mode, ARG_extframe, ARG_baudrate, @@ -635,8 +560,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->general.clkout_divider = 0; self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); self->extframe = args[ARG_extframe].u_bool; - if (args[ARG_auto_restart].u_bool) - { + if (args[ARG_auto_restart].u_bool){ mp_raise_NotImplementedError("Auto-restart not supported"); } can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); @@ -644,8 +568,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->filter.acceptance_code = f_config.acceptance_code; self->config->filter.acceptance_mask = f_config.acceptance_mask; can_timing_config_t *timing; - switch ((int)args[ARG_baudrate].u_int) - { + switch ((int)args[ARG_baudrate].u_int){ case 0: timing = &((can_timing_config_t){ .brp = args[ARG_prescaler].u_int, @@ -690,19 +613,13 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg &self->config->general, &self->config->timing, &(can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); - } - else - { + }else{ status = can_start(); - if (status != ESP_OK) - { + if (status != ESP_OK){ mp_raise_OSError(-status); - } - else - { + }else{ self->config->initialized = true; } } From faf2e9063e907a2f261e79541c99e181e20e2ecf Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 30 Jan 2020 19:02:17 +0100 Subject: [PATCH 59/62] documentation update: from esp32 specifc module to machine module --- docs/esp32/quickref.rst | 13 ++++++------- docs/library/{esp32.CAN.rst => machine.CAN.rst} | 11 ++++++----- 2 files changed, 12 insertions(+), 12 deletions(-) rename docs/library/{esp32.CAN.rst => machine.CAN.rst} (97%) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 2b8893c45881a..9eb063f187dab 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -328,19 +328,18 @@ pins can be used for SCL and SDA. The driver is accessed via the CAN bus ------- -See :ref:`esp32.CAN ` :: +See :ref:`machine.CAN ` :: The CAN driver is based on hardware implementation. Any available output-capablepins can be used for SCL and SDA. The driver is accessed via the :ref:`machine.CAN ` class:: from machine import CAN - - # construct a CAN bus - bus = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=CAN.BAUDRATE_500k) - - bus.send([0,1,2,3], 0x86) #Send the message - bus.recv() #Read the message sent + BAUDRATE_500k = 500 + can = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=BAUDRATE_500k) + dev.setfilter(0, CAN.FILTER_ADDRESS, [0x102, 0]) # set a filter to receive messages with id = 0x102 + can.send([1,2,3], 0x102) # send a message with id 123 + can.recv() # receive message Real time clock (RTC) diff --git a/docs/library/esp32.CAN.rst b/docs/library/machine.CAN.rst similarity index 97% rename from docs/library/esp32.CAN.rst rename to docs/library/machine.CAN.rst index 299e0cc2010f0..4b73f185da0ce 100644 --- a/docs/library/esp32.CAN.rst +++ b/docs/library/machine.CAN.rst @@ -1,19 +1,20 @@ -.. currentmodule:: esp32 -.. _esp32.CAN: +.. currentmodule:: machine +.. _machine.CAN: class CAN -- controller area network communication bus ====================================================== CAN implements the standard CAN communications protocol. At the physical level it consists of 2 lines: RX and TX. Note that -to connect the ESP32 to a CAN bus you must use a CAN transceiver -to convert the CAN logic signals from the ESP32 to the correct +to connect the microcontroller to a CAN bus you must use a CAN transceiver +to convert the CAN logic signals from the microcontroller to the correct voltage levels on the bus. Example usage (works without anything connected):: from machine import CAN - can = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=CAN.BAUDRATE_500k) + BAUDRATE_500k = 500 + can = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=BAUDRATE_500k) dev.setfilter(0, CAN.FILTER_ADDRESS, [0x102, 0]) # set a filter to receive messages with id = 0x102 can.send([1,2,3], 0x102) # send a message with id 123 can.recv() # receive message From d95976244cfd2a425fc8eb0e6606e15c5ddd212a Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Thu, 30 Jan 2020 19:11:00 +0100 Subject: [PATCH 60/62] revert unnecessary changes --- .gitignore | 3 --- docs/library/esp32.rst | 10 +--------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index a4ef09599ecb6..50bd30e877e87 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,3 @@ user.props # Generated rst files ###################### genrst/ -docs/_build -.vscode -esp-idf diff --git a/docs/library/esp32.rst b/docs/library/esp32.rst index 4cd7efc3949e5..77d0485f51414 100644 --- a/docs/library/esp32.rst +++ b/docs/library/esp32.rst @@ -108,12 +108,4 @@ Constants .. data:: esp32.WAKEUP_ALL_LOW esp32.WAKEUP_ANY_HIGH - Selects the wake level for pins. - -Classes -------- - -.. toctree:: - :maxdepth: 1 - - esp32.CAN.rst + Selects the wake level for pins. \ No newline at end of file From 3cf09b09b1554396c1e6f389bb496bb65d7cd696 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Tue, 4 Feb 2020 23:07:03 +0100 Subject: [PATCH 61/62] code beautify --- ports/esp32/machine_can.c | 190 +++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 97 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index e74636470da93..0974b7d37e32d 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -53,17 +53,16 @@ #define CAN_BAUDRATE_1M 1000 #define ESP_STATUS_CHECK(status) \ - if (status != ESP_OK) \ - { \ + if (status != ESP_OK) { \ mp_raise_OSError(-status); \ } -typedef enum _filter_mode_t{ +typedef enum _filter_mode_t { FILTER_RAW_SINGLE = 0, FILTER_RAW_DUAL, FILTER_ADDRESS } filter_mode_t; -typedef struct _machine_can_config_t{ +typedef struct _machine_can_config_t { can_timing_config_t timing; can_filter_config_t filter; can_general_config_t general; @@ -71,7 +70,7 @@ typedef struct _machine_can_config_t{ bool initialized; } machine_can_config_t; -typedef struct _machine_can_obj_t{ +typedef struct _machine_can_obj_t { mp_obj_base_t base; machine_can_config_t *config; mp_obj_t rxcallback; @@ -83,7 +82,7 @@ typedef struct _machine_can_obj_t{ uint16_t num_bus_off; } machine_can_obj_t; -typedef enum _rx_state_t{ +typedef enum _rx_state_t { RX_STATE_FIFO_EMPTY = 0, RX_STATE_MESSAGE_PENDING, RX_STATE_FIFO_FULL, @@ -102,28 +101,25 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); // singleton CAN device object -machine_can_config_t can_config = {.general = CAN_GENERAL_CONFIG_DEFAULT(2, 4, 0), - .filter = CAN_FILTER_CONFIG_ACCEPT_ALL(), - .timing = CAN_TIMING_CONFIG_25KBITS(), - .initialized = false}; +machine_can_config_t can_config = { .general = CAN_GENERAL_CONFIG_DEFAULT(2, 4, 0), + .filter = CAN_FILTER_CONFIG_ACCEPT_ALL(), + .timing = CAN_TIMING_CONFIG_25KBITS(), + .initialized = false }; -STATIC machine_can_obj_t machine_can_obj = {{&machine_can_type}, .config = &can_config}; +STATIC machine_can_obj_t machine_can_obj = { {&machine_can_type}, .config = &can_config }; -// INTERNAL FUNCTION Return status information STATIC can_status_info_t _machine_hw_can_get_status(){ can_status_info_t status; uint32_t err_code = can_get_status_info(&status); - if (err_code != ESP_OK) - { + if (err_code != ESP_OK){ mp_raise_OSError(-err_code); } return status; } -//INTERNAL FUNCTION Populates the filter register according to inputs STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr){ //Check if bank is allowed - if (bank < 0 && bank > ((self->extframe && self->config->filter.single_filter) ? 0 : 1)){ + if ( bank < 0 && bank > ( (self->extframe && self->config->filter.single_filter) ? 0 : 1 ) ){ mp_raise_ValueError("CAN filter parameter error"); } uint32_t preserve_mask; @@ -131,21 +127,21 @@ STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, u addr = (addr & 0x1FFFFFFF) << 3 | (rtr ? 0x04 : 0); mask = (mask & 0x1FFFFFFF) << 3 | 0x03; preserve_mask = 0; - }else if (self->config->filter.single_filter){ - addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); - mask = ((mask & 0x7FF) << 5); + } else if (self->config->filter.single_filter){ + addr = ( ( (addr & 0x7FF) << 5 ) | (rtr ? 0x10 : 0) ); + mask = ( (mask & 0x7FF) << 5 ); mask |= 0xFFFFF000; preserve_mask = 0; - }else{ - addr = (((addr & 0x7FF) << 5) | (rtr ? 0x10 : 0)); - mask = ((mask & 0x7FF) << 5); - preserve_mask = 0xFFFF << (bank == 0 ? 16 : 0); - if ((self->config->filter.acceptance_mask & preserve_mask) == (0xFFFF << (bank == 0 ? 16 : 0))){ + } else { + addr = ( ( (addr & 0x7FF) << 5 ) | (rtr ? 0x10 : 0) ); + mask = ( (mask & 0x7FF) << 5 ); + preserve_mask = 0xFFFF << ( bank == 0 ? 16 : 0 ); + if ( (self->config->filter.acceptance_mask & preserve_mask) == ( 0xFFFF << (bank == 0 ? 16 : 0) ) ){ // Other filter accepts all; it will replaced duplicating current filter addr = addr | (addr << 16); mask = mask | (mask << 16); preserve_mask = 0; - }else{ + } else { addr = addr << (bank == 1 ? 16 : 0); mask = mask << (bank == 1 ? 16 : 0); } @@ -191,7 +187,7 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args){ mp_obj_list_t *list; if (n_args == 1){ list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); - }else{ + } else{ if (!mp_obj_is_type(args[1], &mp_type_list)){ mp_raise_TypeError(NULL); } @@ -264,20 +260,20 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ if (length > 8){ mp_raise_ValueError("CAN data field too long"); } - uint8_t flags = (args[ARG_rtr].u_bool == true ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); + uint8_t flags = (args[ARG_rtr].u_bool ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); uint32_t id = args[ARG_id].u_int; if (self->extframe){ flags += CAN_MSG_FLAG_EXTD; id &= 0x1FFFFFFF; - }else{ + } else { id &= 0x1FF; } if (self->loopback){ flags += CAN_MSG_FLAG_SELF; } - can_message_t tx_msg = {.data_length_code = length, - .identifier = id, - .flags = flags}; + can_message_t tx_msg = { .data_length_code = length, + .identifier = id, + .flags = flags }; for (uint8_t i = 0; i < length; i++){ tx_msg.data[i] = mp_obj_get_int(items[i]); } @@ -287,7 +283,7 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ mp_raise_OSError(-status); } return mp_const_none; - }else{ + } else { nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "CAN Device is not ready")); } } @@ -300,8 +296,8 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ ARG_timeout }; static const mp_arg_t allowed_args[] = { - {MP_QSTR_list, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)}}, - {MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000}}, + { MP_QSTR_list, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, }; // parse args @@ -319,9 +315,9 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ mp_obj_t *items; if (ret_obj == mp_const_none){ ret_obj = mp_obj_new_tuple(4, NULL); - items = ((mp_obj_tuple_t *)MP_OBJ_TO_PTR(ret_obj))->items; + items = ( (mp_obj_tuple_t *)MP_OBJ_TO_PTR(ret_obj) )->items; items[3] = mp_obj_new_bytes(rx_message.data, rx_message.data_length_code); - }else{ + } else { // User should provide a list of length at least 4 to hold the values if (!mp_obj_is_type(ret_obj, &mp_type_list)){ mp_raise_TypeError(NULL); @@ -344,7 +340,7 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ memcpy(mv->items, rx_message.data, rx_message.data_length_code); } items[0] = MP_OBJ_NEW_SMALL_INT(rx_message.identifier); - items[1] = rx_message.flags && CAN_MSG_FLAG_RTR > 0 ? mp_const_true : mp_const_false; + items[1] = mp_obj_new_bool(rx_message.flags && CAN_MSG_FLAG_RTR > 0 ? true : false); items[2] = 0; return ret_obj; } @@ -381,10 +377,10 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args ARG_rtr }; static const mp_arg_t allowed_args[] = { - {MP_QSTR_bank, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0}}, - {MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0}}, - {MP_QSTR_params, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_bool = false}}, + { MP_QSTR_bank, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_params, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_bool = false} }, }; // parse args @@ -404,17 +400,17 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args self->config->filter.single_filter = (args[ARG_mode].u_int == FILTER_RAW_SINGLE); self->config->filter.acceptance_code = id; self->config->filter.acceptance_mask = mask; - }else{ + } else { self->config->filter.single_filter = self->extframe; _machine_hw_can_set_filter(self, id, mask, args[ARG_bank].u_int, args[ARG_rtr].u_int); } - ESP_STATUS_CHECK(can_stop()); - ESP_STATUS_CHECK(can_driver_uninstall()); - ESP_STATUS_CHECK(can_driver_install( + ESP_STATUS_CHECK( can_stop() ); + ESP_STATUS_CHECK( can_driver_uninstall() ); + ESP_STATUS_CHECK( can_driver_install( &self->config->general, &self->config->timing, - &self->config->filter)); - ESP_STATUS_CHECK(can_start()); + &self->config->filter) ); + ESP_STATUS_CHECK( can_start() ); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter); @@ -446,7 +442,7 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p mode, self->loopback, self->extframe); - }else{ + } else { mp_printf(print, "CAN Device is not initialized"); } } @@ -531,18 +527,18 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg ARG_auto_restart }; static const mp_arg_t allowed_args[] = { - {MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL}}, - {MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false}}, - {MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}}, - {MP_QSTR_prescaler, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_PRESCALER}}, - {MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_SJW}}, - {MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS1}}, - {MP_QSTR_bs2, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS2}}, - {MP_QSTR_tx_io, MP_ARG_INT, {.u_int = 4}}, - {MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2}}, - {MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0}}, - {MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5}}, - {MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = false}}, + { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} }, + { MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_prescaler, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_PRESCALER} }, + { MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_SJW} }, + { MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS1} }, + { MP_QSTR_bs2, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = CAN_DEFAULT_BS2} }, + { MP_QSTR_tx_io, MP_ARG_INT, {.u_int = 4} }, + { MP_QSTR_rx_io, MP_ARG_INT, {.u_int = 2} }, + { MP_QSTR_tx_queue, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_rx_queue, MP_ARG_INT, {.u_int = 5} }, + { MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = false} }, }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -578,28 +574,28 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg .triple_sampling = false}); break; case CAN_BAUDRATE_25k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_25KBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_25KBITS() ); break; case CAN_BAUDRATE_50k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_50KBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_50KBITS() ); break; case CAN_BAUDRATE_100k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_100KBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_100KBITS() ); break; case CAN_BAUDRATE_125k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_125KBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_125KBITS() ); break; case CAN_BAUDRATE_250k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_250KBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_250KBITS() ); break; case CAN_BAUDRATE_500k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_500KBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_500KBITS() ); break; case CAN_BAUDRATE_800k: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_800KBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_800KBITS() ); break; case CAN_BAUDRATE_1M: - timing = &((can_timing_config_t)CAN_TIMING_CONFIG_1MBITS()); + timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_1MBITS() ); break; default: mp_raise_ValueError("Unable to set baudrate"); @@ -612,14 +608,14 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg uint32_t status = can_driver_install( &self->config->general, &self->config->timing, - &(can_filter_config_t)CAN_FILTER_CONFIG_ACCEPT_ALL()); + &(can_filter_config_t) CAN_FILTER_CONFIG_ACCEPT_ALL() ); if (status != ESP_OK){ mp_raise_OSError(-status); - }else{ + } else { status = can_start(); if (status != ESP_OK){ mp_raise_OSError(-status); - }else{ + } else { self->config->initialized = true; } } @@ -628,37 +624,37 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg STATIC const mp_rom_map_elem_t machine_can_locals_dict_table[] = { // CAN_ATTRIBUTES - {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN)}, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_CAN) }, // Micropython Generic API - {MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj)}, - {MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj)}, - {MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj)}, - {MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj)}, - {MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj)}, - {MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj)}, - {MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj)}, - {MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj)}, - {MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_hw_can_setfilter_obj)}, - {MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&machine_hw_can_clearfilter_obj)}, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_hw_can_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_hw_can_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_hw_can_restart_obj) }, + { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_hw_can_state_obj) }, + { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_hw_can_info_obj) }, + { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_hw_can_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_hw_can_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_hw_can_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_hw_can_setfilter_obj) }, + { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&machine_hw_can_clearfilter_obj) }, // ESP32 Specific API - {MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj)}, - {MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj)}, - {MP_OBJ_NEW_QSTR(MP_QSTR_get_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_clear_tx_queue), MP_ROM_PTR(&machine_hw_can_clear_tx_queue_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_clear_rx_queue), MP_ROM_PTR(&machine_hw_can_clear_rx_queue_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_alerts), MP_ROM_PTR(&machine_hw_can_alert_obj) }, // CAN_MODE - {MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL)}, - {MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_NORMAL | 0x10)}, - {MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK)}, - {MP_ROM_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_ROM_INT(CAN_MODE_NO_ACK | 0x10)}, - {MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY)}, + { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL) }, + { MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_NORMAL | 0x10) }, + { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_NO_ACK) }, + { MP_ROM_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_ROM_INT(CAN_MODE_NO_ACK | 0x10) }, + { MP_ROM_QSTR(MP_QSTR_LISTEN_ONLY), MP_ROM_INT(CAN_MODE_LISTEN_ONLY) }, // CAN_STATE - {MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED)}, - {MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_RUNNING)}, - {MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF)}, - {MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING)}, + { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, + { MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_RUNNING) }, + { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, + { MP_ROM_QSTR(MP_QSTR_RECOVERING), MP_ROM_INT(CAN_STATE_RECOVERING) }, // CAN_FILTER_MODE - {MP_ROM_QSTR(MP_QSTR_FILTER_RAW_SINGLE), MP_ROM_INT(FILTER_RAW_SINGLE)}, - {MP_ROM_QSTR(MP_QSTR_FILTER_RAW_DUAL), MP_ROM_INT(FILTER_RAW_DUAL)}, - {MP_ROM_QSTR(MP_QSTR_FILTER_ADDRESS), MP_ROM_INT(FILTER_ADDRESS)}, + { MP_ROM_QSTR(MP_QSTR_FILTER_RAW_SINGLE), MP_ROM_INT(FILTER_RAW_SINGLE) }, + { MP_ROM_QSTR(MP_QSTR_FILTER_RAW_DUAL), MP_ROM_INT(FILTER_RAW_DUAL) }, + { MP_ROM_QSTR(MP_QSTR_FILTER_ADDRESS), MP_ROM_INT(FILTER_ADDRESS) }, }; STATIC MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); From 1e7e0384792e320cfcd5af02639ed837f843cee5 Mon Sep 17 00:00:00 2001 From: Salvatore Musumeci Date: Sun, 9 Feb 2020 15:53:13 +0100 Subject: [PATCH 62/62] Beautify --- ports/esp32/machine_can.c | 151 +++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 74 deletions(-) diff --git a/ports/esp32/machine_can.c b/ports/esp32/machine_can.c index 0974b7d37e32d..56c806bd545c2 100644 --- a/ports/esp32/machine_can.c +++ b/ports/esp32/machine_can.c @@ -104,30 +104,31 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p machine_can_config_t can_config = { .general = CAN_GENERAL_CONFIG_DEFAULT(2, 4, 0), .filter = CAN_FILTER_CONFIG_ACCEPT_ALL(), .timing = CAN_TIMING_CONFIG_25KBITS(), - .initialized = false }; + .initialized = false + }; STATIC machine_can_obj_t machine_can_obj = { {&machine_can_type}, .config = &can_config }; -STATIC can_status_info_t _machine_hw_can_get_status(){ +STATIC can_status_info_t _machine_hw_can_get_status() { can_status_info_t status; uint32_t err_code = can_get_status_info(&status); - if (err_code != ESP_OK){ + if (err_code != ESP_OK) { mp_raise_OSError(-err_code); } return status; } -STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr){ +STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, uint32_t mask, uint8_t bank, bool rtr) { //Check if bank is allowed - if ( bank < 0 && bank > ( (self->extframe && self->config->filter.single_filter) ? 0 : 1 ) ){ + if ( bank < 0 && bank > ((self->extframe && self->config->filter.single_filter) ? 0 : 1 )) { mp_raise_ValueError("CAN filter parameter error"); } uint32_t preserve_mask; - if (self->extframe){ + if (self->extframe) { addr = (addr & 0x1FFFFFFF) << 3 | (rtr ? 0x04 : 0); mask = (mask & 0x1FFFFFFF) << 3 | 0x03; preserve_mask = 0; - } else if (self->config->filter.single_filter){ + } else if (self->config->filter.single_filter) { addr = ( ( (addr & 0x7FF) << 5 ) | (rtr ? 0x10 : 0) ); mask = ( (mask & 0x7FF) << 5 ); mask |= 0xFFFFF000; @@ -136,7 +137,7 @@ STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, u addr = ( ( (addr & 0x7FF) << 5 ) | (rtr ? 0x10 : 0) ); mask = ( (mask & 0x7FF) << 5 ); preserve_mask = 0xFFFF << ( bank == 0 ? 16 : 0 ); - if ( (self->config->filter.acceptance_mask & preserve_mask) == ( 0xFFFF << (bank == 0 ? 16 : 0) ) ){ + if ( (self->config->filter.acceptance_mask & preserve_mask) == ( 0xFFFF << (bank == 0 ? 16 : 0) ) ) { // Other filter accepts all; it will replaced duplicating current filter addr = addr | (addr << 16); mask = mask | (mask << 16); @@ -153,14 +154,14 @@ STATIC void _machine_hw_can_set_filter(machine_can_obj_t *self, uint32_t addr, u } // Force a software restart of the controller, to allow transmission after a bus error -STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in) { uint32_t status = can_initiate_recovery(); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } mp_hal_delay_ms(200); status = can_start(); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } return mp_const_none; @@ -168,31 +169,31 @@ STATIC mp_obj_t machine_hw_can_restart(mp_obj_t self_in){ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_restart_obj, machine_hw_can_restart); // any() - return `True` if any message waiting, else `False` -STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_any(mp_obj_t self_in) { can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_bool((status.msgs_to_rx) > 0); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_any_obj, machine_hw_can_any); // Get the state of the controller -STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_state(mp_obj_t self_in) { can_status_info_t status = _machine_hw_can_get_status(); return mp_obj_new_int(status.state); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_state_obj, machine_hw_can_state); // Get info about error states and TX/RX buffers -STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args){ +STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args) { machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_list_t *list; - if (n_args == 1){ + if (n_args == 1) { list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); - } else{ - if (!mp_obj_is_type(args[1], &mp_type_list)){ + } else { + if (!mp_obj_is_type(args[1], &mp_type_list)) { mp_raise_TypeError(NULL); } list = MP_OBJ_TO_PTR(args[1]); - if (list->len < 8){ + if (list->len < 8) { mp_raise_ValueError(NULL); } } @@ -210,10 +211,10 @@ STATIC mp_obj_t machine_hw_can_info(size_t n_args, const mp_obj_t *args){ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_hw_can_info_obj, 1, 2, machine_hw_can_info); // Get Alert info -STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in) { uint32_t alerts; uint32_t status = can_read_alerts(&alerts, 0); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } return mp_obj_new_int(alerts); @@ -221,20 +222,20 @@ STATIC mp_obj_t machine_hw_can_alert(mp_obj_t self_in){ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_alert_obj, machine_hw_can_alert); // Clear TX Queue -STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_clear_tx_queue(mp_obj_t self_in) { return mp_obj_new_bool(can_clear_transmit_queue() == ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_tx_queue_obj, machine_hw_can_clear_tx_queue); // Clear RX Queue -STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_clear_rx_queue(mp_obj_t self_in) { return mp_obj_new_bool(can_clear_receive_queue() == ESP_OK); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clear_rx_queue_obj, machine_hw_can_clear_rx_queue); // send([data], id, *) -STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ - enum{ +STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_data, ARG_id, ARG_timeout, @@ -257,29 +258,30 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ size_t length; mp_obj_t *items; mp_obj_get_array(args[ARG_data].u_obj, &length, &items); - if (length > 8){ + if (length > 8) { mp_raise_ValueError("CAN data field too long"); } uint8_t flags = (args[ARG_rtr].u_bool ? CAN_MSG_FLAG_RTR : CAN_MSG_FLAG_NONE); uint32_t id = args[ARG_id].u_int; - if (self->extframe){ + if (self->extframe) { flags += CAN_MSG_FLAG_EXTD; id &= 0x1FFFFFFF; } else { id &= 0x1FF; } - if (self->loopback){ + if (self->loopback) { flags += CAN_MSG_FLAG_SELF; } can_message_t tx_msg = { .data_length_code = length, .identifier = id, - .flags = flags }; - for (uint8_t i = 0; i < length; i++){ + .flags = flags + }; + for (uint8_t i = 0; i < length; i++) { tx_msg.data[i] = mp_obj_get_int(items[i]); } - if (_machine_hw_can_get_status().state == CAN_STATE_RUNNING){ + if (_machine_hw_can_get_status().state == CAN_STATE_RUNNING) { int status = can_transmit(&tx_msg, args[ARG_timeout].u_int); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } return mp_const_none; @@ -290,8 +292,8 @@ STATIC mp_obj_t machine_hw_can_send(size_t n_args, const mp_obj_t *pos_args, mp_ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_send_obj, 3, machine_hw_can_send); // recv(list=None, *, timeout=5000) -STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ - enum{ +STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_list, ARG_timeout }; @@ -306,48 +308,48 @@ STATIC mp_obj_t machine_hw_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_ can_message_t rx_message; int status = can_receive(&rx_message, 1); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } // Create the tuple, or get the list, that will hold the return values // Also populate the fourth element, either a new bytes or reuse existing memoryview mp_obj_t ret_obj = args[ARG_list].u_obj; mp_obj_t *items; - if (ret_obj == mp_const_none){ + if (ret_obj == mp_const_none) { ret_obj = mp_obj_new_tuple(4, NULL); items = ( (mp_obj_tuple_t *)MP_OBJ_TO_PTR(ret_obj) )->items; items[3] = mp_obj_new_bytes(rx_message.data, rx_message.data_length_code); } else { // User should provide a list of length at least 4 to hold the values - if (!mp_obj_is_type(ret_obj, &mp_type_list)){ + if (!mp_obj_is_type(ret_obj, &mp_type_list)) { mp_raise_TypeError(NULL); } mp_obj_list_t *list = MP_OBJ_TO_PTR(ret_obj); - if (list->len < 4){ + if (list->len < 4) { mp_raise_ValueError(NULL); } items = list->items; // Fourth element must be a memoryview which we assume points to a // byte-like array which is large enough, and then we resize it inplace - if (!mp_obj_is_type(items[3], &mp_type_memoryview)){ + if (!mp_obj_is_type(items[3], &mp_type_memoryview)) { mp_raise_TypeError(NULL); } mp_obj_array_t *mv = MP_OBJ_TO_PTR(items[3]); - if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))){ + if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))) { mp_raise_ValueError(NULL); } mv->len = rx_message.data_length_code; memcpy(mv->items, rx_message.data, rx_message.data_length_code); } items[0] = MP_OBJ_NEW_SMALL_INT(rx_message.identifier); - items[1] = mp_obj_new_bool(rx_message.flags && CAN_MSG_FLAG_RTR > 0 ? true : false); + items[1] = mp_obj_new_bool(rx_message.flags && CAN_MSG_FLAG_RTR > 0); items[2] = 0; return ret_obj; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_recv_obj, 0, machine_hw_can_recv); // Clear filters setting -STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in) { machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); self->config->filter.single_filter = self->extframe; self->config->filter.acceptance_code = 0; @@ -355,9 +357,9 @@ STATIC mp_obj_t machine_hw_can_clearfilter(mp_obj_t self_in){ ESP_STATUS_CHECK(can_stop()); ESP_STATUS_CHECK(can_driver_uninstall()); ESP_STATUS_CHECK(can_driver_install( - &self->config->general, - &self->config->timing, - &self->config->filter)); + &self->config->general, + &self->config->timing, + &self->config->filter)); ESP_STATUS_CHECK(can_start()); return mp_const_none; } @@ -368,7 +370,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_clearfilter_obj, machine_hw_can_ // params: [id, mask] // rtr: ignored if FILTER_RAW // Set CAN HW filter -STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ +STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bank, @@ -391,12 +393,12 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args size_t len; mp_obj_t *params; mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); - if (len != 2){ + if (len != 2) { mp_raise_ValueError("params shall be a 2-values list"); } uint32_t id = mp_obj_get_int(params[0]); uint32_t mask = mp_obj_get_int(params[1]); // FIXME: Overflow in case 0xFFFFFFFF for mask - if (args[ARG_mode].u_int == FILTER_RAW_SINGLE || args[ARG_mode].u_int == FILTER_RAW_DUAL){ + if (args[ARG_mode].u_int == FILTER_RAW_SINGLE || args[ARG_mode].u_int == FILTER_RAW_DUAL) { self->config->filter.single_filter = (args[ARG_mode].u_int == FILTER_RAW_SINGLE); self->config->filter.acceptance_code = id; self->config->filter.acceptance_mask = mask; @@ -407,17 +409,17 @@ STATIC mp_obj_t machine_hw_can_setfilter(size_t n_args, const mp_obj_t *pos_args ESP_STATUS_CHECK( can_stop() ); ESP_STATUS_CHECK( can_driver_uninstall() ); ESP_STATUS_CHECK( can_driver_install( - &self->config->general, - &self->config->timing, - &self->config->filter) ); + &self->config->general, + &self->config->timing, + &self->config->filter) ); ESP_STATUS_CHECK( can_start() ); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_setfilter_obj, 1, machine_hw_can_setfilter); -STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind){ +STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->config->initialized){ + if (self->config->initialized) { qstr mode; switch (self->config->general.mode) { @@ -448,9 +450,9 @@ STATIC void machine_hw_can_print(const mp_print_t *print, mp_obj_t self_in, mp_p } // init(tx, rx, baudrate, mode = CAN_MODE_NORMAL, tx_queue = 2, rx_queue = 5) -STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args){ +STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (self->config->initialized){ + if (self->config->initialized) { ESP_LOGW(DEVICE_NAME, "Device is already initialized"); return mp_const_none; } @@ -459,18 +461,18 @@ STATIC mp_obj_t machine_hw_can_init(size_t n_args, const mp_obj_t *args, mp_map_ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_can_init_obj, 4, machine_hw_can_init); // deinit() -STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in){ +STATIC mp_obj_t machine_hw_can_deinit(const mp_obj_t self_in) { const machine_can_obj_t *self = &machine_can_obj; - if (self->config->initialized != true){ + if (self->config->initialized != true) { ESP_LOGW(DEVICE_NAME, "Device is not initialized"); return mp_const_none; } uint32_t status = can_stop(); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } status = can_driver_uninstall(); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } self->config->initialized = false; @@ -481,19 +483,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hw_can_deinit_obj, machine_hw_can_deini // CAN(bus, ...) No argument to get the object // If no arguments are provided, the initialized object will be returned mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args){ + size_t n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - if (mp_obj_is_int(args[0]) != true){ + if (mp_obj_is_int(args[0]) != true) { mp_raise_TypeError("bus must be a number"); } mp_uint_t can_idx = mp_obj_get_int(args[0]); - if (can_idx > 1){ + if (can_idx > 1) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN(%d) doesn't exist", can_idx)); } machine_can_obj_t *self = &machine_can_obj; - if (n_args > 1 || n_kw > 0){ - if (self->config->initialized){ + if (n_args > 1 || n_kw > 0) { + if (self->config->initialized) { // The caller is requesting a reconfiguration of the hardware // this can only be done if the hardware is in init mode ESP_LOGW(DEVICE_NAME, "Device is going to be reconfigured"); @@ -511,8 +513,8 @@ mp_obj_t machine_hw_can_make_new(const mp_obj_type_t *type, size_t n_args, } // init(mode, extframe=False, baudrate=500, *) -STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args){ - enum{ +STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_mode, ARG_extframe, ARG_baudrate, @@ -556,7 +558,7 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->general.clkout_divider = 0; self->loopback = ((args[ARG_mode].u_int & 0x10) > 0); self->extframe = args[ARG_extframe].u_bool; - if (args[ARG_auto_restart].u_bool){ + if (args[ARG_auto_restart].u_bool) { mp_raise_NotImplementedError("Auto-restart not supported"); } can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL(); @@ -564,14 +566,15 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->filter.acceptance_code = f_config.acceptance_code; self->config->filter.acceptance_mask = f_config.acceptance_mask; can_timing_config_t *timing; - switch ((int)args[ARG_baudrate].u_int){ + switch ((int)args[ARG_baudrate].u_int) { case 0: - timing = &((can_timing_config_t){ + timing = &((can_timing_config_t) { .brp = args[ARG_prescaler].u_int, .sjw = args[ARG_sjw].u_int, .tseg_1 = args[ARG_bs1].u_int, .tseg_2 = args[ARG_bs1].u_int, - .triple_sampling = false}); + .triple_sampling = false + }); break; case CAN_BAUDRATE_25k: timing = &( (can_timing_config_t) CAN_TIMING_CONFIG_25KBITS() ); @@ -606,14 +609,14 @@ STATIC mp_obj_t machine_hw_can_init_helper(machine_can_obj_t *self, size_t n_arg self->config->baudrate = args[ARG_baudrate].u_int; uint32_t status = can_driver_install( - &self->config->general, - &self->config->timing, - &(can_filter_config_t) CAN_FILTER_CONFIG_ACCEPT_ALL() ); - if (status != ESP_OK){ + &self->config->general, + &self->config->timing, + &(can_filter_config_t) CAN_FILTER_CONFIG_ACCEPT_ALL() ); + if (status != ESP_OK) { mp_raise_OSError(-status); } else { status = can_start(); - if (status != ESP_OK){ + if (status != ESP_OK) { mp_raise_OSError(-status); } else { self->config->initialized = true;