merged master

This commit is contained in:
Daniel Pollard 2020-05-12 14:41:28 +10:00
commit ee2cb703c8
96 changed files with 3297 additions and 694 deletions

View File

@ -216,6 +216,7 @@ jobs:
- "pewpew10"
- "pewpew_m4"
- "pirkey_m0"
- "pitaya_go"
- "pyb_nano_v2"
- "pybadge"
- "pybadge_airlift"
@ -249,6 +250,7 @@ jobs:
- "stm32f746g_discovery"
- "stringcar_m0_express"
- "teensy40"
- "teensy41"
- "teknikio_bluebird"
- "thunderpack"
- "trellis_m4_express"

View File

@ -98,7 +98,7 @@ def build_module_map():
for module in modules:
full_name = module
search_name = module.lstrip("_")
re_pattern = "CIRCUITPY_{}\s=\s(.+)".format(search_name.upper())
re_pattern = "CIRCUITPY_{}\s*\??=\s*(.+)".format(search_name.upper())
find_config = re.findall(re_pattern, configs)
if not find_config:
continue

View File

@ -53,6 +53,10 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
#define JSON_DEBUG(...) (void)0
// #define JSON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
// The function below implements a simple non-recursive JSON parser.
//
// The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt
@ -80,6 +84,7 @@ typedef struct _ujson_stream_t {
STATIC byte ujson_stream_next(ujson_stream_t *s) {
mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode);
JSON_DEBUG(" usjon_stream_next err:%2d cur: %c \n", s->errcode, s->cur);
if (s->errcode != 0) {
mp_raise_OSError(s->errcode);
}
@ -89,9 +94,10 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
return s->cur;
}
STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ);
ujson_stream_t s = {stream_obj, stream_p->read, 0, 0};
JSON_DEBUG("got JSON stream\n");
vstr_t vstr;
vstr_init(&vstr, 8);
mp_obj_list_t stack; // we use a list as a simple stack for nested JSON
@ -262,13 +268,18 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
}
}
success:
// eat trailing whitespace
while (unichar_isspace(S_CUR(s))) {
S_NEXT(s);
}
if (!S_END(s)) {
// unexpected chars
goto fail;
// It is legal for a stream to have contents after JSON.
// E.g., A UART is not closed after receiving an object; in load() we will
// return the first complete JSON object, while in loads() we will retain
// strict adherence to the buffer's complete semantic.
if (!return_first_json) {
while (unichar_isspace(S_CUR(s))) {
S_NEXT(s);
}
if (!S_END(s)) {
// unexpected chars
goto fail;
}
}
if (stack_top == MP_OBJ_NULL || stack.len != 0) {
// not exactly 1 object
@ -280,6 +291,10 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
fail:
mp_raise_ValueError(translate("syntax error in JSON"));
}
STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
return _mod_ujson_load(stream_obj, true);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
@ -287,7 +302,7 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
const char *buf = mp_obj_str_get_data(obj, &len);
vstr_t vstr = {len, len, (char*)buf, true};
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
return mod_ujson_load(MP_OBJ_FROM_PTR(&sio));
return _mod_ujson_load(MP_OBJ_FROM_PTR(&sio), false);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -435,6 +435,10 @@ msgstr "buffers harus mempunyai panjang yang sama"
msgid "Bytes must be between 0 and 255."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -672,6 +676,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -683,7 +691,7 @@ msgstr "Channel EXTINT sedang digunakan"
msgid "Error in regex"
msgstr "Error pada regex"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -790,7 +798,8 @@ msgstr ""
msgid "Group full"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -810,6 +819,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "operasi I2C tidak didukung"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -989,6 +1003,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr "LHS dari keyword arg harus menjadi sebuah id"
@ -1034,7 +1052,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1042,7 +1060,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1073,11 +1091,11 @@ msgstr "Tidak ada DAC (Digital Analog Converter) di dalam chip"
msgid "No DMA channel found"
msgstr "tidak ada channel DMA ditemukan"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1097,6 +1115,10 @@ msgstr "Tidak ada pin TX"
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Tidak ada standar bus %q"
@ -1118,6 +1140,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr "Tidak ada dukungan hardware untuk pin"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1303,6 +1329,10 @@ msgstr "sistem file (filesystem) bersifat Read-only"
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Channel Kanan tidak didukung"
@ -1367,6 +1397,10 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Memisahkan dengan menggunakan sub-captures"
@ -1450,6 +1484,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 15:46+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -430,6 +430,10 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -661,6 +665,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -672,7 +680,7 @@ msgstr ""
msgid "Error in regex"
msgstr ""
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -779,7 +787,8 @@ msgstr ""
msgid "Group full"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -799,6 +808,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -978,6 +992,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr ""
@ -1023,7 +1041,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1031,7 +1049,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1062,11 +1080,11 @@ msgstr ""
msgid "No DMA channel found"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1086,6 +1104,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1107,6 +1129,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1288,6 +1314,10 @@ msgstr ""
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr ""
@ -1351,6 +1381,10 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@ -1434,6 +1468,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,15 +7,17 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2020-04-30 17:01+0000\n"
"Last-Translator: Jeff Epler <jepler@gmail.com>\n"
"Language-Team: German <https://later.unpythonic.net/projects/circuitpython/"
"circuitpython-master/de/>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.1.1\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.0.2\n"
#: main.c
msgid ""
@ -31,12 +33,17 @@ msgid ""
"Please file an issue with the contents of your CIRCUITPY drive at \n"
"https://github.com/adafruit/circuitpython/issues\n"
msgstr ""
"\n"
"Bitte melden Sie ein Problem mit dem Inhalt Ihres CIRCUITPY-Laufwerks unter\n"
"https://github.com/adafruit/circuitpython/issues\n"
#: supervisor/shared/safe_mode.c
msgid ""
"\n"
"To exit, please reset the board without "
msgstr ""
"\n"
"Zum Beenden setzen Sie bitte die Karte ohne "
#: py/obj.c
msgid " File \"%q\""
@ -142,11 +149,11 @@ msgstr "'%s' Integer 0x%x passt nicht in Maske 0x%x"
#: py/runtime.c
msgid "'%s' object cannot assign attribute '%q'"
msgstr ""
msgstr "Das Objekt '%s' kann das Attribut '%q' nicht zuweisen"
#: py/proto.c
msgid "'%s' object does not support '%q'"
msgstr ""
msgstr "Das Objekt '%s' unterstützt '%q' nicht"
#: py/obj.c
#, c-format
@ -196,7 +203,7 @@ msgstr "'align' erfordert genau ein Argument"
#: py/compile.c
msgid "'async for' or 'async with' outside async function"
msgstr ""
msgstr "'async for' oder 'async with' außerhalb der asynchronen Funktion"
#: py/compile.c
msgid "'await' outside function"
@ -240,7 +247,7 @@ msgstr ""
#: py/objcomplex.c
msgid "0.0 to a complex power"
msgstr ""
msgstr "0.0 zu einer komplexen Potenz"
#: py/modbuiltins.c
msgid "3-arg pow() not supported"
@ -434,6 +441,10 @@ msgstr "Der Puffer muss 16 Bytes lang sein"
msgid "Bytes must be between 0 and 255."
msgstr "Ein Bytes kann nur Werte zwischen 0 und 255 annehmen."
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr "Rufe super().__init__() vor dem Zugriff auf ein natives Objekt auf."
@ -665,6 +676,10 @@ msgstr "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen"
msgid "Drive mode not used when direction is input."
msgstr "Drive mode wird nicht verwendet, wenn die Richtung input ist."
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -676,7 +691,7 @@ msgstr "EXTINT Kanal ist schon in Benutzung"
msgid "Error in regex"
msgstr "Fehler in regex"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -785,7 +800,8 @@ msgstr "Gruppe schon benutzt"
msgid "Group full"
msgstr "Gruppe voll"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -805,6 +821,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "I2C-operation nicht unterstützt"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -986,6 +1007,10 @@ msgstr "Ungültige wave Datei"
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr "LHS des Schlüsselwortarguments muss eine id sein"
@ -1032,7 +1057,7 @@ msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
"Die Startverzögerung des Mikrofons muss im Bereich von 0,0 bis 1,0 liegen"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1040,7 +1065,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr "Muss eine %q Unterklasse sein."
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1071,11 +1096,11 @@ msgstr "Kein DAC im Chip vorhanden"
msgid "No DMA channel found"
msgstr "Kein DMA Kanal gefunden"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1095,6 +1120,10 @@ msgstr "Kein TX Pin"
msgid "No available clocks"
msgstr "Keine Taktgeber verfügbar"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Kein Standard %q Bus"
@ -1116,6 +1145,10 @@ msgstr "Keine Hardwareunterstützung am clk Pin"
msgid "No hardware support on pin"
msgstr "Keine Hardwareunterstützung an diesem Pin"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1305,6 +1338,10 @@ msgstr "Schreibgeschützte Objekt"
msgid "Refresh too soon"
msgstr "Zu früh neu geladen"
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Rechter Kanal wird nicht unterstützt"
@ -1368,6 +1405,10 @@ msgstr "Slice und Wert (value) haben unterschiedliche Längen."
msgid "Slices not supported"
msgstr "Slices werden nicht unterstützt"
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Splitting mit sub-captures"
@ -1453,6 +1494,10 @@ msgstr ""
msgid "Too many displays"
msgstr "Zu viele displays"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Zurückverfolgung (jüngste Aufforderung zuletzt):\n"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@ -430,6 +430,10 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -661,6 +665,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -672,7 +680,7 @@ msgstr ""
msgid "Error in regex"
msgstr ""
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -779,7 +787,8 @@ msgstr ""
msgid "Group full"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -799,6 +808,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -978,6 +992,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr ""
@ -1023,7 +1041,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1031,7 +1049,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1062,11 +1080,11 @@ msgstr ""
msgid "No DMA channel found"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1086,6 +1104,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1107,6 +1129,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1288,6 +1314,10 @@ msgstr ""
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr ""
@ -1351,6 +1381,10 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@ -1434,6 +1468,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,15 +7,17 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2020-03-30 22:11+0000\n"
"Last-Translator: Tannewt <devnull@unpythonic.net>\n"
"Language-Team: English <https://later.unpythonic.net/projects/circuitpython/"
"circuitpython-master/en_X@pirate/>\n"
"Language: en_x_pirate\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.1.1\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.11.3\n"
#: main.c
msgid ""
@ -31,6 +33,9 @@ msgid ""
"Please file an issue with the contents of your CIRCUITPY drive at \n"
"https://github.com/adafruit/circuitpython/issues\n"
msgstr ""
"\n"
"Yar, there is a hole in the keel. Let the cap'n know at\n"
"https://github.com/adafruit/circuitpython/issues\n"
#: supervisor/shared/safe_mode.c
msgid ""
@ -434,6 +439,10 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -665,6 +674,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -676,7 +689,7 @@ msgstr "Avast! EXTINT channel already in use"
msgid "Error in regex"
msgstr ""
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -783,7 +796,8 @@ msgstr ""
msgid "Group full"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -803,6 +817,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -982,6 +1001,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr ""
@ -1027,7 +1050,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1035,7 +1058,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1066,11 +1089,11 @@ msgstr "Shiver me timbers! There be no DAC on this chip"
msgid "No DMA channel found"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1090,6 +1113,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1111,6 +1138,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1292,6 +1323,10 @@ msgstr ""
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr ""
@ -1355,6 +1390,10 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@ -1438,6 +1477,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@ -436,6 +436,10 @@ msgstr "Byte buffer debe de ser 16 bytes"
msgid "Bytes must be between 0 and 255."
msgstr "Bytes debe estar entre 0 y 255."
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -667,6 +671,10 @@ msgstr "Rotación de display debe ser en incrementos de 90 grados"
msgid "Drive mode not used when direction is input."
msgstr "Modo Drive no se usa cuando la dirección es input."
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -678,7 +686,7 @@ msgstr "El canal EXTINT ya está siendo utilizado"
msgid "Error in regex"
msgstr "Error en regex"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -785,7 +793,8 @@ msgstr ""
msgid "Group full"
msgstr "Group lleno"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -805,6 +814,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "operación I2C no soportada"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -986,6 +1000,10 @@ msgstr "Archivo wave inválido"
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr "LHS del agumento por palabra clave deberia ser un identificador"
@ -1031,7 +1049,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Micrófono demora de inicio debe estar en el rango 0.0 a 1.0"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1039,7 +1057,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr "Debe de ser una subclase de %q"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1070,11 +1088,11 @@ msgstr "El chip no tiene DAC"
msgid "No DMA channel found"
msgstr "No se encontró el canal DMA"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1094,6 +1112,10 @@ msgstr "Sin pin TX"
msgid "No available clocks"
msgstr "Relojes no disponibles"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Sin bus %q por defecto"
@ -1115,6 +1137,10 @@ msgstr "Sin soporte de hardware en el pin clk"
msgid "No hardware support on pin"
msgstr "Sin soporte de hardware en pin"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1305,6 +1331,10 @@ msgstr "Solo-lectura"
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Canal derecho no soportado"
@ -1368,6 +1398,10 @@ msgstr "Slice y value tienen diferentes longitudes"
msgid "Slices not supported"
msgstr "Rebanadas no soportadas"
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Dividiendo con sub-capturas"
@ -1451,6 +1485,10 @@ msgstr "Demasiados buses de pantalla"
msgid "Too many displays"
msgstr "Muchos displays"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (ultima llamada reciente):\n"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@ -437,6 +437,10 @@ msgstr "buffer ay dapat bytes-like object"
msgid "Bytes must be between 0 and 255."
msgstr "Sa gitna ng 0 o 255 dapat ang bytes."
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -673,6 +677,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr "Drive mode ay hindi ginagamit kapag ang direksyon ay input."
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -684,7 +692,7 @@ msgstr "Ginagamit na ang EXTINT channel"
msgid "Error in regex"
msgstr "May pagkakamali sa REGEX"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -793,7 +801,8 @@ msgstr ""
msgid "Group full"
msgstr "Puno ang group"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -813,6 +822,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "Hindi supportado ang operasyong I2C"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -994,6 +1008,10 @@ msgstr "May hindi tama sa wave file"
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr "LHS ng keyword arg ay dapat na id"
@ -1039,7 +1057,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Ang delay ng startup ng mikropono ay dapat na nasa 0.0 hanggang 1.0"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1047,7 +1065,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1078,11 +1096,11 @@ msgstr "Walang DAC sa chip"
msgid "No DMA channel found"
msgstr "Walang DMA channel na mahanap"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1102,6 +1120,10 @@ msgstr "Walang TX pin"
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Walang default na %q bus"
@ -1123,6 +1145,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr "Walang support sa hardware ang pin"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1311,6 +1337,10 @@ msgstr "Basahin-lamang"
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Hindi supportado ang kanang channel"
@ -1374,6 +1404,10 @@ msgstr "Slice at value iba't ibang haba."
msgid "Slices not supported"
msgstr "Hindi suportado ang Slices"
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Binibiyak gamit ang sub-captures"
@ -1457,6 +1491,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (pinakahuling huling tawag): \n"

View File

@ -8,14 +8,17 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2020-05-05 20:24+0000\n"
"Last-Translator: Jeff Epler <jepler@gmail.com>\n"
"Language-Team: French <https://later.unpythonic.net/projects/circuitpython/"
"circuitpython-master/fr/>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.1-dev\n"
#: main.c
msgid ""
@ -31,12 +34,18 @@ msgid ""
"Please file an issue with the contents of your CIRCUITPY drive at \n"
"https://github.com/adafruit/circuitpython/issues\n"
msgstr ""
"\n"
"Veuillez signaler un problème avec le contenu de votre lecteur CIRCUITPY à "
"l'adresse\n"
"https://github.com/adafruit/circuitpython/issues\n"
#: supervisor/shared/safe_mode.c
msgid ""
"\n"
"To exit, please reset the board without "
msgstr ""
"\n"
"Pour repartir, veuillez réinitialiser sans "
#: py/obj.c
msgid " File \"%q\""
@ -48,7 +57,7 @@ msgstr " Fichier \"%q\", ligne %d"
#: main.c
msgid " output:\n"
msgstr " sortie:\n"
msgstr " sortie:\n"
#: py/objstr.c
#, c-format
@ -75,14 +84,12 @@ msgstr "les indices %q doivent être des entiers, pas %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
#: shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "%d doit être >=1"
msgstr "%q doit être >=1"
#: shared-bindings/fontio/BuiltinFont.c
#, fuzzy
msgid "%q should be an int"
msgstr "y doit être un entier (int)"
msgstr "%q doit être un entier (int)"
#: py/bc.c py/objnamedtuple.c
msgid "%q() takes %d positional arguments but %d were given"
@ -113,7 +120,7 @@ msgid "'%s' expects an FPU register"
msgstr "'%s' attend un registre FPU"
#: py/emitinlinethumb.c
#, fuzzy, c-format
#, c-format
msgid "'%s' expects an address of the form [a, b]"
msgstr "'%s' attend une adresse de la forme [a, b]"
@ -144,11 +151,11 @@ msgstr "'%s' l'entier 0x%x ne correspond pas au masque 0x%x"
#: py/runtime.c
msgid "'%s' object cannot assign attribute '%q'"
msgstr ""
msgstr "L'objet '%s' ne peut pas assigner l'attribut '%q'"
#: py/proto.c
msgid "'%s' object does not support '%q'"
msgstr ""
msgstr "L'objet '%s' ne prends pas en charge '%q'"
#: py/obj.c
#, c-format
@ -198,7 +205,7 @@ msgstr "'align' nécessite 1 argument"
#: py/compile.c
msgid "'async for' or 'async with' outside async function"
msgstr ""
msgstr "'async for' ou 'async with' sans fonction async"
#: py/compile.c
msgid "'await' outside function"
@ -441,6 +448,10 @@ msgstr "Le tampon d'octets doit être de 16 octets."
msgid "Bytes must be between 0 and 255."
msgstr "Les octets 'bytes' doivent être entre 0 et 255"
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -676,6 +687,10 @@ msgstr "La rotation d'affichage doit se faire par incréments de 90 degrés"
msgid "Drive mode not used when direction is input."
msgstr "Le mode Drive n'est pas utilisé quand la direction est 'input'."
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -687,7 +702,7 @@ msgstr "Canal EXTINT déjà utilisé"
msgid "Error in regex"
msgstr "Erreur dans l'expression régulière"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -796,7 +811,8 @@ msgstr ""
msgid "Group full"
msgstr "Groupe plein"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -816,6 +832,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "opération sur I2C non supportée"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -1001,6 +1022,10 @@ msgstr "Fichier WAVE invalide"
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr "La partie gauche de l'argument nommé doit être un identifiant"
@ -1046,7 +1071,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1054,7 +1079,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1085,11 +1110,11 @@ msgstr "Pas de DAC sur la puce"
msgid "No DMA channel found"
msgstr "Aucun canal DMA trouvé"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1109,6 +1134,10 @@ msgstr "Pas de broche TX"
msgid "No available clocks"
msgstr "Pas d'horloge disponible"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Pas de bus %q par défaut"
@ -1130,6 +1159,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr "Pas de support matériel pour cette broche"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1324,6 +1357,10 @@ msgstr "Objet en lecture seule"
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Canal droit non supporté"
@ -1388,6 +1425,10 @@ msgstr "Tranche et valeur de tailles différentes"
msgid "Slices not supported"
msgstr "Tranches non supportées"
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Fractionnement avec des sous-captures"
@ -1472,6 +1513,10 @@ msgstr "Trop de bus d'affichage"
msgid "Too many displays"
msgstr "Trop d'affichages"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Trace (appels les plus récents en dernier):\n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@ -437,6 +437,10 @@ msgstr "i buffer devono essere della stessa lunghezza"
msgid "Bytes must be between 0 and 255."
msgstr "I byte devono essere compresi tra 0 e 255"
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -673,6 +677,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -684,7 +692,7 @@ msgstr "Canale EXTINT già in uso"
msgid "Error in regex"
msgstr "Errore nella regex"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -793,7 +801,8 @@ msgstr ""
msgid "Group full"
msgstr "Gruppo pieno"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -813,6 +822,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "operazione I2C non supportata"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -997,6 +1011,10 @@ msgstr "File wave non valido"
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr ""
@ -1043,7 +1061,7 @@ msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
"Il ritardo di avvio del microfono deve essere nell'intervallo tra 0.0 e 1.0"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1051,7 +1069,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1082,11 +1100,11 @@ msgstr "Nessun DAC sul chip"
msgid "No DMA channel found"
msgstr "Nessun canale DMA trovato"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1106,6 +1124,10 @@ msgstr "Nessun pin TX"
msgid "No available clocks"
msgstr "Nessun orologio a disposizione"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Nessun bus %q predefinito"
@ -1127,6 +1149,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr "Nessun supporto hardware sul pin"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1320,6 +1346,10 @@ msgstr "Sola lettura"
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Canale destro non supportato"
@ -1385,6 +1415,10 @@ msgstr ""
msgid "Slices not supported"
msgstr "Slice non supportate"
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Suddivisione con sotto-catture"
@ -1468,6 +1502,10 @@ msgstr ""
msgid "Too many displays"
msgstr "Troppi schermi"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (chiamata più recente per ultima):\n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2019-05-06 14:22-0700\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -434,6 +434,10 @@ msgstr "잘못된 크기의 버퍼. 16 바이트 여야합니다."
msgid "Bytes must be between 0 and 255."
msgstr "바이트는 0에서 255 사이 여야합니다."
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -665,6 +669,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -676,7 +684,7 @@ msgstr ""
msgid "Error in regex"
msgstr "Regex에 오류가 있습니다."
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -783,7 +791,8 @@ msgstr ""
msgid "Group full"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -803,6 +812,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -982,6 +996,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr ""
@ -1027,7 +1045,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1035,7 +1053,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1066,11 +1084,11 @@ msgstr ""
msgid "No DMA channel found"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1090,6 +1108,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1111,6 +1133,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1292,6 +1318,10 @@ msgstr ""
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr ""
@ -1355,6 +1385,10 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@ -1438,6 +1472,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@ -433,6 +433,10 @@ msgstr "Bufor musi mieć 16 bajtów."
msgid "Bytes must be between 0 and 255."
msgstr "Bytes musi być między 0 a 255."
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -664,6 +668,10 @@ msgstr "Wyświetlacz można obracać co 90 stopni"
msgid "Drive mode not used when direction is input."
msgstr "Tryb sterowania nieużywany w trybie wejścia."
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -675,7 +683,7 @@ msgstr "Kanał EXTINT w użyciu"
msgid "Error in regex"
msgstr "Błąd w regex"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -782,7 +790,8 @@ msgstr ""
msgid "Group full"
msgstr "Grupa pełna"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -802,6 +811,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "Operacja I2C nieobsługiwana"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -983,6 +997,10 @@ msgstr "Zły plik wave"
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr "Lewa strona argumentu nazwanego musi być nazwą"
@ -1028,7 +1046,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Opóźnienie włączenia mikrofonu musi być w zakresie od 0.0 do 1.0"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1036,7 +1054,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1067,11 +1085,11 @@ msgstr "Brak DAC"
msgid "No DMA channel found"
msgstr "Nie znaleziono kanału DMA"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1091,6 +1109,10 @@ msgstr "Brak nóżki TX"
msgid "No available clocks"
msgstr "Brak wolnych zegarów"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Nie ma domyślnej magistrali %q"
@ -1112,6 +1134,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr "Brak sprzętowej obsługi na nóżce"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1293,6 +1319,10 @@ msgstr "Obiekt tylko do odczytu"
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Prawy kanał jest niewspierany"
@ -1356,6 +1386,10 @@ msgstr "Fragment i wartość są różnych długości."
msgid "Slices not supported"
msgstr "Fragmenty nieobsługiwane"
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Podział z podgrupami"
@ -1439,6 +1473,10 @@ msgstr "Zbyt wiele magistrali"
msgid "Too many displays"
msgstr "Zbyt wiele wyświetlaczy"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Ślad wyjątku (najnowsze wywołanie na końcu):\n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@ -434,6 +434,10 @@ msgstr "buffers devem ser o mesmo tamanho"
msgid "Bytes must be between 0 and 255."
msgstr "Os bytes devem estar entre 0 e 255."
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -668,6 +672,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -679,7 +687,7 @@ msgstr "Canal EXTINT em uso"
msgid "Error in regex"
msgstr "Erro no regex"
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -788,7 +796,8 @@ msgstr ""
msgid "Group full"
msgstr "Grupo cheio"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -808,6 +817,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr "I2C operação não suportada"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -990,6 +1004,10 @@ msgstr "Aqruivo de ondas inválido"
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr ""
@ -1035,7 +1053,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1043,7 +1061,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1074,11 +1092,11 @@ msgstr "Nenhum DAC no chip"
msgid "No DMA channel found"
msgstr "Nenhum canal DMA encontrado"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1098,6 +1116,10 @@ msgstr "Nenhum pino TX"
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Nenhum barramento %q padrão"
@ -1119,6 +1141,10 @@ msgstr "Sem suporte de hardware no pino de clock"
msgid "No hardware support on pin"
msgstr "Nenhum suporte de hardware no pino"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1305,6 +1331,10 @@ msgstr "Somente leitura"
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Canal direito não suportado"
@ -1368,6 +1398,10 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@ -1451,6 +1485,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 15:46+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -430,6 +430,10 @@ msgstr ""
msgid "Bytes must be between 0 and 255."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr ""
@ -661,6 +665,10 @@ msgstr ""
msgid "Drive mode not used when direction is input."
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -672,7 +680,7 @@ msgstr ""
msgid "Error in regex"
msgstr ""
#: shared-bindings/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -779,7 +787,8 @@ msgstr ""
msgid "Group full"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -799,6 +808,11 @@ msgstr ""
msgid "I2C operation not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -978,6 +992,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr ""
@ -1023,7 +1041,7 @@ msgstr ""
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -1031,7 +1049,7 @@ msgstr ""
msgid "Must be a %q subclass."
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr ""
@ -1062,11 +1080,11 @@ msgstr ""
msgid "No DMA channel found"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr ""
@ -1086,6 +1104,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1107,6 +1129,10 @@ msgstr ""
msgid "No hardware support on pin"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr ""
@ -1288,6 +1314,10 @@ msgstr ""
msgid "Refresh too soon"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr ""
@ -1351,6 +1381,10 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@ -1434,6 +1468,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-05 14:57+1000\n"
"POT-Creation-Date: 2020-05-12 14:37+1000\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@ -439,6 +439,10 @@ msgstr "Zì jié huǎnchōng qū bìxū shì 16 zì jié."
msgid "Bytes must be between 0 and 255."
msgstr "Zì jié bìxū jiè yú 0 dào 255 zhī jiān."
#: shared-bindings/aesio/aes.c
msgid "CBC blocks must be multiples of 16 bytes"
msgstr ""
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
msgstr "Zài fǎngwèn běn jī wùjiàn zhīqián diàoyòng super().__init__()"
@ -672,6 +676,10 @@ msgstr "Xiǎnshì xuánzhuǎn bìxū 90 dù jiā xīn"
msgid "Drive mode not used when direction is input."
msgstr "Fāngxiàng shūrù shí qūdòng móshì méiyǒu shǐyòng."
#: shared-bindings/aesio/aes.c
msgid "ECB only operates on 16 bytes at a time"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
@ -683,7 +691,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/microcontroller/Pin.c
#: shared-bindings/aesio/aes.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c shared-bindings/pulseio/PulseOut.c
#: shared-bindings/terminalio/Terminal.c
msgid "Expected a %q"
@ -790,7 +798,8 @@ msgstr "Jítuán yǐjīng shǐyòngguò"
msgid "Group full"
msgstr "Fēnzǔ yǐ mǎn"
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
msgid "Hardware busy, try alternative pins"
msgstr "Yìngjiàn máng, qǐng chángshì qítā zhēnjiǎo"
@ -810,6 +819,11 @@ msgstr "I2C chūshǐhuà cuòwù"
msgid "I2C operation not supported"
msgstr "I2C cāozuò bù zhīchí"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
msgstr ""
#: py/persistentcode.c
msgid ""
"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/"
@ -991,6 +1005,10 @@ msgstr "Wúxiào de làng làngcháo wénjiàn"
msgid "Invalid word/bit length"
msgstr "Wúxiào de zì/wèi chángdù"
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
#: py/compile.c
msgid "LHS of keyword arg must be an id"
msgstr "Guānjiàn zì arg de LHS bìxū shì id"
@ -1036,7 +1054,7 @@ msgstr "MicroPython zhìmìng cuòwù."
msgid "Microphone startup delay must be in range 0.0 to 1.0"
msgstr "Màikèfēng qǐdòng yánchí bìxū zài 0.0 Dào 1.0 De fànwéi nèi"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr "Quēshǎo MISO huò MOSI yǐn jiǎo"
@ -1044,7 +1062,7 @@ msgstr "Quēshǎo MISO huò MOSI yǐn jiǎo"
msgid "Must be a %q subclass."
msgstr "Bìxū shì %q zi lèi."
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Must provide MISO or MOSI pin"
msgstr "Bìxū tígōng MISO huò MOSI yǐn jiǎo"
@ -1075,11 +1093,11 @@ msgstr "Méiyǒu DAC zài xīnpiàn shàng de"
msgid "No DMA channel found"
msgstr "Wèi zhǎodào DMA píndào"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MISO Pin"
msgstr "Méiyǒu MISO yǐn jiǎo"
#: ports/stm/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "No MOSI Pin"
msgstr "Méiyǒu MOSI yǐn jiǎo"
@ -1099,6 +1117,10 @@ msgstr "Wèi zhǎodào TX yǐn jiǎo"
msgid "No available clocks"
msgstr "Méiyǒu kěyòng de shízhōng"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "wú mòrèn %q zǒngxiàn"
@ -1120,6 +1142,10 @@ msgstr "Shízhōng yǐn jiǎo wú yìngjiàn zhīchí"
msgid "No hardware support on pin"
msgstr "Méiyǒu zài yǐn jiǎo shàng de yìngjiàn zhīchí"
#: shared-bindings/aesio/aes.c
msgid "No key was specified"
msgstr ""
#: ports/stm/common-hal/pulseio/PWMOut.c
msgid "No more timers available on this pin."
msgstr "Gāi yǐn jiǎo shàng méiyǒu kěyòng de dìngshí qì."
@ -1307,6 +1333,10 @@ msgstr "Zhǐ dú duìxiàng"
msgid "Refresh too soon"
msgstr "Shuāxīn tài kuàile"
#: shared-bindings/aesio/aes.c
msgid "Requested AES mode is unsupported"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
msgstr "Bù zhīchí yòu tōngdào"
@ -1370,6 +1400,10 @@ msgstr "Qiēpiàn hé zhí bùtóng chángdù."
msgid "Slices not supported"
msgstr "Qiēpiàn bù shòu zhīchí"
#: shared-bindings/aesio/aes.c
msgid "Source and destination buffers must be the same length"
msgstr ""
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Yǔ zi bǔhuò fēnliè"
@ -1460,6 +1494,10 @@ msgstr "Xiǎnshì zǒngxiàn tài duōle"
msgid "Too many displays"
msgstr "Xiǎnshì tài duō"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (Zuìjìn yīcì dǎ diànhuà):\n"

View File

@ -20,7 +20,7 @@ CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_COUNTIO = 0
CFLAGS_INLINE_LIMIT = 60
CFLAGS_INLINE_LIMIT = 55
SUPEROPT_GC = 0
# Include these Python libraries in firmware.

View File

@ -45,6 +45,9 @@
#include "samd/sercom.h"
#define UART_DEBUG(...) (void)0
// #define UART_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
// Do-nothing callback needed so that usart_async code will enable rx interrupts.
// See comment below re usart_async_register_callback()
static void usart_async_rxc_callback(const struct usart_async_descriptor *const descr) {

View File

@ -174,6 +174,10 @@ static void rtc_init(void) {
#endif
NVIC_ClearPendingIRQ(RTC_IRQn);
NVIC_EnableIRQ(RTC_IRQn);
#if CIRCUITPY_RTC
rtc_reset();
#endif
}
safe_mode_t port_init(void) {

View File

@ -93,6 +93,10 @@ endif
CFLAGS += $(INC) -Wall -Wno-cast-align -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT)
# TODO: add these when -Werror is applied
# Disable some warnings, as do most ports. NXP SDK causes undef, tinyusb causes cast-align
# CFLAGS += -Wno-undef -Wno-cast-align
CFLAGS += \
-mthumb \
-mapcs \

View File

@ -0,0 +1,39 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
* Copyright (c) 2019 Artur Pacholec
*
* 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 "mpconfigboard.h"
void board_init(void) {
}
bool board_requests_safe_mode(void) {
return false;
}
void reset_board(void) {
}

View File

@ -0,0 +1 @@
_ld_reserved_flash_size = 4K;

View File

@ -0,0 +1,126 @@
/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_flexspi_nor_boot.h"
#include "fsl_flexspi_nor_config.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.xip_device"
#endif
__attribute__((section(".boot_hdr.ivt")))
/*************************************
* IVT Data
*************************************/
const ivt image_vector_table = {
IVT_HEADER, /* IVT Header */
IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
IVT_RSVD, /* Reserved = 0 */
(uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
(uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
(uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
(uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
IVT_RSVD /* Reserved = 0 */
};
__attribute__((section(".boot_hdr.boot_data")))
/*************************************
* Boot Data
*************************************/
const BOOT_DATA_T boot_data = {
FLASH_BASE, /* boot start location */
FLASH_SIZE, /* size */
PLUGIN_FLAG, /* Plugin flag*/
0xFFFFFFFF /* empty - extra data word */
};
__attribute__((section(".boot_hdr.conf")))
// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
const flexspi_nor_config_t qspiflash_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
.csHoldTime = 1u,
.csSetupTime = 2u,
// Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
.sflashA1Size = FLASH_SIZE,
.lookupTable =
{
// FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
// (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
// FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
// Read LUTs
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
0,
0,
0x24040405,
0,
0,
0,
0,
0,
0,
0,
0x00000406,
0,
0,
0,
0,
0,
0,
0,
0x08180420,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0x081804D8,
0,
0,
0,
0x08180402,
0x00002004,
0,
0,
0,
0,
0,
0,
0x00000460,
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
.blockSize = 0x00010000,
.isUniformBlockSize = false,
};

View File

@ -0,0 +1,18 @@
#define MICROPY_HW_BOARD_NAME "Teensy 4.1"
#define MICROPY_HW_MCU_NAME "IMXRT1062DVJ6A"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (8 * 1024 * 1024)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO_AD_B1_00)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO_AD_B1_01)
#define DEFAULT_SPI_BUS_SCK (&pin_GPIO_B0_03)
#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO_B0_02)
#define DEFAULT_SPI_BUS_MISO (&pin_GPIO_B0_01)
#define DEFAULT_UART_BUS_RX (&pin_GPIO_AD_B0_03)
#define DEFAULT_UART_BUS_TX (&pin_GPIO_AD_B0_02)

View File

@ -0,0 +1,8 @@
USB_VID = 0x239A
USB_PID = 0x80AE
USB_PRODUCT = "Teensy 4.1"
USB_MANUFACTURER = "PJRC"
CHIP_VARIANT = MIMXRT1062DVJ6A
CHIP_FAMILY = MIMXRT1062
FLASH = W25Q64JV

View File

@ -0,0 +1,116 @@
#include "shared-bindings/board/__init__.h"
#include "boards/board.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
// With USB on left. Bottom edge.
{ MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO_EMC_04) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO_EMC_05) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO_EMC_06) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_EMC_08) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO_B0_10) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO_B1_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO_B1_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_B0_11) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO_B0_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_B0_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO_B0_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_B0_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO_B0_01) },
// Bottom Edge extended for 4.1
{ MP_OBJ_NEW_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_GPIO_EMC_32) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_GPIO_EMC_31) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_GPIO_EMC_37) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_GPIO_EMC_36) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO_B0_12) },
// Top edge
{ MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_B0_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO_B0_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA0), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCL0), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
// Top edge extended for Teensy 4.1
{ MP_OBJ_NEW_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO_EMC_07) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO_B1_13) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO_B1_12) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO_B1_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO_B1_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO_AD_B1_12) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO_AD_B1_13) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO_AD_B1_04) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO_AD_B1_05) },
// SD Card slot
{ MP_OBJ_NEW_QSTR(MP_QSTR_DAT1), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_DAT0), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_CMD), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_DAT3), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_DAT2), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D47), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
// Flash expansion spot and PSRAM expansion spot on a shared QSPI BUS
{ MP_OBJ_NEW_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_GPIO_EMC_24) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PSRAM_CS), MP_ROM_PTR(&pin_GPIO_EMC_24) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D49), MP_ROM_PTR(&pin_GPIO_EMC_27) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO1), MP_ROM_PTR(&pin_GPIO_EMC_27) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D50), MP_ROM_PTR(&pin_GPIO_EMC_28) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO2), MP_ROM_PTR(&pin_GPIO_EMC_28) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D51), MP_ROM_PTR(&pin_GPIO_EMC_22) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_GPIO_EMC_22) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D52), MP_ROM_PTR(&pin_GPIO_EMC_26) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO0), MP_ROM_PTR(&pin_GPIO_EMC_26) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D53), MP_ROM_PTR(&pin_GPIO_EMC_25) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_CLK), MP_ROM_PTR(&pin_GPIO_EMC_25) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D54), MP_ROM_PTR(&pin_GPIO_EMC_29) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO3), MP_ROM_PTR(&pin_GPIO_EMC_29) },
{ 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);

