From c58bd4c04782efad04ffc08f77fda3efce83badb Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Fri, 18 Sep 2020 12:38:15 -0400 Subject: [PATCH 01/55] Add never_reset reservation to RGBMatrix init --- ports/stm/common-hal/rgbmatrix/RGBMatrix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/stm/common-hal/rgbmatrix/RGBMatrix.c b/ports/stm/common-hal/rgbmatrix/RGBMatrix.c index 3b42631adc..2826cf53e9 100644 --- a/ports/stm/common-hal/rgbmatrix/RGBMatrix.c +++ b/ports/stm/common-hal/rgbmatrix/RGBMatrix.c @@ -36,6 +36,7 @@ extern void _PM_IRQ_HANDLER(void); void *common_hal_rgbmatrix_timer_allocate() { TIM_TypeDef * timer = stm_peripherals_find_timer(); stm_peripherals_timer_reserve(timer); + stm_peripherals_timer_never_reset(timer); return timer; } From 3a59d30e1ae1a4d5159dadb5f34534b186cdf9fd Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Fri, 18 Sep 2020 12:48:15 -0400 Subject: [PATCH 02/55] Remove timer debug messages --- ports/stm/peripherals/timers.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ports/stm/peripherals/timers.c b/ports/stm/peripherals/timers.c index baa81d2b5f..7bc5ea495a 100644 --- a/ports/stm/peripherals/timers.c +++ b/ports/stm/peripherals/timers.c @@ -195,9 +195,7 @@ TIM_TypeDef * stm_peripherals_find_timer(void) { // If no results are found, no unclaimed pins with this timer are in this package, // and it is safe to pick if (timer_in_package == false && mcu_tim_banks[i] != NULL) { - // DEBUG: print the timer return mcu_tim_banks[i]; - mp_printf(&mp_plat_print, "Timer: %d\n",i); } } //TODO: secondary search for timers outside the pins in the board profile @@ -205,8 +203,6 @@ TIM_TypeDef * stm_peripherals_find_timer(void) { // Work backwards - higher index timers have fewer pin allocations for (size_t i = (MP_ARRAY_SIZE(mcu_tim_banks) - 1); i >= 0; i--) { if ((!stm_timer_reserved[i]) && (mcu_tim_banks[i] != NULL)) { - // DEBUG: print the timer - mp_printf(&mp_plat_print, "Timer: %d\n",i); return mcu_tim_banks[i]; } } From bfbbbd6c5ce58ba1bcb57323566209902e1000b0 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 19 Sep 2020 10:16:13 -0500 Subject: [PATCH 03/55] makeqstrdata: Work with older Python This construct (which I added without sufficient testing, apparently) is only supported in Python 3.7 and newer. Make it optional so that this script works on other Python versions. This means that if you have a system with non-UTF-8 encoding you will need to use Python 3.7. In particular, this affects a problem building circuitpython in github's ubuntu-18.04 virtual environment when Python 3.7 is not explicitly installed. cookie-cuttered libraries call for Python 3.6: ``` - name: Set up Python 3.6 uses: actions/setup-python@v1 with: python-version: 3.6 ``` Since CircuitPython's own build calls for 3.8, this problem was not detected. This problem was also encountered by discord user mdroberts1243. The failure I encountered was here: https://github.com/jepler/Jepler_CircuitPython_udecimal/runs/1138045020?check_suite_focus=true .. while my step of "clone and build circuitpython unix port" is unusual, I think the same problem would have affected "build assets" if that step had been reached. --- py/makeqstrdata.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 39d4a6840f..96e3956b42 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -17,8 +17,9 @@ import collections import gettext import os.path -sys.stdout.reconfigure(encoding='utf-8') -sys.stderr.reconfigure(errors='backslashreplace') +if hasattr(sys.stdout, 'reconfigure'): + sys.stdout.reconfigure(encoding='utf-8') + sys.stderr.reconfigure(errors='backslashreplace') py = os.path.dirname(sys.argv[0]) top = os.path.dirname(py) From 40ec7a66e424c37da7556bdea303a4e5da30985c Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Mon, 21 Sep 2020 14:39:31 +0530 Subject: [PATCH 04/55] Update microS2 config files --- .../boards/microdev_micro_s2/mpconfigboard.h | 3 ++- .../boards/microdev_micro_s2/mpconfigboard.mk | 1 + ports/esp32s2/boards/microdev_micro_s2/pins.c | 21 ++++++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h index 1a1ef7a6c7..c138c8ed15 100644 --- a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h +++ b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h @@ -26,10 +26,11 @@ //Micropython setup -#define MICROPY_HW_BOARD_NAME "microDev microS2" +#define MICROPY_HW_BOARD_NAME "microS2" #define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_LED (&pin_GPIO21) +#define MICROPY_HW_BUTTON (&pin_GPIO0) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) diff --git a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk index 783e7ad4c7..5156170957 100644 --- a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk +++ b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk @@ -2,6 +2,7 @@ USB_VID = 0x239A USB_PID = 0x80C6 USB_PRODUCT = "microS2" USB_MANUFACTURER = "microDev" +USB_DEVICES = "CDC,MSC,HID" INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ diff --git a/ports/esp32s2/boards/microdev_micro_s2/pins.c b/ports/esp32s2/boards/microdev_micro_s2/pins.c index 25300b5c3c..bd230ed38f 100644 --- a/ports/esp32s2/boards/microdev_micro_s2/pins.c +++ b/ports/esp32s2/boards/microdev_micro_s2/pins.c @@ -42,8 +42,27 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); From 0318eb359fbeb91c6b37ed2050e57711ec2740bc Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 10:02:27 -0500 Subject: [PATCH 05/55] makeqstrdata: Work around python3.6 compatibility problem Discord user Folknology encountered a problem building with Python 3.6.9, `TypeError: ord() expected a character, but string of length 0 found`. I was able to reproduce the problem using Python3.5*, and discovered that the meaning of the regular expression `"|."` had changed in 3.7. Before, ``` >>> [m.group(0) for m in re.finditer("|.", "hello")] ['', '', '', '', '', ''] ``` After: ``` >>> [m.group(0) for m in re.finditer("|.", "hello")] ['', 'h', '', 'e', '', 'l', '', 'l', '', 'o', ''] ``` Check if `words` is empty and if so use `"."` as the regular expression instead. This gives the same result on both versions: ``` ['h', 'e', 'l', 'l', 'o'] ``` and fixes the generation of the huffman dictionary. Folknology verified that this fix worked for them. * I could easily install 3.5 but not 3.6. 3.5 reproduced the same problem --- py/makeqstrdata.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 96e3956b42..b4f4f1b035 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -109,7 +109,11 @@ class TextSplitter: def __init__(self, words): words.sort(key=lambda x: len(x), reverse=True) self.words = set(words) - self.pat = re.compile("|".join(re.escape(w) for w in words) + "|.", flags=re.DOTALL) + if words: + pat = "|".join(re.escape(w) for w in words) + "|." + else: + pat = "." + self.pat = re.compile(pat, flags=re.DOTALL) def iter_words(self, text): s = [] From 22d9a94f2b880c57b7939e3e08a6fecd1ef59720 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Mon, 21 Sep 2020 13:47:14 -0400 Subject: [PATCH 06/55] Use write_value, add missing pin exceptions --- ports/esp32s2/common-hal/busio/SPI.c | 49 +++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/ports/esp32s2/common-hal/busio/SPI.c b/ports/esp32s2/common-hal/busio/SPI.c index 350580ea84..6e4e344740 100644 --- a/ports/esp32s2/common-hal/busio/SPI.c +++ b/ports/esp32s2/common-hal/busio/SPI.c @@ -115,6 +115,16 @@ static void spi_bus_intr_disable(void *self) void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) { + + //SCK is not optional. MOSI and MISO are + if (!clock) { + mp_raise_ValueError(translate("Must provide SCK pin")); + } + + if (!miso && !mosi) { + mp_raise_ValueError(translate("Must provide MISO or MOSI pin")); + } + spi_bus_config_t bus_config; bus_config.mosi_io_num = mosi != NULL ? mosi->number : -1; bus_config.miso_io_num = miso != NULL ? miso->number : -1; @@ -212,8 +222,12 @@ void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { spi_never_reset[self->host_id] = true; common_hal_never_reset_pin(self->clock_pin); - common_hal_never_reset_pin(self->MOSI_pin); - common_hal_never_reset_pin(self->MISO_pin); + if (self->MOSI_pin != NULL) { + common_hal_never_reset_pin(self->MOSI_pin); + } + if (self->MISO_pin != NULL) { + common_hal_never_reset_pin(self->MISO_pin); + } } bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { @@ -236,9 +250,15 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { spi_bus_free(self->host_id); common_hal_reset_pin(self->clock_pin); - common_hal_reset_pin(self->MOSI_pin); - common_hal_reset_pin(self->MISO_pin); + if (self->MOSI_pin != NULL) { + common_hal_reset_pin(self->MOSI_pin); + } + if (self->MISO_pin != NULL) { + common_hal_reset_pin(self->MISO_pin); + } self->clock_pin = NULL; + self->MISO_pin = NULL; + self->MOSI_pin = NULL; } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, @@ -293,18 +313,37 @@ void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len) { + if (self->MOSI_pin == NULL) { + mp_raise_ValueError(translate("No MOSI Pin")); + } return common_hal_busio_spi_transfer(self, data, NULL, len); } bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) { - return common_hal_busio_spi_transfer(self, NULL, data, len); + + if (self->MISO_pin == NULL) { + mp_raise_ValueError(translate("No MISO Pin")); + } + if (self->MOSI_pin == NULL) { + return common_hal_busio_spi_transfer(self, NULL, data, len); + } else { + memset(data, write_value, len); + return common_hal_busio_spi_transfer(self, data, data, len); + } } bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len) { if (len == 0) { return true; } + // Other than the read special case, stop transfers that don't have a pin/array match + if (!self->MOSI_pin && (data_out != data_in)) { + mp_raise_ValueError(translate("No MOSI Pin")); + } + if (!self->MISO_pin && data_in) { + mp_raise_ValueError(translate("No MISO Pin")); + } spi_hal_context_t* hal = &self->hal_context; hal->send_buffer = NULL; From 183649aad888f39f84cb9f81d589f9786c28c73c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 24 Aug 2020 09:00:08 -0500 Subject: [PATCH 07/55] samd: move mcu_find_pin_function to header .. it'll be used in can as well as sdio --- .../common-hal/microcontroller/Pin.c | 18 ++++++++++ .../common-hal/microcontroller/Pin.h | 9 +++++ ports/atmel-samd/common-hal/sdioio/SDCard.c | 34 +++++-------------- ports/atmel-samd/tools/mksdiodata.py | 9 ++--- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index ef1d8fffaa..bec9dc1e26 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include "py/runtime.h" + #include "shared-bindings/microcontroller/Pin.h" #include "atmel_start_pins.h" @@ -256,3 +258,19 @@ void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) { void common_hal_mcu_pin_reset_number(uint8_t pin_no) { reset_pin_number(pin_no); } + +mcu_pin_function_t *mcu_find_pin_function(mcu_pin_function_t *table, const mcu_pin_obj_t *pin, int instance, uint16_t name) { + if (!pin) { + return NULL; + } + + for(; table->obj; table++) { + if (instance != -1 && instance != table->instance) { + continue; + } + if (pin == table->obj) { + return table; + } + } + mp_raise_ValueError_varg(translate("%q pin invalid"), name); +} diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h index 14887207aa..59302713af 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.h +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h @@ -47,4 +47,13 @@ void never_reset_pin_number(uint8_t pin_number); void claim_pin(const mcu_pin_obj_t* pin); bool pin_number_is_free(uint8_t pin_number); +typedef struct { + const mcu_pin_obj_t *obj; + uint8_t instance; + uint8_t pin; + uint16_t function; +} mcu_pin_function_t; + +mcu_pin_function_t *mcu_find_pin_function(mcu_pin_function_t *table, const mcu_pin_obj_t *pin, int instance, uint16_t name); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/atmel-samd/common-hal/sdioio/SDCard.c b/ports/atmel-samd/common-hal/sdioio/SDCard.c index 1f555b6476..4d2539aa5a 100644 --- a/ports/atmel-samd/common-hal/sdioio/SDCard.c +++ b/ports/atmel-samd/common-hal/sdioio/SDCard.c @@ -58,24 +58,6 @@ static Sdhc *sdhc_insts[] = SDHC_INSTS; -STATIC pin_function_t *find_pin_function(pin_function_t *table, const mcu_pin_obj_t *pin, int instance, uint16_t name) { - DEBUG_PRINT("\n\n[inst=% 2d] %q: ", instance, name); - DEBUG_PRINT_OBJ_NL(pin); - - for(; table->obj; table++) { - DEBUG_PRINT("[inst=% 2d] considering table @%p: "); - DEBUG_PRINT_OBJ(table->obj); - DEBUG_PRINT(" %d %d\n", table->instance, table->pin); - if (instance != -1 && instance != table->instance) { - continue; - } - if (pin == table->obj) { - return table; - } - } - mp_raise_ValueError_varg(translate("%q pin invalid"), name); -} - void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * command, uint8_t num_data, mcu_pin_obj_t ** data, uint32_t frequency) { @@ -98,15 +80,15 @@ CLK PA21 PCC_D? (D32) BROWN */ - pin_function_t *functions[6] = {}; - functions[0] = find_pin_function(sdio_cmd, command, -1, MP_QSTR_command); + mcu_pin_function_t *functions[6] = {}; + functions[0] = mcu_find_pin_function(sdio_cmd, command, -1, MP_QSTR_command); int instance = functions[0]->instance; - functions[1] = find_pin_function(sdio_ck, clock, instance, MP_QSTR_clock); - functions[2] = find_pin_function(sdio_dat0, data[0], instance, MP_QSTR_data0); + functions[1] = mcu_find_pin_function(sdio_ck, clock, instance, MP_QSTR_clock); + functions[2] = mcu_find_pin_function(sdio_dat0, data[0], instance, MP_QSTR_data0); if(num_data == 4) { - functions[3] = find_pin_function(sdio_dat1, data[1], instance, MP_QSTR_data1); - functions[4] = find_pin_function(sdio_dat2, data[2], instance, MP_QSTR_data2); - functions[5] = find_pin_function(sdio_dat3, data[3], instance, MP_QSTR_data3); + functions[3] = mcu_find_pin_function(sdio_dat1, data[1], instance, MP_QSTR_data1); + functions[4] = mcu_find_pin_function(sdio_dat2, data[2], instance, MP_QSTR_data2); + functions[5] = mcu_find_pin_function(sdio_dat3, data[3], instance, MP_QSTR_data3); } // We've verified all pins, now set their special functions @@ -114,7 +96,7 @@ CLK PA21 PCC_D? (D32) BROWN self->clock_pin = common_hal_mcu_pin_number(functions[1]->obj); for(int i=0; idata_pins[i] = common_hal_mcu_pin_number(function->obj); } else { diff --git a/ports/atmel-samd/tools/mksdiodata.py b/ports/atmel-samd/tools/mksdiodata.py index 0cce3819f3..48c4a085f5 100755 --- a/ports/atmel-samd/tools/mksdiodata.py +++ b/ports/atmel-samd/tools/mksdiodata.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 def defines(name, function): - print(f'pin_function_t {name} [] = {{') + print(f'mcu_pin_function_t {name} [] = {{') for instance in (0, 1): for port in 'ABCD': for idx in range(32): @@ -23,13 +23,8 @@ print('''\ #include "mpconfigport.h" #include "atmel_start_pins.h" #include "hal/include/hal_gpio.h" +#include "common-hal/microcontroller/Pin.h" -typedef struct { - const mcu_pin_obj_t *obj; - uint8_t instance; - uint8_t pin; - uint16_t function; -} pin_function_t; ''') defines('sdio_ck', 'SDCK') From e7a213a11420ed362dfb672cd0fa6e77c032fa07 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 11:57:09 -0500 Subject: [PATCH 08/55] py: Add enum helper code This makes it much easier to implement enums, and the printing code is shared. We might want to convert other enums to this in the future. --- py/enum.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ py/enum.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ py/py.mk | 1 + 3 files changed, 118 insertions(+) create mode 100644 py/enum.c create mode 100644 py/enum.h diff --git a/py/enum.c b/py/enum.c new file mode 100644 index 0000000000..02a85a168c --- /dev/null +++ b/py/enum.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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/enum.h" +#include "py/runtime.h" + +mp_obj_t cp_enum_find(const mp_obj_type_t *type, int value) { + const mp_obj_dict_t *dict = type->locals_dict; + for (size_t i=0; imap.used; i++) { + const cp_enum_obj_t *v = dict->map.table[i].value; + if (v->value == value) { + return (mp_obj_t)v; + } + } + return mp_const_none; +} + +int cp_enum_value(const mp_obj_type_t *type, mp_obj_t *obj) { + if (!MP_OBJ_IS_TYPE(obj, type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), type->name); + } + return ((cp_enum_obj_t*)MP_OBJ_TO_PTR(obj))->value; +} + +void cp_enum_obj_print_helper(uint16_t module, const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + (void) kind; + cp_enum_obj_t *self = self_in; + mp_printf(print, "%q.%q.%q", module, self->base.type->name, self->name); +} diff --git a/py/enum.h b/py/enum.h new file mode 100644 index 0000000000..1c38ae5ae6 --- /dev/null +++ b/py/enum.h @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + int16_t value; + int16_t name; +} cp_enum_obj_t; + +#define MAKE_ENUM_VALUE(type, prefix, name, value) \ + STATIC const cp_enum_obj_t prefix ## _ ## name ## _obj = { \ + { &type }, value, MP_QSTR_ ## name, \ + } + +#define MAKE_ENUM_MAP(name) \ + STATIC const mp_rom_map_elem_t name ## _locals_table[] = + +#define MAKE_ENUM_MAP_ENTRY(prefix, name) \ + { MP_ROM_QSTR(MP_QSTR_ ## name), MP_ROM_PTR(&prefix ## _ ## name ## _obj) } + +#define MAKE_PRINTER(module, typename) \ + STATIC void typename ## _ ## print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { \ + cp_enum_obj_print_helper(MP_QSTR_ ## module, print, self_in, kind); \ + } + +#define MAKE_ENUM_TYPE(module, type, typename) \ + const mp_obj_type_t typename ## _type = { \ + { &mp_type_type }, \ + .name = MP_QSTR_ ## type, \ + .print = typename ## _print, \ + .locals_dict = (mp_obj_t)&typename ## _locals_dict, \ + } + + + +mp_obj_t cp_enum_find(const mp_obj_type_t *type, int value); +int cp_enum_value(const mp_obj_type_t *type, mp_obj_t *obj); +void cp_enum_obj_print_helper(uint16_t module, const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); diff --git a/py/py.mk b/py/py.mk index 49fb0acaf9..acf5d127bc 100644 --- a/py/py.mk +++ b/py/py.mk @@ -181,6 +181,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ argcheck.o \ warning.o \ map.o \ + enum.o \ obj.o \ objarray.o \ objattrtuple.o \ From a2e1867f69ec2d703a9651e5c36a02b0e14dfd9c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 20 Aug 2020 11:08:00 -0500 Subject: [PATCH 09/55] _canio: Minimal implementation for SAM E5x MCUs Tested & working: * Send standard packets * Receive standard packets (1 FIFO, no filter) Interoperation between SAM E54 Xplained running this tree and MicroPython running on STM32F405 Feather with an external transceiver was also tested. Many other aspects of a full implementation are not yet present, such as error detection and recovery. --- main.c | 8 + ports/atmel-samd/Makefile | 4 + .../asf4_conf/same54/peripheral_clk_config.h | 82 ++++ ports/atmel-samd/boards/common.template.ld | 7 +- .../boards/same54_xplained/mpconfigboard.mk | 1 + .../atmel-samd/boards/same54_xplained/pins.c | 5 +- ports/atmel-samd/common-hal/_canio/CAN.c | 384 ++++++++++++++++++ ports/atmel-samd/common-hal/_canio/CAN.h | 62 +++ ports/atmel-samd/common-hal/_canio/Listener.c | 117 ++++++ ports/atmel-samd/common-hal/_canio/Listener.h | 53 +++ ports/atmel-samd/common-hal/_canio/__init__.c | 25 ++ ports/atmel-samd/common-hal/_canio/__init__.h | 62 +++ ports/atmel-samd/tools/mkcandata.py | 31 ++ py/circuitpy_defns.mk | 9 + py/circuitpy_mpconfig.h | 8 + py/circuitpy_mpconfig.mk | 3 + shared-bindings/_canio/CAN.c | 338 +++++++++++++++ shared-bindings/_canio/CAN.h | 31 ++ shared-bindings/_canio/Listener.c | 197 +++++++++ shared-bindings/_canio/Listener.h | 31 ++ shared-bindings/_canio/Match.c | 140 +++++++ shared-bindings/_canio/Match.h | 33 ++ shared-bindings/_canio/Message.c | 213 ++++++++++ shared-bindings/_canio/Message.h | 31 ++ shared-bindings/_canio/__init__.c | 73 ++++ shared-bindings/_canio/__init__.h | 29 ++ shared-module/_canio/Match.c | 43 ++ shared-module/_canio/Match.h | 41 ++ shared-module/_canio/Message.c | 85 ++++ shared-module/_canio/Message.h | 47 +++ 30 files changed, 2190 insertions(+), 3 deletions(-) create mode 100644 ports/atmel-samd/common-hal/_canio/CAN.c create mode 100644 ports/atmel-samd/common-hal/_canio/CAN.h create mode 100644 ports/atmel-samd/common-hal/_canio/Listener.c create mode 100644 ports/atmel-samd/common-hal/_canio/Listener.h create mode 100644 ports/atmel-samd/common-hal/_canio/__init__.c create mode 100644 ports/atmel-samd/common-hal/_canio/__init__.h create mode 100755 ports/atmel-samd/tools/mkcandata.py create mode 100644 shared-bindings/_canio/CAN.c create mode 100644 shared-bindings/_canio/CAN.h create mode 100644 shared-bindings/_canio/Listener.c create mode 100644 shared-bindings/_canio/Listener.h create mode 100644 shared-bindings/_canio/Match.c create mode 100644 shared-bindings/_canio/Match.h create mode 100644 shared-bindings/_canio/Message.c create mode 100644 shared-bindings/_canio/Message.h create mode 100644 shared-bindings/_canio/__init__.c create mode 100644 shared-bindings/_canio/__init__.h create mode 100644 shared-module/_canio/Match.c create mode 100644 shared-module/_canio/Match.h create mode 100644 shared-module/_canio/Message.c create mode 100644 shared-module/_canio/Message.h diff --git a/main.c b/main.c index 5b719dc4b6..f259fea3f9 100755 --- a/main.c +++ b/main.c @@ -81,6 +81,10 @@ #include "supervisor/shared/bluetooth.h" #endif +#if CIRCUITPY_CANIO +#include "common-hal/_canio/CAN.h" +#endif + void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -226,6 +230,10 @@ void cleanup_after_vm(supervisor_allocation* heap) { free_memory(heap); supervisor_move_memory(); + #ifdef CIRCUITPY_CANIO + common_hal_canio_reset(); + #endif + reset_port(); #if CIRCUITPY_BOARD reset_board_busses(); diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index aba630dbb3..1ee21679d8 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -393,6 +393,10 @@ SRC_QSTR += $(HEADER_BUILD)/sdiodata.h $(HEADER_BUILD)/sdiodata.h: tools/mksdiodata.py | $(HEADER_BUILD) $(Q)$(PYTHON3) $< > $@ +SRC_QSTR += $(HEADER_BUILD)/candata.h +$(HEADER_BUILD)/candata.h: tools/mkcandata.py | $(HEADER_BUILD) + $(Q)$(PYTHON3) $< > $@ + SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR += peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/clocks.c diff --git a/ports/atmel-samd/asf4_conf/same54/peripheral_clk_config.h b/ports/atmel-samd/asf4_conf/same54/peripheral_clk_config.h index 59fe8730e6..51173f6d32 100644 --- a/ports/atmel-samd/asf4_conf/same54/peripheral_clk_config.h +++ b/ports/atmel-samd/asf4_conf/same54/peripheral_clk_config.h @@ -1165,6 +1165,88 @@ #define CONF_SDHC1_SLOW_FREQUENCY 12000000 #endif +// CAN Clock Settings +// CAN Clock source + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CAN. +// sdhc_gclk_selection +#ifndef CONF_GCLK_CAN0_SRC +#define CONF_GCLK_CAN0_SRC GCLK_PCHCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CAN FREQUENCY + * \brief CAN's Clock frequency + */ +#ifndef CONF_CAN0_FREQUENCY +#define CONF_CAN0_FREQUENCY 120000000 +#endif + +// CAN Clock Settings +// CAN Clock source + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CAN. +// sdhc_gclk_selection +#ifndef CONF_GCLK_CAN1_SRC +#define CONF_GCLK_CAN1_SRC GCLK_PCHCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CAN FREQUENCY + * \brief CAN's Clock frequency + */ +#ifndef CONF_CAN1_FREQUENCY +#define CONF_CAN1_FREQUENCY 120000000 +#endif + // <<< end of configuration section >>> #endif // PERIPHERAL_CLK_CONFIG_H diff --git a/ports/atmel-samd/boards/common.template.ld b/ports/atmel-samd/boards/common.template.ld index 1054605c8c..19e4753f8b 100644 --- a/ports/atmel-samd/boards/common.template.ld +++ b/ports/atmel-samd/boards/common.template.ld @@ -51,6 +51,7 @@ SECTIONS { . = ALIGN(4); _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialize the .data section in RAM */ + . = ALIGN(4); *(.ramfunc) *(.ramfunc*) *(.data) /* .data sections */ @@ -61,11 +62,15 @@ SECTIONS } >RAM /* Uninitialized data section */ - .bss : + .bss (NOLOAD) : { . = ALIGN(4); _sbss = .; _szero = .; /* define a global symbol at bss start; used by startup code */ + /* Data accessed by the CAN peripheral must be in the first 64kB RAM */ + _scanram = .; + *(.canram) + _ecanram = .; *(.bss) *(.bss*) *(COMMON) diff --git a/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk b/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk index 7ac1265149..e4472e05d6 100644 --- a/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk +++ b/ports/atmel-samd/boards/same54_xplained/mpconfigboard.mk @@ -12,3 +12,4 @@ EXTERNAL_FLASH_DEVICES = "N25Q256A" LONGINT_IMPL = MPZ CIRCUITPY_SDIOIO = 1 +CIRCUITPY_CANIO = 1 diff --git a/ports/atmel-samd/boards/same54_xplained/pins.c b/ports/atmel-samd/boards/same54_xplained/pins.c index 8a864ab97d..1ed431fbad 100644 --- a/ports/atmel-samd/boards/same54_xplained/pins.c +++ b/ports/atmel-samd/boards/same54_xplained/pins.c @@ -48,8 +48,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_QT), MP_ROM_PTR(&pin_PA16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_CANRX), MP_ROM_PTR(&pin_PB12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_CANTX), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PC13) }, // EXT1 header { MP_OBJ_NEW_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, diff --git a/ports/atmel-samd/common-hal/_canio/CAN.c b/ports/atmel-samd/common-hal/_canio/CAN.c new file mode 100644 index 0000000000..dcd269495e --- /dev/null +++ b/ports/atmel-samd/common-hal/_canio/CAN.c @@ -0,0 +1,384 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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 + +#include "py/runtime.h" +#include "py/mperrno.h" + +#include "peripheral_clk_config.h" + +#include "common-hal/_canio/CAN.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/port.h" + +#include "component/can.h" + +#include "genhdr/candata.h" + +STATIC Can * const can_insts[] = CAN_INSTS; + +STATIC canio_can_obj_t *can_objs[MP_ARRAY_SIZE(can_insts)]; + +// This must be placed in the first 64kB of RAM +STATIC COMPILER_SECTION(".canram") canio_can_state_t can_state[MP_ARRAY_SIZE(can_insts)]; + +__attribute__((optimize("O0"), noinline)) +void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mcu_pin_obj_t *tx, int baudrate, bool loopback, bool silent) +{ + mcu_pin_function_t *tx_function = mcu_find_pin_function(can_tx, tx, -1, MP_QSTR_tx); + int instance = tx_function->instance; + + mcu_pin_function_t *rx_function = mcu_find_pin_function(can_rx, rx, instance, MP_QSTR_rx); + + const uint32_t can_frequency = CONF_CAN0_FREQUENCY; + +#define DIV_ROUND(a, b) (((a) + (b)/2) / (b)) +#define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) + + uint32_t clocks_per_bit = DIV_ROUND(can_frequency, baudrate); + uint32_t clocks_to_sample = DIV_ROUND(clocks_per_bit * 7, 8); + uint32_t clocks_after_sample = clocks_per_bit - clocks_to_sample; + uint32_t divisor = MAX(DIV_ROUND_UP(clocks_to_sample, 256), DIV_ROUND_UP(clocks_after_sample, 128)); + if (divisor > 32) { + mp_raise_OSError(MP_EINVAL); // baudrate cannot be attained (16kHz or something is lower bound, should never happen) + } + + gpio_set_pin_direction(tx_function->pin, GPIO_DIRECTION_OUT); + gpio_set_pin_function(tx_function->pin, tx_function->function); + common_hal_never_reset_pin(tx_function->obj); + + if (rx_function) { + gpio_set_pin_direction(rx_function->pin, GPIO_DIRECTION_IN); + gpio_set_pin_function(rx_function->pin, rx_function->function); + common_hal_never_reset_pin(rx_function->obj); + } + + self->tx_pin_number = common_hal_mcu_pin_number(tx); + self->rx_pin_number = rx ? common_hal_mcu_pin_number(rx) : COMMON_HAL_MCU_NO_PIN; + self->hw = can_insts[instance]; + self->state = &can_state[instance]; + + self->loopback = loopback; + + // Allow configuration change + hri_can_set_CCCR_INIT_bit(self->hw); + while (hri_can_get_CCCR_INIT_bit(self->hw) == 0) { + } + hri_can_set_CCCR_CCE_bit(self->hw); + + if(instance == 0) { + hri_mclk_set_AHBMASK_CAN0_bit(MCLK); + hri_gclk_write_PCHCTRL_reg(GCLK, CAN0_GCLK_ID, CONF_GCLK_CAN0_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); + + NVIC_DisableIRQ(CAN0_IRQn); + NVIC_ClearPendingIRQ(CAN0_IRQn); + NVIC_EnableIRQ(CAN0_IRQn); + hri_can_write_ILE_reg(self->hw, CAN_ILE_EINT0); +#ifdef CAN1_GCLK_ID + } else if(instance == 1) { + hri_mclk_set_AHBMASK_CAN1_bit(MCLK); + hri_gclk_write_PCHCTRL_reg(GCLK, CAN1_GCLK_ID, CONF_GCLK_CAN1_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); + + NVIC_DisableIRQ(CAN1_IRQn); + NVIC_ClearPendingIRQ(CAN1_IRQn); + NVIC_EnableIRQ(CAN1_IRQn); + hri_can_write_ILE_reg(self->hw, CAN_ILE_EINT0); +#endif + } + + self->hw->CCCR.bit.FDOE = 0; // neither FD nor Bit Rate Switch enabled + self->hw->CCCR.bit.BRSE = 0; + + hri_can_write_MRCFG_reg(self->hw, CAN_MRCFG_QOS(CAN_MRCFG_QOS_DISABLE_Val)); // QoS disabled (no sensitive operation) + + // A "nominal bit" is a header bit. With dual rate CAN FD, this is a slower rate + { + CAN_NBTP_Type btp = { + // 0 means "1 tq", but 2 is subtracted from NTSEG1 for the + // fixed 1 "SYNC" tq + .bit.NTSEG1 = DIV_ROUND(clocks_to_sample, divisor) - 2, + .bit.NTSEG2 = DIV_ROUND(clocks_after_sample, divisor) - 1, + .bit.NBRP = divisor - 1, + .bit.NSJW = DIV_ROUND(clocks_after_sample, divisor * 4), + }; + hri_can_write_NBTP_reg(self->hw, btp.reg); + } + + // we don't do the high bit rate yet, so do we need to set this register? + // hri_can_write_DBTP_reg(self->hw, ???); + // A "data bit" is a data bit :) with dul rate CAN FD, this is a higher + // rate. However, CAN FD is not implemented in CircuitPython, and this is the same rate as + // the "nominal rate". + { + CAN_DBTP_Type btp = { + .bit.DTSEG1 = DIV_ROUND(clocks_to_sample, divisor) - 1, + .bit.DTSEG2 = DIV_ROUND(clocks_after_sample, divisor) - 1, + .bit.DBRP = divisor - 1, + .bit.DSJW = DIV_ROUND(clocks_after_sample, divisor * 4), + }; + hri_can_write_DBTP_reg(self->hw, btp.reg); + } + + { + CAN_RXF0C_Type rxf = { + .bit.F0SA = (uint32_t)self->state->rx0_fifo, + .bit.F0S = COMMON_HAL_CANIO_RX_FIFO_SIZE, + }; + hri_can_write_RXF0C_reg(self->hw, rxf.reg); + } + + { + CAN_RXF1C_Type rxf = { + .bit.F1SA = (uint32_t)self->state->rx1_fifo, + .bit.F1S = COMMON_HAL_CANIO_RX_FIFO_SIZE, + }; + hri_can_write_RXF1C_reg(self->hw, rxf.reg); + } + + // All RX data has an 8 byte payload (max) + { + CAN_RXESC_Type esc = { + .bit.F0DS = CAN_RXESC_F0DS_DATA8_Val, + .bit.F1DS = CAN_RXESC_F1DS_DATA8_Val, + .bit.RBDS = CAN_RXESC_RBDS_DATA8_Val, + }; + hri_can_write_RXESC_reg(self->hw, esc.reg); + } + + // All TX data has an 8 byte payload (max) + { + CAN_TXESC_Type esc = { + .bit.TBDS = CAN_TXESC_TBDS_DATA8_Val, + }; + hri_can_write_TXESC_reg(self->hw, esc.reg); + } + + { + CAN_TXBC_Type bc = { + .bit.TBSA = (uint32_t)self->state->tx_fifo, + .bit.NDTB = COMMON_HAL_CANIO_TX_FIFO_SIZE, + .bit.TFQM = 0, // Messages are transmitted in the order submitted + }; + hri_can_write_TXBC_reg(self->hw, bc.reg); + } + + { + CAN_TXEFC_Type efc = { + .bit.EFS = 0, + }; + hri_can_write_TXEFC_reg(self->hw, efc.reg); + } + + { + CAN_GFC_Type gfc = { + .bit.RRFE = 1, + .bit.ANFS = CAN_GFC_ANFS_RXF0_Val, + .bit.ANFE = CAN_GFC_ANFE_REJECT_Val, + }; + hri_can_write_GFC_reg(self->hw, gfc.reg); + } + + { + CAN_SIDFC_Type dfc = { + .bit.LSS = COMMON_HAL_CANIO_RX_FILTER_SIZE, + .bit.FLSSA = (uint32_t)self->state->rx_filter + }; + hri_can_write_SIDFC_reg(self->hw, dfc.reg); + } + + { + CAN_XIDFC_Type dfc = { + .bit.LSE = 0, + }; + hri_can_write_XIDFC_reg(self->hw, dfc.reg); + } + + hri_can_write_XIDAM_reg(self->hw, CAN_XIDAM_RESETVALUE); + +// silent: The CAN is set in Bus Monitoring Mode by programming CCCR.MON to '1'. (tx pin unused) +// external loopback: The CAN can be set in External Loop Back Mode by programming TEST.LBCK and CCCR.MON to '1'. (rx pin unused) +// internal loopback (silent loopback): Internal Loop Back Mode is entered by programming bits TEST.LBCK and CCCR.MON to '1'. (tx, rx unused) + self->hw->CCCR.bit.MON = silent; + self->hw->CCCR.bit.TEST = loopback; + self->hw->TEST.bit.LBCK = loopback; + + if(instance == 0) { + NVIC_DisableIRQ(CAN0_IRQn); + NVIC_ClearPendingIRQ(CAN0_IRQn); + NVIC_EnableIRQ(CAN0_IRQn); +#ifdef CAN1_GCLK_ID + } else if(instance == 1) { + NVIC_DisableIRQ(CAN1_IRQn); + NVIC_ClearPendingIRQ(CAN1_IRQn); + NVIC_EnableIRQ(CAN1_IRQn); +#endif + } + + hri_can_write_ILE_reg(self->hw, CAN_ILE_EINT0); + // Prevent configuration change + hri_can_clear_CCCR_CCE_bit(self->hw); + hri_can_clear_CCCR_INIT_bit(self->hw); + while (hri_can_get_CCCR_INIT_bit(self->hw)) { + } + + can_objs[instance] = self; +} + +int common_hal_canio_can_loopback_get(canio_can_obj_t *self) +{ + return self->loopback; +} + +int common_hal_canio_can_baudrate_get(canio_can_obj_t *self) +{ + return self->baudrate; +} + +int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self) +{ + return -1; +} + +int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self) +{ + return -1; +} + +int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self) +{ + return -1; +} + +int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self) +{ + return -1; +} + +int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self) +{ + return -1; +} + +int common_hal_canio_can_state_get(canio_can_obj_t *self) { + return -1; +} + +void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *message) +{ + // We have just one dedicated TX buffer, use it! + canio_can_fifo_t *ent = &self->state->tx_fifo[0]; + ent->txb0.bit.ESI = false; + ent->txb0.bit.XTD = false; + ent->txb0.bit.RTR = message->rtr; + ent->txb0.bit.ID = message->id << 18; // short addresses are left-justified + + ent->txb1.bit.MM = 0; // "message marker" + ent->txb1.bit.EFC = 0; // don't store fifo events to event queue + ent->txb1.bit.FDF = 0; // Classic CAN format + ent->txb1.bit.BRS = 0; // No bit rate switching + ent->txb1.bit.DLC = message->size; + + if (!message->rtr) { + memcpy(ent->data, message->data, message->size); + } + + // TX buffer add request + self->hw->TXBAR.reg = 1; + + // wait 8ms (hard coded for now) for TX to occur + uint64_t deadline = port_get_raw_ticks(NULL) + 8; + while (port_get_raw_ticks(NULL) < deadline && !(self->hw->TXBTO.reg & 1)) { + RUN_BACKGROUND_TASKS; + } +} + +bool common_hal_canio_can_deinited(canio_can_obj_t *self) { + return !self->hw; +} + +void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self) { + if(common_hal_canio_can_deinited(self)) { + raise_deinited_error(); + } +} + +void common_hal_canio_can_deinit(canio_can_obj_t *self) +{ + if (self->hw) { + hri_can_set_CCCR_INIT_bit(self->hw); + self->hw = 0; + } + if (self->rx_pin_number != COMMON_HAL_MCU_NO_PIN) { + reset_pin_number(self->rx_pin_number); + self->rx_pin_number = COMMON_HAL_MCU_NO_PIN; + } + if (self->tx_pin_number != COMMON_HAL_MCU_NO_PIN) { + reset_pin_number(self->tx_pin_number); + self->tx_pin_number = COMMON_HAL_MCU_NO_PIN; + } +} + +void common_hal_canio_reset(void) { + memset(can_state, 0, sizeof(can_state)); + + for (size_t i=0; i +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/_canio/__init__.h" +#include "common-hal/_canio/Listener.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/tick.h" + +void common_hal_canio_listener_construct(canio_listener_obj_t *self, canio_can_obj_t *can, size_t nmatch, canio_match_obj_t **matches, float timeout) { + if (nmatch) { + mp_raise_NotImplementedError(NULL); + } + + if (!can->fifo0_in_use) { + self->fifo_idx = 0; + self->fifo = can->state->rx0_fifo; + self->hw = (canio_rxfifo_reg_t*)&can->hw->RXF0C; + can->hw->IR.reg = CAN_IR_RF0N | CAN_IR_RF0W | CAN_IR_RF0F | CAN_IR_RF0L; + can->fifo0_in_use = true; + } else if (!can->fifo1_in_use) { + self->fifo_idx = 1; + self->fifo = can->state->rx1_fifo; + self->hw = (canio_rxfifo_reg_t*)&can->hw->RXF1C; + can->fifo1_in_use = true; + can->hw->IR.reg = CAN_IR_RF1N | CAN_IR_RF1W | CAN_IR_RF1F | CAN_IR_RF1L; + } else { + mp_raise_ValueError(translate("All RX FIFOs in use")); + } + + self->can = can; + common_hal_canio_listener_set_timeout(self, timeout); +} + +void common_hal_canio_listener_set_timeout(canio_listener_obj_t *self, float timeout) { + self->timeout_ms = (int)MICROPY_FLOAT_C_FUN(ceil)(timeout * 1000); +} + +float common_hal_canio_listener_get_timeout(canio_listener_obj_t *self) { + return self->timeout_ms / 1000.0f; +} + +void common_hal_canio_listener_check_for_deinit(canio_listener_obj_t *self) { + if(!self->can) { + raise_deinited_error(); + } + common_hal_canio_can_check_for_deinit(self->can); +} + +int common_hal_canio_listener_in_waiting(canio_listener_obj_t *self) { + return self->hw->RXFS.bit.F0FL; +} + +bool common_hal_canio_listener_readinto(canio_listener_obj_t *self, canio_message_obj_t *message) { + if (!common_hal_canio_listener_in_waiting(self)) { + uint64_t deadline = supervisor_ticks_ms64() + self->timeout_ms; + do { + if(supervisor_ticks_ms64() > deadline) { + return false; + } + } while (!common_hal_canio_listener_in_waiting(self)); + } + int index = self->hw->RXFS.bit.F0GI; + canio_can_fifo_t *hw_message = &self->fifo[index]; + message->id = hw_message->rxb0.bit.ID >> 18; // short addresses are left-justified + message->rtr = hw_message->rxb0.bit.RTR; + message->size = hw_message->rxb1.bit.DLC; + if(!message->rtr) { + memcpy(message->data, hw_message->data, message->size); + } + self->hw->RXFA.bit.F0AI = index; + return true; +} + +void common_hal_canio_listener_deinit(canio_listener_obj_t *self) { + // free our FIFO, clear our matches, SOMETHING + if(self->can) { + if(self->fifo_idx == 0) { + self->can->fifo0_in_use = false; + } + if(self->fifo_idx == 1) { + self->can->fifo1_in_use = false; + } + } + self->fifo_idx = -1; + self->fifo = NULL; + self->can = NULL; + self->hw = NULL; +} diff --git a/ports/atmel-samd/common-hal/_canio/Listener.h b/ports/atmel-samd/common-hal/_canio/Listener.h new file mode 100644 index 0000000000..cc6770e6e5 --- /dev/null +++ b/ports/atmel-samd/common-hal/_canio/Listener.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "common-hal/_canio/CAN.h" +#include "shared-module/_canio/Match.h" + +typedef struct { + __IO CAN_RXF0C_Type RXFC; /**< \brief (R/W 32) Rx FIFO n Configuration */ + __I CAN_RXF0S_Type RXFS; /**< \brief (R/ 32) Rx FIFO n Status */ + __IO CAN_RXF0A_Type RXFA; /**< \brief (R/W 32) Rx FIFO n Acknowledge */ +} canio_rxfifo_reg_t; + +typedef struct { + mp_obj_base_t base; + canio_can_obj_t *can; + canio_can_fifo_t *fifo; + canio_rxfifo_reg_t *hw; + uint32_t timeout_ms; + uint8_t fifo_idx; +} canio_listener_obj_t; + +void common_hal_canio_listener_construct(canio_listener_obj_t *self, canio_can_obj_t *can, size_t nmatch, canio_match_obj_t **matches, float timeout); +void common_hal_canio_listener_check_for_deinit(canio_listener_obj_t *self); +void common_hal_canio_listener_deinit(canio_listener_obj_t *self); +bool common_hal_canio_listener_readinto(canio_listener_obj_t *self, canio_message_obj_t *message); +int common_hal_canio_listener_in_waiting(canio_listener_obj_t *self); +float common_hal_canio_listener_get_timeout(canio_listener_obj_t *self); +void common_hal_canio_listener_set_timeout(canio_listener_obj_t *self, float timeout); diff --git a/ports/atmel-samd/common-hal/_canio/__init__.c b/ports/atmel-samd/common-hal/_canio/__init__.c new file mode 100644 index 0000000000..7932bfc2da --- /dev/null +++ b/ports/atmel-samd/common-hal/_canio/__init__.c @@ -0,0 +1,25 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ diff --git a/ports/atmel-samd/common-hal/_canio/__init__.h b/ports/atmel-samd/common-hal/_canio/__init__.h new file mode 100644 index 0000000000..429369e188 --- /dev/null +++ b/ports/atmel-samd/common-hal/_canio/__init__.h @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "hal/utils/include/utils.h" +#include "component/can.h" + +#define COMMON_HAL_CANIO_MAX_MESSAGE_LENGTH (8) +#define COMMON_HAL_CANIO_RX_FIFO_SIZE (3) +#define COMMON_HAL_CANIO_RX_FILTER_SIZE (4) +#define COMMON_HAL_CANIO_TX_FIFO_SIZE (1) + +typedef struct canio_listener canio_listener_t; +typedef struct canio_can canio_can_t; + +typedef struct { + union { + CAN_RXBE_0_Type rxb0; + CAN_TXBE_0_Type txb0; + CAN_RXF0E_0_Type rxf0; + }; + union { + CAN_RXBE_1_Type rxb1; + CAN_TXBE_1_Type txb1; + CAN_RXF0E_1_Type rxf1; + }; + COMPILER_ALIGNED(4) + uint8_t data[COMMON_HAL_CANIO_MAX_MESSAGE_LENGTH]; +} canio_can_fifo_t; + +typedef uint32_t canio_can_filter_t; + +typedef struct { + canio_can_fifo_t tx_fifo[COMMON_HAL_CANIO_TX_FIFO_SIZE]; + canio_can_fifo_t rx0_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; + canio_can_fifo_t rx1_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; + canio_can_filter_t rx_filter[COMMON_HAL_CANIO_RX_FILTER_SIZE]; +} canio_can_state_t; diff --git a/ports/atmel-samd/tools/mkcandata.py b/ports/atmel-samd/tools/mkcandata.py new file mode 100755 index 0000000000..9668d2208a --- /dev/null +++ b/ports/atmel-samd/tools/mkcandata.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 + +def defines(name, suffix): + print(f'mcu_pin_function_t {name} [] = {{') + for instance in (0, 1): + for function in 'HI': + for port in 'ABCD': + for idx in range(32): + pin = f'P{port}{idx:02d}' + pinmux = f'PINMUX_{pin}{function}_CAN{instance}_{suffix}' + print(f'''\ +#if defined({pinmux}) && ! defined(IGNORE_PIN_{pin}) + {{&pin_{pin}, {instance}, PIN_{pin}, {pinmux} & 0xffff}}, +#endif''') + print(f'{{NULL, 0, 0}}') + print(f'}};') + print() + +print('''\ +#include +#include "py/obj.h" +#include "sam.h" +#include "samd/pins.h" +#include "mpconfigport.h" +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" +#include "common-hal/microcontroller/Pin.h" +''') + +defines('can_rx', 'RX') +defines('can_tx', 'TX') diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 6e98af8686..2614dc011f 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -142,6 +142,9 @@ endif ifeq ($(CIRCUITPY_CAMERA),1) SRC_PATTERNS += camera/% endif +ifeq ($(CIRCUITPY_CANIO),1) +SRC_PATTERNS += _canio/% +endif ifeq ($(CIRCUITPY_COUNTIO),1) SRC_PATTERNS += countio/% endif @@ -315,6 +318,9 @@ SRC_COMMON_HAL_ALL = \ busio/__init__.c \ camera/__init__.c \ camera/Camera.c \ + _canio/CAN.c \ + _canio/Listener.c \ + _canio/__init__.c \ countio/Counter.c \ countio/__init__.c \ digitalio/DigitalInOut.c \ @@ -384,6 +390,7 @@ $(filter $(SRC_PATTERNS), \ _bleio/Address.c \ _bleio/Attribute.c \ _bleio/ScanEntry.c \ + _canio/Match.c \ _eve/__init__.c \ camera/ImageFormat.c \ digitalio/Direction.c \ @@ -402,6 +409,8 @@ SRC_SHARED_MODULE_ALL = \ _bleio/Attribute.c \ _bleio/ScanEntry.c \ _bleio/ScanResults.c \ + _canio/Match.c \ + _canio/Message.c \ _eve/__init__.c \ _pixelbuf/PixelBuf.c \ _pixelbuf/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 4272de2ec7..d1b12f3544 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -336,6 +336,13 @@ extern const struct _mp_obj_module_t camera_module; #define CAMERA_MODULE #endif +#if CIRCUITPY_CANIO +extern const struct _mp_obj_module_t canio_module; +#define CANIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__canio), (mp_obj_t)&canio_module }, +#else +#define CANIO_MODULE +#endif + #if CIRCUITPY_COUNTIO extern const struct _mp_obj_module_t countio_module; #define COUNTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_countio), (mp_obj_t)&countio_module }, @@ -766,6 +773,7 @@ extern const struct _mp_obj_module_t wifi_module; BOARD_MODULE \ BUSIO_MODULE \ CAMERA_MODULE \ + CANIO_MODULE \ COUNTIO_MODULE \ DIGITALIO_MODULE \ DISPLAYIO_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 54bdefc6dd..9b9bd83b4d 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -93,6 +93,9 @@ CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO) CIRCUITPY_CAMERA ?= 0 CFLAGS += -DCIRCUITPY_CAMERA=$(CIRCUITPY_CAMERA) +CIRCUITPY_CANIO ?= 0 +CFLAGS += -DCIRCUITPY_CANIO=$(CIRCUITPY_CANIO) + CIRCUITPY_DIGITALIO ?= 1 CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/_canio/CAN.c new file mode 100644 index 0000000000..4c7ae3650a --- /dev/null +++ b/shared-bindings/_canio/CAN.c @@ -0,0 +1,338 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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 "common-hal/_canio/CAN.h" +#include "common-hal/_canio/Listener.h" +#include "shared-bindings/_canio/CAN.h" +#include "shared-bindings/_canio/Listener.h" +#include "shared-bindings/_canio/Match.h" +#include "shared-bindings/_canio/Message.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "py/objproperty.h" +#include "py/runtime.h" + +//| +//| class CAN: +//| """CAN bus protocol""" +//| +//| def __init__(self, +//| rx: microcontroller.Pin, +//| tx: Optional[microcontroller.Pin]=None, +//| *, +//| baudrate: int = 250000, +//| loopback: bool = False, +//| ): +//| """A common shared-bus protocol. The rx and tx pins are generally +//| connected to a transceiver which controls the H and L pins on a shared +//| bus. +//| +//| :param ~microcontrller.Pin rx: the pin to receive with. +//| :param ~microcontrller.Pin tx: the pin to transmit with, or None if the peripheral should operate in "silent" mode. +//| :param int baudrate: The bit rate of the bus in Hz. All devices on the bus must agree on this value. +//| :param bool loopback: True if the peripheral will be operated in loopback mode. +//| """ +//| ... +//| +//## auto_restart: bool = False, # Whether to restart communications after entering bus-off state +//## sample_point: float = .875, # When to sample within bit time (0.0-1.0) +STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_rx, ARG_tx, ARG_baudrate, ARG_loopback, ARG_silent, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_rx, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = 0} }, + { MP_QSTR_tx, MP_ARG_OBJ, {.u_obj = 0} }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 250000} }, + { MP_QSTR_loopback, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_silent, MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + +mp_printf(&mp_plat_print, "ARG_rx=%d args[ARG_rx].u_obj=%p\n", ARG_rx, args[ARG_rx].u_obj); +mp_printf(&mp_plat_print, "ARG_tx=%d args[ARG_tx].u_obj=%p\n", ARG_tx, args[ARG_tx].u_obj); + + mcu_pin_obj_t *rx_pin = validate_obj_is_free_pin(args[ARG_rx].u_obj); +mp_printf(&mp_plat_print, "rx_pin=%p\n", rx_pin); + mcu_pin_obj_t *tx_pin = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj); +mp_printf(&mp_plat_print, "tx_pin=%p\n", tx_pin); + + canio_can_obj_t *self = m_new_obj(canio_can_obj_t); + self->base.type = &canio_can_type; + common_hal_canio_can_construct(self, rx_pin, tx_pin, args[ARG_baudrate].u_int, args[ARG_loopback].u_bool, args[ARG_silent].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + + +//| baudrate: int +//| """The baud rate(read-only)""" +//| +STATIC mp_obj_t canio_can_baudrate_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_baudrate_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_baudrate_get_obj, canio_can_baudrate_get); + +STATIC const mp_obj_property_t canio_can_baudrate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_baudrate_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + +//| state: State +//| """The status of the hardware (read-only)""" +//| +STATIC mp_obj_t canio_can_state_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_state_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_state_get_obj, canio_can_state_get); + +STATIC const mp_obj_property_t canio_can_state_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_state_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + +//| transmit_error_count: int +//| """The number of transmit errors (read-only). Increased for a detected transmission error, decreased for successful transmission. Limited to the range from 0 to 255 inclusive. Also called TEC.""" +//| +STATIC mp_obj_t canio_can_transmit_error_count_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_transmit_error_count_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_transmit_error_count_get_obj, canio_can_transmit_error_count_get); + +STATIC const mp_obj_property_t canio_can_transmit_error_count_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_transmit_error_count_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + +//| receive_error_count: int +//| """The number of receive errors (read-only). Increased for a detected reception error, decreased for successful reception. Limited to the range from 0 to 255 inclusive. Also called REC.""" +//| +STATIC mp_obj_t canio_can_receive_error_count_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_receive_error_count_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_receive_error_count_get_obj, canio_can_receive_error_count_get); + +STATIC const mp_obj_property_t canio_can_receive_error_count_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_receive_error_count_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + +//| error_warning_state_count: int +//| """The number of times the controller enterted the Error Warning state (read-only). This number wraps around to 0 after an implementation-defined number of errors.""" +//| +STATIC mp_obj_t canio_can_error_warning_state_count_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_error_warning_state_count_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_error_warning_state_count_get_obj, canio_can_error_warning_state_count_get); + +STATIC const mp_obj_property_t canio_can_error_warning_state_count_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_error_warning_state_count_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + +//| error_passive_state_count: int +//| """The number of times the controller enterted the Error Passive state (read-only). This number wraps around to 0 after an implementation-defined number of errors.""" +//| +STATIC mp_obj_t canio_can_error_passive_state_count_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_error_passive_state_count_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_error_passive_state_count_get_obj, canio_can_error_passive_state_count_get); + +STATIC const mp_obj_property_t canio_can_error_passive_state_count_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_error_passive_state_count_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + +//| bus_off_state_count: int +//| """The number of times the controller enterted the Bus Off state (read-only). This number wraps around to 0 after an implementation-defined number of errors.""" +//| +STATIC mp_obj_t canio_can_bus_off_state_count_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_bus_off_state_count_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_bus_off_state_count_get_obj, canio_can_bus_off_state_count_get); + +STATIC const mp_obj_property_t canio_can_bus_off_state_count_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_bus_off_state_count_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + +#if 0 +//| # pending_tx_count: int +//| # """The number of messages waiting to be transmitted. (read-only)""" +#endif + +//| def listen(filters: Optional[Sequence[Filter]]=None, *, timeout: float=10) -> Listener: +//| """Start receiving messages that match any one of the filters. +//| Creating a listener is an expensive operation and can interfere with reception of messages by other listeners. +//| There is an implementation-defined maximum number of listeners and limit to the complexity of the filters. +//| If the hardware cannot support all the requested filters, a ValueError is raised. Note that generally there are some number of hardware filters shared among all fifos. +//| A message can be received by at most one Listener. +//| An empty filter list causes all messages to be accepted. +//| Timeout dictates how long readinto, read and next() will block. +//| Readinto will return false(), read will return None, and next() will raise StopIteration.""" +//| ... +//| +STATIC mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + common_hal_canio_can_check_for_deinit(self); + + enum { ARG_match, ARG_timeout, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_match, MP_ARG_OBJ, {.u_obj = 0} }, + { MP_QSTR_timeout, MP_ARG_OBJ, {.u_obj = 0} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + size_t nmatch = 0; + mp_obj_t *match_objects = NULL; + + if (args[ARG_match].u_obj) { + mp_obj_get_array(args[ARG_match].u_obj, &nmatch, &match_objects); + } + + canio_match_obj_t *matches[nmatch]; + for (size_t i=0; iname); + } + matches[i] = MP_OBJ_TO_PTR(match_objects[i]); + } + + float timeout = args[ARG_timeout].u_obj ? mp_obj_get_float(args[ARG_timeout].u_obj) : 10.0f; + canio_listener_obj_t *listener = m_new_obj(canio_listener_obj_t); + listener->base.type = &canio_listener_type; + common_hal_canio_listener_construct(listener, self, nmatch, matches, timeout); + return listener; +} +MP_DEFINE_CONST_FUN_OBJ_KW(canio_can_listen_obj, 1, canio_can_listen); + +//| def send(message: Message) -> None: +//| """Send a message on the bus with the given data and id. +//| If the message could not be sent due to a full fifo or a bus error condition, RuntimeError is raised. +//| """ +//| ... +//| +STATIC mp_obj_t canio_can_send(mp_obj_t self_in, mp_obj_t message_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + mp_obj_type_t *message_type = mp_obj_get_type(message_in); + if (message_type != &canio_message_type) { + mp_raise_TypeError_varg(translate("expected '%q' but got '%q'"), MP_QSTR_Message, message_type->name); + } + + canio_message_obj_t *message = message_in; + common_hal_canio_can_send(self, message); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(canio_can_send_obj, canio_can_send); + +//| def deinit(self) -> None: +//| """Deinitialize this object, freeing its hardware resources""" +//| ... +//| +STATIC mp_obj_t canio_can_deinit(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_deinit_obj, canio_can_deinit); + +//| def __enter__(self) -> CAN: +//| """Returns self, to allow the object to be used in a `with` statement for resource control""" +//| ... +//| +STATIC mp_obj_t canio_can_enter(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_enter_obj, canio_can_enter); + +//| def __exit__(self, unused1, unused2, unused3) -> None: +//| """Calls deinit()""" +//| ... +STATIC mp_obj_t canio_can_exit(size_t num_args, const mp_obj_t args[]) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_canio_can_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(canio_can_exit_obj, 4, 4, canio_can_exit); + +STATIC const mp_rom_map_elem_t canio_can_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&canio_can_enter_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&canio_can_exit_obj) }, + { MP_ROM_QSTR(MP_QSTR_bus_off_state_count), MP_ROM_PTR(&canio_can_bus_off_state_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&canio_can_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_error_passive_state_count), MP_ROM_PTR(&canio_can_error_passive_state_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_error_warning_state_count), MP_ROM_PTR(&canio_can_error_warning_state_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&canio_can_listen_obj) }, + { MP_ROM_QSTR(MP_QSTR_receive_error_count), MP_ROM_PTR(&canio_can_receive_error_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&canio_can_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&canio_can_state_obj) }, + { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&canio_can_baudrate_obj) }, + { MP_ROM_QSTR(MP_QSTR_transmit_error_count), MP_ROM_PTR(&canio_can_transmit_error_count_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(canio_can_locals_dict, canio_can_locals_dict_table); + +const mp_obj_type_t canio_can_type = { + { &mp_type_type }, + .name = MP_QSTR_CAN, + .make_new = canio_can_make_new, + .locals_dict = (mp_obj_t)&canio_can_locals_dict, +}; diff --git a/shared-bindings/_canio/CAN.h b/shared-bindings/_canio/CAN.h new file mode 100644 index 0000000000..81040cf237 --- /dev/null +++ b/shared-bindings/_canio/CAN.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +extern const mp_obj_type_t canio_can_type; diff --git a/shared-bindings/_canio/Listener.c b/shared-bindings/_canio/Listener.c new file mode 100644 index 0000000000..7f83c735f0 --- /dev/null +++ b/shared-bindings/_canio/Listener.c @@ -0,0 +1,197 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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 "shared-bindings/_canio/Listener.h" +#include "shared-bindings/_canio/Message.h" +#include "common-hal/_canio/Listener.h" + +#include "py/runtime.h" +#include "py/objproperty.h" + +//| class Listener: +//| """Listens for CAN message +//| +//| _canio.Listener is not constructed directly, but instead by calling the +//| Listen method of a _canio.CAN object.""" +//| + +//| def read(self) -> Optional[Message]: +//| """Returns a message, after waiting up to self.timeout seconds +//| +//| If no message is received in time, None is returned. Otherwise, +//| a Message is returned.""" +//| ... +//| +STATIC mp_obj_t canio_listener_read(mp_obj_t self_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_check_for_deinit(self); + + canio_message_obj_t *message = m_new_obj(canio_message_obj_t); + self->base.type = &canio_message_type; + + if (common_hal_canio_listener_readinto(self, message)) { + return message; + } else { + m_free(message); // message did not escape into vm + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_read_obj, canio_listener_read); + +//| def readinto(self, message: Message) -> bool: +//| """Returns a message, after waiting up to self.timeout seconds +//| +//| Returns True (and modifies message) if a message was received, +//| False otherwise.""" +//| ... +//| +STATIC mp_obj_t canio_listener_readinto(mp_obj_t self_in, mp_obj_t message) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_type_t *type = mp_obj_get_type(message); + if (type != &canio_message_type) { + mp_raise_TypeError_varg(translate("expected '%q' but got '%q'"), MP_QSTR_Message, type->name); + } + common_hal_canio_listener_check_for_deinit(self); + return mp_obj_new_bool(common_hal_canio_listener_readinto(self, message)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(canio_listener_readinto_obj, canio_listener_readinto); + +//| def in_waiting(self) -> int: +//| """Returns the number of messages waiting""" +//| ... +//| +STATIC mp_obj_t canio_listener_in_waiting(mp_obj_t self_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_listener_in_waiting(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_in_waiting_obj, canio_listener_in_waiting); + +//| def __iter__(self): +//| """Returns self, unless the object is deinitialized""" +//| ... +//| +STATIC mp_obj_t canio_listener_iter(mp_obj_t self_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_check_for_deinit(self); + return self; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_iter_obj, canio_listener_iter); + +//| def __next__(self): +//| """Returns the next waiting message, if one is available +//| +//| If the object is deinitialized, raises ValueError. +//| +//| If no message is waiting raises StopIteration""" +//| ... +//| +STATIC mp_obj_t canio_listener_next(mp_obj_t self_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_check_for_deinit(self); + if(common_hal_canio_listener_in_waiting(self)) { + return canio_listener_read(self_in); + } + return self; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_next_obj, canio_listener_next); + +//| def deinit(self) -> None: +//| """Deinitialize this object, freeing its hardware resources""" +//| ... +//| +STATIC mp_obj_t canio_listener_deinit(mp_obj_t self_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_deinit_obj, canio_listener_deinit); + +//| def __enter__(self) -> CAN: +//| """Returns self, to allow the object to be used in a `with` statement for resource control""" +//| ... +//| +STATIC mp_obj_t canio_listener_enter(mp_obj_t self_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_check_for_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_enter_obj, canio_listener_enter); + +//| def __exit__(self, unused1, unused2, unused3) -> None: +//| """Calls deinit()""" +//| ... +STATIC mp_obj_t canio_listener_exit(size_t num_args, const mp_obj_t args[]) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_canio_listener_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(canio_listener_exit_obj, 4, 4, canio_listener_exit); + + +//| timeout : float +STATIC mp_obj_t canio_listener_timeout_get(mp_obj_t self_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_check_for_deinit(self); + return mp_obj_new_float(common_hal_canio_listener_get_timeout(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_timeout_get_obj, canio_listener_timeout_get); + +STATIC mp_obj_t canio_listener_timeout_set(mp_obj_t self_in, mp_obj_t timeout_in) { + canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_listener_check_for_deinit(self); + common_hal_canio_listener_set_timeout(self, mp_obj_get_float(timeout_in)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(canio_listener_timeout_set_obj, canio_listener_timeout_set); + +STATIC const mp_obj_property_t canio_listener_timeout_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_listener_timeout_get_obj, + (mp_obj_t)&canio_listener_timeout_set_obj, + (mp_obj_t)mp_const_none}, +}; + + + +STATIC const mp_rom_map_elem_t canio_listener_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&canio_listener_enter_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&canio_listener_exit_obj) }, + { MP_ROM_QSTR(MP_QSTR___iter__), MP_ROM_PTR(&canio_listener_iter_obj) }, + { MP_ROM_QSTR(MP_QSTR___next__), MP_ROM_PTR(&canio_listener_next_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&canio_listener_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&canio_listener_in_waiting_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&canio_listener_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&canio_listener_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&canio_listener_timeout_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(canio_listener_locals_dict, canio_listener_locals_dict_table); + +const mp_obj_type_t canio_listener_type = { + { &mp_type_type }, + .name = MP_QSTR_Listener, + .locals_dict = (mp_obj_dict_t*)&canio_listener_locals_dict, +}; diff --git a/shared-bindings/_canio/Listener.h b/shared-bindings/_canio/Listener.h new file mode 100644 index 0000000000..eaa3490dff --- /dev/null +++ b/shared-bindings/_canio/Listener.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +extern const mp_obj_type_t canio_listener_type; diff --git a/shared-bindings/_canio/Match.c b/shared-bindings/_canio/Match.c new file mode 100644 index 0000000000..6c32aa5390 --- /dev/null +++ b/shared-bindings/_canio/Match.c @@ -0,0 +1,140 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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 "shared-bindings/_canio/Match.h" +#include "shared-module/_canio/Match.h" + +#include "py/objproperty.h" +#include "py/runtime.h" + +//| class Match: +//| """Describe CAN bus messages to match""" +//| +//| +//| def __init__(self, address: int, *, mask: int = 0, extended: bool = False): +//| """Construct a Match with the given properties. +//| +//| If mask is nonzero, then the filter is for any sender which matches all +//| the nonzero bits in mask. Otherwise, it matches exactly the given address. +//| If extended is true then only extended addresses are matched, otherwise +//| only standard addresses are matched.""" +//| + +STATIC mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_mask, ARG_extended, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, + { MP_QSTR_mask, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_extended, MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int address_bits = args[ARG_extended].u_bool ? 0x1fffffff : 0x7ff; + int address = args[ARG_address].u_int; + int mask = args[ARG_mask].u_int; + + if(address & ~address_bits) { + mp_raise_ValueError_varg(translate("%q out of range"), MP_QSTR_address); + } + + if(mask & ~address_bits) { + mp_raise_ValueError_varg(translate("%q out of range"), MP_QSTR_mask); + } + + canio_match_obj_t *self = m_new_obj(canio_match_obj_t); + self->base.type = &canio_match_type; + common_hal_canio_match_construct(self, args[ARG_address].u_int, args[ARG_mask].u_int, args[ARG_extended].u_bool); + return self; +} + +//| address: int +//| """The address to match""" +//| + +STATIC mp_obj_t canio_match_address_get(mp_obj_t self_in) { + canio_match_obj_t *self = self_in; + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_match_address_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_match_address_get_obj, canio_match_address_get); + +const mp_obj_property_t canio_match_address_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_match_address_get_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| +//| mask: int +//| """The optional mask of addresses to match""" +//| + +STATIC mp_obj_t canio_match_mask_get(mp_obj_t self_in) { + canio_match_obj_t *self = self_in; + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_match_mask_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_match_mask_get_obj, canio_match_mask_get); + +const mp_obj_property_t canio_match_mask_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_match_mask_get_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| extended: bool +//| """True to match extended addresses, False to match standard addresses""" +//| + +STATIC mp_obj_t canio_match_extended_get(mp_obj_t self_in) { + canio_match_obj_t *self = self_in; + return mp_obj_new_bool(common_hal_canio_match_extended_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_match_extended_get_obj, canio_match_extended_get); + +const mp_obj_property_t canio_match_extended_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_match_extended_get_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t canio_match_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&canio_match_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_mask), MP_ROM_PTR(&canio_match_mask_obj) }, + { MP_ROM_QSTR(MP_QSTR_extended), MP_ROM_PTR(&canio_match_extended_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(canio_match_locals_dict, canio_match_locals_dict_table); + +const mp_obj_type_t canio_match_type = { + { &mp_type_type }, + .name = MP_QSTR_Match, + .make_new = canio_match_make_new, + .locals_dict = (mp_obj_dict_t*)&canio_match_locals_dict, +}; diff --git a/shared-bindings/_canio/Match.h b/shared-bindings/_canio/Match.h new file mode 100644 index 0000000000..adf98eb865 --- /dev/null +++ b/shared-bindings/_canio/Match.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +extern const mp_obj_type_t canio_match_type; + +// Nothing now. diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/_canio/Message.c new file mode 100644 index 0000000000..a8e5883541 --- /dev/null +++ b/shared-bindings/_canio/Message.c @@ -0,0 +1,213 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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 "shared-bindings/_canio/Message.h" +#include "shared-module/_canio/Message.h" + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +//| class Message: +//| def __init__(self, id: int=0, data: Optional[bytes] = None, *, size: Optional[int] = None, rtr: bool = False): +//| """Construct a Message to send on a CAN bus +//| +//| :param int id: The numeric ID of the message +//| :param bytes data: The content of the message +//| :param int size: The amount of data requested, for an rtr +//| :param bool rtr: True if the message represents an rtr (Remote Transmission Request) +//| +//| In CAN, messages can have a size from 0 to 8 bytes. +//| +//| For a non-rtr message, specify `data`. For an rtr-message, specify either `data` (a dummy buffer of the requested size) or `size`. +//| """ +//| ... +//| +STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_id, ARG_data, ARG_size, ARG_rtr, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_obj = 0} }, + { MP_QSTR_data, MP_ARG_OBJ, {.u_obj = 0} }, + { MP_QSTR_size, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_rtr, MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + bool rtr = args[ARG_rtr].u_bool; + size_t size = (size_t)args[ARG_size].u_int; + bool specified_size = (size != (size_t)-1); + bool specified_data = (args[ARG_data].u_obj != NULL); + + if(specified_size && specified_data) { + mp_raise_TypeError(translate("specify size or data, but not both")); + } + + mp_buffer_info_t data; + if (specified_data) { + mp_get_buffer_raise(args[ARG_data].u_obj, &data, MP_BUFFER_READ); + } else if (specified_size) { + data.buf = 0; + data.len = size; + } else { + data.buf = 0; + data.len = 0; + } + + if(data.len > 8) { + mp_raise_ValueError(translate("Messages limited to 8 bytes")); + } + + canio_message_obj_t *self = m_new_obj(canio_message_obj_t); + self->base.type = &canio_message_type; + common_hal_canio_message_construct(self, args[ARG_id].u_int, data.buf, data.len, rtr); + return self; +} + +//| id: int +//| """The numeric ID of the message""" +//| +STATIC mp_obj_t canio_message_id_get(const mp_obj_t self_in) { + canio_message_obj_t *self = self_in; + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_id_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_message_id_get_obj, canio_message_id_get); + +STATIC mp_obj_t canio_message_id_set(const mp_obj_t self_in, const mp_obj_t id) { + canio_message_obj_t *self = self_in; + common_hal_canio_message_id_set(self, mp_obj_get_int(id)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(canio_message_id_set_obj, canio_message_id_set); + +STATIC const mp_obj_property_t canio_message_id_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_message_id_get_obj, + (mp_obj_t)&canio_message_id_set_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| data: bytes +//| """The content of the message, or dummy content in the case of an rtr. +//| +//| Assigning to data sets the bytes to zero""" +//| +STATIC mp_obj_t canio_message_data_get(const mp_obj_t self_in) { + canio_message_obj_t *self = self_in; + return mp_obj_new_bytes((const byte*)common_hal_canio_message_data_get(self), common_hal_canio_message_size_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_message_data_get_obj, canio_message_data_get); + +STATIC mp_obj_t canio_message_data_set(const mp_obj_t self_in, const mp_obj_t data_in) { + canio_message_obj_t *self = self_in; + mp_buffer_info_t data; + mp_get_buffer_raise(data_in, &data, MP_BUFFER_READ); + if(data.len > 8) { + mp_raise_ValueError(translate("Messages limited to 8 bytes")); + } + common_hal_canio_message_data_set(self, data.buf, data.len); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(canio_message_data_set_obj, canio_message_data_set); + + +STATIC const mp_obj_property_t canio_message_data_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_message_data_get_obj, + (mp_obj_t)&canio_message_data_set_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| size: int +//| """The length of the message, or the length of the requested data in the case of an rtr""" +//| +STATIC mp_obj_t canio_message_size_get(const mp_obj_t self_in) { + canio_message_obj_t *self = self_in; + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_size_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_message_size_get_obj, canio_message_size_get); + +STATIC mp_obj_t canio_message_size_set(const mp_obj_t self_in, const mp_obj_t size_in) { + canio_message_obj_t *self = self_in; + int size = mp_obj_get_int(size_in); + if(size > 8) { + mp_raise_ValueError(translate("Messages limited to 8 bytes")); + } + common_hal_canio_message_size_set(self, size); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(canio_message_size_set_obj, canio_message_size_set); + + +STATIC const mp_obj_property_t canio_message_size_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_message_size_get_obj, + (mp_obj_t)&canio_message_size_set_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| rtr: bool +//| """True if the message represents a remote transmission request (RTR)""" +//| +STATIC mp_obj_t canio_message_rtr_get(const mp_obj_t self_in) { + canio_message_obj_t *self = self_in; + return mp_obj_new_bool(common_hal_canio_message_rtr_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_message_rtr_get_obj, canio_message_rtr_get); + +STATIC mp_obj_t canio_message_rtr_set(const mp_obj_t self_in, const mp_obj_t rtr) { + canio_message_obj_t *self = self_in; + common_hal_canio_message_size_set(self, mp_obj_is_true(rtr)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(canio_message_rtr_set_obj, canio_message_rtr_set); + + +STATIC const mp_obj_property_t canio_message_rtr_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_message_rtr_get_obj, + (mp_obj_t)&canio_message_rtr_set_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t canio_message_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&canio_message_id_obj) }, + { MP_ROM_QSTR(MP_QSTR_data), MP_ROM_PTR(&canio_message_data_obj) }, + { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&canio_message_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_rtr), MP_ROM_PTR(&canio_message_rtr_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(canio_message_locals_dict, canio_message_locals_dict_table); + +const mp_obj_type_t canio_message_type = { + { &mp_type_type }, + .name = MP_QSTR_Message, + .make_new = canio_message_make_new, + .locals_dict = (mp_obj_t)&canio_message_locals_dict, +}; diff --git a/shared-bindings/_canio/Message.h b/shared-bindings/_canio/Message.h new file mode 100644 index 0000000000..32d6801bc3 --- /dev/null +++ b/shared-bindings/_canio/Message.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +extern const mp_obj_type_t canio_message_type; diff --git a/shared-bindings/_canio/__init__.c b/shared-bindings/_canio/__init__.c new file mode 100644 index 0000000000..4da008ff21 --- /dev/null +++ b/shared-bindings/_canio/__init__.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +//| """CAN bus access +//| +//| The `_canio` module contains low level classes to support the CAN bus +//| protocol. +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| For example:: +//| +//| import _canio +//| from board import * +//| +//| can = _canio.BUS(board.CANRX, board.CANTX) +//| can.write(408, b"adafruit") +//| can.deinit() +//| +//| This example will write the data 'adafruit' onto the CAN bus to any +//| device listening for message id 408.""" +//| + +#include "py/obj.h" + +#include "shared-bindings/_canio/__init__.h" +#include "shared-bindings/_canio/CAN.h" +#include "shared-bindings/_canio/Match.h" +#include "shared-bindings/_canio/Message.h" + +STATIC const mp_rom_map_elem_t canio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__canio) }, + { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&canio_can_type) }, + { MP_ROM_QSTR(MP_QSTR_Match), MP_ROM_PTR(&canio_match_type) }, + { MP_ROM_QSTR(MP_QSTR_Message), MP_ROM_PTR(&canio_message_type) }, +#if 0 + { MP_ROM_QSTR(MP_QSTR_Listener), MP_ROM_PTR(&canio_listener_type) }, +#endif +}; + + +STATIC MP_DEFINE_CONST_DICT(canio_module_globals, canio_module_globals_table); + +const mp_obj_module_t canio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&canio_module_globals, +}; diff --git a/shared-bindings/_canio/__init__.h b/shared-bindings/_canio/__init__.h new file mode 100644 index 0000000000..45e76369c7 --- /dev/null +++ b/shared-bindings/_canio/__init__.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +// Nothing now. diff --git a/shared-module/_canio/Match.c b/shared-module/_canio/Match.c new file mode 100644 index 0000000000..2b696addb0 --- /dev/null +++ b/shared-module/_canio/Match.c @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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 "shared-module/_canio/Match.h" + +void common_hal_canio_match_construct(canio_match_obj_t *self, int address, int mask, bool extended) { + self->address = address; + self->mask = mask; + self->extended = extended; +} + +int common_hal_canio_match_address_get(const canio_match_obj_t *self) { + return self->address; +} +int common_hal_canio_match_mask_get(const canio_match_obj_t *self) { + return self->mask; +} +bool common_hal_canio_match_extended_get(const canio_match_obj_t *self) { + return self->extended; +} diff --git a/shared-module/_canio/Match.h b/shared-module/_canio/Match.h new file mode 100644 index 0000000000..099df976df --- /dev/null +++ b/shared-module/_canio/Match.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + int address; + int mask; + bool extended; +} canio_match_obj_t; + +void common_hal_canio_match_construct(canio_match_obj_t *self, int address, int mask, bool extended); +int common_hal_canio_match_address_get(const canio_match_obj_t *self); +int common_hal_canio_match_mask_get(const canio_match_obj_t *self); +bool common_hal_canio_match_extended_get(const canio_match_obj_t *self); diff --git a/shared-module/_canio/Message.c b/shared-module/_canio/Message.c new file mode 100644 index 0000000000..df6a40a0af --- /dev/null +++ b/shared-module/_canio/Message.c @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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 "shared-module/_canio/Message.h" + +#include + +void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr) +{ + self->id = id; + self->size = size; + self->rtr = rtr; + if (data) { + memcpy(self->data, data, size); + } else { + memset(self->data, 0, size); + } +} + +int common_hal_canio_message_id_get(const canio_message_obj_t *self) +{ + return self->id; +} + +void common_hal_canio_message_id_set(canio_message_obj_t *self, int id) +{ + self->id = id; +} + + +const void *common_hal_canio_message_data_get(const canio_message_obj_t *self) +{ + return self->data; +} + +const void common_hal_canio_message_data_set(canio_message_obj_t *self, const void *data, size_t size) +{ + memcpy(self->data, data, size); +} + + +size_t common_hal_canio_message_size_get(const canio_message_obj_t *self) +{ + return self->size; +} + +void common_hal_canio_message_size_set(canio_message_obj_t *self, size_t size) +{ + memset(self->data, 0, size); + self->size = size; +} + + +bool common_hal_canio_message_rtr_get(const canio_message_obj_t *self) +{ + return self->rtr; +} + +void common_hal_canio_message_rtr_set(canio_message_obj_t *self, bool rtr) +{ + self->rtr = rtr; +} diff --git a/shared-module/_canio/Message.h b/shared-module/_canio/Message.h new file mode 100644 index 0000000000..e846f1095f --- /dev/null +++ b/shared-module/_canio/Message.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + int id; + size_t size; + uint8_t data[8]; + bool rtr; +} canio_message_obj_t; + +void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr); +bool common_hal_canio_message_rtr_get(const canio_message_obj_t *self); +int common_hal_canio_message_id_get(const canio_message_obj_t *self); +const void *common_hal_canio_message_data_get(const canio_message_obj_t *self); +size_t common_hal_canio_message_size_get(const canio_message_obj_t *self); +void common_hal_canio_message_rtr_set(canio_message_obj_t *self, bool rtr); +void common_hal_canio_message_id_set(canio_message_obj_t *self, int id); +void common_hal_canio_message_data_set(canio_message_obj_t *self, const void *data, size_t size); +void common_hal_canio_message_size_set(canio_message_obj_t *self, size_t size); From 65ca1c7bbc84cd88d3aae69d89d2ff2c287ef884 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 11:57:24 -0500 Subject: [PATCH 10/55] _canio: Message: Setting data should set the size to match --- shared-module/_canio/Message.c | 1 + 1 file changed, 1 insertion(+) diff --git a/shared-module/_canio/Message.c b/shared-module/_canio/Message.c index df6a40a0af..1ac5b81789 100644 --- a/shared-module/_canio/Message.c +++ b/shared-module/_canio/Message.c @@ -58,6 +58,7 @@ const void *common_hal_canio_message_data_get(const canio_message_obj_t *self) const void common_hal_canio_message_data_set(canio_message_obj_t *self, const void *data, size_t size) { + self->size = size; memcpy(self->data, data, size); } From 37af9dde90a65626c60debfe7ede034534a6a823 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 11:57:57 -0500 Subject: [PATCH 11/55] Listener: fix doc markup, include in globals of its module --- shared-bindings/_canio/Listener.c | 6 +++--- shared-bindings/_canio/__init__.c | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/shared-bindings/_canio/Listener.c b/shared-bindings/_canio/Listener.c index 7f83c735f0..d68138d997 100644 --- a/shared-bindings/_canio/Listener.c +++ b/shared-bindings/_canio/Listener.c @@ -32,10 +32,10 @@ #include "py/objproperty.h" //| class Listener: -//| """Listens for CAN message +//| """Listens for CAN message //| -//| _canio.Listener is not constructed directly, but instead by calling the -//| Listen method of a _canio.CAN object.""" +//| _canio.Listener is not constructed directly, but instead by calling the +//| Listen method of a _canio.CAN object.""" //| //| def read(self) -> Optional[Message]: diff --git a/shared-bindings/_canio/__init__.c b/shared-bindings/_canio/__init__.c index 4da008ff21..8b8aba8c49 100644 --- a/shared-bindings/_canio/__init__.c +++ b/shared-bindings/_canio/__init__.c @@ -57,11 +57,9 @@ STATIC const mp_rom_map_elem_t canio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__canio) }, { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&canio_can_type) }, + { MP_ROM_QSTR(MP_QSTR_Listener), MP_ROM_PTR(&canio_listener_type) }, { MP_ROM_QSTR(MP_QSTR_Match), MP_ROM_PTR(&canio_match_type) }, { MP_ROM_QSTR(MP_QSTR_Message), MP_ROM_PTR(&canio_message_type) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_Listener), MP_ROM_PTR(&canio_listener_type) }, -#endif }; From f8dcf2118e453b3adbf8ddbee9705749389b8799 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 11:58:19 -0500 Subject: [PATCH 12/55] _canio: Add _canio.State enum-like class --- shared-bindings/_canio/__init__.c | 38 +++++++++++++++++++++++++++++-- shared-bindings/_canio/__init__.h | 6 ++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/shared-bindings/_canio/__init__.c b/shared-bindings/_canio/__init__.c index 8b8aba8c49..577466ed61 100644 --- a/shared-bindings/_canio/__init__.c +++ b/shared-bindings/_canio/__init__.c @@ -48,21 +48,55 @@ //| #include "py/obj.h" +#include "py/enum.h" #include "shared-bindings/_canio/__init__.h" #include "shared-bindings/_canio/CAN.h" #include "shared-bindings/_canio/Match.h" #include "shared-bindings/_canio/Message.h" +#include "shared-bindings/_canio/Listener.h" + +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_ACTIVE, BUS_STATE_ERROR_ACTIVE); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, BUS_STATE_ERROR_PASSIVE); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_WARNING, BUS_STATE_ERROR_WARNING); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); + +//| class BusState: +//| """The state of the CAN bus""" +//| +//| ERROR_ACTIVE: object +//| """The bus is in the normal (active) state""" +//| +//| ERROR_WARNING: object +//| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently""" +//| +//| ERROR_PASSIVE: object +//| """The bus is in the passive state due to the number of errors that have occurred recently""" +//| +//| BUS_OFF: object +//| """The bus has turned off due to the number of errors that have occurred recently. It must be restarted before it will send or receive packets""" +//| +MAKE_ENUM_MAP(canio_bus_state) { + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_WARNING), + MAKE_ENUM_MAP_ENTRY(bus_state, BUS_OFF), +}; +STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); + +MAKE_PRINTER(_canio, canio_bus_state); + +MAKE_ENUM_TYPE(_canio, BusState, canio_bus_state); STATIC const mp_rom_map_elem_t canio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__canio) }, + { MP_ROM_QSTR(MP_QSTR_BusState), MP_ROM_PTR(&canio_bus_state_type) }, { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&canio_can_type) }, { MP_ROM_QSTR(MP_QSTR_Listener), MP_ROM_PTR(&canio_listener_type) }, { MP_ROM_QSTR(MP_QSTR_Match), MP_ROM_PTR(&canio_match_type) }, { MP_ROM_QSTR(MP_QSTR_Message), MP_ROM_PTR(&canio_message_type) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__canio) }, }; - STATIC MP_DEFINE_CONST_DICT(canio_module_globals, canio_module_globals_table); const mp_obj_module_t canio_module = { diff --git a/shared-bindings/_canio/__init__.h b/shared-bindings/_canio/__init__.h index 45e76369c7..e24eba92c1 100644 --- a/shared-bindings/_canio/__init__.h +++ b/shared-bindings/_canio/__init__.h @@ -26,4 +26,8 @@ #pragma once -// Nothing now. +typedef enum { + BUS_STATE_ERROR_ACTIVE, BUS_STATE_ERROR_PASSIVE, BUS_STATE_ERROR_WARNING, BUS_STATE_OFF +} canio_bus_state_t; + +extern const mp_obj_type_t canio_bus_state_type; From 635fcadb59fdba47d1628c3abff1b9bfc890a5d5 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 11:59:01 -0500 Subject: [PATCH 13/55] _canio.CAN: add error handling & bus state --- ports/atmel-samd/common-hal/_canio/CAN.c | 71 ++++++++++++++++-- ports/atmel-samd/common-hal/_canio/CAN.h | 37 ++++++---- shared-bindings/_canio/CAN.c | 93 ++++++++++++++++++------ 3 files changed, 156 insertions(+), 45 deletions(-) diff --git a/ports/atmel-samd/common-hal/_canio/CAN.c b/ports/atmel-samd/common-hal/_canio/CAN.c index dcd269495e..d2e7d8d9db 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.c +++ b/ports/atmel-samd/common-hal/_canio/CAN.c @@ -218,6 +218,15 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc hri_can_write_XIDFC_reg(self->hw, dfc.reg); } + { + CAN_IE_Type ie = { + .bit.EWE = 1, + .bit.EPE = 1, + .bit.BOE = 1, + }; + hri_can_write_IE_reg(self->hw, ie.reg); + } + hri_can_write_XIDAM_reg(self->hw, CAN_XIDAM_RESETVALUE); // silent: The CAN is set in Bus Monitoring Mode by programming CCCR.MON to '1'. (tx pin unused) @@ -261,35 +270,71 @@ int common_hal_canio_can_baudrate_get(canio_can_obj_t *self) int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self) { - return -1; + return self->hw->ECR.bit.TEC; } int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self) { - return -1; + return self->hw->ECR.bit.REC; } int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self) { - return -1; + return self->error_warning_state_count; } int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self) { - return -1; + return self->error_passive_state_count; } int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self) { - return -1; + return self->bus_off_state_count; } -int common_hal_canio_can_state_get(canio_can_obj_t *self) { - return -1; +canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self) { + CAN_PSR_Type psr = self->hw->PSR; + if(psr.bit.BO) { + return BUS_STATE_OFF; + } + if(psr.bit.EP) { + return BUS_STATE_ERROR_PASSIVE; + } + if(psr.bit.EW) { + return BUS_STATE_ERROR_WARNING; + } + return BUS_STATE_ERROR_ACTIVE; +} + +void common_hal_canio_can_restart(canio_can_obj_t *self) { + if (!self->hw->PSR.bit.BO) { + return; + } + + hri_can_clear_CCCR_INIT_bit(self->hw); + while (hri_can_get_CCCR_INIT_bit(self->hw)) { + } +} + +bool common_hal_canio_can_auto_restart_get(canio_can_obj_t *self) { + return self->auto_restart; +} + +void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool value) { + self->auto_restart = value; +} + +static void maybe_auto_restart(canio_can_obj_t *self) { + if(self->auto_restart) { + common_hal_canio_can_restart(self); + } } void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *message) { + maybe_auto_restart(self); + // We have just one dedicated TX buffer, use it! canio_can_fifo_t *ent = &self->state->tx_fifo[0]; ent->txb0.bit.ESI = false; @@ -365,7 +410,17 @@ STATIC void can_handler(int i) { Can *hw = can_insts[i]; uint32_t ir = hri_can_read_IR_reg(hw); - /* Handle various interrupts */ + + /* Count up errors*/ + if (ir & CAN_IE_EWE) { + self->error_warning_state_count += 1; + } + if (ir & CAN_IE_EPE) { + self->error_passive_state_count += 1; + } + if (ir & CAN_IE_BOE) { + self->bus_off_state_count += 1; + } /* Acknowledge interrupt */ hri_can_write_IR_reg(hw, ir); diff --git a/ports/atmel-samd/common-hal/_canio/CAN.h b/ports/atmel-samd/common-hal/_canio/CAN.h index 0e637fc408..02bc2e41b5 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.h +++ b/ports/atmel-samd/common-hal/_canio/CAN.h @@ -27,6 +27,7 @@ #pragma once #include "py/obj.h" +#include "shared-bindings/_canio/__init__.h" #include "component/can.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/_canio/__init__.h" @@ -38,25 +39,33 @@ typedef struct { mp_obj_base_t base; Can *hw; - int baudrate; - uint8_t rx_pin_number, tx_pin_number; - bool loopback; - bool silent; canio_can_state_t *state; + volatile uint32_t error_warning_state_count; + volatile uint32_t error_passive_state_count; + volatile uint32_t bus_off_state_count; + int baudrate; + uint8_t rx_pin_number:8; + uint8_t tx_pin_number:8; + bool loopback:1; + bool silent:1; + bool auto_restart:1; bool fifo0_in_use:1; bool fifo1_in_use:1; } canio_can_obj_t; void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mcu_pin_obj_t *tx, int baudrate, bool loopback, bool silent); -int common_hal_canio_can_state_get(canio_can_obj_t *self); -int common_hal_canio_can_baudrate_get(canio_can_obj_t *self); -int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self); -int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self); -int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self); -int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self); -int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self); -void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *message); -void common_hal_canio_can_deinit(canio_can_obj_t *self); -void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self); +bool common_hal_canio_can_auto_restart_get(canio_can_obj_t *self); bool common_hal_canio_can_deinited(canio_can_obj_t *self); +int common_hal_canio_can_baudrate_get(canio_can_obj_t *self); +int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self); +int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self); +int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self); +int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self); +canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self); +int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self); +void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool auto_restart); +void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self); +void common_hal_canio_can_deinit(canio_can_obj_t *self); +void common_hal_canio_can_restart(canio_can_obj_t *self); +void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *message); void common_hal_canio_reset(void); diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/_canio/CAN.c index 4c7ae3650a..45640d41e4 100644 --- a/shared-bindings/_canio/CAN.c +++ b/shared-bindings/_canio/CAN.c @@ -24,8 +24,10 @@ * THE SOFTWARE. */ +#include "py/enum.h" #include "common-hal/_canio/CAN.h" #include "common-hal/_canio/Listener.h" +#include "shared-bindings/_canio/__init__.h" #include "shared-bindings/_canio/CAN.h" #include "shared-bindings/_canio/Listener.h" #include "shared-bindings/_canio/Match.h" @@ -45,6 +47,7 @@ //| *, //| baudrate: int = 250000, //| loopback: bool = False, +//| auto_restart: bool = False, //| ): //| """A common shared-bus protocol. The rx and tx pins are generally //| connected to a transceiver which controls the H and L pins on a shared @@ -54,19 +57,19 @@ //| :param ~microcontrller.Pin tx: the pin to transmit with, or None if the peripheral should operate in "silent" mode. //| :param int baudrate: The bit rate of the bus in Hz. All devices on the bus must agree on this value. //| :param bool loopback: True if the peripheral will be operated in loopback mode. +//| :param bool auto_restart: If True, will restart communications after entering bus-off state //| """ //| ... //| -//## auto_restart: bool = False, # Whether to restart communications after entering bus-off state -//## sample_point: float = .875, # When to sample within bit time (0.0-1.0) STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_rx, ARG_tx, ARG_baudrate, ARG_loopback, ARG_silent, NUM_ARGS }; + enum { ARG_rx, ARG_tx, ARG_baudrate, ARG_loopback, ARG_silent, ARG_auto_restart, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_rx, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = 0} }, { MP_QSTR_tx, MP_ARG_OBJ, {.u_obj = 0} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 250000} }, { MP_QSTR_loopback, MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_silent, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_auto_restart, MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); @@ -85,12 +88,40 @@ mp_printf(&mp_plat_print, "tx_pin=%p\n", tx_pin); self->base.type = &canio_can_type; common_hal_canio_can_construct(self, rx_pin, tx_pin, args[ARG_baudrate].u_int, args[ARG_loopback].u_bool, args[ARG_silent].u_bool); + common_hal_canio_can_auto_restart_set(self, args[ARG_auto_restart].u_bool); + return MP_OBJ_FROM_PTR(self); } +//| auto_restart: int +//| """If True, will restart communications after entering bus-off state""" +//| +STATIC mp_obj_t canio_can_auto_restart_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return mp_obj_new_bool(common_hal_canio_can_auto_restart_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_auto_restart_get_obj, canio_can_auto_restart_get); + +STATIC mp_obj_t canio_can_auto_restart_set(mp_obj_t self_in, mp_obj_t flag_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + common_hal_canio_can_auto_restart_set(self, mp_obj_is_true(flag_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(canio_can_auto_restart_set_obj, canio_can_auto_restart_set); + +STATIC const mp_obj_property_t canio_can_auto_restart_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_auto_restart_get_obj, + (mp_obj_t)&canio_can_auto_restart_set_obj, + (mp_obj_t)mp_const_none}, +}; + + //| baudrate: int -//| """The baud rate(read-only)""" +//| """The baud rate (read-only)""" //| STATIC mp_obj_t canio_can_baudrate_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -106,23 +137,6 @@ STATIC const mp_obj_property_t canio_can_baudrate_obj = { (mp_obj_t)mp_const_none}, }; -//| state: State -//| """The status of the hardware (read-only)""" -//| -STATIC mp_obj_t canio_can_state_get(mp_obj_t self_in) { - canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_canio_can_check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_canio_can_state_get(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(canio_can_state_get_obj, canio_can_state_get); - -STATIC const mp_obj_property_t canio_can_state_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&canio_can_state_get_obj, - (mp_obj_t)mp_const_none, - (mp_obj_t)mp_const_none}, -}; - //| transmit_error_count: int //| """The number of transmit errors (read-only). Increased for a detected transmission error, decreased for successful transmission. Limited to the range from 0 to 255 inclusive. Also called TEC.""" //| @@ -208,12 +222,43 @@ STATIC const mp_obj_property_t canio_can_bus_off_state_count_obj = { (mp_obj_t)mp_const_none}, }; +//| state: State +//| """The current state of the bus.""" +STATIC mp_obj_t canio_can_state_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return cp_enum_find(&canio_bus_state_type, common_hal_canio_can_state_get(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_state_get_obj, canio_can_state_get); + +STATIC const mp_obj_property_t canio_can_state_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_state_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + + #if 0 //| # pending_tx_count: int //| # """The number of messages waiting to be transmitted. (read-only)""" +//| #endif -//| def listen(filters: Optional[Sequence[Filter]]=None, *, timeout: float=10) -> Listener: +//| def restart(self) -> None: +//| """If the device is in the bus off state, restart it.""" +//| ... +//| +STATIC mp_obj_t canio_can_restart(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + common_hal_canio_can_restart(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_restart_obj, canio_can_restart); + +//| def listen(self, filters: Optional[Sequence[Filter]]=None, *, timeout: float=10) -> Listener: //| """Start receiving messages that match any one of the filters. //| Creating a listener is an expensive operation and can interfere with reception of messages by other listeners. //| There is an implementation-defined maximum number of listeners and limit to the complexity of the filters. @@ -317,15 +362,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(canio_can_exit_obj, 4, 4, canio_can_e STATIC const mp_rom_map_elem_t canio_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&canio_can_enter_obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&canio_can_exit_obj) }, + { MP_ROM_QSTR(MP_QSTR_auto_restart), MP_ROM_PTR(&canio_can_auto_restart_obj) }, + { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&canio_can_baudrate_obj) }, { MP_ROM_QSTR(MP_QSTR_bus_off_state_count), MP_ROM_PTR(&canio_can_bus_off_state_count_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&canio_can_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_error_passive_state_count), MP_ROM_PTR(&canio_can_error_passive_state_count_obj) }, { MP_ROM_QSTR(MP_QSTR_error_warning_state_count), MP_ROM_PTR(&canio_can_error_warning_state_count_obj) }, { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&canio_can_listen_obj) }, { MP_ROM_QSTR(MP_QSTR_receive_error_count), MP_ROM_PTR(&canio_can_receive_error_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&canio_can_restart_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&canio_can_send_obj) }, { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&canio_can_state_obj) }, - { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&canio_can_baudrate_obj) }, { MP_ROM_QSTR(MP_QSTR_transmit_error_count), MP_ROM_PTR(&canio_can_transmit_error_count_obj) }, }; STATIC MP_DEFINE_CONST_DICT(canio_can_locals_dict, canio_can_locals_dict_table); From 1eb0587917f54aec07104b00f7dd6f3f0b9cf201 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 12:07:15 -0500 Subject: [PATCH 14/55] correct docstring --- shared-bindings/_canio/Message.c | 6 ++++-- shared-bindings/_canio/__init__.c | 9 +++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/_canio/Message.c index a8e5883541..f1cd11d8ec 100644 --- a/shared-bindings/_canio/Message.c +++ b/shared-bindings/_canio/Message.c @@ -115,7 +115,7 @@ STATIC const mp_obj_property_t canio_message_id_obj = { //| data: bytes //| """The content of the message, or dummy content in the case of an rtr. //| -//| Assigning to data sets the bytes to zero""" +//| Assigning to data also sets the length.""" //| STATIC mp_obj_t canio_message_data_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; @@ -145,7 +145,9 @@ STATIC const mp_obj_property_t canio_message_data_obj = { //| size: int -//| """The length of the message, or the length of the requested data in the case of an rtr""" +//| """The length of the message, or the length of the requested data in the case of an rtr +//| +//| Assigning to the length sets all the data bytes to zero""" //| STATIC mp_obj_t canio_message_size_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; diff --git a/shared-bindings/_canio/__init__.c b/shared-bindings/_canio/__init__.c index 577466ed61..cff675f069 100644 --- a/shared-bindings/_canio/__init__.c +++ b/shared-bindings/_canio/__init__.c @@ -29,7 +29,7 @@ //| The `_canio` module contains low level classes to support the CAN bus //| protocol. //| -//| All classes change hardware state and should be deinitialized when they +//| CAN and Listener classes change hardware state and should be deinitialized when they //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See //| :ref:`lifetime-and-contextmanagers` for more info. @@ -39,12 +39,13 @@ //| import _canio //| from board import * //| -//| can = _canio.BUS(board.CANRX, board.CANTX) -//| can.write(408, b"adafruit") +//| can = _canio.CAN(board.CAN_RX, board.CAN_TX, baudrate=1000000) +//| message = _canio.Message(id=0x0408, data="adafruit" +//| can.write(message)) //| can.deinit() //| //| This example will write the data 'adafruit' onto the CAN bus to any -//| device listening for message id 408.""" +//| device listening for message id 0x0408.""" //| #include "py/obj.h" From 40d4a69133e09e66575dee13b7881aead43f66d4 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 12:16:30 -0500 Subject: [PATCH 15/55] more doc improvements --- shared-bindings/_canio/__init__.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/shared-bindings/_canio/__init__.c b/shared-bindings/_canio/__init__.c index cff675f069..29e43c5c46 100644 --- a/shared-bindings/_canio/__init__.c +++ b/shared-bindings/_canio/__init__.c @@ -45,7 +45,16 @@ //| can.deinit() //| //| This example will write the data 'adafruit' onto the CAN bus to any -//| device listening for message id 0x0408.""" +//| device listening for message id 0x0408. +//| +//| A CAN bus involves a transceiver, which is often a separate chip with a "standby" pin. +//| If your board has a CAN_STANDBY pin, ensure to set it to an output with the value False +//| to enable the transceiver. +//| +//| Other implementations of the CAN device may exist (for instance, attached +//| via an SPI bus). If so their constructor arguments may differ, but +//| otherwise we encourage implementors to follow the API that the core uses. +//| """ //| #include "py/obj.h" @@ -69,13 +78,22 @@ MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); //| """The bus is in the normal (active) state""" //| //| ERROR_WARNING: object -//| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently""" +//| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently. +//| +//| NOTE: Not all implementations may use ERROR_WARNING. Do not rely on seeing ERROR_WARNING before ERROR_PASSIVE.""" //| //| ERROR_PASSIVE: object -//| """The bus is in the passive state due to the number of errors that have occurred recently""" +//| """The bus is in the passive state due to the number of errors that have occurred recently. +//| +//| This device will acknowledge packets it receives, but cannot transmit messages. +//| If additional errors occur, this device may progress to BUS_OFF. +//| If it successfully acknowledges other packets on the bus, it can return to ERROR_WARNING or ERROR_ACTIVE and transmit packets. +//| """ //| //| BUS_OFF: object -//| """The bus has turned off due to the number of errors that have occurred recently. It must be restarted before it will send or receive packets""" +//| """The bus has turned off due to the number of errors that have +//| occurred recently. It must be restarted before it will send or receive +//| packets. This device will neither send or acknowledge packets on the bus.""" //| MAKE_ENUM_MAP(canio_bus_state) { MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), From ca32a81bf11301b2aea4fb2a91991dcfecd14902 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 16 Sep 2020 12:18:55 -0500 Subject: [PATCH 16/55] main.c: Correct CANIO if-guard --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index f259fea3f9..4d34e451dd 100755 --- a/main.c +++ b/main.c @@ -230,7 +230,7 @@ void cleanup_after_vm(supervisor_allocation* heap) { free_memory(heap); supervisor_move_memory(); - #ifdef CIRCUITPY_CANIO + #if CIRCUITPY_CANIO common_hal_canio_reset(); #endif From 2cb4707f92ffc65b2f160a7d1ea7d6b28892b548 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 17 Sep 2020 10:57:16 -0500 Subject: [PATCH 17/55] Message: add extended address flag --- shared-bindings/_canio/Message.c | 35 +++++++++++++++++++++++++++++--- shared-module/_canio/Message.c | 13 +++++++++++- shared-module/_canio/Message.h | 9 +++++--- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/_canio/Message.c index f1cd11d8ec..3fa018a834 100644 --- a/shared-bindings/_canio/Message.c +++ b/shared-bindings/_canio/Message.c @@ -32,13 +32,14 @@ #include "py/runtime.h" //| class Message: -//| def __init__(self, id: int=0, data: Optional[bytes] = None, *, size: Optional[int] = None, rtr: bool = False): +//| def __init__(self, id: int=0, data: Optional[bytes] = None, *, size: Optional[int] = None, rtr: bool = False, extended: bool = False): //| """Construct a Message to send on a CAN bus //| //| :param int id: The numeric ID of the message //| :param bytes data: The content of the message //| :param int size: The amount of data requested, for an rtr //| :param bool rtr: True if the message represents an rtr (Remote Transmission Request) +//| :param bool extended: True if the message has an extended identifier, False if it has a standard identifier //| //| In CAN, messages can have a size from 0 to 8 bytes. //| @@ -47,12 +48,13 @@ //| ... //| STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_id, ARG_data, ARG_size, ARG_rtr, NUM_ARGS }; + enum { ARG_id, ARG_data, ARG_size, ARG_rtr, ARG_extended, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_id, MP_ARG_INT, {.u_obj = 0} }, { MP_QSTR_data, MP_ARG_OBJ, {.u_obj = 0} }, { MP_QSTR_size, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_rtr, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_extended, MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); @@ -60,6 +62,7 @@ STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); bool rtr = args[ARG_rtr].u_bool; + bool extended = args[ARG_extended].u_bool; size_t size = (size_t)args[ARG_size].u_int; bool specified_size = (size != (size_t)-1); bool specified_data = (args[ARG_data].u_obj != NULL); @@ -85,7 +88,7 @@ STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, canio_message_obj_t *self = m_new_obj(canio_message_obj_t); self->base.type = &canio_message_type; - common_hal_canio_message_construct(self, args[ARG_id].u_int, data.buf, data.len, rtr); + common_hal_canio_message_construct(self, args[ARG_id].u_int, data.buf, data.len, rtr, extended); return self; } @@ -174,6 +177,31 @@ STATIC const mp_obj_property_t canio_message_size_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| extended: bool +//| """True if the message represents a remote transmission request (RTR)""" +//| +STATIC mp_obj_t canio_message_extended_get(const mp_obj_t self_in) { + canio_message_obj_t *self = self_in; + return mp_obj_new_bool(common_hal_canio_message_extended_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_message_extended_get_obj, canio_message_extended_get); + +STATIC mp_obj_t canio_message_extended_set(const mp_obj_t self_in, const mp_obj_t extended) { + canio_message_obj_t *self = self_in; + common_hal_canio_message_size_set(self, mp_obj_is_true(extended)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(canio_message_extended_set_obj, canio_message_extended_set); + + +STATIC const mp_obj_property_t canio_message_extended_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_message_extended_get_obj, + (mp_obj_t)&canio_message_extended_set_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + //| rtr: bool //| """True if the message represents a remote transmission request (RTR)""" //| @@ -204,6 +232,7 @@ STATIC const mp_rom_map_elem_t canio_message_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_data), MP_ROM_PTR(&canio_message_data_obj) }, { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&canio_message_size_obj) }, { MP_ROM_QSTR(MP_QSTR_rtr), MP_ROM_PTR(&canio_message_rtr_obj) }, + { MP_ROM_QSTR(MP_QSTR_extended), MP_ROM_PTR(&canio_message_extended_obj) }, }; STATIC MP_DEFINE_CONST_DICT(canio_message_locals_dict, canio_message_locals_dict_table); diff --git a/shared-module/_canio/Message.c b/shared-module/_canio/Message.c index 1ac5b81789..c0403b5196 100644 --- a/shared-module/_canio/Message.c +++ b/shared-module/_canio/Message.c @@ -28,11 +28,12 @@ #include -void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr) +void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr, bool extended) { self->id = id; self->size = size; self->rtr = rtr; + self->extended = extended; if (data) { memcpy(self->data, data, size); } else { @@ -84,3 +85,13 @@ void common_hal_canio_message_rtr_set(canio_message_obj_t *self, bool rtr) { self->rtr = rtr; } + +bool common_hal_canio_message_extended_get(const canio_message_obj_t *self) +{ + return self->extended; +} + +void common_hal_canio_message_extended_set(canio_message_obj_t *self, bool extended) +{ + self->extended = extended; +} diff --git a/shared-module/_canio/Message.h b/shared-module/_canio/Message.h index e846f1095f..b9fd8eaf2d 100644 --- a/shared-module/_canio/Message.h +++ b/shared-module/_canio/Message.h @@ -31,17 +31,20 @@ typedef struct { mp_obj_base_t base; int id; - size_t size; uint8_t data[8]; - bool rtr; + size_t size:4; + bool rtr:1; + bool extended:1; } canio_message_obj_t; -void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr); +void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr, bool extended); bool common_hal_canio_message_rtr_get(const canio_message_obj_t *self); +bool common_hal_canio_message_extended_get(const canio_message_obj_t *self); int common_hal_canio_message_id_get(const canio_message_obj_t *self); const void *common_hal_canio_message_data_get(const canio_message_obj_t *self); size_t common_hal_canio_message_size_get(const canio_message_obj_t *self); void common_hal_canio_message_rtr_set(canio_message_obj_t *self, bool rtr); +void common_hal_canio_message_extended_set(canio_message_obj_t *self, bool extended); void common_hal_canio_message_id_set(canio_message_obj_t *self, int id); void common_hal_canio_message_data_set(canio_message_obj_t *self, const void *data, size_t size); void common_hal_canio_message_size_set(canio_message_obj_t *self, size_t size); From 27cbb690e5b634b2791100a258618252476f609d Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 17 Sep 2020 10:57:56 -0500 Subject: [PATCH 18/55] _canio: Add listener matching Lightly tested: * no matches (catch-all) * standard address single address matches (even and odd positions) * standard address mask matches * only tested that extended doesn't match non-extended --- ports/atmel-samd/common-hal/_canio/CAN.c | 34 +- ports/atmel-samd/common-hal/_canio/Listener.c | 295 +++++++++++++++++- ports/atmel-samd/common-hal/_canio/__init__.h | 7 +- shared-bindings/_canio/CAN.c | 15 +- 4 files changed, 321 insertions(+), 30 deletions(-) diff --git a/ports/atmel-samd/common-hal/_canio/CAN.c b/ports/atmel-samd/common-hal/_canio/CAN.c index d2e7d8d9db..4c957c8f86 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.c +++ b/ports/atmel-samd/common-hal/_canio/CAN.c @@ -91,7 +91,7 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc } hri_can_set_CCCR_CCE_bit(self->hw); - if(instance == 0) { + if (instance == 0) { hri_mclk_set_AHBMASK_CAN0_bit(MCLK); hri_gclk_write_PCHCTRL_reg(GCLK, CAN0_GCLK_ID, CONF_GCLK_CAN0_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); @@ -100,7 +100,7 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc NVIC_EnableIRQ(CAN0_IRQn); hri_can_write_ILE_reg(self->hw, CAN_ILE_EINT0); #ifdef CAN1_GCLK_ID - } else if(instance == 1) { + } else if (instance == 1) { hri_mclk_set_AHBMASK_CAN1_bit(MCLK); hri_gclk_write_PCHCTRL_reg(GCLK, CAN1_GCLK_ID, CONF_GCLK_CAN1_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos)); @@ -197,7 +197,7 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc { CAN_GFC_Type gfc = { .bit.RRFE = 1, - .bit.ANFS = CAN_GFC_ANFS_RXF0_Val, + .bit.ANFS = CAN_GFC_ANFS_REJECT_Val, .bit.ANFE = CAN_GFC_ANFE_REJECT_Val, }; hri_can_write_GFC_reg(self->hw, gfc.reg); @@ -206,14 +206,15 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc { CAN_SIDFC_Type dfc = { .bit.LSS = COMMON_HAL_CANIO_RX_FILTER_SIZE, - .bit.FLSSA = (uint32_t)self->state->rx_filter + .bit.FLSSA = (uint32_t)self->state->standard_rx_filter }; hri_can_write_SIDFC_reg(self->hw, dfc.reg); } { CAN_XIDFC_Type dfc = { - .bit.LSE = 0, + .bit.LSE = COMMON_HAL_CANIO_RX_FILTER_SIZE, + .bit.FLESA = (uint32_t)self->state->extended_rx_filter }; hri_can_write_XIDFC_reg(self->hw, dfc.reg); } @@ -236,12 +237,12 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc self->hw->CCCR.bit.TEST = loopback; self->hw->TEST.bit.LBCK = loopback; - if(instance == 0) { + if (instance == 0) { NVIC_DisableIRQ(CAN0_IRQn); NVIC_ClearPendingIRQ(CAN0_IRQn); NVIC_EnableIRQ(CAN0_IRQn); #ifdef CAN1_GCLK_ID - } else if(instance == 1) { + } else if (instance == 1) { NVIC_DisableIRQ(CAN1_IRQn); NVIC_ClearPendingIRQ(CAN1_IRQn); NVIC_EnableIRQ(CAN1_IRQn); @@ -295,13 +296,13 @@ int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self) canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self) { CAN_PSR_Type psr = self->hw->PSR; - if(psr.bit.BO) { + if (psr.bit.BO) { return BUS_STATE_OFF; } - if(psr.bit.EP) { + if (psr.bit.EP) { return BUS_STATE_ERROR_PASSIVE; } - if(psr.bit.EW) { + if (psr.bit.EW) { return BUS_STATE_ERROR_WARNING; } return BUS_STATE_ERROR_ACTIVE; @@ -326,7 +327,7 @@ void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool value) { } static void maybe_auto_restart(canio_can_obj_t *self) { - if(self->auto_restart) { + if (self->auto_restart) { common_hal_canio_can_restart(self); } } @@ -337,10 +338,15 @@ void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *messa // We have just one dedicated TX buffer, use it! canio_can_fifo_t *ent = &self->state->tx_fifo[0]; + ent->txb0.bit.ESI = false; - ent->txb0.bit.XTD = false; + ent->txb0.bit.XTD = message->extended; ent->txb0.bit.RTR = message->rtr; - ent->txb0.bit.ID = message->id << 18; // short addresses are left-justified + if (message->extended) { + ent->txb0.bit.ID = message->id << 18; + } else { + ent->txb0.bit.ID = message->id << 18; // short addresses are left-justified + } ent->txb1.bit.MM = 0; // "message marker" ent->txb1.bit.EFC = 0; // don't store fifo events to event queue @@ -367,7 +373,7 @@ bool common_hal_canio_can_deinited(canio_can_obj_t *self) { } void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self) { - if(common_hal_canio_can_deinited(self)) { + if (common_hal_canio_can_deinited(self)) { raise_deinited_error(); } } diff --git a/ports/atmel-samd/common-hal/_canio/Listener.c b/ports/atmel-samd/common-hal/_canio/Listener.c index ddae61de95..4d54e9f734 100644 --- a/ports/atmel-samd/common-hal/_canio/Listener.c +++ b/ports/atmel-samd/common-hal/_canio/Listener.c @@ -34,12 +34,262 @@ #include "common-hal/_canio/Listener.h" #include "shared-bindings/util.h" #include "supervisor/shared/tick.h" +#include "component/can.h" -void common_hal_canio_listener_construct(canio_listener_obj_t *self, canio_can_obj_t *can, size_t nmatch, canio_match_obj_t **matches, float timeout) { - if (nmatch) { - mp_raise_NotImplementedError(NULL); +STATIC void allow_config_change(canio_can_obj_t *can) { + can->hw->CCCR.bit.INIT = 1; + while (!can->hw->CCCR.bit.INIT) { + } + can->hw->CCCR.bit.CCE = 1; +} + +STATIC void prevent_config_change(canio_can_obj_t *can) { + can->hw->CCCR.bit.CCE = 0; + can->hw->CCCR.bit.INIT = 0; + while (can->hw->CCCR.bit.INIT) { + } +} + +__attribute__((unused)) +STATIC void static_assertions(void) { + MP_STATIC_ASSERT(CAN_GFC_ANFE_RXF0_Val + 1 == CAN_GFC_ANFE_RXF1_Val); + MP_STATIC_ASSERT(CAN_GFC_ANFS_RXF0_Val + 1 == CAN_GFC_ANFS_RXF1_Val); + MP_STATIC_ASSERT(CAN_SIDFE_0_SFEC_STF0M_Val + 1 == CAN_SIDFE_0_SFEC_STF1M_Val); + MP_STATIC_ASSERT(CAN_XIDFE_0_EFEC_STF0M_Val + 1 == CAN_XIDFE_0_EFEC_STF1M_Val); +} + +STATIC bool single_address_filter(canio_match_obj_t *match) { + return match->mask == 0 || match->mask == match->address; +} + +STATIC bool standard_filter_in_use(CanMramSidfe *filter) { + return filter->SIDFE_0.bit.SFEC != CAN_SIDFE_0_SFEC_DISABLE_Val; +} + +STATIC bool extended_filter_in_use(CanMramXidfe *filter) { + return filter->XIDFE_0.bit.EFEC != CAN_XIDFE_0_EFEC_DISABLE_Val; +} + +STATIC size_t num_filters_needed(size_t nmatch, canio_match_obj_t **matches, bool extended) { + size_t num_half_filters_needed = 1; + for(size_t i=0; iextended) { + continue; + } + if (single_address_filter(matches[i])) { + num_half_filters_needed += 1; + } else { + num_half_filters_needed += 2; + } + } + return num_half_filters_needed / 2; +} + +STATIC size_t num_filters_available(canio_can_obj_t *can, bool extended) { + size_t available = 0; + if (extended) { + for(size_t i = 0; i < MP_ARRAY_SIZE(can->state->extended_rx_filter); i++) { + if (!extended_filter_in_use(&can->state->extended_rx_filter[i])) { + available++; + } + } + } else { + for(size_t i = 0; i < MP_ARRAY_SIZE(can->state->standard_rx_filter); i++) { + if (!standard_filter_in_use(&can->state->standard_rx_filter[i])) { + available++; + } + } + } + return available; +} + +STATIC void clear_filters(canio_listener_obj_t *self) { + canio_can_obj_t *can = self->can; + int fifo = self->fifo_idx; + + // If it was a global accept, clear it + allow_config_change(can); + if (can->hw->GFC.bit.ANFS == CAN_GFC_ANFS_RXF0 + fifo) { + can->hw->GFC.bit.ANFS = CAN_GFC_ANFS_REJECT_Val; + } + if (can->hw->GFC.bit.ANFE == CAN_GFC_ANFE_RXF0 + fifo) { + can->hw->GFC.bit.ANFE = CAN_GFC_ANFE_REJECT_Val; + } + prevent_config_change(can); + + // For each filter entry, if it pointed at this FIFO set it to DISABLE + for(size_t i = 0; i < MP_ARRAY_SIZE(can->state->extended_rx_filter); i++) { + int val = CAN_XIDFE_0_EFEC_STF0M_Val + fifo; + if (can->state->extended_rx_filter[i].XIDFE_0.bit.EFEC == val) { + can->state->extended_rx_filter[i].XIDFE_0.bit.EFEC = CAN_XIDFE_0_EFEC_DISABLE_Val; + } + } + for(size_t i = 0; i < MP_ARRAY_SIZE(can->state->standard_rx_filter); i++) { + int val = CAN_SIDFE_0_SFEC_STF1M_Val + fifo; + if (can->state->standard_rx_filter[i].SIDFE_0.bit.SFEC == val) { + can->state->standard_rx_filter[i].SIDFE_0.bit.SFEC = CAN_SIDFE_0_SFEC_DISABLE_Val; + } + } +} + +STATIC CanMramXidfe *next_extended_filter(canio_listener_obj_t *self, CanMramXidfe *start) { + CanMramXidfe *end = &self->can->state->extended_rx_filter[MP_ARRAY_SIZE(self->can->state->extended_rx_filter)]; + if (start == NULL) { + start = self->can->state->extended_rx_filter; + } else { + start = start + 1; + } + while (extended_filter_in_use(start)) { + if (start == end) { + return NULL; + } + start = start + 1; + } + return start; +} + +STATIC CanMramSidfe *next_standard_filter(canio_listener_obj_t *self, CanMramSidfe *start) { + CanMramSidfe *end = &self->can->state->standard_rx_filter[MP_ARRAY_SIZE(self->can->state->standard_rx_filter)]; + if (start == NULL) { + start = self->can->state->standard_rx_filter; + } else { + start = start + 1; + } + while (standard_filter_in_use(start)) { + if (start == end) { + return NULL; + } + start = start + 1; + } + return start; +} + +STATIC void install_standard_filter(CanMramSidfe *standard, int id1, int id2, int sfec, int sft) { + assert(standard); + CAN_SIDFE_0_Type val = { + .bit.SFID1 = id1, + .bit.SFID2 = id2, + .bit.SFEC = sfec, + .bit.SFT = sft, + }; + standard->SIDFE_0 = val; +} + +STATIC void install_extended_filter(CanMramXidfe *extended, int id1, int id2, int efec, int eft) { + assert(extended); + CAN_XIDFE_0_Type val0 = { + .bit.EFID1 = id1, + .bit.EFEC = efec, + }; + CAN_XIDFE_1_Type val1 = { + .bit.EFID2 = id2, + .bit.EFT = eft, + }; + // Set entry 0 second, because it has the enable bits (XIDFE_0_EFEC) + extended->XIDFE_1 = val1; + extended->XIDFE_0 = val0; +} + + +#define NO_ADDRESS (-1) +void set_filters(canio_listener_obj_t *self, size_t nmatch, canio_match_obj_t **matches) { + int fifo = self->fifo_idx; + + if (!nmatch) { + allow_config_change(self->can); + self->can->hw->GFC.bit.ANFS = CAN_GFC_ANFS_RXF0_Val + fifo; + self->can->hw->GFC.bit.ANFE = CAN_GFC_ANFE_RXF0_Val + fifo; + self->can->hw->CCCR.bit.CCE = 0; + prevent_config_change(self->can); + return; } + CanMramSidfe *standard = next_standard_filter(self, NULL); + CanMramXidfe *extended = next_extended_filter(self, NULL); + + int first_address = NO_ADDRESS; + + // step 1: single address standard matches + // we have to gather up pairs and stuff them in a single filter entry + for(size_t i = 0; iextended) { + continue; + } + if (!single_address_filter(match)) { + continue; + } + if (first_address != NO_ADDRESS) { + install_standard_filter(standard, first_address, match->address, CAN_SIDFE_0_SFEC_STF0M_Val + fifo, CAN_SIDFE_0_SFT_DUAL_Val); + first_address = NO_ADDRESS; + standard = next_standard_filter(self, standard); + } else { + first_address = match->address; + } + } + // step 1.5. odd single address standard match + if (first_address != NO_ADDRESS) { + install_standard_filter(standard, first_address, first_address, CAN_SIDFE_0_SFEC_STF0M_Val + fifo, CAN_SIDFE_0_SFT_DUAL_Val); + standard = next_standard_filter(self, standard); + first_address = NO_ADDRESS; + } + + // step 2: standard mask filter + for(size_t i = 0; iextended) { + continue; + } + if (single_address_filter(match)) { + continue; + } + install_standard_filter(standard, match->address, match->mask, CAN_SIDFE_0_SFEC_STF0M_Val + fifo, CAN_SIDFE_0_SFT_CLASSIC_Val); + standard = next_standard_filter(self, standard); + } + + // step 3: single address extended matches + // we have to gather up pairs and stuff them in a single filter entry + for(size_t i = 0; iextended) { + continue; + } + if (!single_address_filter(match)) { + continue; + } + if (first_address != NO_ADDRESS) { + install_extended_filter(extended, first_address, match->address, CAN_XIDFE_0_EFEC_STF0M_Val + fifo, CAN_XIDFE_1_EFT_DUAL_Val); + first_address = NO_ADDRESS; + extended = next_extended_filter(self, extended); + } else { + first_address = match->address; + } + } + // step 3.5. odd single address standard match + if (first_address != NO_ADDRESS) { + install_extended_filter(extended, first_address, first_address, CAN_XIDFE_0_EFEC_STF0M_Val + fifo, CAN_XIDFE_1_EFT_DUAL_Val); + extended = next_extended_filter(self, extended); + first_address = NO_ADDRESS; + } + + // step 4: extended mask filters + for(size_t i = 0; iextended) { + continue; + } + if (single_address_filter(match)) { + continue; + } + install_extended_filter(extended, match->address, match->mask, CAN_XIDFE_0_EFEC_STF0M_Val + fifo, CAN_XIDFE_1_EFT_CLASSIC_Val); + extended = next_extended_filter(self, extended); + } + + // phew, easy(!) +} + + +void common_hal_canio_listener_construct(canio_listener_obj_t *self, canio_can_obj_t *can, size_t nmatch, canio_match_obj_t **matches, float timeout) { if (!can->fifo0_in_use) { self->fifo_idx = 0; self->fifo = can->state->rx0_fifo; @@ -56,7 +306,26 @@ void common_hal_canio_listener_construct(canio_listener_obj_t *self, canio_can_o mp_raise_ValueError(translate("All RX FIFOs in use")); } + if (!nmatch) { + if (can->hw->GFC.bit.ANFS == CAN_GFC_ANFS_RXF1_Val - self->fifo_idx) { + mp_raise_ValueError(translate("Already have all-matches listener")); + } + if (can->hw->GFC.bit.ANFE == CAN_GFC_ANFE_RXF1_Val - self->fifo_idx) { + mp_raise_ValueError(translate("Already have all-matches listener")); + } + } + + if (num_filters_needed(nmatch, matches, false) > num_filters_available(can, false)) { + mp_raise_ValueError(translate("Filters too complex")); + } + + if (num_filters_needed(nmatch, matches, true) > num_filters_available(can, true)) { + mp_raise_ValueError(translate("Filters too complex")); + } + + // Nothing can fail now so it's safe to assign self->can self->can = can; + set_filters(self, nmatch, matches); common_hal_canio_listener_set_timeout(self, timeout); } @@ -69,7 +338,7 @@ float common_hal_canio_listener_get_timeout(canio_listener_obj_t *self) { } void common_hal_canio_listener_check_for_deinit(canio_listener_obj_t *self) { - if(!self->can) { + if (!self->can) { raise_deinited_error(); } common_hal_canio_can_check_for_deinit(self->can); @@ -83,17 +352,22 @@ bool common_hal_canio_listener_readinto(canio_listener_obj_t *self, canio_messag if (!common_hal_canio_listener_in_waiting(self)) { uint64_t deadline = supervisor_ticks_ms64() + self->timeout_ms; do { - if(supervisor_ticks_ms64() > deadline) { + if (supervisor_ticks_ms64() > deadline) { return false; } } while (!common_hal_canio_listener_in_waiting(self)); } int index = self->hw->RXFS.bit.F0GI; canio_can_fifo_t *hw_message = &self->fifo[index]; - message->id = hw_message->rxb0.bit.ID >> 18; // short addresses are left-justified + message->extended = hw_message->rxb0.bit.XTD; + if (message->extended) { + message->id = hw_message->rxb0.bit.ID; + } else { + message->id = hw_message->rxb0.bit.ID >> 18; // short addresses are left-justified + } message->rtr = hw_message->rxb0.bit.RTR; message->size = hw_message->rxb1.bit.DLC; - if(!message->rtr) { + if (!message->rtr) { memcpy(message->data, hw_message->data, message->size); } self->hw->RXFA.bit.F0AI = index; @@ -102,11 +376,12 @@ bool common_hal_canio_listener_readinto(canio_listener_obj_t *self, canio_messag void common_hal_canio_listener_deinit(canio_listener_obj_t *self) { // free our FIFO, clear our matches, SOMETHING - if(self->can) { - if(self->fifo_idx == 0) { + if (self->can) { + clear_filters(self); + if (self->fifo_idx == 0) { self->can->fifo0_in_use = false; } - if(self->fifo_idx == 1) { + if (self->fifo_idx == 1) { self->can->fifo1_in_use = false; } } diff --git a/ports/atmel-samd/common-hal/_canio/__init__.h b/ports/atmel-samd/common-hal/_canio/__init__.h index 429369e188..cb491ab9e6 100644 --- a/ports/atmel-samd/common-hal/_canio/__init__.h +++ b/ports/atmel-samd/common-hal/_canio/__init__.h @@ -34,6 +34,10 @@ #define COMMON_HAL_CANIO_RX_FILTER_SIZE (4) #define COMMON_HAL_CANIO_TX_FIFO_SIZE (1) +// This appears to be a typo (transposition error) in the ASF4 headers +// It's called the "Extended ID Filter Entry" +typedef CanMramXifde CanMramXidfe; + typedef struct canio_listener canio_listener_t; typedef struct canio_can canio_can_t; @@ -58,5 +62,6 @@ typedef struct { canio_can_fifo_t tx_fifo[COMMON_HAL_CANIO_TX_FIFO_SIZE]; canio_can_fifo_t rx0_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; canio_can_fifo_t rx1_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; - canio_can_filter_t rx_filter[COMMON_HAL_CANIO_RX_FILTER_SIZE]; + CanMramSidfe standard_rx_filter[COMMON_HAL_CANIO_RX_FILTER_SIZE]; + CanMramXifde extended_rx_filter[COMMON_HAL_CANIO_RX_FILTER_SIZE]; } canio_can_state_t; diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/_canio/CAN.c index 45640d41e4..8f3e45420d 100644 --- a/shared-bindings/_canio/CAN.c +++ b/shared-bindings/_canio/CAN.c @@ -258,15 +258,20 @@ STATIC mp_obj_t canio_can_restart(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_restart_obj, canio_can_restart); -//| def listen(self, filters: Optional[Sequence[Filter]]=None, *, timeout: float=10) -> Listener: +//| def listen(self, match: Optional[Sequence[Match]]=None, *, timeout: float=10) -> Listener: //| """Start receiving messages that match any one of the filters. +//| //| Creating a listener is an expensive operation and can interfere with reception of messages by other listeners. +//| //| There is an implementation-defined maximum number of listeners and limit to the complexity of the filters. -//| If the hardware cannot support all the requested filters, a ValueError is raised. Note that generally there are some number of hardware filters shared among all fifos. -//| A message can be received by at most one Listener. +//| +//| If the hardware cannot support all the requested matches, a ValueError is raised. Note that generally there are some number of hardware filters shared among all fifos. +//| +//| A message can be received by at most one Listener. If more than one listener matches a message, it is undefined which one actually receives it. +//| //| An empty filter list causes all messages to be accepted. -//| Timeout dictates how long readinto, read and next() will block. -//| Readinto will return false(), read will return None, and next() will raise StopIteration.""" +//| +//| Timeout dictates how long readinto, read and next() will block.""" //| ... //| STATIC mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { From 58b920ed97ac5acdcf3ccb405524c89e32c17b50 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 17 Sep 2020 11:35:34 -0500 Subject: [PATCH 19/55] fix whitespace --- ports/atmel-samd/common-hal/_canio/CAN.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/common-hal/_canio/CAN.c b/ports/atmel-samd/common-hal/_canio/CAN.c index 4c957c8f86..266a1aa1f7 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.c +++ b/ports/atmel-samd/common-hal/_canio/CAN.c @@ -338,7 +338,7 @@ void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *messa // We have just one dedicated TX buffer, use it! canio_can_fifo_t *ent = &self->state->tx_fifo[0]; - + ent->txb0.bit.ESI = false; ent->txb0.bit.XTD = message->extended; ent->txb0.bit.RTR = message->rtr; From a69b298aed6c2b711ab5a9e32102fa4df986406d Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 17 Sep 2020 11:42:33 -0500 Subject: [PATCH 20/55] Whitespace --- shared-bindings/_canio/CAN.c | 2 +- shared-bindings/_canio/Listener.c | 2 +- shared-bindings/_canio/Match.c | 4 ++-- shared-bindings/_canio/Message.c | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/_canio/CAN.c index 8f3e45420d..53045c35ad 100644 --- a/shared-bindings/_canio/CAN.c +++ b/shared-bindings/_canio/CAN.c @@ -298,7 +298,7 @@ STATIC mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map canio_match_obj_t *matches[nmatch]; for (size_t i=0; iname); } matches[i] = MP_OBJ_TO_PTR(match_objects[i]); diff --git a/shared-bindings/_canio/Listener.c b/shared-bindings/_canio/Listener.c index d68138d997..a3890f8dd3 100644 --- a/shared-bindings/_canio/Listener.c +++ b/shared-bindings/_canio/Listener.c @@ -112,7 +112,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_iter_obj, canio_listener_iter); STATIC mp_obj_t canio_listener_next(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); - if(common_hal_canio_listener_in_waiting(self)) { + if (common_hal_canio_listener_in_waiting(self)) { return canio_listener_read(self_in); } return self; diff --git a/shared-bindings/_canio/Match.c b/shared-bindings/_canio/Match.c index 6c32aa5390..b71529b736 100644 --- a/shared-bindings/_canio/Match.c +++ b/shared-bindings/_canio/Match.c @@ -59,11 +59,11 @@ STATIC mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, c int address = args[ARG_address].u_int; int mask = args[ARG_mask].u_int; - if(address & ~address_bits) { + if (address & ~address_bits) { mp_raise_ValueError_varg(translate("%q out of range"), MP_QSTR_address); } - if(mask & ~address_bits) { + if (mask & ~address_bits) { mp_raise_ValueError_varg(translate("%q out of range"), MP_QSTR_mask); } diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/_canio/Message.c index 3fa018a834..bfaaf52b2f 100644 --- a/shared-bindings/_canio/Message.c +++ b/shared-bindings/_canio/Message.c @@ -67,7 +67,7 @@ STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, bool specified_size = (size != (size_t)-1); bool specified_data = (args[ARG_data].u_obj != NULL); - if(specified_size && specified_data) { + if (specified_size && specified_data) { mp_raise_TypeError(translate("specify size or data, but not both")); } @@ -82,7 +82,7 @@ STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, data.len = 0; } - if(data.len > 8) { + if (data.len > 8) { mp_raise_ValueError(translate("Messages limited to 8 bytes")); } @@ -130,7 +130,7 @@ STATIC mp_obj_t canio_message_data_set(const mp_obj_t self_in, const mp_obj_t da canio_message_obj_t *self = self_in; mp_buffer_info_t data; mp_get_buffer_raise(data_in, &data, MP_BUFFER_READ); - if(data.len > 8) { + if (data.len > 8) { mp_raise_ValueError(translate("Messages limited to 8 bytes")); } common_hal_canio_message_data_set(self, data.buf, data.len); @@ -161,7 +161,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(canio_message_size_get_obj, canio_message_size_get); STATIC mp_obj_t canio_message_size_set(const mp_obj_t self_in, const mp_obj_t size_in) { canio_message_obj_t *self = self_in; int size = mp_obj_get_int(size_in); - if(size > 8) { + if (size > 8) { mp_raise_ValueError(translate("Messages limited to 8 bytes")); } common_hal_canio_message_size_set(self, size); From 44c5b2bbb1a00cf07e1725c76d1920e8c73977ed Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 17 Sep 2020 12:44:40 -0500 Subject: [PATCH 21/55] Respond to review comments Thanks @tannewt! --- ports/atmel-samd/common-hal/_canio/Listener.c | 1 - shared-bindings/_canio/CAN.c | 17 +++----------- shared-bindings/_canio/Listener.c | 10 ++++---- shared-bindings/_canio/Match.c | 9 ++++---- shared-bindings/_canio/Match.h | 6 ++++- shared-bindings/_canio/Message.c | 23 +++++++++---------- shared-bindings/_canio/Message.h | 13 +++++++++++ shared-module/_canio/Match.c | 6 ++--- shared-module/_canio/Match.h | 5 ---- shared-module/_canio/Message.c | 20 ++++++++-------- shared-module/_canio/Message.h | 12 ---------- 11 files changed, 53 insertions(+), 69 deletions(-) diff --git a/ports/atmel-samd/common-hal/_canio/Listener.c b/ports/atmel-samd/common-hal/_canio/Listener.c index 4d54e9f734..0a5f629f88 100644 --- a/ports/atmel-samd/common-hal/_canio/Listener.c +++ b/ports/atmel-samd/common-hal/_canio/Listener.c @@ -375,7 +375,6 @@ bool common_hal_canio_listener_readinto(canio_listener_obj_t *self, canio_messag } void common_hal_canio_listener_deinit(canio_listener_obj_t *self) { - // free our FIFO, clear our matches, SOMETHING if (self->can) { clear_filters(self); if (self->fifo_idx == 0) { diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/_canio/CAN.c index 53045c35ad..537aa55804 100644 --- a/shared-bindings/_canio/CAN.c +++ b/shared-bindings/_canio/CAN.c @@ -53,8 +53,8 @@ //| connected to a transceiver which controls the H and L pins on a shared //| bus. //| -//| :param ~microcontrller.Pin rx: the pin to receive with. -//| :param ~microcontrller.Pin tx: the pin to transmit with, or None if the peripheral should operate in "silent" mode. +//| :param ~microcontroller.Pin rx: the pin to receive with. +//| :param ~microcontroller.Pin tx: the pin to transmit with, or None if the peripheral should operate in "silent" mode. //| :param int baudrate: The bit rate of the bus in Hz. All devices on the bus must agree on this value. //| :param bool loopback: True if the peripheral will be operated in loopback mode. //| :param bool auto_restart: If True, will restart communications after entering bus-off state @@ -76,13 +76,8 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, con mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); -mp_printf(&mp_plat_print, "ARG_rx=%d args[ARG_rx].u_obj=%p\n", ARG_rx, args[ARG_rx].u_obj); -mp_printf(&mp_plat_print, "ARG_tx=%d args[ARG_tx].u_obj=%p\n", ARG_tx, args[ARG_tx].u_obj); - mcu_pin_obj_t *rx_pin = validate_obj_is_free_pin(args[ARG_rx].u_obj); -mp_printf(&mp_plat_print, "rx_pin=%p\n", rx_pin); mcu_pin_obj_t *tx_pin = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj); -mp_printf(&mp_plat_print, "tx_pin=%p\n", tx_pin); canio_can_obj_t *self = m_new_obj(canio_can_obj_t); self->base.type = &canio_can_type; @@ -94,7 +89,7 @@ mp_printf(&mp_plat_print, "tx_pin=%p\n", tx_pin); } -//| auto_restart: int +//| auto_restart: bool //| """If True, will restart communications after entering bus-off state""" //| STATIC mp_obj_t canio_can_auto_restart_get(mp_obj_t self_in) { @@ -240,12 +235,6 @@ STATIC const mp_obj_property_t canio_can_state_obj = { }; -#if 0 -//| # pending_tx_count: int -//| # """The number of messages waiting to be transmitted. (read-only)""" -//| -#endif - //| def restart(self) -> None: //| """If the device is in the bus off state, restart it.""" //| ... diff --git a/shared-bindings/_canio/Listener.c b/shared-bindings/_canio/Listener.c index a3890f8dd3..84b2aacb97 100644 --- a/shared-bindings/_canio/Listener.c +++ b/shared-bindings/_canio/Listener.c @@ -39,7 +39,7 @@ //| //| def read(self) -> Optional[Message]: -//| """Returns a message, after waiting up to self.timeout seconds +//| """Reads a message, after waiting up to self.timeout seconds //| //| If no message is received in time, None is returned. Otherwise, //| a Message is returned.""" @@ -62,10 +62,8 @@ STATIC mp_obj_t canio_listener_read(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_read_obj, canio_listener_read); //| def readinto(self, message: Message) -> bool: -//| """Returns a message, after waiting up to self.timeout seconds -//| -//| Returns True (and modifies message) if a message was received, -//| False otherwise.""" +//| """Returns True (and modifies message) if a message was received +//| before ``timeout`` seconds elapsed, False otherwise.""" //| ... //| STATIC mp_obj_t canio_listener_readinto(mp_obj_t self_in, mp_obj_t message) { @@ -115,7 +113,7 @@ STATIC mp_obj_t canio_listener_next(mp_obj_t self_in) { if (common_hal_canio_listener_in_waiting(self)) { return canio_listener_read(self_in); } - return self; + return MP_OBJ_STOP_ITERATION; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_next_obj, canio_listener_next); diff --git a/shared-bindings/_canio/Match.c b/shared-bindings/_canio/Match.c index b71529b736..4ff35906b7 100644 --- a/shared-bindings/_canio/Match.c +++ b/shared-bindings/_canio/Match.c @@ -25,7 +25,6 @@ */ #include "shared-bindings/_canio/Match.h" -#include "shared-module/_canio/Match.h" #include "py/objproperty.h" #include "py/runtime.h" @@ -46,7 +45,7 @@ STATIC mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_mask, ARG_extended, NUM_ARGS }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_address, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, + { MP_QSTR_address, MP_ARG_INT | MP_ARG_REQUIRED }, { MP_QSTR_mask, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_extended, MP_ARG_BOOL, {.u_bool = false} }, }; @@ -79,7 +78,7 @@ STATIC mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, c STATIC mp_obj_t canio_match_address_get(mp_obj_t self_in) { canio_match_obj_t *self = self_in; - return MP_OBJ_NEW_SMALL_INT(common_hal_canio_match_address_get(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_match_get_address(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_match_address_get_obj, canio_match_address_get); @@ -97,7 +96,7 @@ const mp_obj_property_t canio_match_address_obj = { STATIC mp_obj_t canio_match_mask_get(mp_obj_t self_in) { canio_match_obj_t *self = self_in; - return MP_OBJ_NEW_SMALL_INT(common_hal_canio_match_mask_get(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_match_get_mask(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_match_mask_get_obj, canio_match_mask_get); @@ -114,7 +113,7 @@ const mp_obj_property_t canio_match_mask_obj = { STATIC mp_obj_t canio_match_extended_get(mp_obj_t self_in) { canio_match_obj_t *self = self_in; - return mp_obj_new_bool(common_hal_canio_match_extended_get(self)); + return mp_obj_new_bool(common_hal_canio_match_get_extended(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_match_extended_get_obj, canio_match_extended_get); diff --git a/shared-bindings/_canio/Match.h b/shared-bindings/_canio/Match.h index adf98eb865..5522c26367 100644 --- a/shared-bindings/_canio/Match.h +++ b/shared-bindings/_canio/Match.h @@ -27,7 +27,11 @@ #pragma once #include "py/obj.h" +#include "shared-module/_canio/Match.h" extern const mp_obj_type_t canio_match_type; -// Nothing now. +void common_hal_canio_match_construct(canio_match_obj_t *self, int address, int mask, bool extended); +int common_hal_canio_match_get_address(const canio_match_obj_t *self); +int common_hal_canio_match_get_mask(const canio_match_obj_t *self); +bool common_hal_canio_match_get_extended(const canio_match_obj_t *self); diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/_canio/Message.c index bfaaf52b2f..85657e05ef 100644 --- a/shared-bindings/_canio/Message.c +++ b/shared-bindings/_canio/Message.c @@ -25,7 +25,6 @@ */ #include "shared-bindings/_canio/Message.h" -#include "shared-module/_canio/Message.h" #include "py/obj.h" #include "py/objproperty.h" @@ -33,7 +32,7 @@ //| class Message: //| def __init__(self, id: int=0, data: Optional[bytes] = None, *, size: Optional[int] = None, rtr: bool = False, extended: bool = False): -//| """Construct a Message to send on a CAN bus +//| """Construct a Message to use with a CAN bus. Provide arguments to create a message to send. Otherwise, use Listener.readinto() to read a message. //| //| :param int id: The numeric ID of the message //| :param bytes data: The content of the message @@ -97,13 +96,13 @@ STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, //| STATIC mp_obj_t canio_message_id_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; - return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_id_get(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_get_id(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_message_id_get_obj, canio_message_id_get); STATIC mp_obj_t canio_message_id_set(const mp_obj_t self_in, const mp_obj_t id) { canio_message_obj_t *self = self_in; - common_hal_canio_message_id_set(self, mp_obj_get_int(id)); + common_hal_canio_message_set_id(self, mp_obj_get_int(id)); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(canio_message_id_set_obj, canio_message_id_set); @@ -122,7 +121,7 @@ STATIC const mp_obj_property_t canio_message_id_obj = { //| STATIC mp_obj_t canio_message_data_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; - return mp_obj_new_bytes((const byte*)common_hal_canio_message_data_get(self), common_hal_canio_message_size_get(self)); + return mp_obj_new_bytes((const byte*)common_hal_canio_message_get_data(self), common_hal_canio_message_get_size(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_message_data_get_obj, canio_message_data_get); @@ -133,7 +132,7 @@ STATIC mp_obj_t canio_message_data_set(const mp_obj_t self_in, const mp_obj_t da if (data.len > 8) { mp_raise_ValueError(translate("Messages limited to 8 bytes")); } - common_hal_canio_message_data_set(self, data.buf, data.len); + common_hal_canio_message_set_data(self, data.buf, data.len); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(canio_message_data_set_obj, canio_message_data_set); @@ -154,7 +153,7 @@ STATIC const mp_obj_property_t canio_message_data_obj = { //| STATIC mp_obj_t canio_message_size_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; - return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_size_get(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_get_size(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_message_size_get_obj, canio_message_size_get); @@ -164,7 +163,7 @@ STATIC mp_obj_t canio_message_size_set(const mp_obj_t self_in, const mp_obj_t si if (size > 8) { mp_raise_ValueError(translate("Messages limited to 8 bytes")); } - common_hal_canio_message_size_set(self, size); + common_hal_canio_message_set_size(self, size); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(canio_message_size_set_obj, canio_message_size_set); @@ -182,13 +181,13 @@ STATIC const mp_obj_property_t canio_message_size_obj = { //| STATIC mp_obj_t canio_message_extended_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; - return mp_obj_new_bool(common_hal_canio_message_extended_get(self)); + return mp_obj_new_bool(common_hal_canio_message_get_extended(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_message_extended_get_obj, canio_message_extended_get); STATIC mp_obj_t canio_message_extended_set(const mp_obj_t self_in, const mp_obj_t extended) { canio_message_obj_t *self = self_in; - common_hal_canio_message_size_set(self, mp_obj_is_true(extended)); + common_hal_canio_message_set_extended(self, mp_obj_is_true(extended)); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(canio_message_extended_set_obj, canio_message_extended_set); @@ -207,13 +206,13 @@ STATIC const mp_obj_property_t canio_message_extended_obj = { //| STATIC mp_obj_t canio_message_rtr_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; - return mp_obj_new_bool(common_hal_canio_message_rtr_get(self)); + return mp_obj_new_bool(common_hal_canio_message_get_rtr(self)); } MP_DEFINE_CONST_FUN_OBJ_1(canio_message_rtr_get_obj, canio_message_rtr_get); STATIC mp_obj_t canio_message_rtr_set(const mp_obj_t self_in, const mp_obj_t rtr) { canio_message_obj_t *self = self_in; - common_hal_canio_message_size_set(self, mp_obj_is_true(rtr)); + common_hal_canio_message_set_rtr(self, mp_obj_is_true(rtr)); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(canio_message_rtr_set_obj, canio_message_rtr_set); diff --git a/shared-bindings/_canio/Message.h b/shared-bindings/_canio/Message.h index 32d6801bc3..ed739af0d4 100644 --- a/shared-bindings/_canio/Message.h +++ b/shared-bindings/_canio/Message.h @@ -27,5 +27,18 @@ #pragma once #include "py/obj.h" +#include "shared-module/_canio/Message.h" extern const mp_obj_type_t canio_message_type; + +void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr, bool extended); +const void *common_hal_canio_message_get_data(const canio_message_obj_t *self); +void common_hal_canio_message_set_data(canio_message_obj_t *self, const void *data, size_t size); +bool common_hal_canio_message_get_extended(const canio_message_obj_t *self); +void common_hal_canio_message_set_extended(canio_message_obj_t *self, bool extended); +int common_hal_canio_message_get_id(const canio_message_obj_t *self); +void common_hal_canio_message_set_id(canio_message_obj_t *self, int id); +bool common_hal_canio_message_get_rtr(const canio_message_obj_t *self); +void common_hal_canio_message_set_rtr(canio_message_obj_t *self, bool rtr); +size_t common_hal_canio_message_get_size(const canio_message_obj_t *self); +void common_hal_canio_message_set_size(canio_message_obj_t *self, size_t size); diff --git a/shared-module/_canio/Match.c b/shared-module/_canio/Match.c index 2b696addb0..3dcde18a78 100644 --- a/shared-module/_canio/Match.c +++ b/shared-module/_canio/Match.c @@ -32,12 +32,12 @@ void common_hal_canio_match_construct(canio_match_obj_t *self, int address, int self->extended = extended; } -int common_hal_canio_match_address_get(const canio_match_obj_t *self) { +int common_hal_canio_match_get_address(const canio_match_obj_t *self) { return self->address; } -int common_hal_canio_match_mask_get(const canio_match_obj_t *self) { +int common_hal_canio_match_get_mask(const canio_match_obj_t *self) { return self->mask; } -bool common_hal_canio_match_extended_get(const canio_match_obj_t *self) { +bool common_hal_canio_match_get_extended(const canio_match_obj_t *self) { return self->extended; } diff --git a/shared-module/_canio/Match.h b/shared-module/_canio/Match.h index 099df976df..25f047f37e 100644 --- a/shared-module/_canio/Match.h +++ b/shared-module/_canio/Match.h @@ -34,8 +34,3 @@ typedef struct { int mask; bool extended; } canio_match_obj_t; - -void common_hal_canio_match_construct(canio_match_obj_t *self, int address, int mask, bool extended); -int common_hal_canio_match_address_get(const canio_match_obj_t *self); -int common_hal_canio_match_mask_get(const canio_match_obj_t *self); -bool common_hal_canio_match_extended_get(const canio_match_obj_t *self); diff --git a/shared-module/_canio/Message.c b/shared-module/_canio/Message.c index c0403b5196..0caca58f02 100644 --- a/shared-module/_canio/Message.c +++ b/shared-module/_canio/Message.c @@ -41,57 +41,57 @@ void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void } } -int common_hal_canio_message_id_get(const canio_message_obj_t *self) +int common_hal_canio_message_get_id(const canio_message_obj_t *self) { return self->id; } -void common_hal_canio_message_id_set(canio_message_obj_t *self, int id) +void common_hal_canio_message_set_id(canio_message_obj_t *self, int id) { self->id = id; } -const void *common_hal_canio_message_data_get(const canio_message_obj_t *self) +const void *common_hal_canio_message_get_data(const canio_message_obj_t *self) { return self->data; } -const void common_hal_canio_message_data_set(canio_message_obj_t *self, const void *data, size_t size) +const void common_hal_canio_message_set_data(canio_message_obj_t *self, const void *data, size_t size) { self->size = size; memcpy(self->data, data, size); } -size_t common_hal_canio_message_size_get(const canio_message_obj_t *self) +size_t common_hal_canio_message_get_size(const canio_message_obj_t *self) { return self->size; } -void common_hal_canio_message_size_set(canio_message_obj_t *self, size_t size) +void common_hal_canio_message_set_size(canio_message_obj_t *self, size_t size) { memset(self->data, 0, size); self->size = size; } -bool common_hal_canio_message_rtr_get(const canio_message_obj_t *self) +bool common_hal_canio_message_get_rtr(const canio_message_obj_t *self) { return self->rtr; } -void common_hal_canio_message_rtr_set(canio_message_obj_t *self, bool rtr) +void common_hal_canio_message_set_rtr(canio_message_obj_t *self, bool rtr) { self->rtr = rtr; } -bool common_hal_canio_message_extended_get(const canio_message_obj_t *self) +bool common_hal_canio_message_get_extended(const canio_message_obj_t *self) { return self->extended; } -void common_hal_canio_message_extended_set(canio_message_obj_t *self, bool extended) +void common_hal_canio_message_set_extended(canio_message_obj_t *self, bool extended) { self->extended = extended; } diff --git a/shared-module/_canio/Message.h b/shared-module/_canio/Message.h index b9fd8eaf2d..b99c5c48e3 100644 --- a/shared-module/_canio/Message.h +++ b/shared-module/_canio/Message.h @@ -36,15 +36,3 @@ typedef struct { bool rtr:1; bool extended:1; } canio_message_obj_t; - -void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr, bool extended); -bool common_hal_canio_message_rtr_get(const canio_message_obj_t *self); -bool common_hal_canio_message_extended_get(const canio_message_obj_t *self); -int common_hal_canio_message_id_get(const canio_message_obj_t *self); -const void *common_hal_canio_message_data_get(const canio_message_obj_t *self); -size_t common_hal_canio_message_size_get(const canio_message_obj_t *self); -void common_hal_canio_message_rtr_set(canio_message_obj_t *self, bool rtr); -void common_hal_canio_message_extended_set(canio_message_obj_t *self, bool extended); -void common_hal_canio_message_id_set(canio_message_obj_t *self, int id); -void common_hal_canio_message_data_set(canio_message_obj_t *self, const void *data, size_t size); -void common_hal_canio_message_size_set(canio_message_obj_t *self, size_t size); From 67d8f108bb94bd734e218f13201fb31d64a66dd4 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 18 Sep 2020 10:56:52 -0500 Subject: [PATCH 22/55] Add CAN to SAM E51 clock config --- .../asf4_conf/same51/peripheral_clk_config.h | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/ports/atmel-samd/asf4_conf/same51/peripheral_clk_config.h b/ports/atmel-samd/asf4_conf/same51/peripheral_clk_config.h index 59fe8730e6..51173f6d32 100644 --- a/ports/atmel-samd/asf4_conf/same51/peripheral_clk_config.h +++ b/ports/atmel-samd/asf4_conf/same51/peripheral_clk_config.h @@ -1165,6 +1165,88 @@ #define CONF_SDHC1_SLOW_FREQUENCY 12000000 #endif +// CAN Clock Settings +// CAN Clock source + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CAN. +// sdhc_gclk_selection +#ifndef CONF_GCLK_CAN0_SRC +#define CONF_GCLK_CAN0_SRC GCLK_PCHCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CAN FREQUENCY + * \brief CAN's Clock frequency + */ +#ifndef CONF_CAN0_FREQUENCY +#define CONF_CAN0_FREQUENCY 120000000 +#endif + +// CAN Clock Settings +// CAN Clock source + +// Generic clock generator 0 + +// Generic clock generator 1 + +// Generic clock generator 2 + +// Generic clock generator 3 + +// Generic clock generator 4 + +// Generic clock generator 5 + +// Generic clock generator 6 + +// Generic clock generator 7 + +// Generic clock generator 8 + +// Generic clock generator 9 + +// Generic clock generator 10 + +// Generic clock generator 11 + +// Select the clock source for CAN. +// sdhc_gclk_selection +#ifndef CONF_GCLK_CAN1_SRC +#define CONF_GCLK_CAN1_SRC GCLK_PCHCTRL_GEN_GCLK0_Val +#endif + +/** + * \def CAN FREQUENCY + * \brief CAN's Clock frequency + */ +#ifndef CONF_CAN1_FREQUENCY +#define CONF_CAN1_FREQUENCY 120000000 +#endif + // <<< end of configuration section >>> #endif // PERIPHERAL_CLK_CONFIG_H From a76119afcba6d7ceb4eb1e4baa79745528feeb92 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 18 Sep 2020 10:57:15 -0500 Subject: [PATCH 23/55] add _canio to Feather M4 CAN --- ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk index 306e7fe42b..345ac33c5d 100644 --- a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk @@ -12,3 +12,4 @@ EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ CIRCUITPY_VECTORIO = 1 +CIRCUITPY_CANIO = 1 From c39ec1581e3fbc59de7f882adf2e6fbb574fb42e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 18 Sep 2020 11:14:59 -0500 Subject: [PATCH 24/55] _canio: Message: setting data clears rtr, and vice versa --- shared-bindings/_canio/Message.c | 4 ++-- shared-module/_canio/Message.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/_canio/Message.c index 85657e05ef..c7ef5d4582 100644 --- a/shared-bindings/_canio/Message.c +++ b/shared-bindings/_canio/Message.c @@ -117,7 +117,7 @@ STATIC const mp_obj_property_t canio_message_id_obj = { //| data: bytes //| """The content of the message, or dummy content in the case of an rtr. //| -//| Assigning to data also sets the length.""" +//| Assigning to data also sets the length and clears the rtr flag.""" //| STATIC mp_obj_t canio_message_data_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; @@ -202,7 +202,7 @@ STATIC const mp_obj_property_t canio_message_extended_obj = { //| rtr: bool -//| """True if the message represents a remote transmission request (RTR)""" +//| """True if the message represents a remote transmission request (RTR). Setting rtr to true zeros out data""" //| STATIC mp_obj_t canio_message_rtr_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; diff --git a/shared-module/_canio/Message.c b/shared-module/_canio/Message.c index 0caca58f02..a02bd01276 100644 --- a/shared-module/_canio/Message.c +++ b/shared-module/_canio/Message.c @@ -59,6 +59,7 @@ const void *common_hal_canio_message_get_data(const canio_message_obj_t *self) const void common_hal_canio_message_set_data(canio_message_obj_t *self, const void *data, size_t size) { + self->rtr = false; self->size = size; memcpy(self->data, data, size); } @@ -84,6 +85,9 @@ bool common_hal_canio_message_get_rtr(const canio_message_obj_t *self) void common_hal_canio_message_set_rtr(canio_message_obj_t *self, bool rtr) { self->rtr = rtr; + if (rtr) { + memset(self->data, 0, self->size); + } } bool common_hal_canio_message_get_extended(const canio_message_obj_t *self) From 09f8a83a756c784e846d2acd9a929e4a45ea34b4 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 18 Sep 2020 13:54:03 -0500 Subject: [PATCH 25/55] samd: template.ld: put canram in its own output section --- ports/atmel-samd/boards/common.template.ld | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ports/atmel-samd/boards/common.template.ld b/ports/atmel-samd/boards/common.template.ld index 19e4753f8b..b30a7a1d9f 100644 --- a/ports/atmel-samd/boards/common.template.ld +++ b/ports/atmel-samd/boards/common.template.ld @@ -43,6 +43,17 @@ SECTIONS _sidata = .; /* start of .data section */ } >FLASH_FIRMWARE + /* Data accessed by the CAN peripheral must be in the first 64kB RAM */ + /* place it at the very start of RAM, before the .data section */ + /* it is zeroed by reset_port */ + .canram (NOLOAD) : + { + . = ALIGN(4); + _scanram = .; + *(.canram) + _ecanram = .; + } > RAM + /* This is the initialized data section The program executes knowing that the data is in the RAM but the loader puts the initial values in the FLASH_FIRMWARE (inidata). @@ -67,10 +78,6 @@ SECTIONS . = ALIGN(4); _sbss = .; _szero = .; /* define a global symbol at bss start; used by startup code */ - /* Data accessed by the CAN peripheral must be in the first 64kB RAM */ - _scanram = .; - *(.canram) - _ecanram = .; *(.bss) *(.bss*) *(COMMON) From 7fd6cab2ac411b808858c0fac9049a856a592cb1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 18 Sep 2020 14:19:05 -0500 Subject: [PATCH 26/55] canio: Make both tx and rx (but not both) optional .. loopback and silent come from the (optional) constructor parameters not guessing based on the pin specification .. docstring & comment improvements --- ports/atmel-samd/common-hal/_canio/CAN.c | 28 +++++++---- ports/atmel-samd/common-hal/_canio/CAN.h | 2 + shared-bindings/_canio/CAN.c | 64 ++++++++++++++++++++---- 3 files changed, 74 insertions(+), 20 deletions(-) diff --git a/ports/atmel-samd/common-hal/_canio/CAN.c b/ports/atmel-samd/common-hal/_canio/CAN.c index 266a1aa1f7..2d8f1d0312 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.c +++ b/ports/atmel-samd/common-hal/_canio/CAN.c @@ -51,9 +51,10 @@ __attribute__((optimize("O0"), noinline)) void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mcu_pin_obj_t *tx, int baudrate, bool loopback, bool silent) { mcu_pin_function_t *tx_function = mcu_find_pin_function(can_tx, tx, -1, MP_QSTR_tx); - int instance = tx_function->instance; + int instance = tx_function ? tx_function->instance : -1; mcu_pin_function_t *rx_function = mcu_find_pin_function(can_rx, rx, instance, MP_QSTR_rx); + instance = rx_function->instance; const uint32_t can_frequency = CONF_CAN0_FREQUENCY; @@ -68,9 +69,11 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc mp_raise_OSError(MP_EINVAL); // baudrate cannot be attained (16kHz or something is lower bound, should never happen) } - gpio_set_pin_direction(tx_function->pin, GPIO_DIRECTION_OUT); - gpio_set_pin_function(tx_function->pin, tx_function->function); - common_hal_never_reset_pin(tx_function->obj); + if (tx_function) { + gpio_set_pin_direction(tx_function->pin, GPIO_DIRECTION_OUT); + gpio_set_pin_function(tx_function->pin, tx_function->function); + common_hal_never_reset_pin(tx_function->obj); + } if (rx_function) { gpio_set_pin_direction(rx_function->pin, GPIO_DIRECTION_IN); @@ -78,12 +81,13 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc common_hal_never_reset_pin(rx_function->obj); } - self->tx_pin_number = common_hal_mcu_pin_number(tx); + self->tx_pin_number = tx ? common_hal_mcu_pin_number(tx) : COMMON_HAL_MCU_NO_PIN; self->rx_pin_number = rx ? common_hal_mcu_pin_number(rx) : COMMON_HAL_MCU_NO_PIN; self->hw = can_insts[instance]; self->state = &can_state[instance]; self->loopback = loopback; + self->silent = silent; // Allow configuration change hri_can_set_CCCR_INIT_bit(self->hw); @@ -129,11 +133,9 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc hri_can_write_NBTP_reg(self->hw, btp.reg); } - // we don't do the high bit rate yet, so do we need to set this register? - // hri_can_write_DBTP_reg(self->hw, ???); - // A "data bit" is a data bit :) with dul rate CAN FD, this is a higher - // rate. However, CAN FD is not implemented in CircuitPython, and this is the same rate as - // the "nominal rate". + // A "data bit" is a data bit :) with dula rate CAN FD, this is a higher + // rate. However, CAN FD is not implemented in CircuitPython, and this is + // the same rate as the "nominal rate". { CAN_DBTP_Type btp = { .bit.DTSEG1 = DIV_ROUND(clocks_to_sample, divisor) - 1, @@ -259,7 +261,7 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc can_objs[instance] = self; } -int common_hal_canio_can_loopback_get(canio_can_obj_t *self) +bool common_hal_canio_can_loopback_get(canio_can_obj_t *self) { return self->loopback; } @@ -368,6 +370,10 @@ void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *messa } } +bool common_hal_canio_can_silent_get(canio_can_obj_t *self) { + return self->silent; +} + bool common_hal_canio_can_deinited(canio_can_obj_t *self) { return !self->hw; } diff --git a/ports/atmel-samd/common-hal/_canio/CAN.h b/ports/atmel-samd/common-hal/_canio/CAN.h index 02bc2e41b5..893b71550d 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.h +++ b/ports/atmel-samd/common-hal/_canio/CAN.h @@ -60,8 +60,10 @@ int common_hal_canio_can_baudrate_get(canio_can_obj_t *self); int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self); int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self); int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self); +bool common_hal_canio_can_loopback_get(canio_can_obj_t *self); int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self); canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self); +bool common_hal_canio_can_silent_get(canio_can_obj_t *self); int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self); void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool auto_restart); void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self); diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/_canio/CAN.c index 537aa55804..3c80b342f7 100644 --- a/shared-bindings/_canio/CAN.c +++ b/shared-bindings/_canio/CAN.c @@ -42,7 +42,7 @@ //| """CAN bus protocol""" //| //| def __init__(self, -//| rx: microcontroller.Pin, +//| rx: Optional[microcontroller.Pin]=None, //| tx: Optional[microcontroller.Pin]=None, //| *, //| baudrate: int = 250000, @@ -50,13 +50,18 @@ //| auto_restart: bool = False, //| ): //| """A common shared-bus protocol. The rx and tx pins are generally -//| connected to a transceiver which controls the H and L pins on a shared -//| bus. +//| connected to a transceiver which controls the H and L pins on a +//| shared bus. //| -//| :param ~microcontroller.Pin rx: the pin to receive with. -//| :param ~microcontroller.Pin tx: the pin to transmit with, or None if the peripheral should operate in "silent" mode. +//| Normally, both ``tx`` and ``rx`` pins will be specified. However, +//| in silent and loopback modes, the other pin may not be required and +//| can be used for other purposes. +//| +//| :param ~microcontroller.Pin rx: the pin to receive with, or None. +//| :param ~microcontroller.Pin tx: the pin to transmit with, or None. //| :param int baudrate: The bit rate of the bus in Hz. All devices on the bus must agree on this value. -//| :param bool loopback: True if the peripheral will be operated in loopback mode. +//| :param bool loopback: True if the peripheral will be operated in loopback mode. In loopback mode, the ``rx`` pin's value is ignored, and the device receives the packets it sends. +//| :param bool silent: True if the peripheral will be operated in silent mode. In silent mode, the ``tx`` pin is always driven to the high logic level. This mode can be used to "sniff" a CAN bus without interfering. //| :param bool auto_restart: If True, will restart communications after entering bus-off state //| """ //| ... @@ -64,8 +69,8 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_rx, ARG_tx, ARG_baudrate, ARG_loopback, ARG_silent, ARG_auto_restart, NUM_ARGS }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_rx, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = 0} }, - { MP_QSTR_tx, MP_ARG_OBJ, {.u_obj = 0} }, + { MP_QSTR_rx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_tx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 250000} }, { MP_QSTR_loopback, MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_silent, MP_ARG_BOOL, {.u_bool = false} }, @@ -76,8 +81,11 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, con mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mcu_pin_obj_t *rx_pin = validate_obj_is_free_pin(args[ARG_rx].u_obj); + mcu_pin_obj_t *rx_pin = validate_obj_is_free_pin_or_none(args[ARG_rx].u_obj); mcu_pin_obj_t *tx_pin = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj); + if (!rx_pin && !tx_pin) { + mp_raise_ValueError(translate("tx and rx cannot both be None")); + } canio_can_obj_t *self = m_new_obj(canio_can_obj_t); self->base.type = &canio_can_type; @@ -301,6 +309,24 @@ STATIC mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map } MP_DEFINE_CONST_FUN_OBJ_KW(canio_can_listen_obj, 1, canio_can_listen); +//| loopback: bool +//| """True if the device was created in loopback mode, False otherwise""" +//| +STATIC mp_obj_t canio_can_loopback_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return mp_obj_new_bool(common_hal_canio_can_loopback_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_loopback_get_obj, canio_can_loopback_get); + +STATIC const mp_obj_property_t canio_can_loopback_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_loopback_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + + //| def send(message: Message) -> None: //| """Send a message on the bus with the given data and id. //| If the message could not be sent due to a full fifo or a bus error condition, RuntimeError is raised. @@ -321,6 +347,24 @@ STATIC mp_obj_t canio_can_send(mp_obj_t self_in, mp_obj_t message_in) { } MP_DEFINE_CONST_FUN_OBJ_2(canio_can_send_obj, canio_can_send); +//| silent: bool +//| """True if the device was created in silent mode, False otherwise""" +//| +STATIC mp_obj_t canio_can_silent_get(mp_obj_t self_in) { + canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_canio_can_check_for_deinit(self); + return mp_obj_new_bool(common_hal_canio_can_silent_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(canio_can_silent_get_obj, canio_can_silent_get); + +STATIC const mp_obj_property_t canio_can_silent_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&canio_can_silent_get_obj, + (mp_obj_t)mp_const_none, + (mp_obj_t)mp_const_none}, +}; + + //| def deinit(self) -> None: //| """Deinitialize this object, freeing its hardware resources""" //| ... @@ -363,9 +407,11 @@ STATIC const mp_rom_map_elem_t canio_can_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_error_passive_state_count), MP_ROM_PTR(&canio_can_error_passive_state_count_obj) }, { MP_ROM_QSTR(MP_QSTR_error_warning_state_count), MP_ROM_PTR(&canio_can_error_warning_state_count_obj) }, { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&canio_can_listen_obj) }, + { MP_ROM_QSTR(MP_QSTR_loopback), MP_ROM_PTR(&canio_can_loopback_obj) }, { MP_ROM_QSTR(MP_QSTR_receive_error_count), MP_ROM_PTR(&canio_can_receive_error_count_obj) }, { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&canio_can_restart_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&canio_can_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_silent), MP_ROM_PTR(&canio_can_silent_obj) }, { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&canio_can_state_obj) }, { MP_ROM_QSTR(MP_QSTR_transmit_error_count), MP_ROM_PTR(&canio_can_transmit_error_count_obj) }, }; From df379b84cb00a3ad694fb89877529c6862a455cb Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 15:07:40 -0500 Subject: [PATCH 27/55] remove unneeded symbols --- ports/atmel-samd/boards/common.template.ld | 2 -- 1 file changed, 2 deletions(-) diff --git a/ports/atmel-samd/boards/common.template.ld b/ports/atmel-samd/boards/common.template.ld index b30a7a1d9f..8942450d2d 100644 --- a/ports/atmel-samd/boards/common.template.ld +++ b/ports/atmel-samd/boards/common.template.ld @@ -49,9 +49,7 @@ SECTIONS .canram (NOLOAD) : { . = ALIGN(4); - _scanram = .; *(.canram) - _ecanram = .; } > RAM /* This is the initialized data section From fd9df164c0c3f3f5c6da3f2f2e17780c7caa6653 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 15:33:42 -0500 Subject: [PATCH 28/55] canio: Message: remove size property This is just duplicating what len(message.data) gives you. --- shared-bindings/_canio/Message.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/_canio/Message.c index c7ef5d4582..487ac9bfd1 100644 --- a/shared-bindings/_canio/Message.c +++ b/shared-bindings/_canio/Message.c @@ -146,36 +146,6 @@ STATIC const mp_obj_property_t canio_message_data_obj = { }; -//| size: int -//| """The length of the message, or the length of the requested data in the case of an rtr -//| -//| Assigning to the length sets all the data bytes to zero""" -//| -STATIC mp_obj_t canio_message_size_get(const mp_obj_t self_in) { - canio_message_obj_t *self = self_in; - return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_get_size(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(canio_message_size_get_obj, canio_message_size_get); - -STATIC mp_obj_t canio_message_size_set(const mp_obj_t self_in, const mp_obj_t size_in) { - canio_message_obj_t *self = self_in; - int size = mp_obj_get_int(size_in); - if (size > 8) { - mp_raise_ValueError(translate("Messages limited to 8 bytes")); - } - common_hal_canio_message_set_size(self, size); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(canio_message_size_set_obj, canio_message_size_set); - - -STATIC const mp_obj_property_t canio_message_size_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&canio_message_size_get_obj, - (mp_obj_t)&canio_message_size_set_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - //| extended: bool //| """True if the message represents a remote transmission request (RTR)""" //| @@ -229,7 +199,6 @@ STATIC const mp_obj_property_t canio_message_rtr_obj = { STATIC const mp_rom_map_elem_t canio_message_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&canio_message_id_obj) }, { MP_ROM_QSTR(MP_QSTR_data), MP_ROM_PTR(&canio_message_data_obj) }, - { MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&canio_message_size_obj) }, { MP_ROM_QSTR(MP_QSTR_rtr), MP_ROM_PTR(&canio_message_rtr_obj) }, { MP_ROM_QSTR(MP_QSTR_extended), MP_ROM_PTR(&canio_message_extended_obj) }, }; From 4e4853dcb26aa46db3269db45a8cbbbad61c44d8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 15:49:51 -0500 Subject: [PATCH 29/55] common.template.ld: remove unneeded line --- ports/atmel-samd/boards/common.template.ld | 1 - 1 file changed, 1 deletion(-) diff --git a/ports/atmel-samd/boards/common.template.ld b/ports/atmel-samd/boards/common.template.ld index 8942450d2d..53c4cf5eec 100644 --- a/ports/atmel-samd/boards/common.template.ld +++ b/ports/atmel-samd/boards/common.template.ld @@ -60,7 +60,6 @@ SECTIONS { . = ALIGN(4); _srelocate = .; /* create a global symbol at data start; used by startup code in order to initialize the .data section in RAM */ - . = ALIGN(4); *(.ramfunc) *(.ramfunc*) *(.data) /* .data sections */ From 9e8f1820c8b9be728ae0f9e7c197565ac17cc6a8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 15:51:55 -0500 Subject: [PATCH 30/55] canio.CAN: switch rx/tx, make both mandatory, move declarations around --- ports/atmel-samd/common-hal/_canio/CAN.c | 22 ++++++++-------------- ports/atmel-samd/common-hal/_canio/CAN.h | 22 ++-------------------- shared-bindings/_canio/CAN.c | 23 ++++++++++------------- shared-bindings/_canio/CAN.h | 23 +++++++++++++++++++++++ 4 files changed, 43 insertions(+), 47 deletions(-) diff --git a/ports/atmel-samd/common-hal/_canio/CAN.c b/ports/atmel-samd/common-hal/_canio/CAN.c index 2d8f1d0312..0d967d7cae 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.c +++ b/ports/atmel-samd/common-hal/_canio/CAN.c @@ -47,14 +47,12 @@ STATIC canio_can_obj_t *can_objs[MP_ARRAY_SIZE(can_insts)]; // This must be placed in the first 64kB of RAM STATIC COMPILER_SECTION(".canram") canio_can_state_t can_state[MP_ARRAY_SIZE(can_insts)]; -__attribute__((optimize("O0"), noinline)) -void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mcu_pin_obj_t *tx, int baudrate, bool loopback, bool silent) +void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *tx, mcu_pin_obj_t *rx, int baudrate, bool loopback, bool silent) { mcu_pin_function_t *tx_function = mcu_find_pin_function(can_tx, tx, -1, MP_QSTR_tx); - int instance = tx_function ? tx_function->instance : -1; + int instance = tx_function->instance; mcu_pin_function_t *rx_function = mcu_find_pin_function(can_rx, rx, instance, MP_QSTR_rx); - instance = rx_function->instance; const uint32_t can_frequency = CONF_CAN0_FREQUENCY; @@ -69,17 +67,13 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mc mp_raise_OSError(MP_EINVAL); // baudrate cannot be attained (16kHz or something is lower bound, should never happen) } - if (tx_function) { - gpio_set_pin_direction(tx_function->pin, GPIO_DIRECTION_OUT); - gpio_set_pin_function(tx_function->pin, tx_function->function); - common_hal_never_reset_pin(tx_function->obj); - } + gpio_set_pin_direction(tx_function->pin, GPIO_DIRECTION_OUT); + gpio_set_pin_function(tx_function->pin, tx_function->function); + common_hal_never_reset_pin(tx_function->obj); - if (rx_function) { - gpio_set_pin_direction(rx_function->pin, GPIO_DIRECTION_IN); - gpio_set_pin_function(rx_function->pin, rx_function->function); - common_hal_never_reset_pin(rx_function->obj); - } + gpio_set_pin_direction(rx_function->pin, GPIO_DIRECTION_IN); + gpio_set_pin_function(rx_function->pin, rx_function->function); + common_hal_never_reset_pin(rx_function->obj); self->tx_pin_number = tx ? common_hal_mcu_pin_number(tx) : COMMON_HAL_MCU_NO_PIN; self->rx_pin_number = rx ? common_hal_mcu_pin_number(rx) : COMMON_HAL_MCU_NO_PIN; diff --git a/ports/atmel-samd/common-hal/_canio/CAN.h b/ports/atmel-samd/common-hal/_canio/CAN.h index 893b71550d..1cc34e3ac0 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.h +++ b/ports/atmel-samd/common-hal/_canio/CAN.h @@ -28,6 +28,7 @@ #include "py/obj.h" #include "shared-bindings/_canio/__init__.h" +#include "shared-bindings/_canio/CAN.h" #include "component/can.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/_canio/__init__.h" @@ -36,7 +37,7 @@ #define COMMON_HAL_CAN_RX_FIFO_LEN (2) #define COMMON_HAL_CAN_TX_FIFO_LEN (2) -typedef struct { +typedef struct canio_can_obj { mp_obj_base_t base; Can *hw; canio_can_state_t *state; @@ -52,22 +53,3 @@ typedef struct { bool fifo0_in_use:1; bool fifo1_in_use:1; } canio_can_obj_t; - -void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *rx, mcu_pin_obj_t *tx, int baudrate, bool loopback, bool silent); -bool common_hal_canio_can_auto_restart_get(canio_can_obj_t *self); -bool common_hal_canio_can_deinited(canio_can_obj_t *self); -int common_hal_canio_can_baudrate_get(canio_can_obj_t *self); -int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self); -int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self); -int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self); -bool common_hal_canio_can_loopback_get(canio_can_obj_t *self); -int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self); -canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self); -bool common_hal_canio_can_silent_get(canio_can_obj_t *self); -int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self); -void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool auto_restart); -void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self); -void common_hal_canio_can_deinit(canio_can_obj_t *self); -void common_hal_canio_can_restart(canio_can_obj_t *self); -void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *message); -void common_hal_canio_reset(void); diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/_canio/CAN.c index 3c80b342f7..38aed85d33 100644 --- a/shared-bindings/_canio/CAN.c +++ b/shared-bindings/_canio/CAN.c @@ -42,26 +42,23 @@ //| """CAN bus protocol""" //| //| def __init__(self, -//| rx: Optional[microcontroller.Pin]=None, -//| tx: Optional[microcontroller.Pin]=None, +//| tx: microcontroller.Pin, +//| rx: microcontroller.Pin, //| *, //| baudrate: int = 250000, //| loopback: bool = False, +//| silent: bool = False, //| auto_restart: bool = False, //| ): //| """A common shared-bus protocol. The rx and tx pins are generally //| connected to a transceiver which controls the H and L pins on a //| shared bus. //| -//| Normally, both ``tx`` and ``rx`` pins will be specified. However, -//| in silent and loopback modes, the other pin may not be required and -//| can be used for other purposes. -//| -//| :param ~microcontroller.Pin rx: the pin to receive with, or None. -//| :param ~microcontroller.Pin tx: the pin to transmit with, or None. +//| :param ~microcontroller.Pin rx: the pin to receive with +//| :param ~microcontroller.Pin tx: the pin to transmit with //| :param int baudrate: The bit rate of the bus in Hz. All devices on the bus must agree on this value. -//| :param bool loopback: True if the peripheral will be operated in loopback mode. In loopback mode, the ``rx`` pin's value is ignored, and the device receives the packets it sends. -//| :param bool silent: True if the peripheral will be operated in silent mode. In silent mode, the ``tx`` pin is always driven to the high logic level. This mode can be used to "sniff" a CAN bus without interfering. +//| :param bool loopback: When True the ``rx`` pin's value is ignored, and the device receives the packets it sends. +//| :param bool silent: When True the ``tx`` pin is always driven to the high logic level. This mode can be used to "sniff" a CAN bus without interfering. //| :param bool auto_restart: If True, will restart communications after entering bus-off state //| """ //| ... @@ -69,8 +66,8 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_rx, ARG_tx, ARG_baudrate, ARG_loopback, ARG_silent, ARG_auto_restart, NUM_ARGS }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_rx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_tx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_tx, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_rx, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 250000} }, { MP_QSTR_loopback, MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_silent, MP_ARG_BOOL, {.u_bool = false} }, @@ -89,7 +86,7 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, con canio_can_obj_t *self = m_new_obj(canio_can_obj_t); self->base.type = &canio_can_type; - common_hal_canio_can_construct(self, rx_pin, tx_pin, args[ARG_baudrate].u_int, args[ARG_loopback].u_bool, args[ARG_silent].u_bool); + common_hal_canio_can_construct(self, tx_pin, rx_pin, args[ARG_baudrate].u_int, args[ARG_loopback].u_bool, args[ARG_silent].u_bool); common_hal_canio_can_auto_restart_set(self, args[ARG_auto_restart].u_bool); diff --git a/shared-bindings/_canio/CAN.h b/shared-bindings/_canio/CAN.h index 81040cf237..c591c8e6ba 100644 --- a/shared-bindings/_canio/CAN.h +++ b/shared-bindings/_canio/CAN.h @@ -27,5 +27,28 @@ #pragma once #include "py/obj.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/_canio/Message.h" extern const mp_obj_type_t canio_can_type; + +typedef struct canio_can_obj canio_can_obj_t; + +void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *tx, mcu_pin_obj_t *rx, int baudrate, bool loopback, bool silent); +bool common_hal_canio_can_auto_restart_get(canio_can_obj_t *self); +bool common_hal_canio_can_deinited(canio_can_obj_t *self); +int common_hal_canio_can_baudrate_get(canio_can_obj_t *self); +int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self); +int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self); +int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self); +bool common_hal_canio_can_loopback_get(canio_can_obj_t *self); +int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self); +canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self); +bool common_hal_canio_can_silent_get(canio_can_obj_t *self); +int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self); +void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool auto_restart); +void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self); +void common_hal_canio_can_deinit(canio_can_obj_t *self); +void common_hal_canio_can_restart(canio_can_obj_t *self); +void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *message); +void common_hal_canio_reset(void); From 493679da3b5b80b446e805966103a4d6703ec90c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 16:06:17 -0500 Subject: [PATCH 31/55] CAN.listen: block until a message comes in or timeout is reached --- shared-bindings/_canio/Listener.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/shared-bindings/_canio/Listener.c b/shared-bindings/_canio/Listener.c index 84b2aacb97..6186f3bbdb 100644 --- a/shared-bindings/_canio/Listener.c +++ b/shared-bindings/_canio/Listener.c @@ -100,20 +100,18 @@ STATIC mp_obj_t canio_listener_iter(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_iter_obj, canio_listener_iter); //| def __next__(self): -//| """Returns the next waiting message, if one is available +//| """Reads a message, after waiting up to self.timeout seconds //| -//| If the object is deinitialized, raises ValueError. -//| -//| If no message is waiting raises StopIteration""" +//| If no message is received in time, raises StopIteration. Otherwise, +//| a Message is returned.""" //| ... //| STATIC mp_obj_t canio_listener_next(mp_obj_t self_in) { - canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_canio_listener_check_for_deinit(self); - if (common_hal_canio_listener_in_waiting(self)) { - return canio_listener_read(self_in); + mp_obj_t result = canio_listener_read(self_in); + if (result == mp_const_none) { + return MP_OBJ_STOP_ITERATION; } - return MP_OBJ_STOP_ITERATION; + return result; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_next_obj, canio_listener_next); From 4869dbdc670bfa8a5f2e0a639495d03984ea0a6a Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 16:42:12 -0500 Subject: [PATCH 32/55] canio: rename from _canio This reflects our belief that the API is stable enough to avoid incompatible changes during 6.x. --- main.c | 2 +- .../atmel-samd/common-hal/{_canio => canio}/CAN.c | 2 +- .../atmel-samd/common-hal/{_canio => canio}/CAN.h | 8 ++++---- .../common-hal/{_canio => canio}/Listener.c | 4 ++-- .../common-hal/{_canio => canio}/Listener.h | 4 ++-- .../common-hal/{_canio => canio}/__init__.c | 0 .../common-hal/{_canio => canio}/__init__.h | 0 py/circuitpy_defns.mk | 14 +++++++------- py/circuitpy_mpconfig.h | 2 +- shared-bindings/{_canio => canio}/CAN.c | 14 +++++++------- shared-bindings/{_canio => canio}/CAN.h | 2 +- shared-bindings/{_canio => canio}/Listener.c | 6 +++--- shared-bindings/{_canio => canio}/Listener.h | 0 shared-bindings/{_canio => canio}/Match.c | 2 +- shared-bindings/{_canio => canio}/Match.h | 2 +- shared-bindings/{_canio => canio}/Message.c | 2 +- shared-bindings/{_canio => canio}/Message.h | 2 +- shared-bindings/{_canio => canio}/__init__.c | 10 +++++----- shared-bindings/{_canio => canio}/__init__.h | 0 shared-module/{_canio => canio}/Match.c | 2 +- shared-module/{_canio => canio}/Match.h | 0 shared-module/{_canio => canio}/Message.c | 2 +- shared-module/{_canio => canio}/Message.h | 0 23 files changed, 40 insertions(+), 40 deletions(-) rename ports/atmel-samd/common-hal/{_canio => canio}/CAN.c (99%) rename ports/atmel-samd/common-hal/{_canio => canio}/CAN.h (91%) rename ports/atmel-samd/common-hal/{_canio => canio}/Listener.c (99%) rename ports/atmel-samd/common-hal/{_canio => canio}/Listener.h (96%) rename ports/atmel-samd/common-hal/{_canio => canio}/__init__.c (100%) rename ports/atmel-samd/common-hal/{_canio => canio}/__init__.h (100%) rename shared-bindings/{_canio => canio}/CAN.c (98%) rename shared-bindings/{_canio => canio}/CAN.h (98%) rename shared-bindings/{_canio => canio}/Listener.c (98%) rename shared-bindings/{_canio => canio}/Listener.h (100%) rename shared-bindings/{_canio => canio}/Match.c (99%) rename shared-bindings/{_canio => canio}/Match.h (97%) rename shared-bindings/{_canio => canio}/Message.c (99%) rename shared-bindings/{_canio => canio}/Message.h (98%) rename shared-bindings/{_canio => canio}/__init__.c (95%) rename shared-bindings/{_canio => canio}/__init__.h (100%) rename shared-module/{_canio => canio}/Match.c (97%) rename shared-module/{_canio => canio}/Match.h (100%) rename shared-module/{_canio => canio}/Message.c (98%) rename shared-module/{_canio => canio}/Message.h (100%) diff --git a/main.c b/main.c index 4d34e451dd..dbd367a596 100755 --- a/main.c +++ b/main.c @@ -82,7 +82,7 @@ #endif #if CIRCUITPY_CANIO -#include "common-hal/_canio/CAN.h" +#include "common-hal/canio/CAN.h" #endif void do_str(const char *src, mp_parse_input_kind_t input_kind) { diff --git a/ports/atmel-samd/common-hal/_canio/CAN.c b/ports/atmel-samd/common-hal/canio/CAN.c similarity index 99% rename from ports/atmel-samd/common-hal/_canio/CAN.c rename to ports/atmel-samd/common-hal/canio/CAN.c index 0d967d7cae..01cc03dea5 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.c +++ b/ports/atmel-samd/common-hal/canio/CAN.c @@ -31,7 +31,7 @@ #include "peripheral_clk_config.h" -#include "common-hal/_canio/CAN.h" +#include "common-hal/canio/CAN.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" #include "supervisor/port.h" diff --git a/ports/atmel-samd/common-hal/_canio/CAN.h b/ports/atmel-samd/common-hal/canio/CAN.h similarity index 91% rename from ports/atmel-samd/common-hal/_canio/CAN.h rename to ports/atmel-samd/common-hal/canio/CAN.h index 1cc34e3ac0..cdea60e7d0 100644 --- a/ports/atmel-samd/common-hal/_canio/CAN.h +++ b/ports/atmel-samd/common-hal/canio/CAN.h @@ -27,12 +27,12 @@ #pragma once #include "py/obj.h" -#include "shared-bindings/_canio/__init__.h" -#include "shared-bindings/_canio/CAN.h" +#include "shared-bindings/canio/__init__.h" +#include "shared-bindings/canio/CAN.h" #include "component/can.h" #include "common-hal/microcontroller/Pin.h" -#include "common-hal/_canio/__init__.h" -#include "shared-module/_canio/Message.h" +#include "common-hal/canio/__init__.h" +#include "shared-module/canio/Message.h" #define COMMON_HAL_CAN_RX_FIFO_LEN (2) #define COMMON_HAL_CAN_TX_FIFO_LEN (2) diff --git a/ports/atmel-samd/common-hal/_canio/Listener.c b/ports/atmel-samd/common-hal/canio/Listener.c similarity index 99% rename from ports/atmel-samd/common-hal/_canio/Listener.c rename to ports/atmel-samd/common-hal/canio/Listener.c index 0a5f629f88..bf8b3288dc 100644 --- a/ports/atmel-samd/common-hal/_canio/Listener.c +++ b/ports/atmel-samd/common-hal/canio/Listener.c @@ -30,8 +30,8 @@ #include "py/obj.h" #include "py/runtime.h" -#include "common-hal/_canio/__init__.h" -#include "common-hal/_canio/Listener.h" +#include "common-hal/canio/__init__.h" +#include "common-hal/canio/Listener.h" #include "shared-bindings/util.h" #include "supervisor/shared/tick.h" #include "component/can.h" diff --git a/ports/atmel-samd/common-hal/_canio/Listener.h b/ports/atmel-samd/common-hal/canio/Listener.h similarity index 96% rename from ports/atmel-samd/common-hal/_canio/Listener.h rename to ports/atmel-samd/common-hal/canio/Listener.h index cc6770e6e5..a51a9fc379 100644 --- a/ports/atmel-samd/common-hal/_canio/Listener.h +++ b/ports/atmel-samd/common-hal/canio/Listener.h @@ -26,8 +26,8 @@ #pragma once -#include "common-hal/_canio/CAN.h" -#include "shared-module/_canio/Match.h" +#include "common-hal/canio/CAN.h" +#include "shared-module/canio/Match.h" typedef struct { __IO CAN_RXF0C_Type RXFC; /**< \brief (R/W 32) Rx FIFO n Configuration */ diff --git a/ports/atmel-samd/common-hal/_canio/__init__.c b/ports/atmel-samd/common-hal/canio/__init__.c similarity index 100% rename from ports/atmel-samd/common-hal/_canio/__init__.c rename to ports/atmel-samd/common-hal/canio/__init__.c diff --git a/ports/atmel-samd/common-hal/_canio/__init__.h b/ports/atmel-samd/common-hal/canio/__init__.h similarity index 100% rename from ports/atmel-samd/common-hal/_canio/__init__.h rename to ports/atmel-samd/common-hal/canio/__init__.h diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 2614dc011f..98fa7a5f2c 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -143,7 +143,7 @@ ifeq ($(CIRCUITPY_CAMERA),1) SRC_PATTERNS += camera/% endif ifeq ($(CIRCUITPY_CANIO),1) -SRC_PATTERNS += _canio/% +SRC_PATTERNS += canio/% endif ifeq ($(CIRCUITPY_COUNTIO),1) SRC_PATTERNS += countio/% @@ -318,9 +318,9 @@ SRC_COMMON_HAL_ALL = \ busio/__init__.c \ camera/__init__.c \ camera/Camera.c \ - _canio/CAN.c \ - _canio/Listener.c \ - _canio/__init__.c \ + canio/CAN.c \ + canio/Listener.c \ + canio/__init__.c \ countio/Counter.c \ countio/__init__.c \ digitalio/DigitalInOut.c \ @@ -390,7 +390,7 @@ $(filter $(SRC_PATTERNS), \ _bleio/Address.c \ _bleio/Attribute.c \ _bleio/ScanEntry.c \ - _canio/Match.c \ + canio/Match.c \ _eve/__init__.c \ camera/ImageFormat.c \ digitalio/Direction.c \ @@ -409,8 +409,8 @@ SRC_SHARED_MODULE_ALL = \ _bleio/Attribute.c \ _bleio/ScanEntry.c \ _bleio/ScanResults.c \ - _canio/Match.c \ - _canio/Message.c \ + canio/Match.c \ + canio/Message.c \ _eve/__init__.c \ _pixelbuf/PixelBuf.c \ _pixelbuf/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index d1b12f3544..0583ae1c97 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -338,7 +338,7 @@ extern const struct _mp_obj_module_t camera_module; #if CIRCUITPY_CANIO extern const struct _mp_obj_module_t canio_module; -#define CANIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__canio), (mp_obj_t)&canio_module }, +#define CANIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_canio), (mp_obj_t)&canio_module }, #else #define CANIO_MODULE #endif diff --git a/shared-bindings/_canio/CAN.c b/shared-bindings/canio/CAN.c similarity index 98% rename from shared-bindings/_canio/CAN.c rename to shared-bindings/canio/CAN.c index 38aed85d33..482d11546d 100644 --- a/shared-bindings/_canio/CAN.c +++ b/shared-bindings/canio/CAN.c @@ -25,13 +25,13 @@ */ #include "py/enum.h" -#include "common-hal/_canio/CAN.h" -#include "common-hal/_canio/Listener.h" -#include "shared-bindings/_canio/__init__.h" -#include "shared-bindings/_canio/CAN.h" -#include "shared-bindings/_canio/Listener.h" -#include "shared-bindings/_canio/Match.h" -#include "shared-bindings/_canio/Message.h" +#include "common-hal/canio/CAN.h" +#include "common-hal/canio/Listener.h" +#include "shared-bindings/canio/__init__.h" +#include "shared-bindings/canio/CAN.h" +#include "shared-bindings/canio/Listener.h" +#include "shared-bindings/canio/Match.h" +#include "shared-bindings/canio/Message.h" #include "shared-bindings/microcontroller/Pin.h" #include "py/objproperty.h" diff --git a/shared-bindings/_canio/CAN.h b/shared-bindings/canio/CAN.h similarity index 98% rename from shared-bindings/_canio/CAN.h rename to shared-bindings/canio/CAN.h index c591c8e6ba..66c972c285 100644 --- a/shared-bindings/_canio/CAN.h +++ b/shared-bindings/canio/CAN.h @@ -28,7 +28,7 @@ #include "py/obj.h" #include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/_canio/Message.h" +#include "shared-bindings/canio/Message.h" extern const mp_obj_type_t canio_can_type; diff --git a/shared-bindings/_canio/Listener.c b/shared-bindings/canio/Listener.c similarity index 98% rename from shared-bindings/_canio/Listener.c rename to shared-bindings/canio/Listener.c index 6186f3bbdb..0b50e58358 100644 --- a/shared-bindings/_canio/Listener.c +++ b/shared-bindings/canio/Listener.c @@ -24,9 +24,9 @@ * THE SOFTWARE. */ -#include "shared-bindings/_canio/Listener.h" -#include "shared-bindings/_canio/Message.h" -#include "common-hal/_canio/Listener.h" +#include "shared-bindings/canio/Listener.h" +#include "shared-bindings/canio/Message.h" +#include "common-hal/canio/Listener.h" #include "py/runtime.h" #include "py/objproperty.h" diff --git a/shared-bindings/_canio/Listener.h b/shared-bindings/canio/Listener.h similarity index 100% rename from shared-bindings/_canio/Listener.h rename to shared-bindings/canio/Listener.h diff --git a/shared-bindings/_canio/Match.c b/shared-bindings/canio/Match.c similarity index 99% rename from shared-bindings/_canio/Match.c rename to shared-bindings/canio/Match.c index 4ff35906b7..ff5d028fad 100644 --- a/shared-bindings/_canio/Match.c +++ b/shared-bindings/canio/Match.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "shared-bindings/_canio/Match.h" +#include "shared-bindings/canio/Match.h" #include "py/objproperty.h" #include "py/runtime.h" diff --git a/shared-bindings/_canio/Match.h b/shared-bindings/canio/Match.h similarity index 97% rename from shared-bindings/_canio/Match.h rename to shared-bindings/canio/Match.h index 5522c26367..88996d730f 100644 --- a/shared-bindings/_canio/Match.h +++ b/shared-bindings/canio/Match.h @@ -27,7 +27,7 @@ #pragma once #include "py/obj.h" -#include "shared-module/_canio/Match.h" +#include "shared-module/canio/Match.h" extern const mp_obj_type_t canio_match_type; diff --git a/shared-bindings/_canio/Message.c b/shared-bindings/canio/Message.c similarity index 99% rename from shared-bindings/_canio/Message.c rename to shared-bindings/canio/Message.c index 487ac9bfd1..11de6ded92 100644 --- a/shared-bindings/_canio/Message.c +++ b/shared-bindings/canio/Message.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "shared-bindings/_canio/Message.h" +#include "shared-bindings/canio/Message.h" #include "py/obj.h" #include "py/objproperty.h" diff --git a/shared-bindings/_canio/Message.h b/shared-bindings/canio/Message.h similarity index 98% rename from shared-bindings/_canio/Message.h rename to shared-bindings/canio/Message.h index ed739af0d4..34b632e847 100644 --- a/shared-bindings/_canio/Message.h +++ b/shared-bindings/canio/Message.h @@ -27,7 +27,7 @@ #pragma once #include "py/obj.h" -#include "shared-module/_canio/Message.h" +#include "shared-module/canio/Message.h" extern const mp_obj_type_t canio_message_type; diff --git a/shared-bindings/_canio/__init__.c b/shared-bindings/canio/__init__.c similarity index 95% rename from shared-bindings/_canio/__init__.c rename to shared-bindings/canio/__init__.c index 29e43c5c46..bc191913d7 100644 --- a/shared-bindings/_canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -60,11 +60,11 @@ #include "py/obj.h" #include "py/enum.h" -#include "shared-bindings/_canio/__init__.h" -#include "shared-bindings/_canio/CAN.h" -#include "shared-bindings/_canio/Match.h" -#include "shared-bindings/_canio/Message.h" -#include "shared-bindings/_canio/Listener.h" +#include "shared-bindings/canio/__init__.h" +#include "shared-bindings/canio/CAN.h" +#include "shared-bindings/canio/Match.h" +#include "shared-bindings/canio/Message.h" +#include "shared-bindings/canio/Listener.h" MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_ACTIVE, BUS_STATE_ERROR_ACTIVE); MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, BUS_STATE_ERROR_PASSIVE); diff --git a/shared-bindings/_canio/__init__.h b/shared-bindings/canio/__init__.h similarity index 100% rename from shared-bindings/_canio/__init__.h rename to shared-bindings/canio/__init__.h diff --git a/shared-module/_canio/Match.c b/shared-module/canio/Match.c similarity index 97% rename from shared-module/_canio/Match.c rename to shared-module/canio/Match.c index 3dcde18a78..9e33b956f6 100644 --- a/shared-module/_canio/Match.c +++ b/shared-module/canio/Match.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "shared-module/_canio/Match.h" +#include "shared-module/canio/Match.h" void common_hal_canio_match_construct(canio_match_obj_t *self, int address, int mask, bool extended) { self->address = address; diff --git a/shared-module/_canio/Match.h b/shared-module/canio/Match.h similarity index 100% rename from shared-module/_canio/Match.h rename to shared-module/canio/Match.h diff --git a/shared-module/_canio/Message.c b/shared-module/canio/Message.c similarity index 98% rename from shared-module/_canio/Message.c rename to shared-module/canio/Message.c index a02bd01276..b8ebb78596 100644 --- a/shared-module/_canio/Message.c +++ b/shared-module/canio/Message.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "shared-module/_canio/Message.h" +#include "shared-module/canio/Message.h" #include diff --git a/shared-module/_canio/Message.h b/shared-module/canio/Message.h similarity index 100% rename from shared-module/_canio/Message.h rename to shared-module/canio/Message.h From 85756fa0cdef144a45fe7a297c0b86e182837895 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 16:45:51 -0500 Subject: [PATCH 33/55] make translate --- locale/circuitpython.pot | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 37212e2416..c9114dd5c5 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -92,7 +92,11 @@ msgstr "" msgid "%q must be a tuple of length 2" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -280,6 +284,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "" @@ -316,6 +324,10 @@ msgstr "" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -752,7 +764,7 @@ msgstr "" msgid "Error in regex" msgstr "" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -845,6 +857,10 @@ msgstr "" msgid "File exists" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1127,6 +1143,10 @@ msgstr "" msgid "Maximum x value when mirrored is %d" msgstr "" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2310,6 +2330,10 @@ msgstr "" msgid "exceptions must derive from BaseException" msgstr "" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -3147,6 +3171,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3261,7 +3289,7 @@ msgid "tuple/list has wrong length" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" From a8147c125c6775ce844f912901ad750de39d11e7 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 16:47:28 -0500 Subject: [PATCH 34/55] Fix unintentional cross references --- shared-bindings/canio/Message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/canio/Message.c b/shared-bindings/canio/Message.c index 11de6ded92..23645d2e5f 100644 --- a/shared-bindings/canio/Message.c +++ b/shared-bindings/canio/Message.c @@ -42,7 +42,7 @@ //| //| In CAN, messages can have a size from 0 to 8 bytes. //| -//| For a non-rtr message, specify `data`. For an rtr-message, specify either `data` (a dummy buffer of the requested size) or `size`. +//| For a non-rtr message, specify ``data``. For an rtr-message, specify either ``data`` (a dummy buffer of the requested size) or ``size``. //| """ //| ... //| From 10245c0ff8d5847dac5885a7e40838ccc0fe8154 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 21 Sep 2020 17:04:30 -0500 Subject: [PATCH 35/55] canio: a few more stray _canios --- shared-bindings/canio/Listener.c | 4 ++-- shared-bindings/canio/__init__.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/shared-bindings/canio/Listener.c b/shared-bindings/canio/Listener.c index 0b50e58358..137c9e590a 100644 --- a/shared-bindings/canio/Listener.c +++ b/shared-bindings/canio/Listener.c @@ -34,8 +34,8 @@ //| class Listener: //| """Listens for CAN message //| -//| _canio.Listener is not constructed directly, but instead by calling the -//| Listen method of a _canio.CAN object.""" +//| canio.Listener is not constructed directly, but instead by calling the +//| Listen method of a canio.CAN object.""" //| //| def read(self) -> Optional[Message]: diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index bc191913d7..b0b982c950 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -26,7 +26,7 @@ //| """CAN bus access //| -//| The `_canio` module contains low level classes to support the CAN bus +//| The `canio` module contains low level classes to support the CAN bus //| protocol. //| //| CAN and Listener classes change hardware state and should be deinitialized when they @@ -36,11 +36,11 @@ //| //| For example:: //| -//| import _canio +//| import canio //| from board import * //| -//| can = _canio.CAN(board.CAN_RX, board.CAN_TX, baudrate=1000000) -//| message = _canio.Message(id=0x0408, data="adafruit" +//| can = canio.CAN(board.CAN_RX, board.CAN_TX, baudrate=1000000) +//| message = canio.Message(id=0x0408, data="adafruit" //| can.write(message)) //| can.deinit() //| @@ -103,9 +103,9 @@ MAKE_ENUM_MAP(canio_bus_state) { }; STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); -MAKE_PRINTER(_canio, canio_bus_state); +MAKE_PRINTER(canio, canio_bus_state); -MAKE_ENUM_TYPE(_canio, BusState, canio_bus_state); +MAKE_ENUM_TYPE(canio, BusState, canio_bus_state); STATIC const mp_rom_map_elem_t canio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BusState), MP_ROM_PTR(&canio_bus_state_type) }, From add230b4da7c32c1b6fee3a328ccb8eebede42c5 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Tue, 22 Sep 2020 11:37:12 +0530 Subject: [PATCH 36/55] Update port.c --- ports/esp32s2/supervisor/port.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index e52b7f3762..3de63278dc 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -43,6 +43,7 @@ #include "common-hal/wifi/__init__.h" #include "supervisor/memory.h" #include "supervisor/shared/tick.h" +#include "shared-bindings/rtc/__init__.h" #include "peripherals/rmt.h" #include "esp-idf/components/heap/include/esp_heap_caps.h" @@ -106,6 +107,11 @@ void reset_port(void) { spi_reset(); uart_reset(); #endif + +#if CIRCUITPY_RTC + rtc_reset(); +#endif + #if CIRCUITPY_WIFI wifi_reset(); #endif From 59580d0f2d744ac5f04600e371964aea9f79e833 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Sep 2020 09:36:29 -0500 Subject: [PATCH 37/55] canio: Fix implementation bugs in atmel-sam --- ports/atmel-samd/common-hal/canio/CAN.c | 8 +++--- ports/atmel-samd/common-hal/canio/Listener.c | 12 ++++----- ports/atmel-samd/common-hal/canio/Listener.h | 2 +- ports/atmel-samd/common-hal/canio/__init__.h | 27 ++++++++++---------- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/ports/atmel-samd/common-hal/canio/CAN.c b/ports/atmel-samd/common-hal/canio/CAN.c index 01cc03dea5..4f28698fba 100644 --- a/ports/atmel-samd/common-hal/canio/CAN.c +++ b/ports/atmel-samd/common-hal/canio/CAN.c @@ -176,7 +176,7 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *tx, mc { CAN_TXBC_Type bc = { - .bit.TBSA = (uint32_t)self->state->tx_fifo, + .bit.TBSA = (uint32_t)self->state->tx_buffer, .bit.NDTB = COMMON_HAL_CANIO_TX_FIFO_SIZE, .bit.TFQM = 0, // Messages are transmitted in the order submitted }; @@ -192,7 +192,7 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, mcu_pin_obj_t *tx, mc { CAN_GFC_Type gfc = { - .bit.RRFE = 1, + .bit.RRFE = 0, .bit.ANFS = CAN_GFC_ANFS_REJECT_Val, .bit.ANFE = CAN_GFC_ANFE_REJECT_Val, }; @@ -333,13 +333,13 @@ void common_hal_canio_can_send(canio_can_obj_t *self, canio_message_obj_t *messa maybe_auto_restart(self); // We have just one dedicated TX buffer, use it! - canio_can_fifo_t *ent = &self->state->tx_fifo[0]; + canio_can_tx_buffer_t *ent = &self->state->tx_buffer[0]; ent->txb0.bit.ESI = false; ent->txb0.bit.XTD = message->extended; ent->txb0.bit.RTR = message->rtr; if (message->extended) { - ent->txb0.bit.ID = message->id << 18; + ent->txb0.bit.ID = message->id; } else { ent->txb0.bit.ID = message->id << 18; // short addresses are left-justified } diff --git a/ports/atmel-samd/common-hal/canio/Listener.c b/ports/atmel-samd/common-hal/canio/Listener.c index bf8b3288dc..02cfde9cc8 100644 --- a/ports/atmel-samd/common-hal/canio/Listener.c +++ b/ports/atmel-samd/common-hal/canio/Listener.c @@ -358,15 +358,15 @@ bool common_hal_canio_listener_readinto(canio_listener_obj_t *self, canio_messag } while (!common_hal_canio_listener_in_waiting(self)); } int index = self->hw->RXFS.bit.F0GI; - canio_can_fifo_t *hw_message = &self->fifo[index]; - message->extended = hw_message->rxb0.bit.XTD; + canio_can_rx_fifo_t *hw_message = &self->fifo[index]; + message->extended = hw_message->rxf0.bit.XTD; if (message->extended) { - message->id = hw_message->rxb0.bit.ID; + message->id = hw_message->rxf0.bit.ID; } else { - message->id = hw_message->rxb0.bit.ID >> 18; // short addresses are left-justified + message->id = hw_message->rxf0.bit.ID >> 18; // short addresses are left-justified } - message->rtr = hw_message->rxb0.bit.RTR; - message->size = hw_message->rxb1.bit.DLC; + message->rtr = hw_message->rxf0.bit.RTR; + message->size = hw_message->rxf1.bit.DLC; if (!message->rtr) { memcpy(message->data, hw_message->data, message->size); } diff --git a/ports/atmel-samd/common-hal/canio/Listener.h b/ports/atmel-samd/common-hal/canio/Listener.h index a51a9fc379..1b81d82aa6 100644 --- a/ports/atmel-samd/common-hal/canio/Listener.h +++ b/ports/atmel-samd/common-hal/canio/Listener.h @@ -38,7 +38,7 @@ typedef struct { typedef struct { mp_obj_base_t base; canio_can_obj_t *can; - canio_can_fifo_t *fifo; + canio_can_rx_fifo_t *fifo; canio_rxfifo_reg_t *hw; uint32_t timeout_ms; uint8_t fifo_idx; diff --git a/ports/atmel-samd/common-hal/canio/__init__.h b/ports/atmel-samd/common-hal/canio/__init__.h index cb491ab9e6..32adc5bf96 100644 --- a/ports/atmel-samd/common-hal/canio/__init__.h +++ b/ports/atmel-samd/common-hal/canio/__init__.h @@ -42,26 +42,25 @@ typedef struct canio_listener canio_listener_t; typedef struct canio_can canio_can_t; typedef struct { - union { - CAN_RXBE_0_Type rxb0; - CAN_TXBE_0_Type txb0; - CAN_RXF0E_0_Type rxf0; - }; - union { - CAN_RXBE_1_Type rxb1; - CAN_TXBE_1_Type txb1; - CAN_RXF0E_1_Type rxf1; - }; + CAN_TXBE_0_Type txb0; + CAN_TXBE_1_Type txb1; COMPILER_ALIGNED(4) uint8_t data[COMMON_HAL_CANIO_MAX_MESSAGE_LENGTH]; -} canio_can_fifo_t; +} canio_can_tx_buffer_t; + +typedef struct { + CAN_RXF0E_0_Type rxf0; + CAN_RXF0E_1_Type rxf1; + COMPILER_ALIGNED(4) + uint8_t data[COMMON_HAL_CANIO_MAX_MESSAGE_LENGTH]; +} canio_can_rx_fifo_t; typedef uint32_t canio_can_filter_t; typedef struct { - canio_can_fifo_t tx_fifo[COMMON_HAL_CANIO_TX_FIFO_SIZE]; - canio_can_fifo_t rx0_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; - canio_can_fifo_t rx1_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; + canio_can_tx_buffer_t tx_buffer[COMMON_HAL_CANIO_TX_FIFO_SIZE]; + canio_can_rx_fifo_t rx0_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; + canio_can_rx_fifo_t rx1_fifo[COMMON_HAL_CANIO_RX_FIFO_SIZE]; CanMramSidfe standard_rx_filter[COMMON_HAL_CANIO_RX_FILTER_SIZE]; CanMramXifde extended_rx_filter[COMMON_HAL_CANIO_RX_FILTER_SIZE]; } canio_can_state_t; From 9fd9cf1138817184399f381aacfc4aa1c4b16b76 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Sep 2020 09:36:47 -0500 Subject: [PATCH 38/55] canio: fix bugs in shared-bindings --- shared-bindings/canio/CAN.c | 4 ++-- shared-bindings/canio/Listener.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shared-bindings/canio/CAN.c b/shared-bindings/canio/CAN.c index 482d11546d..ff27bb2048 100644 --- a/shared-bindings/canio/CAN.c +++ b/shared-bindings/canio/CAN.c @@ -64,7 +64,7 @@ //| ... //| STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_rx, ARG_tx, ARG_baudrate, ARG_loopback, ARG_silent, ARG_auto_restart, NUM_ARGS }; + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_loopback, ARG_silent, ARG_auto_restart, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_tx, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_rx, MP_ARG_OBJ | MP_ARG_REQUIRED }, @@ -380,7 +380,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_deinit_obj, canio_can_deinit); STATIC mp_obj_t canio_can_enter(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); - return mp_const_none; + return self_in; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_enter_obj, canio_can_enter); diff --git a/shared-bindings/canio/Listener.c b/shared-bindings/canio/Listener.c index 137c9e590a..bca880880d 100644 --- a/shared-bindings/canio/Listener.c +++ b/shared-bindings/canio/Listener.c @@ -133,7 +133,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_deinit_obj, canio_listener_deini STATIC mp_obj_t canio_listener_enter(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); - return mp_const_none; + return self_in; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_enter_obj, canio_listener_enter); From 82f37c92520248cef5086ac62a8483ae087e4531 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Sep 2020 10:28:25 -0500 Subject: [PATCH 39/55] canio: fix read(), iterable bindings --- shared-bindings/canio/Listener.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/shared-bindings/canio/Listener.c b/shared-bindings/canio/Listener.c index bca880880d..1f4176f0c0 100644 --- a/shared-bindings/canio/Listener.c +++ b/shared-bindings/canio/Listener.c @@ -50,7 +50,7 @@ STATIC mp_obj_t canio_listener_read(mp_obj_t self_in) { common_hal_canio_listener_check_for_deinit(self); canio_message_obj_t *message = m_new_obj(canio_message_obj_t); - self->base.type = &canio_message_type; + message->base.type = &canio_message_type; if (common_hal_canio_listener_readinto(self, message)) { return message; @@ -92,13 +92,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_in_waiting_obj, canio_listener_i //| """Returns self, unless the object is deinitialized""" //| ... //| -STATIC mp_obj_t canio_listener_iter(mp_obj_t self_in) { - canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_canio_listener_check_for_deinit(self); - return self; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_iter_obj, canio_listener_iter); - //| def __next__(self): //| """Reads a message, after waiting up to self.timeout seconds //| @@ -106,14 +99,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_iter_obj, canio_listener_iter); //| a Message is returned.""" //| ... //| -STATIC mp_obj_t canio_listener_next(mp_obj_t self_in) { +STATIC mp_obj_t canio_iternext(mp_obj_t self_in) { mp_obj_t result = canio_listener_read(self_in); if (result == mp_const_none) { return MP_OBJ_STOP_ITERATION; } return result; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_next_obj, canio_listener_next); //| def deinit(self) -> None: //| """Deinitialize this object, freeing its hardware resources""" @@ -176,8 +168,6 @@ STATIC const mp_obj_property_t canio_listener_timeout_obj = { STATIC const mp_rom_map_elem_t canio_listener_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&canio_listener_enter_obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&canio_listener_exit_obj) }, - { MP_ROM_QSTR(MP_QSTR___iter__), MP_ROM_PTR(&canio_listener_iter_obj) }, - { MP_ROM_QSTR(MP_QSTR___next__), MP_ROM_PTR(&canio_listener_next_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&canio_listener_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&canio_listener_in_waiting_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&canio_listener_read_obj) }, @@ -189,5 +179,7 @@ STATIC MP_DEFINE_CONST_DICT(canio_listener_locals_dict, canio_listener_locals_di const mp_obj_type_t canio_listener_type = { { &mp_type_type }, .name = MP_QSTR_Listener, + .getiter = mp_identity_getiter, + .iternext = canio_iternext, .locals_dict = (mp_obj_dict_t*)&canio_listener_locals_dict, }; From c2d6405feabcae0de6fe3f0838d885ab9ca68a7e Mon Sep 17 00:00:00 2001 From: Szymon Jakubiak Date: Tue, 22 Sep 2020 07:40:34 +0000 Subject: [PATCH 40/55] Translated using Weblate (Polish) Currently translated at 73.3% (587 of 800 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pl/ --- locale/pl.po | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/locale/pl.po b/locale/pl.po index 2528b25e6f..857d09b9c2 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-16 17:07-0700\n" -"PO-Revision-Date: 2020-09-17 17:58+0000\n" -"Last-Translator: Maciej Stankiewicz \n" +"PO-Revision-Date: 2020-09-22 13:32+0000\n" +"Last-Translator: Szymon Jakubiak \n" "Language-Team: pl\n" "Language: pl\n" "MIME-Version: 1.0\n" @@ -32,6 +32,9 @@ msgid "" "Please file an issue with the contents of your CIRCUITPY drive at \n" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" +"\n" +"Zgłoś problem z zawartością dysku CIRCUITPY pod adresem\n" +"https://github.com/adafruit/circuitpython/issues\n" #: py/obj.c msgid " File \"%q\"" @@ -57,7 +60,7 @@ msgstr "" #: ports/atmel-samd/common-hal/sdioio/SDCard.c msgid "%q failure: %d" -msgstr "" +msgstr "%q niepowodzenie: %d" #: shared-bindings/microcontroller/Pin.c msgid "%q in use" From cabd7539d3c7abab7f1ebc34c82771e92592e5e7 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 22 Sep 2020 21:40:01 +0200 Subject: [PATCH 41/55] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 36 ++++++++++++++++++++++++++++++++---- locale/cs.po | 36 ++++++++++++++++++++++++++++++++---- locale/de_DE.po | 36 ++++++++++++++++++++++++++++++++---- locale/el.po | 36 ++++++++++++++++++++++++++++++++---- locale/es.po | 36 ++++++++++++++++++++++++++++++++---- locale/fil.po | 36 ++++++++++++++++++++++++++++++++---- locale/fr.po | 36 ++++++++++++++++++++++++++++++++---- locale/hi.po | 36 ++++++++++++++++++++++++++++++++---- locale/it_IT.po | 36 ++++++++++++++++++++++++++++++++---- locale/ja.po | 36 ++++++++++++++++++++++++++++++++---- locale/ko.po | 36 ++++++++++++++++++++++++++++++++---- locale/nl.po | 36 ++++++++++++++++++++++++++++++++---- locale/pl.po | 36 ++++++++++++++++++++++++++++++++---- locale/pt_BR.po | 36 ++++++++++++++++++++++++++++++++---- locale/sv.po | 36 ++++++++++++++++++++++++++++++++---- locale/zh_Latn_pinyin.po | 36 ++++++++++++++++++++++++++++++++---- 16 files changed, 512 insertions(+), 64 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index a13d97f9ec..bce444da2e 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-07-06 18:10+0000\n" "Last-Translator: oon arfiandwi \n" "Language-Team: LANGUAGE \n" @@ -96,7 +96,11 @@ msgstr "%q harus >= 1" msgid "%q must be a tuple of length 2" msgstr "%q harus berupa tuple dengan panjang 2" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "pin %q tidak valid" @@ -284,6 +288,10 @@ msgstr "Jenis alamat di luar batas" msgid "All I2C peripherals are in use" msgstr "Semua perangkat I2C sedang digunakan" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Semua perangkat SPI sedang digunakan" @@ -320,6 +328,10 @@ msgstr "Semua timer sedang digunakan" msgid "Already advertising." msgstr "Sudah disebarkan." +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -770,7 +782,7 @@ msgstr "Channel EXTINT sedang digunakan" msgid "Error in regex" msgstr "Error pada regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -863,6 +875,10 @@ msgstr "Gagal menulis flash internal." msgid "File exists" msgstr "File sudah ada" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1148,6 +1164,10 @@ msgstr "Pin MOSI gagal inisialisasi." msgid "Maximum x value when mirrored is %d" msgstr "Nilai x maksimum ketika dicerminkan adalah %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "Lompatan NLR MicroPython gagal. Kemungkinan kerusakan memori." @@ -2343,6 +2363,10 @@ msgstr "error = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -3181,6 +3205,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3296,7 +3324,7 @@ msgid "tuple/list has wrong length" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx dan rx keduanya tidak boleh kosong" diff --git a/locale/cs.po b/locale/cs.po index 8d0827b9a1..f96a054118 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-05-24 03:22+0000\n" "Last-Translator: dronecz \n" "Language-Team: LANGUAGE \n" @@ -96,7 +96,11 @@ msgstr " %q musí být > = 1" msgid "%q must be a tuple of length 2" msgstr " %q musí být n-tice délky 2" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -284,6 +288,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "" @@ -320,6 +328,10 @@ msgstr "" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -756,7 +768,7 @@ msgstr "" msgid "Error in regex" msgstr "" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -849,6 +861,10 @@ msgstr "" msgid "File exists" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1131,6 +1147,10 @@ msgstr "" msgid "Maximum x value when mirrored is %d" msgstr "" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2314,6 +2334,10 @@ msgstr "" msgid "exceptions must derive from BaseException" msgstr "" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -3151,6 +3175,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3265,7 +3293,7 @@ msgid "tuple/list has wrong length" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index b1eefc98e8..81d24c818c 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-06-16 18:24+0000\n" "Last-Translator: Andreas Buchen \n" "Language: de_DE\n" @@ -95,7 +95,11 @@ msgstr "%q muss >= 1 sein" msgid "%q must be a tuple of length 2" msgstr "%q muss ein Tupel der Länge 2 sein" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -283,6 +287,10 @@ msgstr "Adresstyp außerhalb des zulässigen Bereichs" msgid "All I2C peripherals are in use" msgstr "Alle I2C-Peripheriegeräte sind in Benutzung" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Alle SPI-Peripheriegeräte sind in Benutzung" @@ -319,6 +327,10 @@ msgstr "Alle timer werden benutzt" msgid "Already advertising." msgstr "Bereits am anbieten (advertising)." +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -766,7 +778,7 @@ msgstr "EXTINT Kanal ist schon in Benutzung" msgid "Error in regex" msgstr "Fehler in regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -860,6 +872,10 @@ msgstr "Interner Flash konnte nicht geschrieben werden." msgid "File exists" msgstr "Datei existiert" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1148,6 +1164,10 @@ msgstr "MOSI pin Initialisierung fehlgeschlagen." msgid "Maximum x value when mirrored is %d" msgstr "Maximaler x-Wert beim Spiegeln ist %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2384,6 +2404,10 @@ msgstr "Fehler = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "Exceptions müssen von BaseException abgeleitet sein" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "erwarte ':' nach format specifier" @@ -3234,6 +3258,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "start/end Indizes" @@ -3349,7 +3377,7 @@ msgid "tuple/list has wrong length" msgstr "tupel/list hat falsche Länge" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" diff --git a/locale/el.po b/locale/el.po index acdb64d5a5..1f830deb42 100644 --- a/locale/el.po +++ b/locale/el.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -91,7 +91,11 @@ msgstr "" msgid "%q must be a tuple of length 2" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -279,6 +283,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "" @@ -315,6 +323,10 @@ msgstr "" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -751,7 +763,7 @@ msgstr "" msgid "Error in regex" msgstr "" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -844,6 +856,10 @@ msgstr "" msgid "File exists" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1126,6 +1142,10 @@ msgstr "" msgid "Maximum x value when mirrored is %d" msgstr "" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2309,6 +2329,10 @@ msgstr "" msgid "exceptions must derive from BaseException" msgstr "" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -3146,6 +3170,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3260,7 +3288,7 @@ msgid "tuple/list has wrong length" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" diff --git a/locale/es.po b/locale/es.po index 990908b7c3..a1be03bfc1 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-09-18 23:14+0000\n" "Last-Translator: Alvaro Figueroa \n" "Language-Team: \n" @@ -99,7 +99,11 @@ msgstr "%q debe ser >= 1" msgid "%q must be a tuple of length 2" msgstr "%q debe ser una tupla de longitud 2" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "pin inválido %q" @@ -287,6 +291,10 @@ msgstr "Tipo de dirección fuera de rango" msgid "All I2C peripherals are in use" msgstr "Todos los periféricos I2C están siendo usados" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Todos los periféricos SPI están siendo usados" @@ -325,6 +333,10 @@ msgstr "Todos los timers en uso" msgid "Already advertising." msgstr "Ya se encuentra publicando." +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -771,7 +783,7 @@ msgstr "El canal EXTINT ya está siendo utilizado" msgid "Error in regex" msgstr "Error en regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -864,6 +876,10 @@ msgstr "Error al escribir al flash interno." msgid "File exists" msgstr "El archivo ya existe" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "Sin capacidades para el formato" @@ -1149,6 +1165,10 @@ msgstr "MOSI pin init fallido." msgid "Maximum x value when mirrored is %d" msgstr "Valor máximo de x cuando se refleja es %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "MicroPython NLR jump falló. Probable corrupción de la memoria." @@ -2377,6 +2397,10 @@ msgstr "error = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "las excepciones deben derivar de BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "se esperaba ':' después de un especificador de tipo format" @@ -3222,6 +3246,10 @@ msgstr "sosfilt requiere argumentos iterables" msgid "source palette too large" msgstr "paleta fuente muy larga" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "índices inicio/final" @@ -3337,7 +3365,7 @@ msgid "tuple/list has wrong length" msgstr "tupla/lista tiene una longitud incorrecta" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "Ambos tx y rx no pueden ser None" diff --git a/locale/fil.po b/locale/fil.po index 6ef8829981..a53dd4c6a0 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -91,7 +91,11 @@ msgstr "aarehas na haba dapat ang buffer slices" msgid "%q must be a tuple of length 2" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -281,6 +285,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "Lahat ng I2C peripherals ginagamit" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Lahat ng SPI peripherals ay ginagamit" @@ -318,6 +326,10 @@ msgstr "Lahat ng timer ginagamit" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -762,7 +774,7 @@ msgstr "Ginagamit na ang EXTINT channel" msgid "Error in regex" msgstr "May pagkakamali sa REGEX" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -857,6 +869,10 @@ msgstr "" msgid "File exists" msgstr "Mayroong file" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1141,6 +1157,10 @@ msgstr "Hindi ma-initialize ang MOSI pin." msgid "Maximum x value when mirrored is %d" msgstr "" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2353,6 +2373,10 @@ msgstr "" msgid "exceptions must derive from BaseException" msgstr "ang mga exceptions ay dapat makuha mula sa BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "umaasa ng ':' pagkatapos ng format specifier" @@ -3199,6 +3223,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "start/end indeks" @@ -3315,7 +3343,7 @@ msgid "tuple/list has wrong length" msgstr "mali ang haba ng tuple/list" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" diff --git a/locale/fr.po b/locale/fr.po index d4a68c3f48..31881c873b 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-09-16 13:47+0000\n" "Last-Translator: Hugo Dahl \n" "Language: fr\n" @@ -100,7 +100,11 @@ msgstr "%q doit être >=1" msgid "%q must be a tuple of length 2" msgstr "%q doit être un tuple de longueur 2" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "PIN %q invalide" @@ -288,6 +292,10 @@ msgstr "Type d'adresse hors plage" msgid "All I2C peripherals are in use" msgstr "Tous les périphériques I2C sont utilisés" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Tous les périphériques SPI sont utilisés" @@ -324,6 +332,10 @@ msgstr "Tous les timers sont utilisés" msgid "Already advertising." msgstr "S'annonce déjà." +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -775,7 +787,7 @@ msgstr "Canal EXTINT déjà utilisé" msgid "Error in regex" msgstr "Erreur dans l'expression régulière" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -869,6 +881,10 @@ msgstr "Échec de l'écriture du flash interne." msgid "File exists" msgstr "Le fichier existe" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1154,6 +1170,10 @@ msgstr "Echec de l'init. de la broche MOSI." msgid "Maximum x value when mirrored is %d" msgstr "La valeur max. de x est %d lors d'une opération miroir" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "Le saut MicroPython NLR a échoué. Altération probable de la mémoire." @@ -2390,6 +2410,10 @@ msgstr "erreur = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "les exceptions doivent dériver de 'BaseException'" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "':' attendu après la spécification de format" @@ -3242,6 +3266,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "indices de début/fin" @@ -3357,7 +3385,7 @@ msgid "tuple/list has wrong length" msgstr "tuple/liste a une mauvaise longueur" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx et rx ne peuvent être 'None' tous les deux" diff --git a/locale/hi.po b/locale/hi.po index b2a4bccafe..c6fbe49fd5 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -91,7 +91,11 @@ msgstr "" msgid "%q must be a tuple of length 2" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -279,6 +283,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "" @@ -315,6 +323,10 @@ msgstr "" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -751,7 +763,7 @@ msgstr "" msgid "Error in regex" msgstr "" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -844,6 +856,10 @@ msgstr "" msgid "File exists" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1126,6 +1142,10 @@ msgstr "" msgid "Maximum x value when mirrored is %d" msgstr "" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2309,6 +2329,10 @@ msgstr "" msgid "exceptions must derive from BaseException" msgstr "" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -3146,6 +3170,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3260,7 +3288,7 @@ msgid "tuple/list has wrong length" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 146e4ced14..94c7f1f847 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -91,7 +91,11 @@ msgstr "slice del buffer devono essere della stessa lunghezza" msgid "%q must be a tuple of length 2" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -280,6 +284,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Tutte le periferiche SPI sono in uso" @@ -317,6 +325,10 @@ msgstr "Tutti i timer utilizzati" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -762,7 +774,7 @@ msgstr "Canale EXTINT già in uso" msgid "Error in regex" msgstr "Errore nella regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -857,6 +869,10 @@ msgstr "" msgid "File exists" msgstr "File esistente" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1144,6 +1160,10 @@ msgstr "inizializzazione del pin MOSI fallita." msgid "Maximum x value when mirrored is %d" msgstr "Valore massimo di x quando rispachiato è %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2354,6 +2374,10 @@ msgstr "errore = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "le eccezioni devono derivare da BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "':' atteso dopo lo specificatore di formato" @@ -3206,6 +3230,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3322,7 +3350,7 @@ msgid "tuple/list has wrong length" msgstr "tupla/lista ha la lunghezza sbagliata" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx e rx non possono essere entrambi None" diff --git a/locale/ja.po b/locale/ja.po index cd0ae7b50f..6bc29b069f 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-09-01 18:44+0000\n" "Last-Translator: Jeff Epler \n" "Language-Team: none\n" @@ -98,7 +98,11 @@ msgstr "%qは1以上でなければなりません" msgid "%q must be a tuple of length 2" msgstr "%qは長さ2のタプルでなければなりません" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "%q ピンは無効" @@ -287,6 +291,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "全てのI2C周辺機器が使用中" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "全てのSPI周辺機器が使用中" @@ -323,6 +331,10 @@ msgstr "全てのタイマーが使用中" msgid "Already advertising." msgstr "すでにアドバータイズ中" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -765,7 +777,7 @@ msgstr "EXTINTチャネルはすでに使用されています" msgid "Error in regex" msgstr "正規表現にエラーがあります" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -858,6 +870,10 @@ msgstr "内部フラッシュの書き込みに失敗" msgid "File exists" msgstr "ファイルが存在します" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1142,6 +1158,10 @@ msgstr "MOSIピンの初期化に失敗" msgid "Maximum x value when mirrored is %d" msgstr "" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "MicroPythonのNLRジャンプに失敗。メモリ破壊の可能性あり" @@ -2339,6 +2359,10 @@ msgstr "error = 0x1%08lX" msgid "exceptions must derive from BaseException" msgstr "例外はBaseExceptionから派生していなければなりません" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "書式化指定子の後に':'が必要" @@ -3179,6 +3203,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3293,7 +3321,7 @@ msgid "tuple/list has wrong length" msgstr "タプル/リストの長さが正しくありません" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "txとrxを両方ともNoneにできません" diff --git a/locale/ko.po b/locale/ko.po index 4072553a60..e2214b2bf5 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2019-05-06 14:22-0700\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" @@ -92,7 +92,11 @@ msgstr "%q 는 >=1이어야합니다" msgid "%q must be a tuple of length 2" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -280,6 +284,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "사용중인 모든 I2C주변 기기" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "사용중인 모든 SPI주변 기기" @@ -316,6 +324,10 @@ msgstr "모든 타이머가 사용 중입니다" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -754,7 +766,7 @@ msgstr "" msgid "Error in regex" msgstr "Regex에 오류가 있습니다." -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -847,6 +859,10 @@ msgstr "" msgid "File exists" msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1129,6 +1145,10 @@ msgstr "" msgid "Maximum x value when mirrored is %d" msgstr "" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2313,6 +2333,10 @@ msgstr "" msgid "exceptions must derive from BaseException" msgstr "" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "':'이 예상되었습니다" @@ -3150,6 +3174,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "" @@ -3264,7 +3292,7 @@ msgid "tuple/list has wrong length" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index d74a2e07d0..567734f19f 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-09-09 16:05+0000\n" "Last-Translator: Jelle Jager \n" "Language-Team: none\n" @@ -96,7 +96,11 @@ msgstr "%q moet >= 1 zijn" msgid "%q must be a tuple of length 2" msgstr "%q moet een tuple van lengte 2 zijn" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "%q pin onjuist" @@ -284,6 +288,10 @@ msgstr "Adres type buiten bereik" msgid "All I2C peripherals are in use" msgstr "Alle I2C peripherals zijn in gebruik" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Alle SPI peripherals zijn in gebruik" @@ -320,6 +328,10 @@ msgstr "Alle timers zijn in gebruik" msgid "Already advertising." msgstr "Advertising is al bezig." +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -764,7 +776,7 @@ msgstr "EXTINT kanaal al in gebruik" msgid "Error in regex" msgstr "Fout in regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -857,6 +869,10 @@ msgstr "Schrijven naar interne flash mislukt." msgid "File exists" msgstr "Bestand bestaat" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1143,6 +1159,10 @@ msgstr "MOSI pin init mislukt." msgid "Maximum x value when mirrored is %d" msgstr "Maximale x waarde indien gespiegeld is %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "MicroPython NLR sprong mislukt. Waarschijnlijk geheugen corruptie." @@ -2365,6 +2385,10 @@ msgstr "fout = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "uitzonderingen moeten afleiden van BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "verwachtte ':' na format specifier" @@ -3209,6 +3233,10 @@ msgstr "sosfilt vereist itereerbare argumenten" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "start/stop indices" @@ -3323,7 +3351,7 @@ msgid "tuple/list has wrong length" msgstr "tuple of lijst heeft onjuiste lengte" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx en rx kunnen niet beiden None zijn" diff --git a/locale/pl.po b/locale/pl.po index 857d09b9c2..0538f61784 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-09-22 13:32+0000\n" "Last-Translator: Szymon Jakubiak \n" "Language-Team: pl\n" @@ -98,7 +98,11 @@ msgstr "%q musi być >= 1" msgid "%q must be a tuple of length 2" msgstr "%q musi być krotką o długości 2" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -286,6 +290,10 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "Wszystkie peryferia I2C w użyciu" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Wszystkie peryferia SPI w użyciu" @@ -322,6 +330,10 @@ msgstr "Wszystkie timery w użyciu" msgid "Already advertising." msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -764,7 +776,7 @@ msgstr "Kanał EXTINT w użyciu" msgid "Error in regex" msgstr "Błąd w regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -857,6 +869,10 @@ msgstr "Nie udało się zapisać wewnętrznej pamięci flash." msgid "File exists" msgstr "Plik istnieje" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1141,6 +1157,10 @@ msgstr "Nie powiodło się ustawienie pinu MOSI." msgid "Maximum x value when mirrored is %d" msgstr "Największa wartość x przy odwróceniu to %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -2332,6 +2352,10 @@ msgstr "błąd = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "wyjątki muszą dziedziczyć po BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "oczekiwano ':' po specyfikacji formatu" @@ -3171,6 +3195,10 @@ msgstr "" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "początkowe/końcowe indeksy" @@ -3285,7 +3313,7 @@ msgid "tuple/list has wrong length" msgstr "krotka/lista ma złą długość" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx i rx nie mogą być oba None" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 2574786db8..e4d5a5afe9 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-09-19 17:41+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" @@ -96,7 +96,11 @@ msgstr "%q deve ser >= 1" msgid "%q must be a tuple of length 2" msgstr "%q deve ser uma tupla de comprimento 2" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "%q pino inválido" @@ -288,6 +292,10 @@ msgstr "O tipo do endereço está fora do alcance" msgid "All I2C peripherals are in use" msgstr "Todos os periféricos I2C estão em uso" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Todos os periféricos SPI estão em uso" @@ -324,6 +332,10 @@ msgstr "Todos os temporizadores em uso" msgid "Already advertising." msgstr "Já está anunciando." +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -773,7 +785,7 @@ msgstr "Canal EXTINT em uso" msgid "Error in regex" msgstr "Erro no regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -866,6 +878,10 @@ msgstr "Falha ao gravar o flash interno." msgid "File exists" msgstr "Arquivo já existe" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "O formato não é suportado" @@ -1152,6 +1168,10 @@ msgstr "Inicialização do pino MOSI falhou." msgid "Maximum x value when mirrored is %d" msgstr "O valor máximo de x quando espelhado é %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "O salto do MicroPython NLR falhou. Possível corrupção de memória." @@ -2388,6 +2408,10 @@ msgstr "erro = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "as exceções devem derivar a partir do BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "é esperado ':' após o especificador do formato" @@ -3237,6 +3261,10 @@ msgstr "o sosfilt requer que os argumentos sejam iteráveis" msgid "source palette too large" msgstr "a paleta de origem é muito grande" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "os índices de início/fim" @@ -3351,7 +3379,7 @@ msgid "tuple/list has wrong length" msgstr "a tupla/lista está com tamanho incorreto" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" diff --git a/locale/sv.po b/locale/sv.po index a88c91b532..f2b7cae3e2 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2020-09-07 19:36+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" @@ -96,7 +96,11 @@ msgstr "%q måste vara >= 1" msgid "%q must be a tuple of length 2" msgstr "%q måste vara en tuple av längd 2" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "Pinne %q ogiltig" @@ -284,6 +288,10 @@ msgstr "Adresstyp utanför intervallet" msgid "All I2C peripherals are in use" msgstr "All I2C-kringutrustning används" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "All SPI-kringutrustning används" @@ -320,6 +328,10 @@ msgstr "Alla timers används" msgid "Already advertising." msgstr "Annonserar redan." +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -764,7 +776,7 @@ msgstr "EXTINT-kanalen används redan" msgid "Error in regex" msgstr "Fel i regex" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -857,6 +869,10 @@ msgstr "Det gick inte att skriva till intern flash." msgid "File exists" msgstr "Filen finns redan" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1141,6 +1157,10 @@ msgstr "init för MOSI-pinne misslyckades." msgid "Maximum x value when mirrored is %d" msgstr "Maximum x-värde vid spegling är %d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "MicroPython NLR jump misslyckades. Troligen korrupt minne." @@ -2361,6 +2381,10 @@ msgstr "fel = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "exceptions måste ärvas från BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "förväntade ':' efter formatspecifikation" @@ -3204,6 +3228,10 @@ msgstr "sosfilt kräver iterable argument" msgid "source palette too large" msgstr "källpalett för stor" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "start-/slutindex" @@ -3318,7 +3346,7 @@ msgid "tuple/list has wrong length" msgstr "tupel/lista har fel längd" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx och rx kan inte båda vara None" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index de19d2b602..780f5be222 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -97,7 +97,11 @@ msgstr "%q bìxū dàyú huò děngyú 1" msgid "%q must be a tuple of length 2" msgstr "%q bìxū shì chángdù wèi 2 de yuán zǔ" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: shared-bindings/canio/Match.c +msgid "%q out of range" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "%q yǐn jiǎo wúxiào" @@ -285,6 +289,10 @@ msgstr "Dìzhǐ lèixíng chāochū fànwéi" msgid "All I2C peripherals are in use" msgstr "Suǒyǒu I2C wàiwéi qì zhèngzài shǐyòng" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" msgstr "Suǒyǒu SPI wàiwéi qì zhèngzài shǐyòng" @@ -321,6 +329,10 @@ msgstr "Suǒyǒu jìshí qì shǐyòng" msgid "Already advertising." msgstr "Mùqián zhèngzài guǎngbò" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" @@ -761,7 +773,7 @@ msgstr "EXTINT píndào yǐjīng shǐyòng" msgid "Error in regex" msgstr "Zhèngzé biǎodá shì cuòwù" -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c +#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c #: shared-bindings/terminalio/Terminal.c @@ -854,6 +866,10 @@ msgstr "Wúfǎ xiě rù nèibù shǎncún." msgid "File exists" msgstr "Wénjiàn cúnzài" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1138,6 +1154,10 @@ msgstr "MOSI yǐn jiǎo shūrù shībài." msgid "Maximum x value when mirrored is %d" msgstr "Jìngxiàng shí de zuìdà X zhí wèi%d" +#: shared-bindings/canio/Message.c +msgid "Messages limited to 8 bytes" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "MicroPython NLR tiào zhuǎn shībài. Kěnéng shì nèicún sǔnhuài." @@ -2351,6 +2371,10 @@ msgstr "cuòwù = 0x%08lX" msgid "exceptions must derive from BaseException" msgstr "lìwài bìxū láizì BaseException" +#: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c +msgid "expected '%q' but got '%q'" +msgstr "" + #: py/objstr.c msgid "expected ':' after format specifier" msgstr "zài géshì shuōmíng fú zhīhòu yùqí ':'" @@ -3192,6 +3216,10 @@ msgstr "sosfilt xūyào diédài cānshù" msgid "source palette too large" msgstr "" +#: shared-bindings/canio/Message.c +msgid "specify size or data, but not both" +msgstr "" + #: py/objstr.c msgid "start/end indices" msgstr "kāishǐ/jiéshù zhǐshù" @@ -3306,7 +3334,7 @@ msgid "tuple/list has wrong length" msgstr "yuán zǔ/lièbiǎo chángdù cuòwù" #: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: shared-bindings/busio/UART.c +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx hé rx bùnéng dōu shì wú" From 28e80e47d708fe346be0ae8d430f1a86d5d3049b Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 22 Sep 2020 17:38:58 -0500 Subject: [PATCH 42/55] makeqstrdefs: don't make _and_, _or_ poisoned substrings for QSTRs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New contributor @mdroberts1243 encountered an interesting problem in which the argument they had named "column_underscore_and_page_addressing" simply couldn't be used; I discovered that internally this had been transformed into "column_underscore∧page_addressing", because QSTR makes _ENTITY_ stand for the same thing as &ENTITY; does in HTML. This might be nice for some things, but we don't want it here! I was unable to find a sensible way to "escape" and prevent this entity coding, so instead I ripped out support for the _and_ and _or_ escapes. --- py/makeqstrdefs.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py index cb27ced356..d3e90ba486 100644 --- a/py/makeqstrdefs.py +++ b/py/makeqstrdefs.py @@ -57,6 +57,10 @@ name2codepoint['caret'] = ord('^') name2codepoint['pipe'] = ord('|') name2codepoint['tilde'] = ord('~') +# These are just vexing! +del name2codepoint['and'] +del name2codepoint['or'] + def write_out(fname, output): if output: for m, r in [("/", "__"), ("\\", "__"), (":", "@"), ("..", "@@")]: From 5384479a619b0bfbf6d3a184d43108936558869e Mon Sep 17 00:00:00 2001 From: lady ada Date: Tue, 22 Sep 2020 23:28:23 -0400 Subject: [PATCH 43/55] fix pins for rev C --- ports/atmel-samd/boards/qtpy_m0/board.c | 6 +++--- ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h | 8 ++++---- ports/atmel-samd/boards/qtpy_m0/pins.c | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ports/atmel-samd/boards/qtpy_m0/board.c b/ports/atmel-samd/boards/qtpy_m0/board.c index 2add1867c0..499be113f1 100644 --- a/ports/atmel-samd/boards/qtpy_m0/board.c +++ b/ports/atmel-samd/boards/qtpy_m0/board.c @@ -30,9 +30,9 @@ #include "hal/include/hal_gpio.h" void board_init(void) { - gpio_set_pin_function(PIN_PA18, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(PIN_PA18, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA18, true); // Turn on neopixel by default + gpio_set_pin_function(PIN_PA15, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(PIN_PA15, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA15, true); // Turn on neopixel by default } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h index a88c1992de..713d2c03eb 100644 --- a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.h @@ -1,7 +1,7 @@ #define MICROPY_HW_BOARD_NAME "Adafruit QT Py M0" #define MICROPY_HW_MCU_NAME "samd21e18" -#define MICROPY_HW_NEOPIXEL (&pin_PA19) +#define MICROPY_HW_NEOPIXEL (&pin_PA18) #define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) @@ -9,9 +9,9 @@ #define IGNORE_PIN_PA00 1 #define IGNORE_PIN_PA01 1 -#define IGNORE_PIN_PA09 1 #define IGNORE_PIN_PA12 1 #define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 #define IGNORE_PIN_PA20 1 #define IGNORE_PIN_PA21 1 // USB is always used internally so skip the pin objects for it. @@ -48,8 +48,8 @@ #define DEFAULT_I2C_BUS_SDA (&pin_PA16) #define DEFAULT_SPI_BUS_SCK (&pin_PA11) -#define DEFAULT_SPI_BUS_MOSI (&pin_PA08) -#define DEFAULT_SPI_BUS_MISO (&pin_PA10) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA09) #define DEFAULT_UART_BUS_RX (&pin_PA07) #define DEFAULT_UART_BUS_TX (&pin_PA06) diff --git a/ports/atmel-samd/boards/qtpy_m0/pins.c b/ports/atmel-samd/boards/qtpy_m0/pins.c index 4ac10a7a66..636c48bffc 100644 --- a/ports/atmel-samd/boards/qtpy_m0/pins.c +++ b/ports/atmel-samd/boards/qtpy_m0/pins.c @@ -31,16 +31,16 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA11) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA10) }, - { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA10) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) }, - { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA08) }, - { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA08) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA10) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA19) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_PA15) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, From 9db7625717ffee90eac0a88b8c1b0a4e68256ec1 Mon Sep 17 00:00:00 2001 From: lady ada Date: Wed, 23 Sep 2020 11:19:01 -0400 Subject: [PATCH 44/55] neopix is default on! --- ports/atmel-samd/boards/qtpy_m0/board.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/boards/qtpy_m0/board.c b/ports/atmel-samd/boards/qtpy_m0/board.c index 499be113f1..1a65a561f7 100644 --- a/ports/atmel-samd/boards/qtpy_m0/board.c +++ b/ports/atmel-samd/boards/qtpy_m0/board.c @@ -33,6 +33,7 @@ void board_init(void) { gpio_set_pin_function(PIN_PA15, GPIO_PIN_FUNCTION_OFF); gpio_set_pin_direction(PIN_PA15, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PA15, true); // Turn on neopixel by default + never_reset_pin_number(PIN_PA15); } bool board_requests_safe_mode(void) { From 00517b26009d6b721145995e40725625b5152afd Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Wed, 23 Sep 2020 11:39:39 -0400 Subject: [PATCH 45/55] Move missing pin warning to shared-bindings --- ports/esp32s2/common-hal/busio/SPI.c | 9 --------- ports/stm/common-hal/busio/SPI.c | 9 --------- shared-bindings/busio/SPI.c | 4 ++++ 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/ports/esp32s2/common-hal/busio/SPI.c b/ports/esp32s2/common-hal/busio/SPI.c index 6e4e344740..eaafa87b74 100644 --- a/ports/esp32s2/common-hal/busio/SPI.c +++ b/ports/esp32s2/common-hal/busio/SPI.c @@ -116,15 +116,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) { - //SCK is not optional. MOSI and MISO are - if (!clock) { - mp_raise_ValueError(translate("Must provide SCK pin")); - } - - if (!miso && !mosi) { - mp_raise_ValueError(translate("Must provide MISO or MOSI pin")); - } - spi_bus_config_t bus_config; bus_config.mosi_io_num = mosi != NULL ? mosi->number : -1; bus_config.miso_io_num = miso != NULL ? miso->number : -1; diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c index 913385e962..29fbdee569 100644 --- a/ports/stm/common-hal/busio/SPI.c +++ b/ports/stm/common-hal/busio/SPI.c @@ -127,15 +127,6 @@ STATIC int check_pins(busio_spi_obj_t *self, uint8_t mosi_len = MP_ARRAY_SIZE(mcu_spi_mosi_list); uint8_t miso_len = MP_ARRAY_SIZE(mcu_spi_miso_list); - //SCK is not optional. MOSI and MISO are - if (!sck) { - mp_raise_ValueError(translate("Must provide SCK pin")); - } - - if (!miso && !mosi) { - mp_raise_ValueError(translate("Must provide MISO or MOSI pin")); - } - // Loop over each possibility for SCK. Check whether MISO and/or MOSI can be used on the same peripheral for (uint i = 0; i < sck_len; i++) { const mcu_periph_obj_t *mcu_spi_sck = &mcu_spi_sck_list[i]; diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index aefe4f5a77..e47564c8c2 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -96,6 +96,10 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con const mcu_pin_obj_t* mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj); const mcu_pin_obj_t* miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj); + if (!miso && !mosi) { + mp_raise_ValueError(translate("Must provide MISO or MOSI pin")); + } + common_hal_busio_spi_construct(self, clock, mosi, miso); return MP_OBJ_FROM_PTR(self); } From c1830d62122604840a05007b823b021280c9aee1 Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Tue, 22 Sep 2020 20:25:34 +0000 Subject: [PATCH 46/55] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (807 of 807 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pt_BR/ --- locale/pt_BR.po | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index e4d5a5afe9..0f5885ccf5 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-21 16:45-0500\n" -"PO-Revision-Date: 2020-09-19 17:41+0000\n" +"PO-Revision-Date: 2020-09-22 21:30+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -98,7 +98,7 @@ msgstr "%q deve ser uma tupla de comprimento 2" #: shared-bindings/canio/Match.c msgid "%q out of range" -msgstr "" +msgstr "%q fora do alcance" #: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" @@ -294,7 +294,7 @@ msgstr "Todos os periféricos I2C estão em uso" #: ports/atmel-samd/common-hal/canio/Listener.c msgid "All RX FIFOs in use" -msgstr "" +msgstr "Todos os FIFOs RX estão em uso" #: ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" @@ -334,7 +334,7 @@ msgstr "Já está anunciando." #: ports/atmel-samd/common-hal/canio/Listener.c msgid "Already have all-matches listener" -msgstr "" +msgstr "Já há um ouvinte com todas as correspondências" #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -880,7 +880,7 @@ msgstr "Arquivo já existe" #: ports/atmel-samd/common-hal/canio/Listener.c msgid "Filters too complex" -msgstr "" +msgstr "Os filtros são muito complexos" #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" @@ -1170,7 +1170,7 @@ msgstr "O valor máximo de x quando espelhado é %d" #: shared-bindings/canio/Message.c msgid "Messages limited to 8 bytes" -msgstr "" +msgstr "As mensagens estão limitadas a 8 bytes" #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." @@ -2410,7 +2410,7 @@ msgstr "as exceções devem derivar a partir do BaseException" #: shared-bindings/canio/CAN.c shared-bindings/canio/Listener.c msgid "expected '%q' but got '%q'" -msgstr "" +msgstr "o retorno esperado era '%q', porém obteve '% q'" #: py/objstr.c msgid "expected ':' after format specifier" @@ -3263,7 +3263,7 @@ msgstr "a paleta de origem é muito grande" #: shared-bindings/canio/Message.c msgid "specify size or data, but not both" -msgstr "" +msgstr "defina o tamanho ou os dados, porém não ambos" #: py/objstr.c msgid "start/end indices" From 3a6f7986df617e4330fdb267542ccf2cd619dc38 Mon Sep 17 00:00:00 2001 From: Maciej Stankiewicz Date: Tue, 22 Sep 2020 23:50:11 +0000 Subject: [PATCH 47/55] Translated using Weblate (Polish) Currently translated at 73.7% (595 of 807 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pl/ --- locale/pl.po | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locale/pl.po b/locale/pl.po index 0538f61784..5428885c1d 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-21 16:45-0500\n" -"PO-Revision-Date: 2020-09-22 13:32+0000\n" -"Last-Translator: Szymon Jakubiak \n" +"PO-Revision-Date: 2020-09-23 18:31+0000\n" +"Last-Translator: Maciej Stankiewicz \n" "Language-Team: pl\n" "Language: pl\n" "MIME-Version: 1.0\n" @@ -100,7 +100,7 @@ msgstr "%q musi być krotką o długości 2" #: shared-bindings/canio/Match.c msgid "%q out of range" -msgstr "" +msgstr "%q poza zakresem" #: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" @@ -438,7 +438,7 @@ msgstr "Jasność nie jest regulowana" #: shared-bindings/_bleio/UUID.c #, c-format msgid "Buffer + offset too small %d %d %d" -msgstr "" +msgstr "Bufor + przesunięcie za małe %d %d %d" #: shared-module/usb_hid/Device.c #, c-format @@ -480,7 +480,7 @@ msgstr "Bufor jest zbyt duży i nie można go przydzielić" #: shared-bindings/_bleio/PacketBuffer.c #, c-format msgid "Buffer too short by %d bytes" -msgstr "Bufor za krótki o% d bajtów" +msgstr "Bufor za krótki o %d bajtów" #: ports/atmel-samd/common-hal/displayio/ParallelBus.c #: ports/nrf/common-hal/displayio/ParallelBus.c @@ -790,7 +790,7 @@ msgstr "Oczekiwano charakterystyki" #: shared-bindings/_bleio/Adapter.c msgid "Expected a DigitalInOut" -msgstr "" +msgstr "Oczekiwano DigitalInOut" #: shared-bindings/_bleio/Characteristic.c msgid "Expected a Service" @@ -875,7 +875,7 @@ msgstr "" #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" -msgstr "" +msgstr "Nie wspierany format" #: shared-module/framebufferio/FramebufferDisplay.c #, c-format @@ -924,7 +924,7 @@ msgstr "Błąd inicjalizacji I2C" #: shared-bindings/audiobusio/I2SOut.c msgid "I2SOut not available" -msgstr "" +msgstr "I2SOut niedostępne" #: shared-bindings/aesio/aes.c #, c-format @@ -1159,7 +1159,7 @@ msgstr "Największa wartość x przy odwróceniu to %d" #: shared-bindings/canio/Message.c msgid "Messages limited to 8 bytes" -msgstr "" +msgstr "Wiadomości ograniczone do 8 bajtów" #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." @@ -1176,7 +1176,7 @@ msgstr "Opóźnienie włączenia mikrofonu musi być w zakresie od 0.0 do 1.0" #: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c msgid "Missing MISO or MOSI Pin" -msgstr "" +msgstr "Brak pinu MISO lub MOSI" #: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." @@ -1219,7 +1219,7 @@ msgstr "Brak pinu MISO" #: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c msgid "No MOSI Pin" -msgstr "" +msgstr "Brak pinu MOSI" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c From 832869b257b50b12f9388c83021c53ece8761160 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 24 Sep 2020 16:56:07 -0500 Subject: [PATCH 48/55] make translate --- locale/circuitpython.pot | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index c9114dd5c5..2b395356ca 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-21 16:45-0500\n" +"POT-Creation-Date: 2020-09-24 16:55-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1167,14 +1167,10 @@ msgstr "" msgid "Must be a %q subclass." msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c msgid "Must provide MISO or MOSI pin" msgstr "" -#: ports/stm/common-hal/busio/SPI.c -msgid "Must provide SCK pin" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "Must use a multiple of 6 rgb pins, not %d" From 6bcbe51f7fcfaca6ee3ee40b4ce64fd791725e8f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 24 Sep 2020 16:57:10 -0500 Subject: [PATCH 49/55] supervisor: stub: make unimplemented safe_mode loop forever --- supervisor/stub/safe_mode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/supervisor/stub/safe_mode.c b/supervisor/stub/safe_mode.c index 1a792becd9..8072be2c65 100644 --- a/supervisor/stub/safe_mode.c +++ b/supervisor/stub/safe_mode.c @@ -32,6 +32,8 @@ safe_mode_t wait_for_safe_mode_reset(void) { void reset_into_safe_mode(safe_mode_t reason) { (void) reason; + for (;;) { + } } void print_safe_mode_message(safe_mode_t reason) { From eadb4de144005503dd648d16926527e5c40823f6 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 24 Sep 2020 16:58:24 -0500 Subject: [PATCH 50/55] qtpy_m0_haxpress: add --- .../boards/qtpy_m0_haxpress/board.c | 44 ++++++++++++++ .../boards/qtpy_m0_haxpress/mpconfigboard.h | 60 +++++++++++++++++++ .../boards/qtpy_m0_haxpress/mpconfigboard.mk | 33 ++++++++++ .../atmel-samd/boards/qtpy_m0_haxpress/pins.c | 49 +++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 ports/atmel-samd/boards/qtpy_m0_haxpress/board.c create mode 100644 ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/qtpy_m0_haxpress/pins.c diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/board.c b/ports/atmel-samd/boards/qtpy_m0_haxpress/board.c new file mode 100644 index 0000000000..1a65a561f7 --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/board.c @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "supervisor/shared/board.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { + gpio_set_pin_function(PIN_PA15, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(PIN_PA15, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA15, true); // Turn on neopixel by default + never_reset_pin_number(PIN_PA15); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.h b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.h new file mode 100644 index 0000000000..4e557751fc --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.h @@ -0,0 +1,60 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit QT Py M0 Haxpress" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_NEOPIXEL (&pin_PA18) + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define SPI_FLASH_MOSI_PIN &pin_PA22 +#define SPI_FLASH_MISO_PIN &pin_PA19 +#define SPI_FLASH_SCK_PIN &pin_PA23 +#define SPI_FLASH_CS_PIN &pin_PA08 + +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA17) +#define DEFAULT_I2C_BUS_SDA (&pin_PA16) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA09) + +#define DEFAULT_UART_BUS_RX (&pin_PA07) +#define DEFAULT_UART_BUS_TX (&pin_PA06) diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk new file mode 100644 index 0000000000..6c7bb3fca2 --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk @@ -0,0 +1,33 @@ +USB_VID = 0x239A +USB_PID = 0x80CC +USB_PRODUCT = "QT Py M0 Haxpress" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 0 +LONGINT_IMPL = MPZ +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q16C + +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_COUNTIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CPERIPHERAL = 0 + +SUPEROPT_GC = 0 + +CFLAGS_BOARD = --param max-inline-insns-auto=15 +ifeq ($(TRANSLATION), zh_Latn_pinyin) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CFLAGS_INLINE_LIMIT = 35 +endif +ifeq ($(TRANSLATION), de_DE) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CFLAGS_INLINE_LIMIT = 35 +SUPEROPT_VM = 0 +endif diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/pins.c b/ports/atmel-samd/boards/qtpy_m0_haxpress/pins.c new file mode 100644 index 0000000000..636c48bffc --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA16) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA11) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_PA15) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); From 33952023e89b96530bc2acaaf6a5f03da01d9a3c Mon Sep 17 00:00:00 2001 From: askpatricw <4002194+askpatrickw@users.noreply.github.com> Date: Fri, 25 Sep 2020 10:08:26 -0700 Subject: [PATCH 51/55] Print package if it exists for pin or module only if it does not --- shared-bindings/microcontroller/Pin.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index 1294b78f00..6ba02a0e7d 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -71,7 +71,11 @@ STATIC void mcu_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki qstr name; get_pin_name(self, &package, &module, &name); - mp_printf(print, "%q.%q.%q", MP_QSTR_microcontroller, MP_QSTR_pin, name); + if (package){ + mp_printf(print, "%q.%q.%q", package, module, name); + } else { + mp_printf(print, "%q.%q", module , name); + } } const mp_obj_type_t mcu_pin_type = { From b9d68bc5a6b7b63f52da6c7034d379d6de51be7e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 25 Sep 2020 11:07:22 -0700 Subject: [PATCH 52/55] Change I2C default to 100khz Greater that 100khz is technically out of the original spec. Background here: https://github.com/adafruit/Adafruit_CircuitPython_CLUE/issues/36 --- shared-bindings/busio/I2C.c | 4 ++-- shared-module/board/__init__.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 157e779fdc..8b456dbd35 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -39,7 +39,7 @@ //| class I2C: //| """Two wire serial protocol""" //| -//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 400000, timeout: int = 255) -> None: +//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 100000, timeout: int = 255) -> None: //| //| """I2C is a two-wire protocol for communicating between devices. At the //| physical level it consists of 2 wires: SCL and SDA, the clock and data @@ -70,7 +70,7 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, con static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} }, + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 7d99f2d4e3..fb4f731b88 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -61,7 +61,7 @@ mp_obj_t common_hal_board_create_i2c(void) { busio_i2c_obj_t *self = &i2c_obj; self->base.type = &busio_i2c_type; - common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0); + common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 100000, 0); i2c_singleton = (mp_obj_t)self; return i2c_singleton; } From 9944935fdeb0783a8b1d1ce3fd98f9c7ea0924e3 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 26 Sep 2020 11:31:54 -0500 Subject: [PATCH 53/55] qtpy haxpress: enable RTC --- ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk index 6c7bb3fca2..df452688e6 100644 --- a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk @@ -15,7 +15,6 @@ EXTERNAL_FLASH_DEVICES = GD25Q16C CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_BITBANGIO = 0 CIRCUITPY_COUNTIO = 0 -CIRCUITPY_RTC = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 From 8b27febf324d754ccc9bb07080453e33098a4e31 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 26 Sep 2020 11:43:46 -0500 Subject: [PATCH 54/55] add new board to actions build --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f8edec5616..1c68a3e5c6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -279,6 +279,7 @@ jobs: - "pyportal_titano" - "pyruler" - "qtpy_m0" + - "qtpy_m0_haxpress" - "raytac_mdbt50q-db-40" - "robohatmm1_m4" - "sam32" From 791d20f16ccfc0328ef0fab0159a2b4985480928 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 26 Sep 2020 11:43:55 -0500 Subject: [PATCH 55/55] give qtpy haxpress its own USB PID --- ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk index df452688e6..a63f142742 100644 --- a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk @@ -1,5 +1,5 @@ USB_VID = 0x239A -USB_PID = 0x80CC +USB_PID = 0x00CC USB_PRODUCT = "QT Py M0 Haxpress" USB_MANUFACTURER = "Adafruit Industries LLC"