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" 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/circuitpython.pot b/locale/circuitpython.pot index 37212e2416..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-16 17:07-0700\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" @@ -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 "" @@ -1147,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" @@ -2310,6 +2326,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 +3167,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 +3285,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/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 2528b25e6f..5428885c1d 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -6,8 +6,8 @@ msgid "" 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" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" +"PO-Revision-Date: 2020-09-23 18:31+0000\n" "Last-Translator: Maciej Stankiewicz \n" "Language-Team: pl\n" "Language: pl\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" @@ -95,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 "%q poza zakresem" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" msgstr "" @@ -283,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" @@ -319,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" @@ -423,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 @@ -465,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 @@ -761,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 @@ -775,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" @@ -854,9 +869,13 @@ 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 "" +msgstr "Nie wspierany format" #: shared-module/framebufferio/FramebufferDisplay.c #, c-format @@ -905,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 @@ -1138,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 "Wiadomości ograniczone do 8 bajtów" + #: supervisor/shared/safe_mode.c msgid "MicroPython NLR jump failed. Likely memory corruption." msgstr "" @@ -1153,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." @@ -1196,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 @@ -2329,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" @@ -3168,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" @@ -3282,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..0f5885ccf5 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-16 17:07-0700\n" -"PO-Revision-Date: 2020-09-19 17:41+0000\n" +"POT-Creation-Date: 2020-09-21 16:45-0500\n" +"PO-Revision-Date: 2020-09-22 21:30+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\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 "%q fora do alcance" + +#: 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 "Todos os FIFOs RX estão em uso" + #: 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 "Já há um ouvinte com todas as correspondências" + #: 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 "Os filtros são muito complexos" + #: 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 "As mensagens estão limitadas a 8 bytes" + #: 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 "o retorno esperado era '%q', porém obteve '% q'" + #: 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 "defina o tamanho ou os dados, porém não ambos" + #: 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ú" diff --git a/main.c b/main.c index 5b719dc4b6..dbd367a596 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(); + #if 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/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 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..53c4cf5eec 100644 --- a/ports/atmel-samd/boards/common.template.ld +++ b/ports/atmel-samd/boards/common.template.ld @@ -43,6 +43,15 @@ 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); + *(.canram) + } > 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). @@ -61,7 +70,7 @@ SECTIONS } >RAM /* Uninitialized data section */ - .bss : + .bss (NOLOAD) : { . = ALIGN(4); _sbss = .; 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 diff --git a/ports/atmel-samd/boards/qtpy_m0/board.c b/ports/atmel-samd/boards/qtpy_m0/board.c index 2add1867c0..1a65a561f7 100644 --- a/ports/atmel-samd/boards/qtpy_m0/board.c +++ b/ports/atmel-samd/boards/qtpy_m0/board.c @@ -30,9 +30,10 @@ #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 + never_reset_pin_number(PIN_PA15); } 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) }, 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..a63f142742 --- /dev/null +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk @@ -0,0 +1,32 @@ +USB_VID = 0x239A +USB_PID = 0x00CC +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_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); 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..4f28698fba --- /dev/null +++ b/ports/atmel-samd/common-hal/canio/CAN.c @@ -0,0 +1,445 @@ +/* + * 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)]; + +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->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); + + 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; + 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); + 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); + } + + // 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, + .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_buffer, + .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 = 0, + .bit.ANFS = CAN_GFC_ANFS_REJECT_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->standard_rx_filter + }; + hri_can_write_SIDFC_reg(self->hw, dfc.reg); + } + + { + CAN_XIDFC_Type dfc = { + .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); + } + + { + 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) +// 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; +} + +bool 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 self->hw->ECR.bit.TEC; +} + +int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self) +{ + return self->hw->ECR.bit.REC; +} + +int common_hal_canio_can_error_warning_state_count_get(canio_can_obj_t *self) +{ + return self->error_warning_state_count; +} + +int common_hal_canio_can_error_passive_state_count_get(canio_can_obj_t *self) +{ + return self->error_passive_state_count; +} + +int common_hal_canio_can_bus_off_state_count_get(canio_can_obj_t *self) +{ + return self->bus_off_state_count; +} + +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_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; + } 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 + 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_silent_get(canio_can_obj_t *self) { + return self->silent; +} + +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; ierror_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); +} + +__attribute__((used)) +void CAN0_Handler(void) { + can_handler(0); +} + +#ifdef CAN1_GCLK_ID +__attribute__((used)) +void CAN1_Handler(void) { + can_handler(1); +} +#endif diff --git a/ports/atmel-samd/common-hal/canio/CAN.h b/ports/atmel-samd/common-hal/canio/CAN.h new file mode 100644 index 0000000000..cdea60e7d0 --- /dev/null +++ b/ports/atmel-samd/common-hal/canio/CAN.h @@ -0,0 +1,55 @@ +/* + * 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" +#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" + +#define COMMON_HAL_CAN_RX_FIFO_LEN (2) +#define COMMON_HAL_CAN_TX_FIFO_LEN (2) + +typedef struct canio_can_obj { + mp_obj_base_t base; + Can *hw; + 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; diff --git a/ports/atmel-samd/common-hal/canio/Listener.c b/ports/atmel-samd/common-hal/canio/Listener.c new file mode 100644 index 0000000000..02cfde9cc8 --- /dev/null +++ b/ports/atmel-samd/common-hal/canio/Listener.c @@ -0,0 +1,391 @@ +/* + * 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 + +#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" +#include "component/can.h" + +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; + 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")); + } + + 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); +} + +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_rx_fifo_t *hw_message = &self->fifo[index]; + message->extended = hw_message->rxf0.bit.XTD; + if (message->extended) { + message->id = hw_message->rxf0.bit.ID; + } else { + message->id = hw_message->rxf0.bit.ID >> 18; // short addresses are left-justified + } + 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); + } + self->hw->RXFA.bit.F0AI = index; + return true; +} + +void common_hal_canio_listener_deinit(canio_listener_obj_t *self) { + if (self->can) { + clear_filters(self); + 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..1b81d82aa6 --- /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_rx_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..32adc5bf96 --- /dev/null +++ b/ports/atmel-samd/common-hal/canio/__init__.h @@ -0,0 +1,66 @@ +/* + * 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) + +// 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; + +typedef struct { + CAN_TXBE_0_Type txb0; + CAN_TXBE_1_Type txb1; + COMPILER_ALIGNED(4) + uint8_t data[COMMON_HAL_CANIO_MAX_MESSAGE_LENGTH]; +} 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_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; 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/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/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') 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); diff --git a/ports/esp32s2/common-hal/busio/SPI.c b/ports/esp32s2/common-hal/busio/SPI.c index 350580ea84..eaafa87b74 100644 --- a/ports/esp32s2/common-hal/busio/SPI.c +++ b/ports/esp32s2/common-hal/busio/SPI.c @@ -115,6 +115,7 @@ 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) { + 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 +213,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 +241,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 +304,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; 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 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/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; } 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]; } } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 6e98af8686..98fa7a5f2c 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..0583ae1c97 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/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/makeqstrdata.py b/py/makeqstrdata.py index 39d4a6840f..b4f4f1b035 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) @@ -108,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 = [] 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 [("/", "__"), ("\\", "__"), (":", "@"), ("..", "@@")]: 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 \ 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-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); } diff --git a/shared-bindings/canio/CAN.c b/shared-bindings/canio/CAN.c new file mode 100644 index 0000000000..ff27bb2048 --- /dev/null +++ b/shared-bindings/canio/CAN.c @@ -0,0 +1,422 @@ +/* + * 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 "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 "shared-bindings/microcontroller/Pin.h" + +#include "py/objproperty.h" +#include "py/runtime.h" + +//| +//| class CAN: +//| """CAN bus protocol""" +//| +//| def __init__(self, +//| 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. +//| +//| :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: 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 +//| """ +//| ... +//| +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_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 }, + { 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 ); + + 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_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; + 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); + + return MP_OBJ_FROM_PTR(self); +} + + +//| 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) { + 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)""" +//| +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}, +}; + +//| 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}, +}; + +//| 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}, +}; + + +//| 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, 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 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.""" +//| ... +//| +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); + +//| 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. +//| """ +//| ... +//| +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); + +//| 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""" +//| ... +//| +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 self_in; +} +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_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_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) }, +}; +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..66c972c285 --- /dev/null +++ b/shared-bindings/canio/CAN.h @@ -0,0 +1,54 @@ +/* + * 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" +#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); diff --git a/shared-bindings/canio/Listener.c b/shared-bindings/canio/Listener.c new file mode 100644 index 0000000000..1f4176f0c0 --- /dev/null +++ b/shared-bindings/canio/Listener.c @@ -0,0 +1,185 @@ +/* + * 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]: +//| """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.""" +//| ... +//| +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); + message->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 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) { + 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""" +//| ... +//| +//| def __next__(self): +//| """Reads a message, after waiting up to self.timeout seconds +//| +//| If no message is received in time, raises StopIteration. Otherwise, +//| a Message is returned.""" +//| ... +//| +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; +} + +//| 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 self_in; +} +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_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, + .getiter = mp_identity_getiter, + .iternext = canio_iternext, + .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..ff5d028fad --- /dev/null +++ b/shared-bindings/canio/Match.c @@ -0,0 +1,139 @@ +/* + * 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 "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 }, + { 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_get_address(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_get_mask(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_get_extended(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..88996d730f --- /dev/null +++ b/shared-bindings/canio/Match.h @@ -0,0 +1,37 @@ +/* + * 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" +#include "shared-module/canio/Match.h" + +extern const mp_obj_type_t canio_match_type; + +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 new file mode 100644 index 0000000000..23645d2e5f --- /dev/null +++ b/shared-bindings/canio/Message.c @@ -0,0 +1,212 @@ +/* + * 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 "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, extended: bool = False): +//| """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 +//| :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. +//| +//| 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, 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 ); + + 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); + + 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, extended); + 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_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_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); + +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 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; + 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); + +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_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); + + +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}, +}; + + +//| 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_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_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); + + +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). 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; + 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_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); + + +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_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); + +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..34b632e847 --- /dev/null +++ b/shared-bindings/canio/Message.h @@ -0,0 +1,44 @@ +/* + * 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" +#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-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c new file mode 100644 index 0000000000..b0b982c950 --- /dev/null +++ b/shared-bindings/canio/__init__.c @@ -0,0 +1,124 @@ +/* + * 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. +//| +//| 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. +//| +//| For example:: +//| +//| import canio +//| from board import * +//| +//| 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 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" +#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. +//| +//| 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. +//| +//| 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. 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), + 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_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 = { + .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..e24eba92c1 --- /dev/null +++ b/shared-bindings/canio/__init__.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 + +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; 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 = { 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; } diff --git a/shared-module/canio/Match.c b/shared-module/canio/Match.c new file mode 100644 index 0000000000..9e33b956f6 --- /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_get_address(const canio_match_obj_t *self) { + return self->address; +} +int common_hal_canio_match_get_mask(const canio_match_obj_t *self) { + return self->mask; +} +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 new file mode 100644 index 0000000000..25f047f37e --- /dev/null +++ b/shared-module/canio/Match.h @@ -0,0 +1,36 @@ +/* + * 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; diff --git a/shared-module/canio/Message.c b/shared-module/canio/Message.c new file mode 100644 index 0000000000..b8ebb78596 --- /dev/null +++ b/shared-module/canio/Message.c @@ -0,0 +1,101 @@ +/* + * 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, bool extended) +{ + self->id = id; + self->size = size; + self->rtr = rtr; + self->extended = extended; + if (data) { + memcpy(self->data, data, size); + } else { + memset(self->data, 0, size); + } +} + +int common_hal_canio_message_get_id(const canio_message_obj_t *self) +{ + return self->id; +} + +void common_hal_canio_message_set_id(canio_message_obj_t *self, int id) +{ + self->id = id; +} + + +const void *common_hal_canio_message_get_data(const canio_message_obj_t *self) +{ + return self->data; +} + +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); +} + + +size_t common_hal_canio_message_get_size(const canio_message_obj_t *self) +{ + return self->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_get_rtr(const canio_message_obj_t *self) +{ + return self->rtr; +} + +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) +{ + return self->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 new file mode 100644 index 0000000000..b99c5c48e3 --- /dev/null +++ b/shared-module/canio/Message.h @@ -0,0 +1,38 @@ +/* + * 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; + uint8_t data[8]; + size_t size:4; + bool rtr:1; + bool extended:1; +} canio_message_obj_t; 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) {