View File

@ -25,7 +25,6 @@
* THE SOFTWARE.
*/
//TODO
#include "shared-bindings/busio/SPI.h"
#include "py/mperrno.h"
#include "py/runtime.h"
@ -35,48 +34,12 @@
#include <stdio.h>
//bool never_reset_sercoms[SERCOM_INST_NUM];
//
//void never_reset_sercom(Sercom* sercom) {
// // Reset all SERCOMs except the ones being used by on-board devices.
// Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
// for (int i = 0; i < SERCOM_INST_NUM; i++) {
// if (sercom_instances[i] == sercom) {
// never_reset_sercoms[i] = true;
// break;
// }
// }
//}
//
//void allow_reset_sercom(Sercom* sercom) {
// // Reset all SERCOMs except the ones being used by on-board devices.
// Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
// for (int i = 0; i < SERCOM_INST_NUM; i++) {
// if (sercom_instances[i] == sercom) {
// never_reset_sercoms[i] = false;
// break;
// }
// }
//}
//
//void reset_sercoms(void) {
// // Reset all SERCOMs except the ones being used by on-board devices.
// Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
// for (int i = 0; i < SERCOM_INST_NUM; i++) {
// if (never_reset_sercoms[i]) {
// continue;
// }
// #ifdef MICROPY_HW_APA102_SERCOM
// if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) {
// continue;
// }
// #endif
// // SWRST is same for all modes of SERCOMs.
// sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1;
// }
//}
//arrays use 0 based numbering: SPI1 is stored at index 0
#define MAX_SPI 4
STATIC bool reserved_spi[MAX_SPI];
STATIC bool never_reset_spi[MAX_SPI];
static void config_periph_pin(const mcu_periph_obj_t *periph) {
STATIC void config_periph_pin(const mcu_periph_obj_t *periph) {
IOMUXC_SetPinMux(
periph->pin->mux_reg, periph->mux_mode,
periph->input_reg, periph->input_idx,
@ -97,52 +60,117 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
#define LPSPI_MASTER_CLK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (CLOCK_GetDiv(kCLOCK_LpspiDiv)))
void spi_reset(void) {
for (int i = 0; i < MAX_SPI; i++) {
reserved_spi[i] = false;
}
}
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) {
// TODO: Allow none mosi or miso
const uint32_t sck_count = MP_ARRAY_SIZE(mcu_spi_sck_list);
const uint32_t miso_count = MP_ARRAY_SIZE(mcu_spi_miso_list);
const uint32_t mosi_count = MP_ARRAY_SIZE(mcu_spi_mosi_list);
bool spi_taken = false;
const uint32_t sck_count = sizeof(mcu_spi_sck_list) / sizeof(mcu_periph_obj_t);
const uint32_t miso_count = sizeof(mcu_spi_miso_list) / sizeof(mcu_periph_obj_t);
const uint32_t mosi_count = sizeof(mcu_spi_mosi_list) / sizeof(mcu_periph_obj_t);
for (uint32_t i = 0; i < sck_count; ++i) {
if (mcu_spi_sck_list[i].pin != clock)
for (uint i = 0; i < sck_count; i++) {
if (mcu_spi_sck_list[i].pin != clock) {
continue;
for (uint32_t j = 0; j < miso_count; ++j) {
if (mcu_spi_miso_list[j].pin != miso)
continue;
if (mcu_spi_miso_list[j].bank_idx != mcu_spi_sck_list[i].bank_idx)
continue;
for (uint32_t k = 0; k < mosi_count; ++k) {
if (mcu_spi_mosi_list[k].pin != mosi)
}
//if both MOSI and MISO exist, loop search normally
if ((mosi != NULL) && (miso != NULL)) {
for (uint j = 0; j < mosi_count; j++) {
if ((mcu_spi_mosi_list[i].pin != mosi)
|| (mcu_spi_sck_list[i].bank_idx != mcu_spi_mosi_list[j].bank_idx)){
continue;
if (mcu_spi_mosi_list[k].bank_idx != mcu_spi_miso_list[j].bank_idx)
continue;
self->clock_pin = &mcu_spi_sck_list[i];
self->miso_pin = &mcu_spi_miso_list[j];
self->mosi_pin = &mcu_spi_mosi_list[k];
}
for (uint k = 0; k < miso_count; k++) {
if ((mcu_spi_miso_list[k].pin != miso) //everything needs the same index
|| (mcu_spi_sck_list[i].bank_idx != mcu_spi_miso_list[k].bank_idx)) {
continue;
}
//keep looking if the SPI is taken, edge case
if (reserved_spi[mcu_spi_sck_list[i].bank_idx - 1]) {
spi_taken = true;
continue;
}
//store pins if not
self->clock = &mcu_spi_sck_list[i];
self->mosi = &mcu_spi_mosi_list[j];
self->miso = &mcu_spi_miso_list[k];
break;
}
if (self->clock != NULL) {
break; // Multi-level break to pick lowest peripheral
}
}
if (self->clock != NULL) {
break;
}
// if just MISO, reduce search
} else if (miso != NULL) {
for (uint j = 0; j < miso_count; j++) {
if ((mcu_spi_miso_list[j].pin != miso) //only SCK and MISO need the same index
|| (mcu_spi_sck_list[i].bank_idx != mcu_spi_miso_list[j].bank_idx)) {
continue;
}
if (reserved_spi[mcu_spi_sck_list[i].bank_idx - 1]) {
spi_taken = true;
continue;
}
self->clock = &mcu_spi_sck_list[i];
self->mosi = NULL;
self->miso = &mcu_spi_miso_list[j];
break;
}
if (self->clock != NULL) {
break;
}
// if just MOSI, reduce search
} else if (mosi != NULL) {
for (uint j = 0; j < mosi_count; j++) {
if ((mcu_spi_mosi_list[j].pin != mosi) //only SCK and MOSI need the same index
|| (mcu_spi_sck_list[i].bank_idx != mcu_spi_mosi_list[j].bank_idx)) {
continue;
}
if (reserved_spi[mcu_spi_sck_list[i].bank_idx - 1]) {
spi_taken = true;
continue;
}
self->clock = &mcu_spi_sck_list[i];
self->mosi = &mcu_spi_mosi_list[j];
self->miso = NULL;
break;
}
if (self->clock != NULL) {
break;
}
} else {
//throw an error immediately
mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
}
}
if(self->clock_pin == NULL || self->mosi_pin == NULL || self->miso_pin == NULL) {
mp_raise_RuntimeError(translate("Invalid SPI pin selection"));
if (self->clock != NULL && (self->mosi != NULL || self->miso != NULL)) {
self->spi = mcu_spi_banks[self->clock->bank_idx - 1];
} else {
self->spi = mcu_spi_banks[self->clock_pin->bank_idx - 1];
if (spi_taken) {
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
} else {
mp_raise_ValueError(translate("Invalid SPI pin selection"));
}
}
config_periph_pin(self->mosi_pin);
config_periph_pin(self->miso_pin);
config_periph_pin(self->clock_pin);
config_periph_pin(self->clock);
if (self->mosi != NULL) {
config_periph_pin(self->mosi);
}
if (self->miso != NULL) {
config_periph_pin(self->miso);
}
reserved_spi[self->clock->bank_idx - 1] = true;
lpspi_master_config_t config = { 0 };
LPSPI_MasterGetDefaultConfig(&config);
@ -150,47 +178,27 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
// Always start at 250khz which is what SD cards need. They are sensitive to
// SPI bus noise before they are put into SPI mode.
config.baudRate = 250000;
LPSPI_MasterInit(self->spi, &config, LPSPI_MASTER_CLK_FREQ);
LPSPI_Enable(self->spi, false);
uint32_t tcrPrescaleValue;
self->baudrate = LPSPI_MasterSetBaudRate(self->spi, config.baudRate, LPSPI_MASTER_CLK_FREQ, &tcrPrescaleValue);
LPSPI_Enable(self->spi, true);
claim_pin(self->clock_pin->pin);
// if (mosi_none) {
// self->MOSI_pin = NO_PIN;
// } else {
// gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_OUT);
// gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF);
// gpio_set_pin_function(mosi->number, mosi_pinmux);
// self->MOSI_pin = mosi->number;
claim_pin(self->mosi_pin->pin);
// }
// if (miso_none) {
// self->MISO_pin = NO_PIN;
// } else {
// gpio_set_pin_direction(miso->number, GPIO_DIRECTION_IN);
// gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF);
// gpio_set_pin_function(miso->number, miso_pinmux);
// self->MISO_pin = miso->number;
claim_pin(self->miso_pin->pin);
// }
claim_pin(self->clock->pin);
if (self->mosi != NULL) {
claim_pin(self->mosi->pin);
}
if (self->miso != NULL) {
claim_pin(self->miso->pin);
}
}
void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
// never_reset_sercom(self->spi_desc.dev.prvt);
// never_reset_pin_number(self->clock_pin);
// never_reset_pin_number(self->MOSI_pin);
// never_reset_pin_number(self->MISO_pin);
// TODO
}
bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
return self->clock_pin == NULL;
return self->clock == NULL;
}
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
@ -198,14 +206,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
return;
}
// allow_reset_sercom(self->spi_desc.dev.prvt);
// spi_m_sync_disable(&self->spi_desc);
// spi_m_sync_deinit(&self->spi_desc);
// reset_pin_number(self->clock_pin);
// reset_pin_number(self->MOSI_pin);
// reset_pin_number(self->MISO_pin);
self->clock_pin = NULL;
self->clock = NULL;
}
bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
@ -260,6 +261,9 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self,
if (len == 0) {
return true;
}
if (self->mosi == NULL) {
mp_raise_ValueError(translate("No MOSI Pin"));
}
lpspi_transfer_t xfer = { 0 };
xfer.txData = (uint8_t*)data;
@ -278,6 +282,9 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self,
if (len == 0) {
return true;
}
if (self->miso == NULL) {
mp_raise_ValueError(translate("No MISO Pin"));
}
LPSPI_SetDummyData(self->spi, write_value);
@ -296,6 +303,9 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uin
if (len == 0) {
return true;
}
if (self->miso == NULL || self->mosi == NULL) {
mp_raise_ValueError(translate("Missing MISO or MOSI Pin"));
}
LPSPI_SetDummyData(self->spi, 0xFF);

View File

@ -38,9 +38,11 @@ typedef struct {
LPSPI_Type *spi;
bool has_lock;
uint32_t baudrate;
const mcu_periph_obj_t *clock_pin;
const mcu_periph_obj_t *mosi_pin;
const mcu_periph_obj_t *miso_pin;
const mcu_periph_obj_t *clock;
const mcu_periph_obj_t *mosi;
const mcu_periph_obj_t *miso;
} busio_spi_obj_t;
void spi_reset(void);
#endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_BUSIO_SPI_H

View File

@ -198,15 +198,18 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
claim_pin(self->tx_pin->pin);
if (self->rx_pin != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
// The LPUART ring buffer wastes one byte to distinguish between full and empty.
self->ringbuf = gc_alloc(receiver_buffer_size + 1, false, true /*long-lived*/);
if (!self->rbuf.buf) {
if (!self->ringbuf) {
LPUART_Deinit(self->uart);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}
LPUART_TransferCreateHandle(self->uart, &self->handle, LPUART_UserCallback, self);
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->rbuf.buf, self->rbuf.size);
// Pass actual allocated size; the LPUART routines are cognizant that
// the capacity is one less than the size.
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->ringbuf, receiver_buffer_size + 1);
claim_pin(self->rx_pin->pin);
}
@ -223,9 +226,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
LPUART_Deinit(self->uart);
gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
gc_free(self->ringbuf);
// reset_pin_number(self->rx_pin);
// reset_pin_number(self->tx_pin);

View File

@ -40,7 +40,7 @@ typedef struct {
mp_obj_base_t base;
LPUART_Type *uart;
lpuart_handle_t handle;
ringbuf_t rbuf;
uint8_t* ringbuf;
bool rx_ongoing;
uint32_t baudrate;
uint8_t character_bits;

View File

@ -41,6 +41,7 @@
#include "common-hal/pulseio/PulseOut.h"
#include "common-hal/pulseio/PWMOut.h"
#include "common-hal/rtc/RTC.h"
#include "common-hal/busio/SPI.h"
#include "reset.h"
@ -267,7 +268,7 @@ safe_mode_t port_init(void) {
}
void reset_port(void) {
//reset_sercoms();
spi_reset();
#if CIRCUITPY_AUDIOIO
audio_dma_reset();

View File

@ -11,7 +11,6 @@ EXTERNAL_FLASH_DEVICES = "GD25Q16C"
# Allocate two, not just one I2C peripheral for CPB, so that we have both
# on-board and off-board I2C available.
# When SPIM3 becomes available we'll be able to have two I2C and two SPI peripherals.
# We use a CFLAGS define here because there are include order issues
# if we try to include "mpconfigport.h" into nrfx_config.h .
CFLAGS += -DCIRCUITPY_NRF_NUM_I2C=2

View File

@ -0,0 +1,40 @@
# Makerdiary Pitaya Go
>Pitaya Go is a compact and versatile development platform for IoT solutions,
combining the Nordic's high-end multiprotocol SoC nRF52840 and the Microchip's
extreme low power Wi-Fi® network controller ATWINC1500B. It offers a complete
solution for wireless connectivity with IEEE 802.11 b/g/n, Bluetooth 5, Thread
and Zigbee, that is specifically designed for the IoT.
Pitaya Go features a Battery Charger with power path management, 64Mbit ultra
low power QSPI Flash memory, additional NFC-A Tag PCB Antenna, user
programmable RGB LED and Buttons, reversible USB-C Connector and easily
expandable Header Sockets. All these features above make this board an ideal
choice for the next IoT project.
from [Makerdiary](https://store.makerdiary.com/products/pitaya-go)
## Installing CircuitPython submodules
Before you can build, you will need to run the following commands once, which
will install the submodules that are part of the CircuitPython ecosystem, and
build the `mpy-cross` tool:
```
$ cd circuitpython
$ git submodule update --init
$ make -C mpy-cross
```
## Building
```sh
$ cd ports/nrf
$ make BOARD=pitaya_go SD=s140 -V=1 -j4
```
# Flashing CircuitPython
The Pitaya Go has a pre-programmed bootloader which can be used to program the
Pitaya Go. Follow [the guide - How to Program Pitaya Go](https://wiki.makerdiary.com/pitaya-go/programming/)
to flash the CircuitPython firmware.

View File

@ -0,0 +1,38 @@
/*
* 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"
void board_init(void) {
}
bool board_requests_safe_mode(void) {
return false;
}
void reset_board(void) {
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Glenn Ruben Bakke
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2020 Yihui Xiong
*
* 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 "nrfx/hal/nrf_gpio.h"
#define MAKERDIARYPITAYAGO
#define MICROPY_HW_BOARD_NAME "Makerdiary Pitaya Go"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 6)
#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 1)
#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 5)
#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 2)
#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 4)
#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 3)
#define BOARD_HAS_CRYSTAL 1

View File

@ -0,0 +1,11 @@
# Using Nordic's VID - https://devzone.nordicsemi.com/f/nordic-q-a/50638/usb-pid-for-nrf52840
USB_VID = 0x1915
USB_PID = 0xb001
USB_PRODUCT = "Pitaya Go"
USB_MANUFACTURER = "Makerdiary"
MCU_CHIP = nrf52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "MX25R6435F"

View File

@ -0,0 +1,64 @@
#include "shared-bindings/board/__init__.h"
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) },
{ MP_ROM_QSTR(MP_QSTR_AIN1), MP_ROM_PTR(&pin_P0_03) },
{ MP_ROM_QSTR(MP_QSTR_AIN2), MP_ROM_PTR(&pin_P0_04) },
{ MP_ROM_QSTR(MP_QSTR_AIN3), MP_ROM_PTR(&pin_P0_05) },
{ MP_ROM_QSTR(MP_QSTR_AIN4), MP_ROM_PTR(&pin_P0_28) },
{ MP_ROM_QSTR(MP_QSTR_AIN5), MP_ROM_PTR(&pin_P0_29) },
{ MP_ROM_QSTR(MP_QSTR_AIN6), MP_ROM_PTR(&pin_P0_30) },
{ MP_ROM_QSTR(MP_QSTR_AIN7), MP_ROM_PTR(&pin_P0_31) },
{ MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_04) },
{ MP_ROM_QSTR(MP_QSTR_VDIV), MP_ROM_PTR(&pin_P0_05) },
{ MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) },
{ MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) },
{ MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_P0_02) },
{ MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_P0_03) },
{ MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_P0_04) },
{ MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_P0_05) },
{ MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_P0_06) },
{ MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_P0_07) },
{ MP_ROM_QSTR(MP_QSTR_P8), MP_ROM_PTR(&pin_P0_08) },
{ MP_ROM_QSTR(MP_QSTR_P9), MP_ROM_PTR(&pin_P0_09) },
{ MP_ROM_QSTR(MP_QSTR_P10), MP_ROM_PTR(&pin_P0_10) },
{ MP_ROM_QSTR(MP_QSTR_P11), MP_ROM_PTR(&pin_P0_11) },
{ MP_ROM_QSTR(MP_QSTR_P12), MP_ROM_PTR(&pin_P0_12) },
{ MP_ROM_QSTR(MP_QSTR_P13), MP_ROM_PTR(&pin_P0_13) },
{ MP_ROM_QSTR(MP_QSTR_P14), MP_ROM_PTR(&pin_P0_14) },
{ MP_ROM_QSTR(MP_QSTR_P15), MP_ROM_PTR(&pin_P0_15) },
{ MP_ROM_QSTR(MP_QSTR_P16), MP_ROM_PTR(&pin_P0_16) },
{ MP_ROM_QSTR(MP_QSTR_P17), MP_ROM_PTR(&pin_P0_17) },
{ MP_ROM_QSTR(MP_QSTR_P18), MP_ROM_PTR(&pin_P0_18) },
{ MP_ROM_QSTR(MP_QSTR_P19), MP_ROM_PTR(&pin_P0_19) },
{ MP_ROM_QSTR(MP_QSTR_P20), MP_ROM_PTR(&pin_P0_20) },
{ MP_ROM_QSTR(MP_QSTR_P21), MP_ROM_PTR(&pin_P0_21) },
{ MP_ROM_QSTR(MP_QSTR_P22), MP_ROM_PTR(&pin_P0_22) },
{ MP_ROM_QSTR(MP_QSTR_P23), MP_ROM_PTR(&pin_P0_23) },
{ MP_ROM_QSTR(MP_QSTR_P24), MP_ROM_PTR(&pin_P0_24) },
{ MP_ROM_QSTR(MP_QSTR_P25), MP_ROM_PTR(&pin_P0_25) },
{ MP_ROM_QSTR(MP_QSTR_P26), MP_ROM_PTR(&pin_P0_26) },
{ MP_ROM_QSTR(MP_QSTR_P27), MP_ROM_PTR(&pin_P0_27) },
{ MP_ROM_QSTR(MP_QSTR_P28), MP_ROM_PTR(&pin_P0_28) },
{ MP_ROM_QSTR(MP_QSTR_P29), MP_ROM_PTR(&pin_P0_29) },
{ MP_ROM_QSTR(MP_QSTR_P30), MP_ROM_PTR(&pin_P0_30) },
{ MP_ROM_QSTR(MP_QSTR_P31), MP_ROM_PTR(&pin_P0_31) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_04) },
{ MP_ROM_QSTR(MP_QSTR_CSN), MP_ROM_PTR(&pin_P1_03) },
{ MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_P1_06) },
{ MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_P1_01) },
{ MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_P1_05) },
{ MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_P1_02) },
{ MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_P0_10) },
{ MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_P0_11) },
{ MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P0_12) },
{ MP_ROM_QSTR(MP_QSTR_USR_BTN), MP_ROM_PTR(&pin_P1_00) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View File

@ -127,6 +127,7 @@ size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *sel
// self->value is set by evt handler.
return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
// conn_handle is ignored for non-system attributes.
return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len);
}
}
@ -152,6 +153,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
(self->props & CHAR_PROP_WRITE_NO_RESPONSE));
} else {
// Always write the value locally even if no connections are active.
// conn_handle is ignored for non-system attributes, so we use BLE_CONN_HANDLE_INVALID.
common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo);
// Check to see if we need to notify or indicate any active connections.
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {

View File

@ -40,13 +40,11 @@
#include "supervisor/shared/tick.h"
#include "common-hal/_bleio/CharacteristicBuffer.h"
// Push all the data onto the ring buffer. When the buffer is full, new bytes will be dropped.
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
// Push all the data onto the ring buffer.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
for (size_t i = 0; i < len; i++) {
ringbuf_put(&self->ringbuf, data[i]);
}
ringbuf_put_n(&self->ringbuf, data, len);
sd_nvic_critical_region_exit(is_nested_critical_region);
}
@ -98,11 +96,11 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
}
int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
while ( (ringbuf_count(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@ -114,21 +112,18 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
size_t rx_bytes = MIN(ringbuf_count(&self->ringbuf), len);
for ( size_t i = 0; i < rx_bytes; i++ ) {
data[i] = ringbuf_get(&self->ringbuf);
}
uint32_t num_bytes_read = ringbuf_get_n(&self->ringbuf, data, len);
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
return rx_bytes;
return num_bytes_read;
}
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
uint16_t count = ringbuf_count(&self->ringbuf);
uint16_t count = ringbuf_num_filled(&self->ringbuf);
sd_nvic_critical_region_exit(is_nested_critical_region);
return count;
}

View File

@ -371,6 +371,11 @@ mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_
return 1.25f * self->conn_params.min_conn_interval;
}
// Return the current negotiated MTU length, minus overhead.
mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self) {
return (self->mtu == 0 ? BLE_GATT_ATT_MTU_DEFAULT : self->mtu) - 3;
}
void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) {
self->conn_params_updating = true;
uint16_t interval = new_interval / 1.25f;
@ -752,3 +757,16 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* interna
return MP_OBJ_FROM_PTR(connection);
}
// Find the connection that uses the given conn_handle. Return NULL if not found.
bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle) {
bleio_connection_internal_t *connection;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
connection = &bleio_connections[i];
if (connection->conn_handle == conn_handle) {
return connection;
}
}
return NULL;
}

View File

@ -87,5 +87,6 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in);
uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* connection);
bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle);
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H

View File

@ -41,7 +41,7 @@
#include "supervisor/shared/tick.h"
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
if (len + sizeof(uint16_t) > self->ringbuf.size) {
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
// This shouldn't happen.
return;
}
@ -49,7 +49,7 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
// Make room for the new value by dropping the oldest packets first.
while (self->ringbuf.size - ringbuf_count(&self->ringbuf) < (int) (len + sizeof(uint16_t))) {
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
for (uint16_t i = 0; i < packet_length; i++) {
@ -105,12 +105,18 @@ STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
}
STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
const uint16_t evt_id = ble_evt->header.evt_id;
// Check if this is a GATTC event so we can make sure the conn_handle is valid.
if (evt_id < BLE_GATTC_EVT_BASE || evt_id > BLE_GATTC_EVT_LAST) {
return false;
}
uint16_t conn_handle = ble_evt->evt.gattc_evt.conn_handle;
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
if (conn_handle != self->conn_handle) {
return false;
}
switch (ble_evt->header.evt_id) {
switch (evt_id) {
case BLE_GATTC_EVT_HVX: {
// A remote service wrote to this characteristic.
ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
@ -140,9 +146,9 @@ STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
switch (ble_evt->header.evt_id) {
case BLE_GATTS_EVT_WRITE: {
uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
// A client wrote to this server characteristic.
ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
@ -166,7 +172,7 @@ STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
break;
}
case BLE_GAP_EVT_DISCONNECTED: {
if (self->conn_handle == conn_handle) {
if (self->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
self->conn_handle = BLE_CONN_HANDLE_INVALID;
}
}
@ -200,10 +206,7 @@ void common_hal_bleio_packet_buffer_construct(
}
if (incoming) {
// This is a macro.
ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false);
if (self->ringbuf.buf == NULL) {
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
}
}
@ -247,45 +250,66 @@ void common_hal_bleio_packet_buffer_construct(
}
}
int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
if (ringbuf_count(&self->ringbuf) < 2) {
mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
if (ringbuf_num_filled(&self->ringbuf) < 2) {
return 0;
}
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
// Copy received data. Lock out write interrupt handler while copying.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
if (packet_length > len) {
return len - packet_length;
}
// Get packet length, which is in first two bytes of packet.
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
ringbuf_get_n(&self->ringbuf, data, packet_length);
mp_int_t ret;
if (packet_length > len) {
// Packet is longer than requested. Return negative of overrun value.
ret = len - packet_length;
// Discard the packet if it's too large. Don't fill data.
while (packet_length--) {
(void) ringbuf_get(&self->ringbuf);
}
} else {
// Read as much as possible, but might be shorter than len.
ringbuf_get_n(&self->ringbuf, data, packet_length);
ret = packet_length;
}
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
return packet_length;
return ret;
}
void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
if (self->outgoing[0] == NULL) {
mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic"));
}
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return;
return -1;
}
uint16_t packet_size = common_hal_bleio_packet_buffer_get_packet_size(self);
uint16_t max_size = packet_size - len;
while (max_size < self->pending_size && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
RUN_BACKGROUND_TASKS;
uint16_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
if (len + header_len > outgoing_packet_length) {
// Supplied data will not fit in a single BLE packet.
mp_raise_ValueError(translate("Total data to write is larger than outgoing_packet_length"));
}
if (len + self->pending_size > outgoing_packet_length) {
// No room to append len bytes to packet. Wait until we get a free buffer,
// and keep checking that we haven't been disconnected.
while (self->pending_size != 0 && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
RUN_BACKGROUND_TASKS;
}
}
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return;
return -1;
}
size_t num_bytes_written = 0;
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
@ -294,9 +318,11 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
if (self->pending_size == 0) {
memcpy(pending, header, header_len);
self->pending_size += header_len;
num_bytes_written += header_len;
}
memcpy(pending + self->pending_size, data, len);
self->pending_size += len;
num_bytes_written += len;
sd_nvic_critical_region_exit(is_nested_critical_region);
@ -304,28 +330,69 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
if (!self->packet_queued) {
queue_next_write(self);
}
return num_bytes_written;
}
uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self) {
uint16_t mtu;
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return 0;
mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self) {
// If this PacketBuffer is coming from a remote service via NOTIFY or INDICATE
// the maximum size is what can be sent in one
// BLE packet. But we must be connected to know that value.
//
// Otherwise it can be as long as the characteristic
// will permit, whether or not we're connected.
if (self->characteristic == NULL) {
return -1;
}
bleio_connection_internal_t *connection;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
connection = &bleio_connections[i];
if (connection->conn_handle == self->conn_handle) {
break;
if (self->characteristic->service != NULL &&
self->characteristic->service->is_remote &&
(common_hal_bleio_characteristic_get_properties(self->characteristic) &
(CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
// We are talking to a remote service, and data is arriving via NOTIFY or INDICATE.
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
if (connection) {
return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
self->characteristic->max_length);
}
}
// There's no current connection, so we don't know the MTU, and
// we can't tell what the largest incoming packet length would be.
return -1;
}
if (connection->mtu == 0) {
mtu = BLE_GATT_ATT_MTU_DEFAULT;
return self->characteristic->max_length;
}
mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_buffer_obj_t *self) {
// If we are sending data via NOTIFY or INDICATE, the maximum size
// is what can be sent in one BLE packet. But we must be connected
// to know that value.
//
// Otherwise it can be as long as the characteristic
// will permit, whether or not we're connected.
if (self->characteristic == NULL) {
return -1;
}
if (self->characteristic->max_length > mtu) {
mtu = self->characteristic->max_length;
if (self->characteristic->service != NULL &&
!self->characteristic->service->is_remote &&
(common_hal_bleio_characteristic_get_properties(self->characteristic) &
(CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
// We are sending to a client, via NOTIFY or INDICATE.
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
if (connection) {
return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
self->characteristic->max_length);
}
}
// There's no current connection, so we don't know the MTU, and
// we can't tell what the largest outgoing packet length would be.
return -1;
}
uint16_t att_overhead = 3;
return mtu - att_overhead;
return self->characteristic->max_length;
}
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {

View File

@ -40,8 +40,10 @@ typedef struct {
// Two outgoing buffers to alternate between. One will be queued for transmission by the SD and
// the other is waiting to be queued and can be extended.
uint8_t* outgoing[2];
uint16_t pending_size;
uint16_t conn_handle;
volatile uint16_t pending_size;
// We remember the conn_handle so we can do a NOTIFY/INDICATE to a client.
// We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read).
volatile uint16_t conn_handle;
uint8_t pending_index;
uint8_t write_type;
bool client;

View File

@ -39,6 +39,8 @@ typedef struct bleio_service_obj {
bool is_remote;
bool is_secondary;
bleio_uuid_obj_t *uuid;
// The connection object is set only when this is a remote service.
// A local service doesn't know the connection.
mp_obj_t connection;
mp_obj_list_t *characteristic_list;
// Range of attribute handles of this remote service.

View File

@ -118,8 +118,8 @@ void common_hal_bleio_check_connected(uint16_t conn_handle) {
// GATTS read of a Characteristic or Descriptor.
size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
// conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
// we can still read and write the local value.
// conn_handle is ignored unless this is a system attribute.
// If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = buf,
@ -132,8 +132,8 @@ size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_
}
void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) {
// conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
// we can still read and write the local value.
// conn_handle is ignored unless this is a system attribute.
// If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = bufinfo->buf,

View File

@ -98,7 +98,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
switch ( event->type ) {
case NRFX_UARTE_EVT_RX_DONE:
ringbuf_put_n(&self->rbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
// keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
@ -112,7 +112,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
// Possible Error source is Overrun, Parity, Framing, Break
// uint32_t errsrc = event->data.error.error_mask;
ringbuf_put_n(&self->rbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
ringbuf_put_n(&self->ringbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
// Keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
@ -190,9 +190,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// pointers like this are NOT moved, allocating the buffer
// in the long-lived pool is not strictly necessary)
// (This is a macro.)
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
if ( !self->rbuf.buf ) {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
nrfx_uarte_uninit(self->uarte);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}
@ -226,10 +224,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx_pin_number);
self->tx_pin_number = NO_PIN;
self->rx_pin_number = NO_PIN;
gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
ringbuf_free(&self->ringbuf);
}
}
@ -239,11 +234,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
mp_raise_ValueError(translate("No RX pin"));
}
size_t rx_bytes = 0;
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@ -254,12 +248,8 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// prevent conflict with uart irq
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
// copy received data
rx_bytes = ringbuf_count(&self->rbuf);
rx_bytes = MIN(rx_bytes, len);
for ( uint16_t i = 0; i < rx_bytes; i++ ) {
data[i] = ringbuf_get(&self->rbuf);
}
// Copy as much received data as available, up to len bytes.
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
@ -316,13 +306,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return ringbuf_count(&self->rbuf);
return ringbuf_num_filled(&self->ringbuf);
}
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// prevent conflict with uart irq
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
ringbuf_clear(&self->rbuf);
ringbuf_clear(&self->ringbuf);
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
}

View File

@ -41,7 +41,7 @@ typedef struct {
uint32_t baudrate;
uint32_t timeout_ms;
ringbuf_t rbuf;
ringbuf_t ringbuf;
uint8_t rx_char; // EasyDMA buf
uint8_t tx_pin_number;

View File

@ -14,39 +14,21 @@ USB_SERIAL_NUMBER_LENGTH = 16
# All nRF ports have longints.
LONGINT_IMPL = MPZ
# The ?='s allow overriding in mpconfigboard.mk.
# Audio via PWM
ifndef CIRCUITPY_AUDIOCORE
CIRCUITPY_AUDIOCORE = 1
endif
CIRCUITPY_AUDIOIO = 0
CIRCUITPY_AUDIOBUSIO ?= 1
CIRCUITPY_AUDIOCORE ?= 1
CIRCUITPY_AUDIOMIXER ?= 1
CIRCUITPY_AUDIOPWMIO ?= 1
# The ifndef's allow overriding in mpconfigboard.mk.
ifndef
CIRCUITPY_BLEIO = 1
endif
ifndef CIRCUITPY_AUDIOMIXER
CIRCUITPY_AUDIOMIXER = 1
endif
ifndef CIRCUITPY_AUDIOPWMIO
CIRCUITPY_AUDIOPWMIO = 1
endif
ifndef CIRCUITPY_AUDIOBUSIO
CIRCUITPY_AUDIOBUSIO = 1
endif
CIRCUITPY_BLEIO ?= 1
# No I2CSlave implementation
CIRCUITPY_I2CSLAVE = 0
# enable RTC
ifndef CIRCUITPY_RTC
CIRCUITPY_RTC = 1
endif
CIRCUITPY_RTC ?= 1
# frequencyio not yet implemented
CIRCUITPY_FREQUENCYIO = 0
@ -74,8 +56,6 @@ NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
# Defined here because system_nrf52840.c doesn't #include any of our own include files.
CFLAGS += -DCONFIG_NFCT_PINS_AS_GPIOS
CIRCUITPY_ULAB = 1
else
ifeq ($(MCU_CHIP),nrf52833)
MCU_SERIES = m4

View File

@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -12,7 +12,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define the top end of the stack. The stack is full descending so begins just

View File

@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -14,7 +14,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -14,7 +14,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -14,7 +14,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define the top end of the stack. The stack is full descending so begins just

View File

@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -38,7 +38,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just

View File

@ -12,8 +12,8 @@ MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 128K /* sector 0, 128K */
FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 128K /* sector 1, 128K */
FLASH_FIRMWARE (rx) : ORIGIN = 0x08040000, LENGTH = 1792K /* sectors 6*128 + 8*128 */
FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 384K /* sector 1-3, 128K */
FLASH_FIRMWARE (rx) : ORIGIN = 0x08080000, LENGTH = 1536K /* sectors 4*128 + 8*128 */
DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K /* AXI SRAM */
SRAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K /* AHB1 SRAM */
@ -22,7 +22,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_stack_size = 24K; /*TODO: this can probably be bigger, but how big?*/
_minimum_heap_size = 16K;
/* brainless copy paste for stack code. Results in ambiguous hard crash */

View File

@ -209,8 +209,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// Init buffer for rx and claim pins
if (self->rx != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
if (!self->rbuf.buf) {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
mp_raise_ValueError(translate("UART Buffer allocation error"));
}
claim_pin(rx);
@ -246,9 +245,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx->pin->port,self->rx->pin->number);
self->tx = NULL;
self->rx = NULL;
gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
ringbuf_free(&self->ringbuf);
}
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
@ -256,11 +253,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
mp_raise_ValueError(translate("No RX pin"));
}
size_t rx_bytes = 0;
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout, same as nrf
while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
//restart if it failed in the callback
if (errflag != HAL_OK) {
@ -274,12 +270,8 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
// copy received data
rx_bytes = ringbuf_count(&self->rbuf);
rx_bytes = MIN(rx_bytes, len);
for (uint16_t i = 0; i < rx_bytes; i++) {
data[i] = ringbuf_get(&self->rbuf);
}
// Copy as much received data as available, up to len bytes.
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
HAL_NVIC_EnableIRQ(self->irq);
if (rx_bytes == 0) {
@ -319,7 +311,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
if ((HAL_UART_GetState(handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
return;
}
ringbuf_put_n(&context->rbuf, &context->rx_char, 1);
ringbuf_put_n(&context->ringbuf, &context->rx_char, 1);
errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1);
return;
@ -378,13 +370,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return ringbuf_count(&self->rbuf);
return ringbuf_num_filled(&self->ringbuf);
}
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
ringbuf_clear(&self->rbuf);
ringbuf_clear(&self->ringbuf);
HAL_NVIC_EnableIRQ(self->irq);
}

View File

@ -47,7 +47,7 @@ typedef struct {
const mcu_periph_obj_t *tx;
const mcu_periph_obj_t *rx;
ringbuf_t rbuf;
ringbuf_t ringbuf;
uint8_t rx_char;
uint32_t baudrate;

View File

@ -134,3 +134,15 @@ GPIO_TypeDef * pin_port(uint8_t pin_port) {
uint16_t pin_mask(uint8_t pin_number) {
return 1<<pin_number;
}
uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin) {
return pin->port * 16 + pin->number;
}
void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) {
claim_pin(pin);
}
void common_hal_mcu_pin_reset_number(uint8_t pin_no) {
reset_pin_number(pin_no / 16, pin_no % 16);
}

View File

@ -0,0 +1,54 @@
/*
* This file is part of the Micro Python 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 <stddef.h>
#include "common-hal/rgbmatrix/RGBMatrix.h"
#include STM32_HAL_H
extern void _PM_IRQ_HANDLER(void);
void *common_hal_rgbmatrix_timer_allocate() {
// TODO(jepler) properly handle resource allocation including never-reset
return TIM6;
}
void common_hal_rgbmatrix_timer_enable(void* ptr) {
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
}
void common_hal_rgbmatrix_timer_disable(void* ptr) {
TIM_TypeDef *tim = (TIM_TypeDef*)ptr;
tim->DIER &= ~TIM_DIER_UIE;
HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn);
}
void common_hal_rgbmatrix_timer_free(void* ptr) {
common_hal_rgbmatrix_timer_disable(ptr);
// TODO(jepler) properly handle resource allocation including never-reset
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the Micro Python 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.
*/
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
void *common_hal_rgbmatrix_timer_allocate(void);
void common_hal_rgbmatrix_timer_enable(void*);
void common_hal_rgbmatrix_timer_disable(void*);
void common_hal_rgbmatrix_timer_free(void*);
#endif

View File

@ -3,6 +3,11 @@ LONGINT_IMPL = MPZ
INTERNAL_LIBM = 1
USB_SERIAL_NUMBER_LENGTH = 24
ifeq ($(MCU_VARIANT),STM32F405xx)
CIRCUITPY_FRAMEBUFFERIO = 1
CIRCUITPY_RGBMATRIX = 1
endif
ifeq ($(MCU_SERIES),F4)
# Not yet implemented common-hal modules:
CIRCUITPY_AUDIOBUSIO = 0
@ -23,7 +28,6 @@ ifeq ($(MCU_SERIES),H7)
CIRCUITPY_ANALOGIO = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_PULSEIO = 0
CIRCUITPY_OS = 1
CIRCUITPY_NVM = 0
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_AUDIOIO = 0
@ -32,18 +36,12 @@ ifeq ($(MCU_SERIES),H7)
CIRCUITPY_RTC = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
# shared-module modules that still need prerequisites filled
CIRCUITPY_DISPLAYIO = 0 # Requires SPI, PulseIO, and common-hal module (stub ok)
CIRCUITPY_RANDOM = 0 # Requires OS
CIRCUITPY_STORAGE = 0 # Requires OS, filesystem
endif
ifeq ($(MCU_SERIES),F7)
# Not yet implemented common-hal modules:
CIRCUITPY_ANALOGIO = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_PULSEIO = 1
CIRCUITPY_OS = 1
CIRCUITPY_NVM = 0
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_AUDIOIO = 0
@ -52,8 +50,4 @@ ifeq ($(MCU_SERIES),F7)
CIRCUITPY_RTC = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
# shared-module modules that still need prerequisites filled
CIRCUITPY_DISPLAYIO = 0 # Requires SPI, PulseIO, and common-hal module (stub ok)
CIRCUITPY_RANDOM = 0 # Requires OS
CIRCUITPY_STORAGE = 0 # Requires OS, filesystem
endif

View File

@ -83,7 +83,7 @@
#ifdef STM32H743xx
#define STM32_FLASH_SIZE 0x200000 //2MB
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x20000 //128KiB
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x60000 //384KiB
#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08020000
#endif

View File

@ -49,7 +49,7 @@
#include STM32_HAL_H
//only enable the Reset Handler overwrite for the H7 for now
#if defined(STM32H7)
#if (CPY_STM32H7)
// Device memories must be accessed in order.
#define DEVICE 2
@ -153,16 +153,16 @@ __attribute__((used, naked)) void Reset_Handler(void) {
static RTC_HandleTypeDef _hrtc;
#if BOARD_HAS_LOW_SPEED_CRYSTAL
#define RTC_CLOCK_FREQUENCY LSE_VALUE
static uint32_t rtc_clock_frequency = LSE_VALUE;
#else
#define RTC_CLOCK_FREQUENCY LSI_VALUE
static uint32_t rtc_clock_frequency = LSI_VALUE;
#endif
safe_mode_t port_init(void) {
HAL_Init();
__HAL_RCC_SYSCFG_CLK_ENABLE();
#if defined(STM32F4)
#if (CPY_STM32F4)
__HAL_RCC_PWR_CLK_ENABLE();
#endif
@ -170,24 +170,70 @@ safe_mode_t port_init(void) {
stm32_peripherals_gpio_init();
HAL_PWR_EnableBkUpAccess();
// TODO: move all of this to clocks.c
#if BOARD_HAS_LOW_SPEED_CRYSTAL
uint32_t tickstart = HAL_GetTick();
// H7/F7 untested with LSE, so autofail them until above move is done
#if (CPY_STM32F4)
bool lse_setupsuccess = true;
#else
bool lse_setupsuccess = false;
#endif
// Update LSE configuration in Backup Domain control register
// Requires to enable write access to Backup Domain of necessary
// TODO: should be using the HAL OSC initializer, otherwise we'll need
// preprocessor defines for every register to account for F7/H7
#if (CPY_STM32F4)
if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
// Enable write access to Backup domain
SET_BIT(PWR->CR, PWR_CR_DBP);
// Wait for Backup domain Write protection disable
tickstart = HAL_GetTick();
while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
{
lse_setupsuccess = false;
}
}
}
#endif
__HAL_RCC_LSE_CONFIG(RCC_LSE_ON);
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {}
tickstart = HAL_GetTick();
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
if((HAL_GetTick() - tickstart ) > LSE_STARTUP_TIMEOUT)
{
lse_setupsuccess = false;
__HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
__HAL_RCC_LSI_ENABLE();
rtc_clock_frequency = LSI_VALUE;
break;
}
}
if (lse_setupsuccess) {
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
} else {
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
}
#else
__HAL_RCC_LSI_ENABLE();
#endif
#if BOARD_HAS_LOW_SPEED_CRYSTAL
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
#else
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
#endif
__HAL_RCC_RTC_ENABLE();
_hrtc.Instance = RTC;
_hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
// Divide async as little as possible so that we have RTC_CLOCK_FREQUENCY count in subseconds.
// Divide async as little as possible so that we have rtc_clock_frequency count in subseconds.
// This ensures our timing > 1 second is correct.
_hrtc.Init.AsynchPrediv = 0x0;
_hrtc.Init.SynchPrediv = RTC_CLOCK_FREQUENCY - 1;
_hrtc.Init.SynchPrediv = rtc_clock_frequency - 1;
_hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
HAL_RTC_Init(&_hrtc);
@ -293,7 +339,7 @@ volatile uint32_t cached_date = 0;
volatile uint32_t seconds_to_minute = 0;
volatile uint32_t cached_hours_minutes = 0;
uint64_t port_get_raw_ticks(uint8_t* subticks) {
uint32_t subseconds = RTC_CLOCK_FREQUENCY - (uint32_t)(RTC->SSR);
uint32_t subseconds = rtc_clock_frequency - (uint32_t)(RTC->SSR);
uint32_t time = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK);
uint32_t date = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK);
if (date != cached_date) {
@ -341,7 +387,7 @@ void RTC_Alarm_IRQHandler(void) {
// Enable 1/1024 second tick.
void port_enable_tick(void) {
HAL_RTCEx_SetWakeUpTimer_IT(&_hrtc, RTC_CLOCK_FREQUENCY / 1024 / 2, RTC_WAKEUPCLOCK_RTCCLK_DIV2);
HAL_RTCEx_SetWakeUpTimer_IT(&_hrtc, rtc_clock_frequency / 1024 / 2, RTC_WAKEUPCLOCK_RTCCLK_DIV2);
HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 1, 0U);
HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
}
@ -372,7 +418,7 @@ void port_interrupt_after_ticks(uint32_t ticks) {
alarm.AlarmMask = RTC_ALARMMASK_ALL;
}
alarm.AlarmTime.SubSeconds = RTC_CLOCK_FREQUENCY -
alarm.AlarmTime.SubSeconds = rtc_clock_frequency -
((raw_ticks % 1024) * 32);
alarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
alarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_SET;

View File

@ -99,6 +99,9 @@ endif
###
# Select which builtin modules to compile and include.
ifeq ($(CIRCUITPY_AESIO),1)
SRC_PATTERNS += aesio/%
endif
ifeq ($(CIRCUITPY_ANALOGIO),1)
SRC_PATTERNS += analogio/%
endif
@ -346,6 +349,8 @@ SRC_SHARED_MODULE_ALL = \
bitbangio/__init__.c \
board/__init__.c \
busio/OneWire.c \
aesio/__init__.c \
aesio/aes.c \
displayio/Bitmap.c \
displayio/ColorConverter.c \
displayio/Display.c \

View File

@ -223,6 +223,13 @@ typedef long mp_off_t;
// These CIRCUITPY_xxx values should all be defined in the *.mk files as being on or off.
// So if any are not defined in *.mk, they'll throw an error here.
#if CIRCUITPY_AESIO
extern const struct _mp_obj_module_t aesio_module;
#define AESIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_aesio), (mp_obj_t)&aesio_module },
#else
#define AESIO_MODULE
#endif
#if CIRCUITPY_ANALOGIO
#define ANALOGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module },
extern const struct _mp_obj_module_t analogio_module;
@ -626,6 +633,7 @@ extern const struct _mp_obj_module_t ustack_module;
// Some of these definitions will be blank depending on what is turned on and off.
// Some are omitted because they're in MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS above.
#define MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \
AESIO_MODULE \
ANALOGIO_MODULE \
AUDIOBUSIO_MODULE \
AUDIOCORE_MODULE \

View File

@ -27,37 +27,28 @@
# Manually disable by overriding in #mpconfigboard.mk
# Smaller builds can be forced for resource constrained chips (typically SAMD21s
# without external flash) by setting CIRCUITPY_FULL_BUILD=0. Avoid using this
# without external flash) by setting CIRCUITPY_FULL_BUILD=0. Avoid using this
# for merely incomplete ports, as it changes settings in other files.
ifndef CIRCUITPY_FULL_BUILD
CIRCUITPY_FULL_BUILD = 1
endif
CIRCUITPY_FULL_BUILD ?= 1
CFLAGS += -DCIRCUITPY_FULL_BUILD=$(CIRCUITPY_FULL_BUILD)
ifndef CIRCUITPY_ANALOGIO
CIRCUITPY_ANALOGIO = 1
endif
CIRCUITPY_AESIO ?= 0
CFLAGS += -DCIRCUITPY_AESIO=$(CIRCUITPY_AESIO)
CIRCUITPY_ANALOGIO ?= 1
CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO)
ifndef CIRCUITPY_AUDIOBUSIO
CIRCUITPY_AUDIOBUSIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_AUDIOBUSIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_AUDIOBUSIO=$(CIRCUITPY_AUDIOBUSIO)
ifndef CIRCUITPY_AUDIOIO
CIRCUITPY_AUDIOIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_AUDIOIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_AUDIOIO=$(CIRCUITPY_AUDIOIO)
ifndef CIRCUITPY_AUDIOIO_COMPAT
CIRCUITPY_AUDIOIO_COMPAT = $(CIRCUITPY_AUDIOIO)
endif
CIRCUITPY_AUDIOIO_COMPAT ?= $(CIRCUITPY_AUDIOIO)
CFLAGS += -DCIRCUITPY_AUDIOIO_COMPAT=$(CIRCUITPY_AUDIOIO_COMPAT)
ifndef CIRCUITPY_AUDIOPWMIO
CIRCUITPY_AUDIOPWMIO = 0
endif
CIRCUITPY_AUDIOPWMIO ?= 0
CFLAGS += -DCIRCUITPY_AUDIOPWMIO=$(CIRCUITPY_AUDIOPWMIO)
ifndef CIRCUITPY_AUDIOCORE
@ -69,9 +60,7 @@ endif
endif
CFLAGS += -DCIRCUITPY_AUDIOCORE=$(CIRCUITPY_AUDIOCORE)
ifndef CIRCUITPY_AUDIOMIXER
CIRCUITPY_AUDIOMIXER = $(CIRCUITPY_AUDIOIO)
endif
CIRCUITPY_AUDIOMIXER ?= $(CIRCUITPY_AUDIOIO)
CFLAGS += -DCIRCUITPY_AUDIOMIXER=$(CIRCUITPY_AUDIOMIXER)
ifndef CIRCUITPY_AUDIOMP3
@ -83,251 +72,159 @@ endif
endif
CFLAGS += -DCIRCUITPY_AUDIOMP3=$(CIRCUITPY_AUDIOMP3)
ifndef CIRCUITPY_BITBANGIO
CIRCUITPY_BITBANGIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_BITBANGIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO)
# Explicitly enabled for boards that support _bleio.
ifndef CIRCUITPY_BLEIO
CIRCUITPY_BLEIO = 0
endif
CIRCUITPY_BLEIO ?= 0
CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO)
ifndef CIRCUITPY_BOARD
CIRCUITPY_BOARD = 1
endif
CIRCUITPY_BOARD ?= 1
CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
ifndef CIRCUITPY_BUSIO
CIRCUITPY_BUSIO = 1
endif
CIRCUITPY_BUSIO ?= 1
CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO)
ifndef CIRCUITPY_DIGITALIO
CIRCUITPY_DIGITALIO = 1
endif
CIRCUITPY_DIGITALIO ?= 1
CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO)
CIRCUITPY_COUNTIO ?= 1
CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO)
ifndef CIRCUITPY_DISPLAYIO
CIRCUITPY_DISPLAYIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
ifndef CIRCUITPY_FRAMEBUFFERIO
CIRCUITPY_FRAMEBUFFERIO = 0
endif
CIRCUITPY_FRAMEBUFFERIO ?= 0
CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO)
ifndef CIRCUITPY_FREQUENCYIO
CIRCUITPY_FREQUENCYIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_FREQUENCYIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_FREQUENCYIO=$(CIRCUITPY_FREQUENCYIO)
ifndef CIRCUITPY_GAMEPAD
CIRCUITPY_GAMEPAD = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_GAMEPAD ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_GAMEPAD=$(CIRCUITPY_GAMEPAD)
ifndef CIRCUITPY_GAMEPADSHIFT
CIRCUITPY_GAMEPADSHIFT = 0
endif
CIRCUITPY_GAMEPADSHIFT ?= 0
CFLAGS += -DCIRCUITPY_GAMEPADSHIFT=$(CIRCUITPY_GAMEPADSHIFT)
ifndef CIRCUITPY_I2CSLAVE
CIRCUITPY_I2CSLAVE = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_I2CSLAVE ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_I2CSLAVE=$(CIRCUITPY_I2CSLAVE)
ifndef CIRCUITPY_MATH
CIRCUITPY_MATH = 1
endif
CIRCUITPY_MATH ?= 1
CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
ifndef CIRCUITPY__EVE
CIRCUITPY__EVE = 0
endif
CIRCUITPY__EVE ?= 0
CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE)
ifndef CIRCUITPY_MICROCONTROLLER
CIRCUITPY_MICROCONTROLLER = 1
endif
CIRCUITPY_MICROCONTROLLER ?= 1
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)
ifndef CIRCUITPY_NEOPIXEL_WRITE
CIRCUITPY_NEOPIXEL_WRITE = 1
endif
CIRCUITPY_NEOPIXEL_WRITE ?= 1
CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE)
# Enabled on SAMD51. Won't fit on SAMD21 builds. Not tested on nRF or STM32F4 builds.
ifndef CIRCUITPY_NETWORK
CIRCUITPY_NETWORK = 0
endif
CIRCUITPY_NETWORK ?= 0
CFLAGS += -DCIRCUITPY_NETWORK=$(CIRCUITPY_NETWORK)
ifndef CIRCUITPY_NVM
CIRCUITPY_NVM = 1
endif
CIRCUITPY_NVM ?= 1
CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM)
ifndef CIRCUITPY_OS
CIRCUITPY_OS = 1
endif
CIRCUITPY_OS ?= 1
CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS)
ifndef CIRCUITPY_PIXELBUF
CIRCUITPY_PIXELBUF = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
# Only for SAMD boards for the moment
ifndef CIRCUITPY_RGBMATRIX
CIRCUITPY_RGBMATRIX = 0
endif
CIRCUITPY_RGBMATRIX ?= 0
CFLAGS += -DCIRCUITPY_RGBMATRIX=$(CIRCUITPY_RGBMATRIX)
ifndef CIRCUITPY_PULSEIO
CIRCUITPY_PULSEIO = 1
endif
CIRCUITPY_PULSEIO ?= 1
CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO)
# Only for SAMD boards for the moment
ifndef CIRCUITPY_PS2IO
CIRCUITPY_PS2IO = 0
endif
CIRCUITPY_PS2IO ?= 0
CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO)
ifndef CIRCUITPY_RANDOM
CIRCUITPY_RANDOM = 1
endif
CIRCUITPY_RANDOM ?= 1
CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM)
ifndef CIRCUITPY_ROTARYIO
CIRCUITPY_ROTARYIO = 1
endif
CIRCUITPY_ROTARYIO ?= 1
CFLAGS += -DCIRCUITPY_ROTARYIO=$(CIRCUITPY_ROTARYIO)
ifndef CIRCUITPY_RTC
CIRCUITPY_RTC = 1
endif
CIRCUITPY_RTC ?= 1
CFLAGS += -DCIRCUITPY_RTC=$(CIRCUITPY_RTC)
# CIRCUITPY_SAMD is handled in the atmel-samd tree.
# Only for SAMD chips.
# Assume not a SAMD build.
ifndef CIRCUITPY_SAMD
CIRCUITPY_SAMD = 0
endif
CIRCUITPY_SAMD ?= 0
CFLAGS += -DCIRCUITPY_SAMD=$(CIRCUITPY_SAMD)
# Currently always off.
ifndef CIRCUITPY_STAGE
CIRCUITPY_STAGE = 0
endif
CIRCUITPY_STAGE ?= 0
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)
ifndef CIRCUITPY_STORAGE
CIRCUITPY_STORAGE = 1
endif
CIRCUITPY_STORAGE ?= 1
CFLAGS += -DCIRCUITPY_STORAGE=$(CIRCUITPY_STORAGE)
ifndef CIRCUITPY_STRUCT
CIRCUITPY_STRUCT = 1
endif
CIRCUITPY_STRUCT ?= 1
CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT)
ifndef CIRCUITPY_SUPERVISOR
CIRCUITPY_SUPERVISOR = 1
endif
CIRCUITPY_SUPERVISOR ?= 1
CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR)
ifndef CIRCUITPY_TIME
CIRCUITPY_TIME = 1
endif
CIRCUITPY_TIME ?= 1
CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME)
# touchio might be native or generic. See circuitpy_defns.mk.
ifndef CIRCUITPY_TOUCHIO_USE_NATIVE
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
endif
CIRCUITPY_TOUCHIO_USE_NATIVE ?= 0
CFLAGS += -DCIRCUITPY_TOUCHIO_USE_NATIVE=$(CIRCUITPY_TOUCHIO_USE_NATIVE)
ifndef CIRCUITPY_TOUCHIO
CIRCUITPY_TOUCHIO = 1
endif
CIRCUITPY_TOUCHIO ?= 1
CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO)
# For debugging.
ifndef CIRCUITPY_UHEAP
CIRCUITPY_UHEAP = 0
endif
CIRCUITPY_UHEAP ?= 0
CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
ifndef CIRCUITPY_USB_HID
CIRCUITPY_USB_HID = 1
endif
CIRCUITPY_USB_HID ?= 1
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
ifndef CIRCUITPY_USB_MIDI
CIRCUITPY_USB_MIDI = 1
endif
CIRCUITPY_USB_MIDI ?= 1
CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
ifndef CIRCUITPY_PEW
CIRCUITPY_PEW = 0
endif
CIRCUITPY_PEW ?= 0
CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
# For debugging.
ifndef CIRCUITPY_USTACK
CIRCUITPY_USTACK = 0
endif
CIRCUITPY_USTACK ?= 0
CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK)
# Non-module conditionals
ifndef CIRCUITPY_BITBANG_APA102
CIRCUITPY_BITBANG_APA102 = 0
endif
CIRCUITPY_BITBANG_APA102 ?= 0
CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102)
# Should busio.I2C() check for pullups?
# Some boards in combination with certain peripherals may not want this.
ifndef CIRCUITPY_REQUIRE_I2C_PULLUPS
CIRCUITPY_REQUIRE_I2C_PULLUPS = 1
endif
CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1
CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS)
# REPL over BLE
ifndef CIRCUITPY_SERIAL_BLE
CIRCUITPY_SERIAL_BLE = 0
endif
CIRCUITPY_SERIAL_BLE ?= 0
CFLAGS += -DCIRCUITPY_SERIAL_BLE=$(CIRCUITPY_SERIAL_BLE)
ifndef CIRCUITPY_BLE_FILE_SERVICE
CIRCUITPY_BLE_FILE_SERVICE = 0
endif
CIRCUITPY_BLE_FILE_SERVICE ?= 0
CFLAGS += -DCIRCUITPY_BLE_FILE_SERVICE=$(CIRCUITPY_BLE_FILE_SERVICE)
# REPL over UART
ifndef CIRCUITPY_SERIAL_UART
CIRCUITPY_SERIAL_UART = 0
endif
CIRCUITPY_SERIAL_UART ?= 0
CFLAGS += -DCIRCUITPY_SERIAL_UART=$(CIRCUITPY_SERIAL_UART)
# ulab numerics library
ifndef CIRCUITPY_ULAB
CIRCUITPY_ULAB = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_ULAB ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_ULAB=$(CIRCUITPY_ULAB)
# Enabled micropython.native decorator (experimental)
ifndef CIRCUITPY_ENABLE_MPY_NATIVE
CIRCUITPY_ENABLE_MPY_NATIVE = 0
endif
CIRCUITPY_ENABLE_MPY_NATIVE ?= 0
CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE)

View File

@ -258,6 +258,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\
repl.o \
smallint.o \
frozenmod.o \
ringbuf.o \
)
PY_EXTMOD_O_BASENAME = \

115
py/ringbuf.c Normal file
View File

@ -0,0 +1,115 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Paul Sokolovsky
*
* 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 "ringbuf.h"
// Dynamic initialization. This should be accessible from a root pointer.
// capacity is the number of bytes the ring buffer can hold. The actual
// size of the buffer is one greater than that, due to how the buffer
// handles empty and full statuses.
bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived) {
r->buf = gc_alloc(capacity + 1, false, long_lived);
r->size = capacity + 1;
r->iget = r->iput = 0;
return r->buf != NULL;
}
void ringbuf_free(ringbuf_t *r) {
gc_free(r->buf);
r->size = 0;
ringbuf_clear(r);
}
size_t ringbuf_capacity(ringbuf_t *r) {
return r->size - 1;
}
// Returns -1 if buffer is empty, else returns byte fetched.
int ringbuf_get(ringbuf_t *r) {
if (r->iget == r->iput) {
return -1;
}
uint8_t v = r->buf[r->iget++];
if (r->iget >= r->size) {
r->iget = 0;
}
return v;
}
// Returns -1 if no room in buffer, else returns 0.
int ringbuf_put(ringbuf_t *r, uint8_t v) {
uint32_t iput_new = r->iput + 1;
if (iput_new >= r->size) {
iput_new = 0;
}
if (iput_new == r->iget) {
return -1;
}
r->buf[r->iput] = v;
r->iput = iput_new;
return 0;
}
void ringbuf_clear(ringbuf_t *r) {
r->iput = r->iget = 0;
}
// Number of free slots that can be written.
size_t ringbuf_num_empty(ringbuf_t *r) {
return (r->size + r->iget - r->iput - 1) % r->size;
}
// Number of bytes available to read.
size_t ringbuf_num_filled(ringbuf_t *r) {
return (r->size + r->iput - r->iget) % r->size;
}
// If the ring buffer fills up, not all bytes will be written.
// Returns how many bytes were successfully written.
size_t ringbuf_put_n(ringbuf_t* r, uint8_t* buf, size_t bufsize)
{
for(size_t i=0; i < bufsize; i++) {
if ( ringbuf_put(r, buf[i]) < 0 ) {
// If ringbuf is full, give up and return how many bytes
// we wrote so far.
return i;
}
}
return bufsize;
}
// Returns how many bytes were fetched.
size_t ringbuf_get_n(ringbuf_t* r, uint8_t* buf, size_t bufsize)
{
for(size_t i=0; i < bufsize; i++) {
int b = ringbuf_get(r);
if (b < 0) {
return i;
}
buf[i] = b;
}
return bufsize;
}

View File

@ -32,78 +32,27 @@
typedef struct _ringbuf_t {
uint8_t *buf;
uint16_t size;
uint16_t iget;
uint16_t iput;
// Allocated size; capacity is one less. Don't reference this directly.
uint32_t size;
uint32_t iget;
uint32_t iput;
} ringbuf_t;
// Note that the capacity of the buffer is N-1!
// Static initialization:
// byte buf_array[N];
// ringbuf_t buf = {buf_array, sizeof(buf_array)};
// Dynamic initialization. This creates root pointer!
#define ringbuf_alloc(r, sz, long_lived) \
{ \
(r)->buf = gc_alloc(sz, false, long_lived); \
(r)->size = sz; \
(r)->iget = (r)->iput = 0; \
}
bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived);
void ringbuf_free(ringbuf_t *r);
size_t ringbuf_capacity(ringbuf_t *r);
int ringbuf_get(ringbuf_t *r);
int ringbuf_put(ringbuf_t *r, uint8_t v);
void ringbuf_clear(ringbuf_t *r);
size_t ringbuf_num_empty(ringbuf_t *r);
size_t ringbuf_num_filled(ringbuf_t *r);
size_t ringbuf_put_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);
size_t ringbuf_get_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);
static inline int ringbuf_get(ringbuf_t *r) {
if (r->iget == r->iput) {
return -1;
}
uint8_t v = r->buf[r->iget++];
if (r->iget >= r->size) {
r->iget = 0;
}
return v;
}
static inline int ringbuf_put(ringbuf_t *r, uint8_t v) {
uint32_t iput_new = r->iput + 1;
if (iput_new >= r->size) {
iput_new = 0;
}
if (iput_new == r->iget) {
return -1;
}
r->buf[r->iput] = v;
r->iput = iput_new;
return 0;
}
static inline uint16_t ringbuf_count(ringbuf_t *r)
{
volatile int count = r->iput - r->iget;
if ( count < 0 ) {
count += r->size;
}
return (uint16_t) count;
}
static inline void ringbuf_clear(ringbuf_t *r)
{
r->iput = r->iget = 0;
}
// will overwrite old data
static inline void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
{
for(uint8_t i=0; i < bufsize; i++) {
if ( ringbuf_put(r, buf[i]) < 0 ) {
// if full overwrite old data
(void) ringbuf_get(r);
ringbuf_put(r, buf[i]);
}
}
}
static inline void ringbuf_get_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
{
for(uint8_t i=0; i < bufsize; i++) {
buf[i] = ringbuf_get(r);
}
}
#endif // MICROPY_INCLUDED_PY_RINGBUF_H

View File

@ -32,7 +32,7 @@
extern const mp_obj_type_t bleio_characteristic_buffer_type;
extern void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_float_t timeout, size_t buffer_size);
int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode);
uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode);
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self);
void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self);
bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self);

View File

@ -214,6 +214,25 @@ STATIC mp_obj_t bleio_connection_get_connection_interval(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_connection_interval_obj, bleio_connection_get_connection_interval);
//| .. attribute:: max_packet_length
//|
//| The maximum number of data bytes that can be sent in a single transmission,
//| not including overhead bytes.
//|
//| This is the maximum number of bytes that can be sent in a notification,
//| which must be sent in a single packet.
//| But for a regular characteristic read or write, may be sent in multiple packets,
//| so this limit does not apply.
//|
STATIC mp_obj_t bleio_connection_get_max_packet_length(mp_obj_t self_in) {
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
bleio_connection_ensure_connected(self);
return mp_obj_new_int(common_hal_bleio_connection_get_max_packet_length(self->connection));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_max_packet_length_obj, bleio_connection_get_max_packet_length);
STATIC mp_obj_t bleio_connection_set_connection_interval(mp_obj_t self_in, mp_obj_t interval_in) {
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
@ -233,6 +252,13 @@ const mp_obj_property_t bleio_connection_connection_interval_obj = {
(mp_obj_t)&mp_const_none_obj },
};
const mp_obj_property_t bleio_connection_max_packet_length_obj = {
.base.type = &mp_type_property,
.proxy = { (mp_obj_t)&bleio_connection_get_max_packet_length_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
// Methods
{ MP_ROM_QSTR(MP_QSTR_pair), MP_ROM_PTR(&bleio_connection_pair_obj) },
@ -243,7 +269,7 @@ STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
{ MP_ROM_QSTR(MP_QSTR_paired), MP_ROM_PTR(&bleio_connection_paired_obj) },
{ MP_ROM_QSTR(MP_QSTR_connection_interval), MP_ROM_PTR(&bleio_connection_connection_interval_obj) },
{ MP_ROM_QSTR(MP_QSTR_max_packet_length), MP_ROM_PTR(&bleio_connection_max_packet_length_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_connection_locals_dict, bleio_connection_locals_dict_table);

View File

@ -34,11 +34,12 @@
extern const mp_obj_type_t bleio_connection_type;
extern void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond);
extern void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self);
extern bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self);
extern bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self);
extern mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond);
void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self);
bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self);
mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self);
bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self);
mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self);
void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval);

View File

@ -42,8 +42,8 @@
//|
//| Accumulates a Characteristic's incoming packets in a FIFO buffer and facilitates packet aware
//| outgoing writes. A packet's size is either the characteristic length or the maximum transmission
//| unit (MTU), whichever is smaller. The MTU can change so check `packet_size` before creating a
//| buffer to store data.
//| unit (MTU) minus overhead, whichever is smaller. The MTU can change so check `incoming_packet_length`
//| and `outgoing_packet_length` before creating a buffer to store data.
//|
//| When we're the server, we ignore all connections besides the first to subscribe to
//| notifications.
@ -51,7 +51,7 @@
//| .. class:: PacketBuffer(characteristic, *, buffer_size)
//|
//| Monitor the given Characteristic. Each time a new value is written to the Characteristic
//| add the newly-written bytes to a FIFO buffer.
//| add the newly-written packet of bytes to a FIFO buffer.
//|
//| :param Characteristic characteristic: The Characteristic to monitor.
//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic
@ -71,7 +71,7 @@ STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n
const mp_obj_t characteristic = args[ARG_characteristic].u_obj;
const int buffer_size = args[ARG_buffer_size].u_int;
const mp_int_t buffer_size = args[ARG_buffer_size].u_int;
if (buffer_size < 1) {
mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_buffer_size);
}
@ -109,7 +109,7 @@ STATIC mp_obj_t bleio_packet_buffer_readinto(mp_obj_t self_in, mp_obj_t buffer_o
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buffer_obj, &bufinfo, MP_BUFFER_WRITE);
int size = common_hal_bleio_packet_buffer_readinto(self, bufinfo.buf, bufinfo.len);
mp_int_t size = common_hal_bleio_packet_buffer_readinto(self, bufinfo.buf, bufinfo.len);
if (size < 0) {
mp_raise_ValueError_varg(translate("Buffer too short by %d bytes"), size * -1);
}
@ -125,6 +125,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_packet_buffer_readinto_obj, bleio_packet_
//|
//| This does not block until the data is sent. It only blocks until the data is pending.
//|
//| :return: number of bytes written. May include header bytes when packet is empty.
//| :rtype: int
//|
// TODO: Add a kwarg `merge=False` to dictate whether subsequent writes are merged into a pending
// one.
STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@ -149,9 +152,21 @@ STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_
mp_get_buffer_raise(args[ARG_header].u_obj, &header_bufinfo, MP_BUFFER_READ);
}
common_hal_bleio_packet_buffer_write(self, data_bufinfo.buf, data_bufinfo.len,
header_bufinfo.buf, header_bufinfo.len);
return mp_const_none;
mp_int_t num_bytes_written = common_hal_bleio_packet_buffer_write(
self, data_bufinfo.buf, data_bufinfo.len, header_bufinfo.buf, header_bufinfo.len);
if (num_bytes_written < 0) {
// TODO: Raise an error if not connected. Right now the not-connected error
// is unreliable, because common_hal_bleio_packet_buffer_write()
// checks for conn_handle being set, but setting that
// can be delayed because conn_handle is discovered by spying on
// gatts write events, which may not have been sent yet.
//
// IDEAL:
// mp_raise_bleio_ConnectionError(translate("Not connected"));
// TEMPORARY:
num_bytes_written = 0;
}
return MP_OBJ_NEW_SMALL_INT(num_bytes_written);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_packet_buffer_write_obj, 1, bleio_packet_buffer_write);
@ -168,31 +183,66 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_deinit_obj, bleio_packet_bu
//| .. attribute:: packet_size
//|
//| Maximum size of each packet in bytes. This is the minimum of the Characteristic length and
//| the negotiated Maximum Transfer Unit (MTU).
//| `packet_size` is the same as `incoming_packet_length`.
//| The name `packet_size` is deprecated and
//| will be removed in CircuitPython 6.0.0.
//|
STATIC mp_obj_t bleio_packet_buffer_get_packet_size(mp_obj_t self_in) {
//| .. attribute:: incoming_packet_length
//|
//| Maximum length in bytes of a packet we are reading.
//|
STATIC mp_obj_t bleio_packet_buffer_get_incoming_packet_length(mp_obj_t self_in) {
bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_packet_buffer_get_packet_size(self));
mp_int_t size = common_hal_bleio_packet_buffer_get_incoming_packet_length(self);
if (size < 0) {
mp_raise_ValueError(translate("No connection: length cannot be determined"));
}
return MP_OBJ_NEW_SMALL_INT(size);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_packet_size_obj, bleio_packet_buffer_get_packet_size);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_incoming_packet_length_obj, bleio_packet_buffer_get_incoming_packet_length);
const mp_obj_property_t bleio_packet_buffer_packet_size_obj = {
const mp_obj_property_t bleio_packet_buffer_incoming_packet_length_obj = {
.base.type = &mp_type_property,
.proxy = { (mp_obj_t)&bleio_packet_buffer_get_packet_size_obj,
.proxy = { (mp_obj_t)&bleio_packet_buffer_get_incoming_packet_length_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
//| .. attribute:: outgoing_packet_length
//|
//| Maximum length in bytes of a packet we are writing.
//|
STATIC mp_obj_t bleio_packet_buffer_get_outgoing_packet_length(mp_obj_t self_in) {
bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_int_t size = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
if (size < 0) {
mp_raise_ValueError(translate("No connection: length cannot be determined"));
}
return MP_OBJ_NEW_SMALL_INT(size);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_outgoing_packet_length_obj, bleio_packet_buffer_get_outgoing_packet_length);
const mp_obj_property_t bleio_packet_buffer_outgoing_packet_length_obj = {
.base.type = &mp_type_property,
.proxy = { (mp_obj_t)&bleio_packet_buffer_get_outgoing_packet_length_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
STATIC const mp_rom_map_elem_t bleio_packet_buffer_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_packet_buffer_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_packet_buffer_deinit_obj) },
// Standard stream methods.
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_packet_size), MP_ROM_PTR(&bleio_packet_buffer_packet_size_obj) },
// .packet_size is now an alias for .incoming_packet_length
// TODO: Remove in 6.0.0.
{ MP_OBJ_NEW_QSTR(MP_QSTR_packet_size), MP_ROM_PTR(&bleio_packet_buffer_incoming_packet_length_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_incoming_packet_length), MP_ROM_PTR(&bleio_packet_buffer_incoming_packet_length_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_outgoing_packet_length), MP_ROM_PTR(&bleio_packet_buffer_outgoing_packet_length_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_packet_buffer_locals_dict, bleio_packet_buffer_locals_dict_table);

View File

@ -34,9 +34,10 @@ extern const mp_obj_type_t bleio_packet_buffer_type;
extern void common_hal_bleio_packet_buffer_construct(
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
size_t buffer_size);
void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len);
int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len);
uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self);
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len);
mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len);
mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self);
mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_buffer_obj_t *self);
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self);
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self);

View File

@ -44,7 +44,7 @@ extern const int32_t colorwheel(float pos);
static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t* parsed);
//| .. currentmodule:: pixelbuf
//| .. currentmodule:: _pixelbuf
//|
//| :class:`PixelBuf` -- A fast RGB[W] pixel buffer for LED and similar devices
//| ===========================================================================
@ -58,13 +58,13 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t
//| When brightness is less than 1.0, a second buffer will be used to store the color values
//| before they are adjusted for brightness.
//|
//| When ``P`` (pwm duration) is present as the 4th character of the byteorder
//| When ``P`` (pwm duration) is present as the first character of the byteorder
//| string, the 4th value in the tuple/list for a pixel is the individual pixel
//| brightness (0.0-1.0) and will enable a Dotstar compatible 1st byte in the
//| output buffer (``buf``).
//|
//| :param ~int size: Number of pixelsx
//| :param ~str byteorder: Byte order string (such as "BGR" or "PBGR")
//| :param ~int size: Number of pixels
//| :param ~str byteorder: Byte order string (such as "BGR" or "BGRP")
//| :param ~float brightness: Brightness (0 to 1.0, default 1.0)
//| :param ~bool auto_write: Whether to automatically write pixels (Default False)
//| :param bytes header: Sequence of bytes to always send before pixel values.
@ -265,7 +265,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_show(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_show);
//| .. function:: fill(color)
//| .. method:: fill(color)
//|
//| Fills the given pixelbuf with the given color.
//|

View File

@ -53,36 +53,39 @@
//| PixelBuf
//| .. function:: wheel(n)
//| .. function:: colorwheel(n)
//|
//| C implementation of the common wheel() function found in many examples.
//| Returns the colorwheel RGB value as an integer value for n (usable in :py:class:`PixelBuf`, neopixel, and dotstar).
//|
//| .. function:: wheel(n)
//| Use of wheel() is deprecated. Please use colorwheel().
STATIC mp_obj_t pixelbuf_wheel(mp_obj_t n) {
STATIC mp_obj_t pixelbuf_colorwheel(mp_obj_t n) {
return MP_OBJ_NEW_SMALL_INT(colorwheel(MP_OBJ_IS_SMALL_INT(n) ? MP_OBJ_SMALL_INT_VALUE(n) : mp_obj_float_get(n)));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_wheel_obj, pixelbuf_wheel);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_colorwheel_obj, pixelbuf_colorwheel);
const int32_t colorwheel(float pos) {
if (pos > 255) {
pos = pos - ((uint32_t)(pos / 256) * 256);
}
if (pos < 85)
return (uint8_t)(pos * 3) << 16 | (uint8_t)(255 - (pos * 3)) << 8;
return (uint8_t)(255 - (pos * 3)) << 16 | (uint8_t)(pos * 3) << 8;
else if (pos < 170) {
pos -= 85;
return (uint8_t)(255 - (pos * 3)) << 16 | (uint8_t)(pos * 3);
return (uint8_t)(255 - (pos * 3)) << 8 | (uint8_t)(pos * 3);
} else {
pos -= 170;
return (uint8_t)(pos * 3) << 8 | (uint8_t)(255 - pos * 3);
return (uint8_t)(pos * 3) << 16 | (uint8_t)(255 - (pos * 3));
}
}
STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pixelbuf) },
{ MP_ROM_QSTR(MP_QSTR_PixelBuf), MP_ROM_PTR(&pixelbuf_pixelbuf_type) },
{ MP_ROM_QSTR(MP_QSTR_wheel), MP_ROM_PTR(&pixelbuf_wheel_obj) },
{ MP_ROM_QSTR(MP_QSTR_wheel), MP_ROM_PTR(&pixelbuf_colorwheel_obj) },
{ MP_ROM_QSTR(MP_QSTR_colorwheel), MP_ROM_PTR(&pixelbuf_colorwheel_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pixelbuf_module_globals, pixelbuf_module_globals_table);

View File

@ -0,0 +1,79 @@
/*
* 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 <stdint.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "__init__.h"
//| :mod:`aesio` --- AES encryption routines
//| ========================================
//|
//| .. module:: aesio
//| :synopsis: Embedded implementation of AES
//|
//| The `AES` module contains classes used to implement encryption
//| and decryption. It aims to be low overhead in terms of memory.
//|
//|
//| Libraries
//|
//| .. toctree::
//| :maxdepth: 3
//|
//| aes
STATIC const mp_obj_tuple_t mp_aes_key_size_obj = {
{&mp_type_tuple},
3,
{
MP_OBJ_NEW_SMALL_INT(16),
MP_OBJ_NEW_SMALL_INT(24),
MP_OBJ_NEW_SMALL_INT(32),
}
};
STATIC const mp_rom_map_elem_t aesio_module_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_aesio)},
{MP_ROM_QSTR(MP_QSTR_AES), MP_ROM_PTR(&aesio_aes_type) },
{MP_ROM_QSTR(MP_QSTR_MODE_ECB), MP_ROM_INT(AES_MODE_ECB)},
{MP_ROM_QSTR(MP_QSTR_MODE_CBC), MP_ROM_INT(AES_MODE_CBC)},
{MP_ROM_QSTR(MP_QSTR_MODE_CTR), MP_ROM_INT(AES_MODE_CTR)},
{MP_ROM_QSTR(MP_QSTR_block_size), MP_ROM_INT(AES_BLOCKLEN)},
{MP_ROM_QSTR(MP_QSTR_key_size), (mp_obj_t)&mp_aes_key_size_obj},
};
STATIC MP_DEFINE_CONST_DICT(aesio_module_globals, aesio_module_globals_table);
const mp_obj_module_t aesio_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&aesio_module_globals,
};

View File

@ -0,0 +1,53 @@
/*
* This file is part of the Micro Python 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.
*/
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AESIO_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_AESIO_H
#include "shared-module/aesio/__init__.h"
extern const mp_obj_type_t aesio_aes_type;
void common_hal_aesio_aes_construct(aesio_aes_obj_t* self,
const uint8_t* key,
uint32_t key_length,
const uint8_t* iv,
int mode,
int counter);
void common_hal_aesio_aes_rekey(aesio_aes_obj_t* self,
const uint8_t* key,
uint32_t key_length,
const uint8_t* iv);
void common_hal_aesio_aes_set_mode(aesio_aes_obj_t* self,
int mode);
void common_hal_aesio_aes_encrypt(aesio_aes_obj_t* self,
uint8_t* buffer,
size_t len);
void common_hal_aesio_aes_decrypt(aesio_aes_obj_t* self,
uint8_t* buffer,
size_t len);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AESIO_H

271
shared-bindings/aesio/aes.c Normal file
View File

@ -0,0 +1,271 @@
#include <stdint.h>
#include <string.h>
#include "py/obj.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/aesio/__init__.h"
// Defined at the end of this file
//| .. currentmodule:: aesio
//|
//| :class:`aesio` -- Encrypt and decrypt AES streams
//| =====================================================
//|
//| An object that represents an AES stream, including the current state.
//|
//| .. class:: AES(key, mode=0, iv=None, segment_size=8)
//|
//| Create a new AES state with the given key.
//|
//| :param bytearray key: A 16-, 24-, or 32-byte key
//| :param int mode: AES mode to use. One of: AES.MODE_ECB, AES.MODE_CBC, or
//| AES.MODE_CTR
//| :param bytearray iv: Initialization vector to use for CBC or CTR mode
//|
//| Additional arguments are supported for legacy reasons.
//|
//| Encrypting a string::
//|
//| import aesio
//| from binascii import hexlify
//|
//| key = b'Sixteen byte key'
//| inp = b'Circuit Python!!' # Note: 16-bytes long
//| outp = bytearray(len(inp))
//| cipher = aesio.AES(key, aesio.mode.MODE_ECB)
//| cipher.encrypt_into(inp, outp)
//| hexlify(outp)
//|
STATIC mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args,
const mp_obj_t *pos_args,
mp_map_t *kw_args) {
(void)type;
enum { ARG_key, ARG_mode, ARG_IV, ARG_counter, ARG_segment_size };
static const mp_arg_t allowed_args[] = {
{MP_QSTR_key, MP_ARG_OBJ | MP_ARG_REQUIRED},
{MP_QSTR_mode, MP_ARG_INT, {.u_int = AES_MODE_ECB}},
{MP_QSTR_IV, MP_ARG_OBJ},
{MP_QSTR_counter, MP_ARG_OBJ},
{MP_QSTR_segment_size, MP_ARG_INT, {.u_int = 8}},
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args),
allowed_args, args);
aesio_aes_obj_t *self = m_new_obj(aesio_aes_obj_t);
self->base.type = &aesio_aes_type;
mp_buffer_info_t bufinfo;
const uint8_t *key = NULL;
uint32_t key_length = 0;
if (mp_get_buffer(args[ARG_key].u_obj, &bufinfo, MP_BUFFER_READ)) {
if ((bufinfo.len != 16) && (bufinfo.len != 24) && (bufinfo.len != 32)) {
mp_raise_TypeError(translate("Key must be 16, 24, or 32 bytes long"));
}
key = bufinfo.buf;
key_length = bufinfo.len;
} else {
mp_raise_TypeError(translate("No key was specified"));
}
int mode = args[ARG_mode].u_int;
switch (args[ARG_mode].u_int) {
case AES_MODE_CBC:
case AES_MODE_ECB:
case AES_MODE_CTR:
break;
default:
mp_raise_TypeError(translate("Requested AES mode is unsupported"));
}
// IV is required for CBC mode and is ignored for other modes.
const uint8_t *iv = NULL;
if (args[ARG_IV].u_obj != NULL &&
mp_get_buffer(args[ARG_IV].u_obj, &bufinfo, MP_BUFFER_READ)) {
if (bufinfo.len != AES_BLOCKLEN) {
mp_raise_TypeError_varg(translate("IV must be %d bytes long"),
AES_BLOCKLEN);
}
iv = bufinfo.buf;
}
common_hal_aesio_aes_construct(self, key, key_length, iv, mode,
args[ARG_counter].u_int);
return MP_OBJ_FROM_PTR(self);
}
STATIC mp_obj_t aesio_aes_rekey(size_t n_args, const mp_obj_t *pos_args) {
aesio_aes_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
size_t key_length = 0;
const uint8_t *key =
(const uint8_t *)mp_obj_str_get_data(pos_args[1], &key_length);
if (key == NULL) {
mp_raise_ValueError(translate("No key was specified"));
}
if ((key_length != 16) && (key_length != 24) && (key_length != 32)) {
mp_raise_TypeError(translate("Key must be 16, 24, or 32 bytes long"));
}
const uint8_t *iv = NULL;
if (n_args > 2) {
size_t iv_length = 0;
iv = (const uint8_t *)mp_obj_str_get_data(pos_args[2], &iv_length);
if (iv_length != AES_BLOCKLEN) {
mp_raise_TypeError_varg(translate("IV must be %d bytes long"),
AES_BLOCKLEN);
}
}
common_hal_aesio_aes_rekey(self, key, key_length, iv);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR(aesio_aes_rekey_obj, 2, aesio_aes_rekey);
STATIC void validate_length(aesio_aes_obj_t *self, size_t src_length,
size_t dest_length) {
if (src_length != dest_length) {
mp_raise_ValueError(
translate("Source and destination buffers must be the same length"));
}
switch (self->mode) {
case AES_MODE_ECB:
if (src_length != 16) {
mp_raise_msg(&mp_type_ValueError,
translate("ECB only operates on 16 bytes at a time"));
}
break;
case AES_MODE_CBC:
if ((src_length & 15) != 0) {
mp_raise_msg(&mp_type_ValueError,
translate("CBC blocks must be multiples of 16 bytes"));
}
break;
case AES_MODE_CTR:
break;
}
}
//| .. method:: encrypt_into(src, dest)
//|
//| Encrypt the buffer from ``src`` into ``dest``.
//| For ECB mode, the buffers must be 16 bytes long. For CBC mode, the
//| buffers must be a multiple of 16 bytes, and must be equal length. For
//| CTX mode, there are no restrictions.
//|
STATIC mp_obj_t aesio_aes_encrypt_into(mp_obj_t aesio_obj, mp_obj_t src,
mp_obj_t dest) {
if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name);
}
// Convert parameters into expected types.
aesio_aes_obj_t *aes = MP_OBJ_TO_PTR(aesio_obj);
mp_buffer_info_t srcbufinfo, destbufinfo;
mp_get_buffer_raise(src, &srcbufinfo, MP_BUFFER_READ);
mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_READ);
validate_length(aes, srcbufinfo.len, destbufinfo.len);
memcpy(destbufinfo.buf, srcbufinfo.buf, srcbufinfo.len);
common_hal_aesio_aes_encrypt(aes, (uint8_t *)destbufinfo.buf,
destbufinfo.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_encrypt_into_obj,
aesio_aes_encrypt_into);
//| .. method:: decrypt_into(src, dest)
//|
//| Decrypt the buffer from ``src`` into ``dest``.
//| For ECB mode, the buffers must be 16 bytes long. For CBC mode, the
//| buffers must be a multiple of 16 bytes, and must be equal length. For
//| CTX mode, there are no restrictions.
//|
STATIC mp_obj_t aesio_aes_decrypt_into(mp_obj_t aesio_obj, mp_obj_t src,
mp_obj_t dest) {
if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name);
}
// Convert parameters into expected types.
aesio_aes_obj_t *aes = MP_OBJ_TO_PTR(aesio_obj);
mp_buffer_info_t srcbufinfo, destbufinfo;
mp_get_buffer_raise(src, &srcbufinfo, MP_BUFFER_READ);
mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_READ);
validate_length(aes, srcbufinfo.len, destbufinfo.len);
memcpy(destbufinfo.buf, srcbufinfo.buf, srcbufinfo.len);
common_hal_aesio_aes_decrypt(aes, (uint8_t *)destbufinfo.buf,
destbufinfo.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_decrypt_into_obj,
aesio_aes_decrypt_into);
STATIC mp_obj_t aesio_aes_get_mode(mp_obj_t aesio_obj) {
if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name);
}
aesio_aes_obj_t *self = MP_OBJ_TO_PTR(aesio_obj);
return MP_OBJ_NEW_SMALL_INT(self->mode);
}
MP_DEFINE_CONST_FUN_OBJ_1(aesio_aes_get_mode_obj, aesio_aes_get_mode);
STATIC mp_obj_t aesio_aes_set_mode(mp_obj_t aesio_obj, mp_obj_t mode_obj) {
if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name);
}
aesio_aes_obj_t *self = MP_OBJ_TO_PTR(aesio_obj);
int mode = mp_obj_get_int(mode_obj);
switch (mode) {
case AES_MODE_CBC:
case AES_MODE_ECB:
case AES_MODE_CTR:
break;
default:
mp_raise_TypeError(translate("Requested AES mode is unsupported"));
}
common_hal_aesio_aes_set_mode(self, mode);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(aesio_aes_set_mode_obj, aesio_aes_set_mode);
const mp_obj_property_t aesio_aes_mode_obj = {
.base.type = &mp_type_property,
.proxy = {
(mp_obj_t)&aesio_aes_get_mode_obj,
(mp_obj_t)&aesio_aes_set_mode_obj,
(mp_obj_t)&mp_const_none_obj
},
};
STATIC const mp_rom_map_elem_t aesio_locals_dict_table[] = {
// Methods
{MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_AES)},
{MP_ROM_QSTR(MP_QSTR_encrypt_into), (mp_obj_t)&aesio_aes_encrypt_into_obj},
{MP_ROM_QSTR(MP_QSTR_decrypt_into), (mp_obj_t)&aesio_aes_decrypt_into_obj},
{MP_ROM_QSTR(MP_QSTR_rekey), (mp_obj_t)&aesio_aes_rekey_obj},
{MP_ROM_QSTR(MP_QSTR_mode), (mp_obj_t)&aesio_aes_mode_obj},
};
STATIC MP_DEFINE_CONST_DICT(aesio_locals_dict, aesio_locals_dict_table);
const mp_obj_type_t aesio_aes_type = {
{&mp_type_type},
.name = MP_QSTR_AES,
.make_new = aesio_aes_make_new,
.locals_dict = (mp_obj_dict_t *)&aesio_locals_dict,
};

View File

@ -39,6 +39,9 @@
#include "py/stream.h"
#include "supervisor/shared/translate.h"
#define STREAM_DEBUG(...) (void)0
// #define STREAM_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
//| .. currentmodule:: busio
//|
@ -219,6 +222,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_
// These three methods are used by the shared stream methods.
STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
STREAM_DEBUG("busio_uart_read stream %d\n", size);
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
check_for_deinit(self);
byte *buf = buf_in;

View File

@ -65,7 +65,7 @@ STATIC mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, const
//| import time
//|
//| r = rtc.RTC()
//| r.datetime = rtctime.struct_time((2019, 5, 29, 15, 14, 15, 0, -1, -1))
//| r.datetime = time.struct_time((2019, 5, 29, 15, 14, 15, 0, -1, -1))
//|
//|
//| Once set, the RTC will automatically update this value as time passes. You can read this

View File

@ -45,10 +45,10 @@ bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size,
}
mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self) {
while (ringbuf_count(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
while (ringbuf_num_filled(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
}
if (ringbuf_count(&self->buf) == 0 || mp_hal_is_interrupted()) {
if (ringbuf_num_filled(&self->buf) == 0 || mp_hal_is_interrupted()) {
return mp_const_none;
}
@ -97,7 +97,7 @@ void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
uint16_t len) {
int32_t packet_size = sizeof(uint8_t) + sizeof(ticks_ms) + sizeof(rssi) + NUM_BLEIO_ADDRESS_BYTES +
sizeof(addr_type) + sizeof(len) + len;
int32_t empty_space = self->buf.size - ringbuf_count(&self->buf);
int32_t empty_space = self->buf.size - ringbuf_num_filled(&self->buf);
if (packet_size >= empty_space) {
// We can't fit the packet so skip it.
return;

View File

@ -0,0 +1,58 @@
#include <string.h>
#include "py/runtime.h"
#include "shared-bindings/aesio/__init__.h"
#include "shared-module/aesio/__init__.h"
void common_hal_aesio_aes_construct(aesio_aes_obj_t *self, const uint8_t *key,
uint32_t key_length, const uint8_t *iv,
int mode, int counter) {
self->mode = mode;
self->counter = counter;
common_hal_aesio_aes_rekey(self, key, key_length, iv);
}
void common_hal_aesio_aes_rekey(aesio_aes_obj_t *self, const uint8_t *key,
uint32_t key_length, const uint8_t *iv) {
memset(&self->ctx, 0, sizeof(self->ctx));
if (iv != NULL) {
AES_init_ctx_iv(&self->ctx, key, key_length, iv);
} else {
AES_init_ctx(&self->ctx, key, key_length);
}
}
void common_hal_aesio_aes_set_mode(aesio_aes_obj_t *self, int mode) {
self->mode = mode;
}
void common_hal_aesio_aes_encrypt(aesio_aes_obj_t *self, uint8_t *buffer,
size_t length) {
switch (self->mode) {
case AES_MODE_ECB:
AES_ECB_encrypt(&self->ctx, buffer);
break;
case AES_MODE_CBC:
AES_CBC_encrypt_buffer(&self->ctx, buffer, length);
break;
case AES_MODE_CTR:
AES_CTR_xcrypt_buffer(&self->ctx, buffer, length);
break;
}
}
void common_hal_aesio_aes_decrypt(aesio_aes_obj_t *self, uint8_t *buffer,
size_t length) {
switch (self->mode) {
case AES_MODE_ECB:
AES_ECB_decrypt(&self->ctx, buffer);
break;
case AES_MODE_CBC:
AES_CBC_decrypt_buffer(&self->ctx, buffer, length);
break;
case AES_MODE_CTR:
AES_CTR_xcrypt_buffer(&self->ctx, buffer, length);
break;
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Dan Halbert 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.
*/
#ifndef MICROPY_INCLUDED_SHARED_MODULE_AESIO__INIT__H
#define MICROPY_INCLUDED_SHARED_MODULE_AESIO__INIT__H
#include <stdbool.h>
#include <stdint.h>
#include "py/obj.h"
#include "py/proto.h"
#include "shared-module/aesio/aes.h"
// These values were chosen to correspond with the values
// present in pycrypto.
enum AES_MODE {
AES_MODE_ECB = 1,
AES_MODE_CBC = 2,
AES_MODE_CTR = 6,
};
typedef struct {
mp_obj_base_t base;
// The tinyaes context
struct AES_ctx ctx;
// Which AES mode this instance of the object is configured to use
enum AES_MODE mode;
// Counter for running in CTR mode
uint32_t counter;
} aesio_aes_obj_t;
#endif // MICROPY_INCLUDED_SHARED_MODULE_AESIO__INIT__H

608
shared-module/aesio/aes.c Normal file
View File

@ -0,0 +1,608 @@
/*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
ECB-AES128
----------
plain-text:
6bc1bee22e409f96e93d7e117393172a
ae2d8a571e03ac9c9eb76fac45af8e51
30c81c46a35ce411e5fbc1191a0a52ef
f69f2445df4f9b17ad2b417be66c3710
key:
2b7e151628aed2a6abf7158809cf4f3c
resulting cipher
3ad77bb40d7a3660a89ecaf32466ef97
f5d3d58503b9699de785895a96fdbaaf
43b1cd7f598ece23881b00e3ed030688
7b0c785e27e8ad3f8223207104725dd4
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
You should pad the end of the string with zeros if this is not the case.
For AES192/256 the key size is proportionally larger.
*/
/*****************************************************************************/
/* Includes: */
/*****************************************************************************/
#include <string.h> // CBC mode, for memset
#include "aes.h"
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES.
// Value=4
#define Nb 4UL
#if defined(AES256) && (AES256 == 1)
#define Nk256 8UL
#define Nr256 14UL
#endif
#if defined(AES192) && (AES192 == 1)
#define Nk192 6UL
#define Nr192 12UL
#endif
#if defined(AES128) && (AES128 == 1)
#define Nk128 4UL // The number of 32 bit words in a key.
#define Nr128 10UL // The number of rounds in AES Cipher.
#endif
// jcallan@github points out that declaring Multiply as a function reduces code
// size considerably with the Keil ARM compiler. See this link for more
// information: https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
/*****************************************************************************/
/* Private variables: */
/*****************************************************************************/
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage
// instead of RAM The numbers below can be computed dynamically trading ROM for
// RAM - This can be useful in (embedded) bootloader applications, where ROM is
// often limited.
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// The round constant word array, Rcon[i], contains the values given by x to the
// power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
/*
* Jordan Goulder points out in PR #12
* (https://github.com/kokke/tiny-AES-C/pull/12), that you can remove most of
* the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @
* https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used up to rcon[10]
* for AES-128 (as 11 round keys are needed), up to rcon[8] for AES-192, up to
* rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/
/*****************************************************************************/
/* Private functions: */
/*****************************************************************************/
static const uint8_t *GetRoundKey(const struct AES_ctx *ctx) {
switch (ctx->KeyLength) {
#if defined(AES128) && (AES128 == 1)
case 16: return ctx->RoundKey128;
#endif
#if defined(AES192) && (AES192 == 1)
case 24: return ctx->RoundKey192;
#endif
#if defined(AES256) && (AES256 == 1)
case 32: return ctx->RoundKey256;
#endif
}
return NULL;
}
/*
static uint8_t getSBoxValue(uint8_t num)
{
return sbox[num];
}
*/
#define getSBoxValue(num) (sbox[(num)])
/*
static uint8_t getSBoxInvert(uint8_t num)
{
return rsbox[num];
}
*/
#define getSBoxInvert(num) (rsbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each
// round to decrypt the states.
static void KeyExpansion(struct AES_ctx* ctx, const uint8_t* Key)
{
uint8_t* RoundKey = (uint8_t *)GetRoundKey(ctx);
unsigned i, j, k;
uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself.
for (i = 0; i < ctx->Nk; ++i)
{
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
// All other round keys are found from the previous round keys.
for (i = ctx->Nk; i < Nb * (ctx->Nr + 1); ++i)
{
{
k = (i - 1) * 4;
tempa[0]=RoundKey[k + 0];
tempa[1]=RoundKey[k + 1];
tempa[2]=RoundKey[k + 2];
tempa[3]=RoundKey[k + 3];
}
if (i % ctx->Nk == 0)
{
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
{
const uint8_t u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
}
// SubWord() is a function that takes a four-byte input word and applies
// the S-box to each of the four bytes to produce an output word.
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
tempa[0] = tempa[0] ^ Rcon[i/ctx->Nk];
}
#if defined(AES256) && (AES256 == 1)
if (ctx->KeyLength == 32) {
if (i % ctx->Nk == 4)
{
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
}
}
#endif
j = i * 4; k=(i - ctx->Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key, uint32_t keylen)
{
ctx->KeyLength = keylen;
switch (ctx->KeyLength) {
#if defined(AES128) && (AES128 == 1)
case 16: ctx->Nr = Nr128; ctx->Nk = Nk128; break;
#endif
#if defined(AES192) && (AES192 == 1)
case 24: ctx->Nr = Nr192; ctx->Nk = Nk192; break;
#endif
#if defined(AES256) && (AES256 == 1)
case 32: ctx->Nr = Nr256; ctx->Nk = Nk256; break;
#endif
default: ctx->Nr = 0; ctx->Nk = 0; break;
}
KeyExpansion(ctx, key);
}
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, uint32_t keylen, const uint8_t* iv)
{
AES_init_ctx(ctx, key, keylen);
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
{
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
#endif
// This function adds the round key to state. The round key is added to the
// state by an XOR function.
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
{
uint8_t i,j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
}
}
}
// The SubBytes Function Substitutes the values in the state matrix with values
// in an S-box.
static void SubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxValue((*state)[j][i]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left. Each row
// is shifted with different offset. Offset = Row number. So the first row is
// not shifted.
static void ShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to left
temp = (*state)[0][1];
(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];
(*state)[2][1] = (*state)[3][1];
(*state)[3][1] = temp;
// Rotate second row 2 columns to left
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to left
temp = (*state)[0][3];
(*state)[0][3] = (*state)[3][3];
(*state)[3][3] = (*state)[2][3];
(*state)[2][3] = (*state)[1][3];
(*state)[1][3] = temp;
}
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
// MixColumns function mixes the columns of the state matrix
static void MixColumns(state_t* state)
{
uint8_t i;
uint8_t Tmp, Tm, t;
for (i = 0; i < 4; ++i)
{
t = (*state)[i][0];
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
}
}
// Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
// The compiler seems to be able to vectorize the operation better this way.
// See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
}
#else
#define Multiply(x, y) \
( ((y & 1) * x) ^ \
((y>>1 & 1) * xtime(x)) ^ \
((y>>2 & 1) * xtime(xtime(x))) ^ \
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
#endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// MixColumns function mixes the columns of the state matrix. The method used to
// multiply may be difficult to understand for the inexperienced. Please use the
// references to gain more information.
static void InvMixColumns(state_t* state)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
// The SubBytes Function Substitutes the values in the state matrix with values
// in an S-box.
static void InvSubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}
static void InvShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;
// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// Cipher is the main function that encrypts the PlainText.
static void Cipher(state_t* state, const struct AES_ctx* ctx)
{
const uint8_t* RoundKey = GetRoundKey(ctx);
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(0, state, RoundKey);
// There will be Nr rounds. The first Nr-1 rounds are identical. These Nr
// rounds are executed in the loop below. Last one without MixColumns()
for (round = 1; ; ++round)
{
SubBytes(state);
ShiftRows(state);
if (round == ctx->Nr) {
break;
}
MixColumns(state);
AddRoundKey(round, state, RoundKey);
}
// Add round key to last round
AddRoundKey(ctx->Nr, state, RoundKey);
}
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static void InvCipher(state_t* state, const struct AES_ctx* ctx)
{
const uint8_t* RoundKey = GetRoundKey(ctx);
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(ctx->Nr, state, RoundKey);
// There will be Nr rounds. The first Nr-1 rounds are identical. These Nr
// rounds are executed in the loop below. Last one without InvMixColumn()
for (round = (ctx->Nr - 1); ; --round)
{
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(round, state, RoundKey);
if (round == 0) {
break;
}
InvMixColumns(state);
}
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*****************************************************************************/
/* Public functions: */
/*****************************************************************************/
#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call encrypts the PlainText with the Key using AES
// algorithm.
Cipher((state_t*)buf, ctx);
}
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call decrypts the PlainText with the Key using AES
// algorithm.
InvCipher((state_t*)buf, ctx);
}
#endif // #if defined(ECB) && (ECB == 1)
#if defined(CBC) && (CBC == 1)
static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
{
uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
{
buf[i] ^= Iv[i];
}
}
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t *Iv = ctx->Iv;
for (i = 0; i < length; i += AES_BLOCKLEN)
{
XorWithIv(buf, Iv);
Cipher((state_t*)buf, ctx);
Iv = buf;
buf += AES_BLOCKLEN;
}
/* store Iv in ctx for next call */
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t storeNextIv[AES_BLOCKLEN];
for (i = 0; i < length; i += AES_BLOCKLEN)
{
memcpy(storeNextIv, buf, AES_BLOCKLEN);
InvCipher((state_t*)buf, ctx);
XorWithIv(buf, ctx->Iv);
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
buf += AES_BLOCKLEN;
}
}
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note
any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uint8_t buffer[AES_BLOCKLEN];
unsigned i;
int bi;
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
{
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
{
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
Cipher((state_t*)buffer, ctx);
/* Increment Iv and handle overflow */
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
{
/* inc will overflow */
if (ctx->Iv[bi] == 255)
{
ctx->Iv[bi] = 0;
continue;
}
ctx->Iv[bi] += 1;
break;
}
bi = 0;
}
buf[i] = (buf[i] ^ buffer[bi]);
}
}
#endif // #if defined(CTR) && (CTR == 1)

105
shared-module/aesio/aes.h Normal file
View File

@ -0,0 +1,105 @@
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 1
#endif
#ifndef CTR
#define CTR 1
#endif
#define AES128 1
#define AES192 1
#define AES256 1
#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
#if defined(AES256) && (AES256 == 1)
#define AES_KEYLEN256 32
#define AES_keyExpSize256 240
#endif
#if defined(AES192) && (AES192 == 1)
#define AES_KEYLEN192 24
#define AES_keyExpSize192 208
#endif
#if defined(AES128) && (AES128 == 1)
#define AES_KEYLEN128 16 // Key length in bytes
#define AES_keyExpSize128 176
#endif
struct AES_ctx
{
union {
#if defined(AES256) && (AES256 == 1)
uint8_t RoundKey256[AES_keyExpSize256];
#endif
#if defined(AES192) && (AES192 == 1)
uint8_t RoundKey192[AES_keyExpSize192];
#endif
#if defined(AES128) && (AES128 == 1)
uint8_t RoundKey128[AES_keyExpSize128];
#endif
};
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
uint8_t Iv[AES_BLOCKLEN];
#endif
uint32_t KeyLength;
uint8_t Nr;
uint8_t Nk;
};
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key, uint32_t keylen);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, uint32_t keylen, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif
#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes;
// you need only AES_init_ctx as IV is not used in ECB
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
#endif // #if defined(ECB) && (ECB == !)
#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CTR) && (CTR == 1)
#endif // _AES_H_

View File

@ -109,6 +109,8 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
// Always set the backlight type in case we're reusing memory.
self->backlight_inout.base.type = &mp_type_NoneType;
if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) {
// Avoid PWM types and functions when the module isn't enabled
#if (CIRCUITPY_PULSEIO)
pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false);
if (result != PWMOUT_OK) {
self->backlight_inout.base.type = &digitalio_digitalinout_type;
@ -118,6 +120,12 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->backlight_pwm.base.type = &pulseio_pwmout_type;
common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm);
}
#else
// Otherwise default to digital
self->backlight_inout.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin);
common_hal_never_reset_pin(backlight_pin);
#endif
}
if (!self->auto_brightness && (self->backlight_inout.base.type != &mp_type_NoneType ||
brightness_command != NO_BRIGHTNESS_COMMAND)) {
@ -162,9 +170,21 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self,
brightness = 1.0-brightness;
}
bool ok = false;
if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
// Avoid PWM types and functions when the module isn't enabled
#if (CIRCUITPY_PULSEIO)
bool ispwm = (self->backlight_pwm.base.type == &pulseio_pwmout_type) ? true : false;
#else
bool ispwm = false;
#endif
if (ispwm) {
#if (CIRCUITPY_PULSEIO)
common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness));
ok = true;
#else
ok = false;
#endif
} else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99);
ok = true;
@ -390,12 +410,16 @@ void displayio_display_background(displayio_display_obj_t* self) {
void release_display(displayio_display_obj_t* self) {
release_display_core(&self->core);
#if (CIRCUITPY_PULSEIO)
if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm);
common_hal_pulseio_pwmout_deinit(&self->backlight_pwm);
common_hal_pulseio_pwmout_deinit(&self->backlight_pwm);
} else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) {
common_hal_digitalio_digitalinout_deinit(&self->backlight_inout);
}
#else
common_hal_digitalio_digitalinout_deinit(&self->backlight_inout);
#endif
}
void reset_display(displayio_display_obj_t* self) {