Merge branch 'main' into pixelbuf-iterable

This commit is contained in:
Scott Shawcroft 2020-08-13 11:55:51 -07:00 committed by GitHub
commit ff5902f9f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
96 changed files with 5384 additions and 286 deletions

View File

@ -253,6 +253,7 @@ jobs:
- "pca10100"
- "pewpew10"
- "pewpew_m4"
- "picoplanet"
- "pirkey_m0"
- "pitaya_go"
- "pyb_nano_v2"

View File

@ -8,6 +8,10 @@
version: 2
submodules:
include:
- extmod/ulab
python:
version: 3
install:

View File

@ -58,6 +58,16 @@ STATIC char *str_dup_maybe(const char *str) {
return s2;
}
STATIC size_t count_cont_bytes(char *start, char *end) {
int count = 0;
for (char *pos = start; pos < end; pos++) {
if(UTF8_IS_CONT(*pos)) {
count++;
}
}
return count;
}
// By default assume terminal which implements VT100 commands...
#ifndef MICROPY_HAL_HAS_VT100
#define MICROPY_HAL_HAS_VT100 (1)
@ -92,6 +102,7 @@ typedef struct _readline_t {
int escape_seq;
int hist_cur;
size_t cursor_pos;
uint8_t utf8_cont_chars;
char escape_seq_buf[1];
const char *prompt;
} readline_t;
@ -99,7 +110,8 @@ typedef struct _readline_t {
STATIC readline_t rl;
int readline_process_char(int c) {
size_t last_line_len = rl.line->len;
size_t last_line_len = utf8_charlen((byte *)rl.line->buf, rl.line->len);
int cont_chars = 0;
int redraw_step_back = 0;
bool redraw_from_cursor = false;
int redraw_step_forward = 0;
@ -178,6 +190,12 @@ int readline_process_char(int c) {
int nspace = 1;
#endif
// Check if we have moved into a UTF-8 continuation byte
while (UTF8_IS_CONT(rl.line->buf[rl.cursor_pos-nspace])) {
nspace++;
cont_chars++;
}
// do the backspace
vstr_cut_out_bytes(rl.line, rl.cursor_pos - nspace, nspace);
// set redraw parameters
@ -206,12 +224,27 @@ int readline_process_char(int c) {
redraw_step_forward = compl_len;
}
#endif
} else if (32 <= c ) {
} else if (32 <= c) {
// printable character
vstr_ins_char(rl.line, rl.cursor_pos, c);
// set redraw parameters
redraw_from_cursor = true;
redraw_step_forward = 1;
char lcp = rl.line->buf[rl.cursor_pos];
uint8_t cont_need = 0;
if (!UTF8_IS_CONT(c)) {
// ASCII or Lead code point
rl.utf8_cont_chars = 0;
lcp = c;
}else {
rl.utf8_cont_chars += 1;
}
if (lcp >= 0xc0 && lcp < 0xf8) {
cont_need = (0xe5 >> ((lcp >> 3) & 0x6)) & 3; // From unicode.c L195
}
vstr_ins_char(rl.line, rl.cursor_pos+rl.utf8_cont_chars, c);
// set redraw parameters if we have the entire character
if (rl.utf8_cont_chars == cont_need) {
redraw_from_cursor = true;
redraw_step_forward = rl.utf8_cont_chars+1;
cont_chars = rl.utf8_cont_chars;
}
}
} else if (rl.escape_seq == ESEQ_ESC) {
switch (c) {
@ -237,6 +270,8 @@ up_arrow_key:
#endif
// up arrow
if (rl.hist_cur + 1 < (int)READLINE_HIST_SIZE && MP_STATE_PORT(readline_hist)[rl.hist_cur + 1] != NULL) {
// Check for continuation characters
cont_chars = count_cont_bytes(rl.line->buf+rl.orig_line_len, rl.line->buf+rl.cursor_pos);
// increase hist num
rl.hist_cur += 1;
// set line to history
@ -253,6 +288,8 @@ down_arrow_key:
#endif
// down arrow
if (rl.hist_cur >= 0) {
// Check for continuation characters
cont_chars = count_cont_bytes(rl.line->buf+rl.orig_line_len, rl.line->buf+rl.cursor_pos);
// decrease hist num
rl.hist_cur -= 1;
// set line to history
@ -272,6 +309,11 @@ right_arrow_key:
// right arrow
if (rl.cursor_pos < rl.line->len) {
redraw_step_forward = 1;
// Check if we have moved into a UTF-8 continuation byte
while (UTF8_IS_CONT(rl.line->buf[rl.cursor_pos+redraw_step_forward]) &&
rl.cursor_pos+redraw_step_forward < rl.line->len) {
redraw_step_forward++;
}
}
} else if (c == 'D') {
#if MICROPY_REPL_EMACS_KEYS
@ -280,6 +322,11 @@ left_arrow_key:
// left arrow
if (rl.cursor_pos > rl.orig_line_len) {
redraw_step_back = 1;
// Check if we have moved into a UTF-8 continuation byte
while (UTF8_IS_CONT(rl.line->buf[rl.cursor_pos-redraw_step_back])) {
redraw_step_back++;
cont_chars++;
}
}
} else if (c == 'H') {
// home
@ -331,18 +378,20 @@ delete_key:
// redraw command prompt, efficiently
if (redraw_step_back > 0) {
mp_hal_move_cursor_back(redraw_step_back);
mp_hal_move_cursor_back(redraw_step_back-cont_chars);
rl.cursor_pos -= redraw_step_back;
}
if (redraw_from_cursor) {
if (rl.line->len < last_line_len) {
if (utf8_charlen((byte *)rl.line->buf, rl.line->len) < last_line_len) {
// erase old chars
mp_hal_erase_line_from_cursor(last_line_len - rl.cursor_pos);
}
// Check for continuation characters
cont_chars = count_cont_bytes(rl.line->buf+rl.cursor_pos+redraw_step_forward, rl.line->buf+rl.line->len);
// draw new chars
mp_hal_stdout_tx_strn(rl.line->buf + rl.cursor_pos, rl.line->len - rl.cursor_pos);
// move cursor forward if needed (already moved forward by length of line, so move it back)
mp_hal_move_cursor_back(rl.line->len - (rl.cursor_pos + redraw_step_forward));
mp_hal_move_cursor_back(rl.line->len - (rl.cursor_pos + redraw_step_forward) - cont_chars);
rl.cursor_pos += redraw_step_forward;
} else if (redraw_step_forward > 0) {
// draw over old chars to move cursor forwards

View File

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-07-06 18:10+0000\n"
"Last-Translator: oon arfiandwi <oon.arfiandwi@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -882,10 +882,6 @@ msgstr "operasi I/O pada file tertutup"
msgid "I2C Init Error"
msgstr "Gagal Inisialisasi I2C"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-08-08 18:40-0400\n"
"POT-Creation-Date: 2020-08-11 15:37-0500\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"
@ -447,6 +447,10 @@ msgstr ""
msgid "Buffer length must be a multiple of 512"
msgstr ""
#: ports/stm/common-hal/sdioio/SDCard.c
msgid "Buffer must be a multiple of 512 bytes"
msgstr ""
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
@ -819,6 +823,11 @@ msgstr ""
msgid "File exists"
msgstr ""
#: shared-module/framebufferio/FramebufferDisplay.c
#, c-format
msgid "Framebuffer requires %d bytes"
msgstr ""
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
msgid "Frequency captured is above capability. Capture Paused."
msgstr ""
@ -843,7 +852,7 @@ msgid "Group full"
msgstr ""
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c
#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/sdioio/SDCard.c
msgid "Hardware busy, try alternative pins"
msgstr ""
@ -908,6 +917,11 @@ msgstr ""
msgid "Invalid %q pin"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c ports/stm/common-hal/busio/SPI.c
#: ports/stm/common-hal/busio/UART.c ports/stm/common-hal/sdioio/SDCard.c
msgid "Invalid %q pin selection"
msgstr ""
#: ports/stm/common-hal/analogio/AnalogIn.c
msgid "Invalid ADC Unit value"
msgstr ""
@ -920,24 +934,12 @@ msgstr ""
msgid "Invalid DAC pin supplied"
msgstr ""
#: ports/stm/common-hal/busio/I2C.c
msgid "Invalid I2C pin selection"
msgstr ""
#: ports/atmel-samd/common-hal/pulseio/PWMOut.c
#: ports/cxd56/common-hal/pulseio/PWMOut.c
#: ports/nrf/common-hal/pulseio/PWMOut.c shared-bindings/pulseio/PWMOut.c
msgid "Invalid PWM frequency"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
msgid "Invalid SPI pin selection"
msgstr ""
#: ports/stm/common-hal/busio/UART.c
msgid "Invalid UART pin selection"
msgstr ""
#: py/moduerrno.c shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid argument"
msgstr ""
@ -1406,6 +1408,16 @@ msgstr ""
msgid "SDA or SCL needs a pull up"
msgstr ""
#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
msgid "SDIO GetCardInfo Error %d"
msgstr ""
#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
msgid "SDIO Init Error %d"
msgstr ""
#: ports/stm/common-hal/busio/SPI.c
msgid "SPI Init Error"
msgstr ""

View File

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-05-24 03:22+0000\n"
"Last-Translator: dronecz <mzuzelka@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -44,11 +44,11 @@ msgstr ""
#: py/obj.c
msgid " File \"%q\""
msgstr "  Soubor \"%q\""
msgstr "  Soubor \"% q\""
#: py/obj.c
msgid " File \"%q\", line %d"
msgstr "  Soubor \"%q\", řádek %d"
msgstr "  Soubor \"% q\", řádek% d"
#: main.c
msgid " output:\n"
@ -57,7 +57,7 @@ msgstr " výstup:\n"
#: py/objstr.c
#, c-format
msgid "%%c requires int or char"
msgstr "%%c vyžaduje int nebo char"
msgstr "%% c vyžaduje int nebo char"
#: shared-bindings/rgbmatrix/RGBMatrix.c
#, c-format
@ -78,11 +78,11 @@ msgstr "%q index je mimo rozsah"
#: py/obj.c
msgid "%q indices must be integers, not %s"
msgstr "Indexy %q musí být celá čísla, nikoli %s"
msgstr "Indexy% q musí být celá čísla, nikoli% s"
#: shared-bindings/vectorio/Polygon.c
msgid "%q list must be a list"
msgstr "Seznam %q musí být seznam"
msgstr "Seznam% q musí být seznam"
#: shared-bindings/memorymonitor/AllocationAlarm.c
msgid "%q must be >= 0"
@ -94,11 +94,11 @@ msgstr ""
#: shared-bindings/memorymonitor/AllocationAlarm.c
#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c
msgid "%q must be >= 1"
msgstr " %q musí být > = 1"
msgstr "% q musí být > = 1"
#: shared-module/vectorio/Polygon.c
msgid "%q must be a tuple of length 2"
msgstr " %q musí být n-tice délky 2"
msgstr "% q musí být n-tice délky 2"
#: ports/atmel-samd/common-hal/sdioio/SDCard.c
msgid "%q pin invalid"
@ -106,7 +106,7 @@ msgstr ""
#: shared-bindings/fontio/BuiltinFont.c
msgid "%q should be an int"
msgstr " %q by měl být int"
msgstr "% q by měl být int"
#: py/bc.c py/objnamedtuple.c
msgid "%q() takes %d positional arguments but %d were given"
@ -867,10 +867,6 @@ msgstr ""
msgid "I2C Init Error"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"

View File

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-06-16 18:24+0000\n"
"Last-Translator: Andreas Buchen <andreas.buchen@gmail.com>\n"
"Language: de_DE\n"
@ -882,10 +882,6 @@ msgstr "Lese/Schreibe-operation an geschlossener Datei"
msgid "I2C Init Error"
msgstr "I2C-Init-Fehler"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
@ -3487,12 +3483,12 @@ msgstr ""
#~ msgid "'async for' or 'async with' outside async function"
#~ msgstr "'async for' oder 'async with' außerhalb der asynchronen Funktion"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PulseIn wird auf diesem Chip nicht unterstützt"
#~ msgid "PulseOut not supported on this chip"
#~ msgstr "PulseOut wird auf diesem Chip nicht unterstützt"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PulseIn wird auf diesem Chip nicht unterstützt"
#~ msgid "AP required"
#~ msgstr "AP erforderlich"

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"PO-Revision-Date: 2020-07-22 20:48+0000\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-07-24 21:12+0000\n"
"Last-Translator: Alvaro Figueroa <alvaro@greencore.co.cr>\n"
"Language-Team: \n"
"Language: es\n"
@ -89,7 +89,7 @@ msgstr "%q lista debe ser una lista"
#: shared-bindings/memorymonitor/AllocationAlarm.c
msgid "%q must be >= 0"
msgstr ""
msgstr "%q debe ser >= 0"
#: shared-bindings/_bleio/CharacteristicBuffer.c
#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
@ -241,7 +241,7 @@ msgstr "'continue' fuera de un bucle"
#: py/objgenerator.c
msgid "'coroutine' object is not an iterator"
msgstr ""
msgstr "el objeto 'coroutine' no es un iterador"
#: py/compile.c
msgid "'data' requires at least 2 arguments"
@ -338,7 +338,7 @@ msgstr "Ya se encuentra publicando."
#: shared-module/memorymonitor/AllocationAlarm.c
#: shared-module/memorymonitor/AllocationSize.c
msgid "Already running"
msgstr ""
msgstr "Ya está en ejecución"
#: ports/cxd56/common-hal/analogio/AnalogIn.c
msgid "AnalogIn not supported on given pin"
@ -378,7 +378,7 @@ msgstr "Como máximo %d %q se puede especificar (no %d)"
#: shared-module/memorymonitor/AllocationAlarm.c
#, c-format
msgid "Attempt to allocate %d blocks"
msgstr ""
msgstr "Tratando de localizar %d bloques"
#: supervisor/shared/safe_mode.c
msgid "Attempted heap allocation when MicroPython VM not running."
@ -883,10 +883,6 @@ msgstr "Operación I/O en archivo cerrado"
msgid "I2C Init Error"
msgstr "Error de inicio de I2C"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
@ -1591,6 +1587,8 @@ msgstr ""
msgid ""
"Timer was reserved for internal use - declare PWM pins earlier in the program"
msgstr ""
"El temporizador es utilizado para uso interno - declare los pines para PWM "
"más temprano en el programa"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample."
@ -3470,12 +3468,12 @@ msgstr "zi debe ser una forma (n_section,2)"
#~ msgid "'async for' or 'async with' outside async function"
#~ msgstr "'async for' o 'async with' fuera de la función async"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PulseIn no es compatible con este chip"
#~ msgid "PulseOut not supported on this chip"
#~ msgstr "PulseOut no es compatible con este chip"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PulseIn no es compatible con este chip"
#~ msgid "AP required"
#~ msgstr "AP requerido"
@ -3719,8 +3717,8 @@ msgstr "zi debe ser una forma (n_section,2)"
#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d "
#~ "bpp given"
#~ msgstr ""
#~ "Solo se admiten BMP monocromos, indexados de 8bpp y 16bpp o superiores:%d "
#~ "bppdado"
#~ "Solo se admiten BMP monocromos, indexados de 8bpp y 16bpp o superiores:% "
#~ "d bppdado"
#, fuzzy
#~ msgid "Only slices with step=1 (aka None) are supported"

View File

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@ -873,10 +873,6 @@ msgstr "I/O operasyon sa saradong file"
msgid "I2C Init Error"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
@ -2055,7 +2051,7 @@ msgstr "hindi puede ang maraming *x"
#: py/emitnative.c
msgid "can't implicitly convert '%q' to 'bool'"
msgstr "hindi maaaring ma-convert ang ' %q' sa 'bool'"
msgstr "hindi maaaring ma-convert ang '% qt' sa 'bool'"
#: py/emitnative.c
msgid "can't load from '%q'"

View File

@ -7,15 +7,15 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"PO-Revision-Date: 2020-06-05 17:29+0000\n"
"Last-Translator: aberwag <aberwag@gmail.com>\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-07-27 21:27+0000\n"
"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\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"
"X-Generator: Weblate 4.2-dev\n"
#: main.c
msgid ""
@ -70,7 +70,7 @@ msgstr ""
#: ports/atmel-samd/common-hal/sdioio/SDCard.c
msgid "%q failure: %d"
msgstr ""
msgstr "Échec de %q : %d"
#: shared-bindings/microcontroller/Pin.c
msgid "%q in use"
@ -90,7 +90,7 @@ msgstr "La liste %q doit être une liste"
#: shared-bindings/memorymonitor/AllocationAlarm.c
msgid "%q must be >= 0"
msgstr ""
msgstr "%q doit être >= 0"
#: shared-bindings/_bleio/CharacteristicBuffer.c
#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
@ -106,7 +106,7 @@ msgstr "%q doit être un tuple de longueur 2"
#: ports/atmel-samd/common-hal/sdioio/SDCard.c
msgid "%q pin invalid"
msgstr ""
msgstr "PIN %q invalide"
#: shared-bindings/fontio/BuiltinFont.c
msgid "%q should be an int"
@ -242,7 +242,7 @@ msgstr "'continue' en dehors d'une boucle"
#: py/objgenerator.c
msgid "'coroutine' object is not an iterator"
msgstr ""
msgstr "L'objet « coroutine » n'est pas un itérateur"
#: py/compile.c
msgid "'data' requires at least 2 arguments"
@ -337,7 +337,7 @@ msgstr "S'annonce déjà."
#: shared-module/memorymonitor/AllocationAlarm.c
#: shared-module/memorymonitor/AllocationSize.c
msgid "Already running"
msgstr ""
msgstr "Déjà en cours d'exécution"
#: ports/cxd56/common-hal/analogio/AnalogIn.c
msgid "AnalogIn not supported on given pin"
@ -378,7 +378,7 @@ msgstr "Au plus %d %q peut être spécifié (pas %d)"
#: shared-module/memorymonitor/AllocationAlarm.c
#, c-format
msgid "Attempt to allocate %d blocks"
msgstr ""
msgstr "Tentative d'allocation de %d blocs"
#: supervisor/shared/safe_mode.c
msgid "Attempted heap allocation when MicroPython VM not running."
@ -462,7 +462,7 @@ msgstr "La longueur du tampon %d est trop grande. Il doit être inférieur à %d
#: ports/atmel-samd/common-hal/sdioio/SDCard.c
#: ports/cxd56/common-hal/sdioio/SDCard.c shared-module/sdcardio/SDCard.c
msgid "Buffer length must be a multiple of 512"
msgstr ""
msgstr "La longueur de la mémoire tampon doit être un multiple de 512"
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
@ -633,11 +633,11 @@ msgstr "Code brut corrompu"
#: ports/cxd56/common-hal/gnss/GNSS.c
msgid "Could not initialize GNSS"
msgstr ""
msgstr "Impossible d'initialiser GNSS"
#: ports/cxd56/common-hal/sdioio/SDCard.c
msgid "Could not initialize SDCard"
msgstr ""
msgstr "Impossible d'initialiser la carte SD"
#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c
msgid "Could not initialize UART"
@ -887,10 +887,6 @@ msgstr "opération d'E/S sur un fichier fermé"
msgid "I2C Init Error"
msgstr "Erreur d'initialisation I2C"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
@ -931,7 +927,7 @@ msgstr "Erreur interne #%d"
#: shared-bindings/sdioio/SDCard.c
msgid "Invalid %q"
msgstr ""
msgstr "%q invalide"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
@ -1147,7 +1143,7 @@ msgstr "Doit fournir une broche MISO ou MOSI"
#: ports/stm/common-hal/busio/SPI.c
msgid "Must provide SCK pin"
msgstr ""
msgstr "Vous devez fournir un code PIN SCK"
#: shared-bindings/rgbmatrix/RGBMatrix.c
#, c-format
@ -1446,7 +1442,7 @@ msgstr "Mode sans-échec ! Le code sauvegardé n'est pas éxecuté.\n"
#: shared-module/sdcardio/SDCard.c
msgid "SD card CSD format not supported"
msgstr ""
msgstr "Le format de carte SD CSD n'est pas pris en charge"
#: ports/atmel-samd/common-hal/busio/I2C.c
#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
@ -1520,7 +1516,7 @@ msgstr "Fournissez au moins une broche UART"
#: shared-bindings/gnss/GNSS.c
msgid "System entry must be gnss.SatelliteSystem"
msgstr ""
msgstr "L'entrée du système doit être gnss.SatelliteSystem"
#: ports/stm/common-hal/microcontroller/Processor.c
msgid "Temperature read timed out"
@ -2113,7 +2109,7 @@ msgstr ""
#: shared-module/sdcardio/SDCard.c
msgid "can't set 512 block size"
msgstr ""
msgstr "impossible de définir une taille de bloc de 512"
#: py/objnamedtuple.c
msgid "can't set attribute"
@ -2250,7 +2246,7 @@ msgstr "n'a pas pu inverser la matrice Vandermonde"
#: shared-module/sdcardio/SDCard.c
msgid "couldn't determine SD card version"
msgstr ""
msgstr "impossible de déterminer la version de la carte SD"
#: extmod/ulab/code/approx/approx.c
msgid "data must be iterable"
@ -2821,7 +2817,7 @@ msgstr "compte de décalage négatif"
#: shared-module/sdcardio/SDCard.c
msgid "no SD card"
msgstr ""
msgstr "pas de carte SD"
#: py/vm.c
msgid "no active exception to reraise"
@ -2846,7 +2842,7 @@ msgstr "pas de broche de réinitialisation disponible"
#: shared-module/sdcardio/SDCard.c
msgid "no response from SD card"
msgstr ""
msgstr "pas de réponse de la carte SD"
#: py/runtime.c
msgid "no such attribute"
@ -3490,12 +3486,12 @@ msgstr ""
#~ msgid "'async for' or 'async with' outside async function"
#~ msgstr "'async for' ou 'async with' sans fonction asynchrone extérieure"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PulseIn non pris en charge sur cette puce"
#~ msgid "PulseOut not supported on this chip"
#~ msgstr "PulseOut non pris en charge sur cette puce"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PulseIn non pris en charge sur cette puce"
#~ msgid "AP required"
#~ msgstr "'AP' requis"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@ -860,10 +860,6 @@ msgstr ""
msgid "I2C Init Error"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@ -873,10 +873,6 @@ msgstr "operazione I/O su file chiuso"
msgid "I2C Init Error"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"

3346
locale/ja.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2019-05-06 14:22-0700\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -863,10 +863,6 @@ msgstr ""
msgid "I2C Init Error"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"

View File

@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"PO-Revision-Date: 2020-08-02 20:41+0000\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-07-27 21:27+0000\n"
"Last-Translator: _fonzlate <vooralfred@gmail.com>\n"
"Language-Team: none\n"
"Language: nl\n"
@ -226,7 +226,7 @@ msgstr "'await' buiten de functie"
#: py/compile.c
msgid "'await', 'async for' or 'async with' outside async function"
msgstr "'await', 'async for' of 'async with' buiten async functie"
msgstr ""
#: py/compile.c
msgid "'break' outside loop"
@ -877,10 +877,6 @@ msgstr "I/O actie op gesloten bestand"
msgid "I2C Init Error"
msgstr "I2C Init Fout"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr "I2SOut is niet beschikbaar"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
@ -1861,7 +1857,7 @@ msgstr "argument heeft onjuist type"
#: extmod/ulab/code/linalg/linalg.c
msgid "argument must be ndarray"
msgstr "argument moet ndarray zijn"
msgstr ""
#: py/argcheck.c shared-bindings/_stage/__init__.c
#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c
@ -2568,7 +2564,7 @@ msgstr "integer vereist"
#: extmod/ulab/code/approx/approx.c
msgid "interp is defined for 1D arrays of equal length"
msgstr "interp is gedefinieerd voor eendimensionale arrays van gelijke lengte"
msgstr "interp is gedefinieerd for eendimensionale arrays van gelijke lengte"
#: shared-bindings/_bleio/Adapter.c
#, c-format
@ -3256,7 +3252,7 @@ msgstr "te veel waarden om uit te pakken (%d verwacht)"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays of equal length"
msgstr "trapz is gedefinieerd voor eendimensionale arrays van gelijke lengte"
msgstr ""
#: extmod/ulab/code/linalg/linalg.c py/objstr.c
msgid "tuple index out of range"
@ -3388,7 +3384,7 @@ msgstr "value_count moet groter dan 0 zijn"
#: extmod/ulab/code/linalg/linalg.c
msgid "vectors must have same lengths"
msgstr "vectoren moeten van gelijke lengte zijn"
msgstr ""
#: shared-bindings/watchdog/WatchDogTimer.c
msgid "watchdog timeout must be greater than 0"
@ -3454,15 +3450,18 @@ msgstr "zi moet van type float zijn"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi moet vorm (n_section, 2) hebben"
#~ msgid "'%q' object is not bytes-like"
#~ msgstr "'%q' object is niet bytes-achtig"
#~ msgid "'async for' or 'async with' outside async function"
#~ msgstr "'async for' of 'async with' buiten async functie"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PusleIn niet ondersteund door deze chip"
#~ msgid "PulseOut not supported on this chip"
#~ msgstr "PulseOut niet ondersteund door deze chip"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PusleIn niet ondersteund door deze chip"
#~ msgid "I2C operation not supported"
#~ msgstr "I2C actie niet ondersteund"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@ -863,10 +863,6 @@ msgstr "Operacja I/O na zamkniętym pliku"
msgid "I2C Init Error"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"

View File

@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"PO-Revision-Date: 2020-07-31 14:41+0000\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-07-28 15:41+0000\n"
"Last-Translator: Wellington Terumi Uemura <wellingtonuemura@gmail.com>\n"
"Language-Team: \n"
"Language: pt_BR\n"
@ -886,10 +886,6 @@ msgstr "Operação I/O no arquivo fechado"
msgid "I2C Init Error"
msgstr "Erro de inicialização do I2C"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr "O I2SOut não está disponível"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
@ -1876,7 +1872,7 @@ msgstr "argumento tem tipo errado"
#: extmod/ulab/code/linalg/linalg.c
msgid "argument must be ndarray"
msgstr "o argumento deve ser um ndarray"
msgstr ""
#: py/argcheck.c shared-bindings/_stage/__init__.c
#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c
@ -3074,7 +3070,7 @@ msgstr "a anotação do retorno deve ser um identificador"
#: py/emitnative.c
msgid "return expected '%q' but got '%q'"
msgstr "o retorno esperado era '%q', porém obteve '%q'"
msgstr "o retorno esperado era '%q', porém obteve '% q'"
#: shared-bindings/rgbmatrix/RGBMatrix.c
#, c-format
@ -3282,7 +3278,7 @@ msgstr "valores demais para descompactar (esperado %d)"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays of equal length"
msgstr "o trapz está definido para 1D arrays de igual tamanho"
msgstr ""
#: extmod/ulab/code/linalg/linalg.c py/objstr.c
msgid "tuple index out of range"
@ -3414,7 +3410,7 @@ msgstr "o value_count deve ser > 0"
#: extmod/ulab/code/linalg/linalg.c
msgid "vectors must have same lengths"
msgstr "os vetores devem ter os mesmos comprimentos"
msgstr ""
#: shared-bindings/watchdog/WatchDogTimer.c
msgid "watchdog timeout must be greater than 0"
@ -3486,12 +3482,12 @@ msgstr "zi deve estar na forma (n_section, 2)"
#~ msgid "'async for' or 'async with' outside async function"
#~ msgstr "'assíncrono para' ou 'assíncrono com' função assíncrona externa"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "O PulseIn não é compatível neste CI"
#~ msgid "PulseOut not supported on this chip"
#~ msgstr "O PulseOut não é compatível neste CI"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "O PulseIn não é compatível neste CI"
#~ msgid "AP required"
#~ msgstr "AP requerido"

View File

@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"PO-Revision-Date: 2020-08-05 20:32+0000\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2020-07-25 20:58+0000\n"
"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: sv\n"
@ -226,7 +226,7 @@ msgstr "'await' utanför funktion"
#: py/compile.c
msgid "'await', 'async for' or 'async with' outside async function"
msgstr "'await', 'async for' eller 'async with' utanför async-funktion"
msgstr ""
#: py/compile.c
msgid "'break' outside loop"
@ -875,10 +875,6 @@ msgstr "I/O-operation på stängd fil"
msgid "I2C Init Error"
msgstr "I2C init-fel"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr "I2SOut är inte tillgängligt"
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"
@ -1854,7 +1850,7 @@ msgstr "argumentet har fel typ"
#: extmod/ulab/code/linalg/linalg.c
msgid "argument must be ndarray"
msgstr "argumentet måste vara ndarray"
msgstr ""
#: py/argcheck.c shared-bindings/_stage/__init__.c
#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c
@ -2119,7 +2115,7 @@ msgstr ""
#: py/objtype.c
msgid "cannot create '%q' instances"
msgstr "kan inte skapa instanser av '%q'"
msgstr "kan inte skapa instanser av '% q'"
#: py/objtype.c
msgid "cannot create instance"
@ -3249,7 +3245,7 @@ msgstr "för många värden att packa upp (förväntat %d)"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays of equal length"
msgstr "interp är definierad för 1D-matriser med samma längd"
msgstr ""
#: extmod/ulab/code/linalg/linalg.c py/objstr.c
msgid "tuple index out of range"
@ -3381,7 +3377,7 @@ msgstr "value_count måste vara > 0"
#: extmod/ulab/code/linalg/linalg.c
msgid "vectors must have same lengths"
msgstr "vektorer måste ha samma längd"
msgstr ""
#: shared-bindings/watchdog/WatchDogTimer.c
msgid "watchdog timeout must be greater than 0"
@ -3447,13 +3443,16 @@ msgstr "zi måste vara av typ float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi måste vara i formen (n_section, 2)"
#~ msgid "'%q' object is not bytes-like"
#~ msgstr "%q-objektet är inte byte-lik"
#~ msgid "'async for' or 'async with' outside async function"
#~ msgstr "'async for' eller 'async with' utanför async-funktion"
#~ msgid "PulseIn not supported on this chip"
#~ msgid "PulseOut not supported on this chip"
#~ msgstr "PulseIn stöds inte av detta chip"
#~ msgid "PulseOut not supported on this chip"
#~ msgid "PulseIn not supported on this chip"
#~ msgstr "PulseIn stöds inte av detta chip"
#~ msgid "I2C operation not supported"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-07-30 07:23-0500\n"
"POT-Creation-Date: 2020-07-28 16:57-0500\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@ -871,10 +871,6 @@ msgstr "Wénjiàn shàng de I/ O cāozuò"
msgid "I2C Init Error"
msgstr "I2C chūshǐhuà cuòwù"
#: shared-bindings/audiobusio/I2SOut.c
msgid "I2SOut not available"
msgstr ""
#: shared-bindings/aesio/aes.c
#, c-format
msgid "IV must be %d bytes long"

2
main.c
View File

@ -282,7 +282,7 @@ bool run_code_py(safe_mode_t safe_mode) {
}
}
// Wait for connection or character.
// Display a different completion message if the user has no USB attached (cannot save files)
if (!serial_connected_at_start) {
serial_write_compressed(translate("\nCode done running. Waiting for reload.\n"));
}

View File

@ -361,7 +361,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
SRC_QSTR += $(HEADER_BUILD)/sdiodata.h
$(HEADER_BUILD)/sdiodata.h: $(TOP)/tools/mksdiodata.py | $(HEADER_BUILD)
$(HEADER_BUILD)/sdiodata.h: tools/mksdiodata.py | $(HEADER_BUILD)
$(Q)$(PYTHON3) $< > $@
SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)

View File

@ -16,3 +16,20 @@ CIRCUITPY_COUNTIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_VECTORIO = 0
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -13,9 +13,11 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
# Turn off features and optimizations for Crickit build to make room for additional frozen libs.
LONGINT_IMPL = NONE
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_PIXELBUF = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
# So not all of displayio, sorry!
CIRCUITPY_VECTORIO = 0
@ -29,3 +31,18 @@ FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 15
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -13,8 +13,24 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_VECTORIO = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -13,9 +13,25 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
# supersized, not ultra-supersized
CIRCUITPY_VECTORIO = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -15,6 +15,25 @@ LONGINT_IMPL = MPZ
CIRCUITPY_AUDIOBUSIO = 0
# No DAC on SAMR21G
CIRCUITPY_AUDIOIO = 0
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
# Too much flash for Korean translations
CIRCUITPY_VECTORIO = 0
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -9,11 +9,12 @@ CHIP_FAMILY = samd21
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ
LONGINT_IMPL = NONE
# To keep the build small
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CPERIPHERAL = 0
@ -29,3 +30,18 @@ SUPEROPT_GC = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -13,7 +13,10 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANG_APA102 = 1
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_RTC = 0
@ -22,3 +25,18 @@ CIRCUITPY_VECTORIO = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -12,8 +12,24 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_VECTORIO = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -0,0 +1,37 @@
/*
* 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,42 @@
#define MICROPY_HW_BOARD_NAME "PicoPlanet"
#define MICROPY_HW_MCU_NAME "samd21e18"
#define MICROPY_PORT_A (PORT_PA00 | PORT_PA01)
#define MICROPY_PORT_B (0)
#define MICROPY_PORT_C (0)
#define IGNORE_PIN_PA00 1
#define IGNORE_PIN_PA01 1
#define IGNORE_PIN_PA10 1
#define IGNORE_PIN_PA11 1
#define IGNORE_PIN_PA12 1
#define IGNORE_PIN_PA13 1
#define IGNORE_PIN_PA14 1
#define IGNORE_PIN_PA15 1
#define IGNORE_PIN_PA18 1
#define IGNORE_PIN_PA19 1
#define IGNORE_PIN_PA20 1
#define IGNORE_PIN_PA21 1
#define IGNORE_PIN_PA22 1
#define IGNORE_PIN_PA23 1
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1
#define IGNORE_PIN_PA27 1
#define IGNORE_PIN_PA28 1
#define IGNORE_PIN_PA31 1
#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
#define DEFAULT_SPI_BUS_MISO (&pin_PA30)
#define DEFAULT_SPI_BUS_SCK (&pin_PA17)
#define DEFAULT_SPI_BUS_MOSI (&pin_PA16)
//#define CP_RGB_STATUS_R (&pin_PA06)
//#define CP_RGB_STATUS_G (&pin_PA05)
//#define CP_RGB_STATUS_B (&pin_PA07)
//#define CP_RGB_STATUS_INVERTED_PWM
//#define CP_RGB_STATUS_LED
#define MICROPY_HW_LED_STATUS (&pin_PA06)

View File

@ -0,0 +1,24 @@
USB_VID = 0x239A
USB_PID = 0x80C2
USB_PRODUCT = "PicoPlanet"
USB_MANUFACTURER = "bleeptrack"
CHIP_VARIANT = SAMD21E18A
CHIP_FAMILY = samd21
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_FULL_BUILD = 0
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -0,0 +1,32 @@
#include "shared-bindings/board/__init__.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA02) },
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA03) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) },
{ MP_ROM_QSTR(MP_QSTR_D5),MP_ROM_PTR(&pin_PA05) },
{ MP_ROM_QSTR(MP_QSTR_D6),MP_ROM_PTR(&pin_PA06) },
{ MP_ROM_QSTR(MP_QSTR_D7),MP_ROM_PTR(&pin_PA07) },
{ MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA08) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA08) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
{ MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA09) },
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA09) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
{ MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA16) },
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) },
{ MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA17) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
{ MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA30) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA30) },
{ 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_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);

View File

@ -14,3 +14,20 @@ LONGINT_IMPL = NONE
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_GAMEPAD = 0
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -17,4 +17,20 @@ CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_VECTORIO = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -12,8 +12,25 @@ EXTERNAL_FLASH_DEVICES = "W25Q32FV"
LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_VECTORIO = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANG_APA102 = 1
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CPERIPHERAL = 0
@ -22,3 +23,18 @@ CIRCUITPY_VECTORIO = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -11,6 +11,7 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = W25Q32BV
LONGINT_IMPL = MPZ
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_RTC = 0
@ -18,3 +19,18 @@ CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
SUPEROPT_GC = 0
CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), zh_Latn_pinyin)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), ja)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
endif
ifeq ($(TRANSLATION), de_DE)
RELEASE_NEEDS_CLEAN_BUILD = 1
CFLAGS_INLINE_LIMIT = 35
SUPEROPT_VM = 0
endif

View File

@ -39,6 +39,9 @@ endif
CIRCUITPY_SDCARDIO ?= 0
# Not enough RAM for framebuffers
CIRCUITPY_FRAMEBUFFERIO ?= 0
# SAMD21 needs separate endpoint pairs for MSC BULK IN and BULK OUT, otherwise it's erratic.
USB_MSC_EP_NUM_OUT = 1

View File

@ -171,6 +171,7 @@ SRC_C += \
lib/utils/stdout_helpers.c \
lib/utils/sys_stdio_mphal.c \
peripherals/pins.c \
peripherals/rmt.c \
supervisor/shared/memory.c
ifneq ($(USB),FALSE)

View File

@ -29,4 +29,6 @@
#define MICROPY_HW_BOARD_NAME "Saola 1 w/Wroom"
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO18)
#define AUTORESET_DELAY_MS 500

View File

@ -10,8 +10,6 @@ LONGINT_IMPL = MPZ
# so increase it to 32.
CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_ESP_FLASH_MODE=dio
CIRCUITPY_ESP_FLASH_FREQ=40m
CIRCUITPY_ESP_FLASH_SIZE=4MB

View File

@ -29,4 +29,6 @@
#define MICROPY_HW_BOARD_NAME "Saola 1 w/Wrover"
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO18)
#define AUTORESET_DELAY_MS 500

View File

@ -10,8 +10,6 @@ LONGINT_IMPL = MPZ
# so increase it to 32.
CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_ESP_FLASH_MODE=dio
CIRCUITPY_ESP_FLASH_FREQ=40m
CIRCUITPY_ESP_FLASH_SIZE=4MB

View File

@ -42,5 +42,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) },
{ MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) },
{ MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) },
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);

View File

@ -4,7 +4,6 @@ USB_PRODUCT = "FeatherS2"
USB_MANUFACTURER = "UnexpectedMaker"
USB_DEVICES = "CDC,MSC,HID"
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
@ -12,8 +11,6 @@ LONGINT_IMPL = MPZ
# so increase it to 32.
CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_ESP_FLASH_MODE=qio
CIRCUITPY_ESP_FLASH_FREQ=40m
CIRCUITPY_ESP_FLASH_SIZE=16MB

View File

@ -26,12 +26,18 @@
*/
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "supervisor/shared/rgb_led_status.h"
#include "py/mphal.h"
#include "esp-idf/components/driver/include/driver/gpio.h"
#include "esp-idf/components/soc/include/hal/gpio_hal.h"
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
#endif
STATIC uint32_t never_reset_pins[2];
STATIC uint32_t in_use[2];
@ -50,6 +56,14 @@ void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
void reset_pin_number(gpio_num_t pin_number) {
never_reset_pins[pin_number / 32] &= ~(1 << pin_number % 32);
in_use[pin_number / 32] &= ~(1 << pin_number % 32);
#ifdef MICROPY_HW_NEOPIXEL
if (pin_number == MICROPY_HW_NEOPIXEL->number) {
neopixel_in_use = false;
rgb_led_status_init();
return;
}
#endif
}
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
@ -69,13 +83,32 @@ void reset_all_pins(void) {
}
in_use[0] = 0;
in_use[1] = 0;
#ifdef MICROPY_HW_NEOPIXEL
neopixel_in_use = false;
#endif
}
void claim_pin(const mcu_pin_obj_t* pin) {
in_use[pin->number / 32] |= (1 << pin->number % 32);
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
neopixel_in_use = true;
}
#endif
}
void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) {
claim_pin(pin);
}
bool pin_number_is_free(gpio_num_t pin_number) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin_number == MICROPY_HW_NEOPIXEL->number) {
return !neopixel_in_use;
}
#endif
uint8_t offset = pin_number / 32;
uint8_t mask = 1 << pin_number % 32;
return (never_reset_pins[offset] & mask) == 0 && (in_use[offset] & mask) == 0;

View File

@ -34,6 +34,10 @@
extern bool apa102_mosi_in_use;
extern bool apa102_sck_in_use;
#ifdef MICROPY_HW_NEOPIXEL
extern bool neopixel_in_use;
#endif
void reset_all_pins(void);
// reset_pin_number takes the pin number instead of the pointer so that objects don't
// need to store a full pointer.

View File

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2018 hathach for Adafruit Industries
* Copyright (c) 2020 Lucian Copeland 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
@ -24,10 +24,102 @@
* THE SOFTWARE.
*/
/* Uses code from Espressif RGB LED Strip demo and drivers
* Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "py/mphal.h"
#include "py/runtime.h"
#include "shared-bindings/neopixel_write/__init__.h"
#include "driver/rmt.h"
#include "rmt.h"
#define WS2812_T0H_NS (350)
#define WS2812_T0L_NS (1000)
#define WS2812_T1H_NS (1000)
#define WS2812_T1L_NS (350)
#define WS2812_RESET_US (280)
static uint32_t ws2812_t0h_ticks = 0;
static uint32_t ws2812_t1h_ticks = 0;
static uint32_t ws2812_t0l_ticks = 0;
static uint32_t ws2812_t1l_ticks = 0;
static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size,
size_t wanted_num, size_t *translated_size, size_t *item_num)
{
if (src == NULL || dest == NULL) {
*translated_size = 0;
*item_num = 0;
return;
}
const rmt_item32_t bit0 = {{{ ws2812_t0h_ticks, 1, ws2812_t0l_ticks, 0 }}}; //Logical 0
const rmt_item32_t bit1 = {{{ ws2812_t1h_ticks, 1, ws2812_t1l_ticks, 0 }}}; //Logical 1
size_t size = 0;
size_t num = 0;
uint8_t *psrc = (uint8_t *)src;
rmt_item32_t *pdest = dest;
while (size < src_size && num < wanted_num) {
for (int i = 0; i < 8; i++) {
// MSB first
if (*psrc & (1 << (7 - i))) {
pdest->val = bit1.val;
} else {
pdest->val = bit0.val;
}
num++;
pdest++;
}
size++;
psrc++;
}
*translated_size = size;
*item_num = num;
}
void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) {
(void)digitalinout;
(void)numBytes;
// Reserve channel
uint8_t number = digitalinout->pin->number;
rmt_channel_t channel = esp32s2_peripherals_find_and_reserve_rmt();
// Configure Channel
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(number, channel);
config.clk_div = 2; // set counter clock to 40MHz
rmt_config(&config);
rmt_driver_install(config.channel, 0, 0);
// Convert NS timings to ticks
uint32_t counter_clk_hz = 0;
if (rmt_get_counter_clock(config.channel, &counter_clk_hz) != ESP_OK) {
mp_raise_RuntimeError(translate("Could not retrieve clock"));
}
float ratio = (float)counter_clk_hz / 1e9;
ws2812_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS);
ws2812_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS);
ws2812_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS);
ws2812_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS);
// Initialize automatic timing translator
rmt_translator_init(config.channel, ws2812_rmt_adapter);
// Write and wait to finish
if(rmt_write_sample(config.channel, pixels, (size_t)numBytes, true) != ESP_OK) {
mp_raise_RuntimeError(translate("Input/output error"));
}
rmt_wait_tx_done(config.channel, pdMS_TO_TICKS(100));
// Free channel again
esp32s2_peripherals_free_rmt(config.channel);
}

View File

@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
* Uses code from Micropython, Copyright (c) 2013-2016 Damien P. George
* Copyright (c) 2020 Lucian Copeland 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
@ -33,6 +32,7 @@
#define INDEX_EMPTY 0xFF
STATIC bool not_first_reset = false;
STATIC uint32_t reserved_timer_freq[LEDC_TIMER_MAX];
STATIC uint8_t reserved_channels[LEDC_CHANNEL_MAX];
STATIC bool never_reset_tim[LEDC_TIMER_MAX];
@ -40,17 +40,22 @@ STATIC bool never_reset_chan[LEDC_CHANNEL_MAX];
void pwmout_reset(void) {
for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++ ) {
ledc_stop(LEDC_LOW_SPEED_MODE, i, 0);
if (reserved_channels[i] != INDEX_EMPTY && not_first_reset) {
ledc_stop(LEDC_LOW_SPEED_MODE, i, 0);
}
if (!never_reset_chan[i]) {
reserved_channels[i] = INDEX_EMPTY;
}
}
for (size_t i = 0; i < LEDC_TIMER_MAX; i++ ) {
ledc_timer_rst(LEDC_LOW_SPEED_MODE, i);
if (reserved_timer_freq[i]) {
ledc_timer_rst(LEDC_LOW_SPEED_MODE, i);
}
if (!never_reset_tim[i]) {
reserved_timer_freq[i] = 0;
}
}
not_first_reset = true;
}
pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
@ -158,7 +163,10 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
if (common_hal_pulseio_pwmout_deinited(self)) {
return;
}
ledc_stop(LEDC_LOW_SPEED_MODE, self->chan_handle.channel, 0);
if (reserved_channels[self->chan_handle.channel] != INDEX_EMPTY) {
ledc_stop(LEDC_LOW_SPEED_MODE, self->chan_handle.channel, 0);
}
// Search if any other channel is using the timer
bool taken = false;
for (size_t i =0; i < LEDC_CHANNEL_MAX; i++) {
@ -168,7 +176,9 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
}
// Variable frequency means there's only one channel on the timer
if (!taken || self->variable_frequency) {
ledc_timer_rst(LEDC_LOW_SPEED_MODE, self->tim_handle.timer_num);
if (reserved_timer_freq[self->tim_handle.timer_num] != 0) {
ledc_timer_rst(LEDC_LOW_SPEED_MODE, self->tim_handle.timer_num);
}
reserved_timer_freq[self->tim_handle.timer_num] = 0;
}
reset_pin_number(self->pin_number);

View File

@ -12,26 +12,21 @@ USB_SERIAL_NUMBER_LENGTH = 12
# Longints can be implemented as mpz, as longlong, or not
LONGINT_IMPL = MPZ
CIRCUITPY_FULL_BUILD = 0
# These modules are implemented in ports/<port>/common-hal:
CIRCUITPY_ANALOGIO = 0
CIRCUITPY_NVM = 0
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_AUDIOIO = 0
CIRCUITPY_BITBANGIO = 1
CIRCUITPY_BOARD = 1
CIRCUITPY_DIGITALIO = 1
CIRCUITPY_BUSIO = 1
CIRCUITPY_DISPLAYIO = 1
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_MICROCONTROLLER = 1
CIRCUITPY_NVM = 0
CIRCUITPY_PULSEIO = 1
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_COUNTIO = 0
# Enable USB HID support
CIRCUITPY_USB_HID = 1
CIRCUITPY_USB_MIDI = 0
# These modules are implemented in shared-module/ - they can be included in
# any port once their prerequisites in common-hal are complete.
CIRCUITPY_RANDOM = 0 # Requires OS
CIRCUITPY_USB_MIDI = 0 # Requires USB
CIRCUITPY_ULAB = 0 # No requirements, but takes extra flash
CIRCUITPY_MODULE ?= none

View File

@ -0,0 +1,46 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Lucian Copeland 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 "rmt.h"
#include "py/runtime.h"
bool rmt_reserved_channels[RMT_CHANNEL_MAX];
rmt_channel_t esp32s2_peripherals_find_and_reserve_rmt(void) {
for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
if (!rmt_reserved_channels[i]) {
rmt_reserved_channels[i] = true;
return i;
}
}
mp_raise_RuntimeError(translate("All timers in use"));
return false;
}
void esp32s2_peripherals_free_rmt(rmt_channel_t chan) {
rmt_reserved_channels[chan] = false;
rmt_driver_uninstall(chan);
}

View File

@ -0,0 +1,37 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Lucian Copeland 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_ESP32S2_PERIPHERALS_RMT_H
#define MICROPY_INCLUDED_ESP32S2_PERIPHERALS_RMT_H
#include "py/mphal.h"
#include "driver/rmt.h"
#include <stdint.h>
rmt_channel_t esp32s2_peripherals_find_and_reserve_rmt(void);
void esp32s2_peripherals_free_rmt(rmt_channel_t chan);
#endif

View File

@ -43,6 +43,11 @@
STATIC const esp_partition_t * _partition;
// TODO: Split the caching out of supervisor/shared/external_flash so we can use it.
#define SECTOR_SIZE 4096
STATIC uint8_t _cache[SECTOR_SIZE];
STATIC uint32_t _cache_lba = 0xffffffff;
void supervisor_flash_init(void) {
_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_DATA_FAT,
@ -61,11 +66,6 @@ void port_internal_flash_flush(void) {
}
// TODO: Split the caching out of supervisor/shared/external_flash so we can use it.
#define SECTOR_SIZE 4096
STATIC uint8_t _cache[SECTOR_SIZE];
STATIC uint32_t _cache_lba;
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
esp_partition_read(_partition,
block * FILESYSTEM_BLOCK_SIZE,

View File

@ -73,11 +73,11 @@ INC += -I$(BUILD)
INC += -I$(BUILD)/genhdr
INC += -I./../../lib/cmsis/inc
INC += -I./boards/$(BOARD)
INC += -I./nrfx
INC += -I./nrfx/hal
INC += -I./nrfx/mdk
INC += -I./nrfx/drivers/include
INC += -I./nrfx/drivers/src
INC += -isystem ./nrfx
INC += -isystem ./nrfx/hal
INC += -isystem ./nrfx/mdk
INC += -isystem ./nrfx/drivers/include
INC += -isystem ./nrfx/drivers/src
INC += -I./bluetooth
INC += -I./peripherals
INC += -I../../lib/mp-readline
@ -100,8 +100,6 @@ CFLAGS += $(OPTIMIZATION_FLAGS)
CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT)
# Undo some warnings.
# nrfx uses undefined preprocessor variables quite casually, so we can't do warning checks for these.
CFLAGS += -Wno-undef
# nrfx does casts that increase alignment requirements.
CFLAGS += -Wno-cast-align
@ -240,6 +238,11 @@ endif
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
# nrfx uses undefined preprocessor variables quite casually, so we can't do
# warning checks for these. Happily, we've confined the offenders to the NRFX
# source files themselves.
$(addprefix $(BUILD)/, $(SRC_NRFX:.c=.o)): CFLAGS += -Wno-undef
$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os

View File

@ -30,9 +30,10 @@
#define MICROPY_HW_BOARD_NAME "Makerdiary M60 Keyboard"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define CP_RGB_STATUS_R (&pin_P0_30)
#define CP_RGB_STATUS_G (&pin_P0_29)
#define CP_RGB_STATUS_B (&pin_P0_31)
// RGB LEDs use PWM peripheral, avoid using them to save energy
// #define CP_RGB_STATUS_R (&pin_P0_30)
// #define CP_RGB_STATUS_G (&pin_P0_29)
// #define CP_RGB_STATUS_B (&pin_P0_31)
#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 10)
#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 14)

View File

@ -34,6 +34,22 @@
#include "nrfx_spim.h"
#include "nrf_gpio.h"
#ifndef NRFX_SPIM3_ENABLED
#define NRFX_SPIM3_ENABLED (0)
#endif
#ifndef NRFX_SPIM2_ENABLED
#define NRFX_SPIM2_ENABLED (0)
#endif
#ifndef NRFX_SPIM1_ENABLED
#define NRFX_SPIM1_ENABLED (0)
#endif
#ifndef NRFX_SPIM0_ENABLED
#define NRFX_SPIM0_ENABLED (0)
#endif
// These are in order from highest available frequency to lowest (32MHz first, then 8MHz).
STATIC spim_peripheral_t spim_peripherals[] = {
#if NRFX_CHECK(NRFX_SPIM3_ENABLED)

View File

@ -93,6 +93,7 @@ void reset_pin_number(uint8_t pin_number) {
// Clear claimed bit.
claimed_pins[nrf_pin_port(pin_number)] &= ~(1 << nrf_relative_pin_number(pin_number));
never_reset_pins[nrf_pin_port(pin_number)] &= ~(1 << nrf_relative_pin_number(pin_number));
#ifdef MICROPY_HW_NEOPIXEL
if (pin_number == MICROPY_HW_NEOPIXEL->number) {

View File

@ -65,6 +65,10 @@
#include "common-hal/audiopwmio/PWMAudioOut.h"
#endif
#if defined(MICROPY_QSPI_CS)
extern void qspi_disable(void);
#endif
static void power_warning_handler(void) {
reset_into_safe_mode(BROWNOUT);
}
@ -295,6 +299,10 @@ void port_interrupt_after_ticks(uint32_t ticks) {
}
void port_sleep_until_interrupt(void) {
#if defined(MICROPY_QSPI_CS)
qspi_disable();
#endif
// Clear the FPU interrupt because it can prevent us from sleeping.
if (NVIC_GetPendingIRQ(FPU_IRQn)) {
__set_FPSCR(__get_FPSCR() & ~(0x9f));

View File

@ -38,7 +38,44 @@
#include "supervisor/shared/external_flash/common_commands.h"
#include "supervisor/shared/external_flash/qspi_flash.h"
// When USB is disconnected, disable QSPI in sleep mode to save energy
void qspi_disable(void)
{
// If VBUS is detected, no need to disable QSPI
if (NRF_QSPI->ENABLE && !(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk)) {
// Keep CS high when QSPI is diabled
nrf_gpio_cfg_output(MICROPY_QSPI_CS);
nrf_gpio_pin_write(MICROPY_QSPI_CS, 1);
// Workaround to disable QSPI according to nRF52840 Revision 1 Errata V1.4 - 3.8
NRF_QSPI->TASKS_DEACTIVATE = 1;
*(volatile uint32_t *)0x40029054 = 1;
NRF_QSPI->ENABLE = 0;
}
}
void qspi_enable(void)
{
if (NRF_QSPI->ENABLE) {
return;
}
nrf_qspi_enable(NRF_QSPI);
nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE);
uint32_t remaining_attempts = 100;
do {
if (nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)) {
break;
}
NRFX_DELAY_US(10);
} while (--remaining_attempts);
}
bool spi_flash_command(uint8_t command) {
qspi_enable();
nrf_qspi_cinstr_conf_t cinstr_cfg = {
.opcode = command,
.length = 1,
@ -51,6 +88,7 @@ bool spi_flash_command(uint8_t command) {
}
bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length) {
qspi_enable();
nrf_qspi_cinstr_conf_t cinstr_cfg = {
.opcode = command,
.length = length + 1,
@ -64,6 +102,7 @@ bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length)
}
bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
qspi_enable();
nrf_qspi_cinstr_conf_t cinstr_cfg = {
.opcode = command,
.length = length + 1,
@ -76,6 +115,7 @@ bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
}
bool spi_flash_sector_command(uint8_t command, uint32_t address) {
qspi_enable();
if (command != CMD_SECTOR_ERASE) {
return false;
}
@ -83,6 +123,7 @@ bool spi_flash_sector_command(uint8_t command, uint32_t address) {
}
bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
qspi_enable();
// TODO: In theory, this also needs to handle unaligned data and
// non-multiple-of-4 length. (in practice, I don't think the fat layer
// generates such writes)
@ -90,6 +131,7 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
}
bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
qspi_enable();
int misaligned = ((intptr_t)data) & 3;
// If the data is misaligned, we need to read 4 bytes
// into an aligned buffer, and then copy 1, 2, or 3 bytes from the aligned
@ -159,7 +201,7 @@ void spi_flash_init(void) {
.irq_priority = 7,
};
#if EXTERNAL_FLASH_QSPI_DUAL
#if defined(EXTERNAL_FLASH_QSPI_DUAL)
qspi_cfg.pins.io1_pin = MICROPY_QSPI_DATA1;
qspi_cfg.prot_if.readoc = NRF_QSPI_READOC_READ2O;
qspi_cfg.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;

View File

@ -1,5 +1,17 @@
#include "py/objtuple.h"
#include "shared-bindings/board/__init__.h"
STATIC const mp_rom_obj_tuple_t sdio_data_tuple = {
{&mp_type_tuple},
4,
{
MP_ROM_PTR(&pin_PC08),
MP_ROM_PTR(&pin_PC09),
MP_ROM_PTR(&pin_PC10),
MP_ROM_PTR(&pin_PC11),
}
};
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA04) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
@ -31,5 +43,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ 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_ROM_QSTR(MP_QSTR_SDIO_CLOCK), MP_ROM_PTR(&pin_PC12) },
{ MP_ROM_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_PD02) },
{ MP_ROM_QSTR(MP_QSTR_SDIO_DATA), MP_ROM_PTR(&sdio_data_tuple) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View File

@ -14,6 +14,8 @@ MCU_SERIES = F4
MCU_VARIANT = STM32F401xE
MCU_PACKAGE = LQFP64
OPTIMIZATION_FLAGS = -Os
LD_COMMON = boards/common_default.ld
LD_FILE = boards/STM32F401xe_boot.ld
# LD_FILE = boards/STM32F401xe_fs.ld # use for internal flash

View File

@ -112,7 +112,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
if (i2c_taken) {
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
} else {
mp_raise_ValueError(translate("Invalid I2C pin selection"));
mp_raise_ValueError_varg(translate("Invalid %q pin selection"), MP_QSTR_I2C);
}
}

View File

@ -169,7 +169,7 @@ STATIC int check_pins(busio_spi_obj_t *self,
if (spi_taken) {
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
} else {
mp_raise_ValueError(translate("Invalid SPI pin selection"));
mp_raise_ValueError_varg(translate("Invalid %q pin selection"), MP_QSTR_SPI);
}
}

View File

@ -58,7 +58,7 @@ STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eva
if (uart_taken) {
mp_raise_ValueError(translate("Hardware in use, try alternative pins"));
} else {
mp_raise_ValueError(translate("Invalid UART pin selection"));
mp_raise_ValueError_varg(translate("Invalid %q pin selection"), MP_QSTR_UART);
}
}
}

View File

@ -0,0 +1,327 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdbool.h>
#include "shared-bindings/sdioio/SDCard.h"
#include "py/mperrno.h"
#include "py/runtime.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/util.h"
#include "boards/board.h"
#include "supervisor/shared/translate.h"
#include "common-hal/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/Pin.h"
STATIC bool reserved_sdio[MP_ARRAY_SIZE(mcu_sdio_banks)];
STATIC bool never_reset_sdio[MP_ARRAY_SIZE(mcu_sdio_banks)];
STATIC const mcu_periph_obj_t *find_pin_function(const mcu_periph_obj_t *table, size_t sz, const mcu_pin_obj_t *pin, int periph_index) {
for(size_t i = 0; i<sz; i++, table++) {
if(periph_index == table->periph_index && pin == table->pin ) {
return table;
}
}
return NULL;
}
//match pins to SDIO objects
STATIC int check_pins(sdioio_sdcard_obj_t *self,
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * command,
uint8_t num_data, mcu_pin_obj_t ** data) {
bool sdio_taken = false;
const uint8_t sdio_clock_len = MP_ARRAY_SIZE(mcu_sdio_clock_list);
const uint8_t sdio_command_len = MP_ARRAY_SIZE(mcu_sdio_command_list);
const uint8_t sdio_data0_len = MP_ARRAY_SIZE(mcu_sdio_data0_list);
const uint8_t sdio_data1_len = MP_ARRAY_SIZE(mcu_sdio_data1_list);
const uint8_t sdio_data2_len = MP_ARRAY_SIZE(mcu_sdio_data2_list);
const uint8_t sdio_data3_len = MP_ARRAY_SIZE(mcu_sdio_data3_list);
// Loop over each possibility for clock. Check whether all other pins can
// be used on the same peripheral
for (uint i = 0; i < sdio_clock_len; i++) {
const mcu_periph_obj_t *mcu_sdio_clock = &mcu_sdio_clock_list[i];
if (mcu_sdio_clock->pin != clock) {
continue;
}
int periph_index = mcu_sdio_clock->periph_index;
const mcu_periph_obj_t *mcu_sdio_command = NULL;
if (!(mcu_sdio_command = find_pin_function(mcu_sdio_command_list, sdio_command_len, command, periph_index))) {
continue;
}
const mcu_periph_obj_t *mcu_sdio_data0 = NULL;
if(!(mcu_sdio_data0 = find_pin_function(mcu_sdio_data0_list, sdio_data0_len, data[0], periph_index))) {
continue;
}
const mcu_periph_obj_t *mcu_sdio_data1 = NULL;
if(num_data > 1 && !(mcu_sdio_data1 = find_pin_function(mcu_sdio_data1_list, sdio_data1_len, data[1], periph_index))) {
continue;
}
const mcu_periph_obj_t *mcu_sdio_data2 = NULL;
if(num_data > 2 && !(mcu_sdio_data2 = find_pin_function(mcu_sdio_data2_list, sdio_data2_len, data[2], periph_index))) {
continue;
}
const mcu_periph_obj_t *mcu_sdio_data3 = NULL;
if(num_data > 3 && !(mcu_sdio_data3 = find_pin_function(mcu_sdio_data3_list, sdio_data3_len, data[3], periph_index))) {
continue;
}
if (reserved_sdio[periph_index-1]) {
sdio_taken = true;
continue;
}
self->clock = mcu_sdio_clock;
self->command = mcu_sdio_command;
self->data[0] = mcu_sdio_data0;
self->data[1] = mcu_sdio_data1;
self->data[2] = mcu_sdio_data2;
self->data[3] = mcu_sdio_data3;
return periph_index;
}
if (sdio_taken) {
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
} else {
mp_raise_ValueError_varg(translate("Invalid %q pin selection"), MP_QSTR_SDIO);
}
}
void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self,
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * command,
uint8_t num_data, mcu_pin_obj_t ** data, uint32_t frequency) {
int periph_index = check_pins(self, clock, command, num_data, data);
SDIO_TypeDef * SDIOx = mcu_sdio_banks[periph_index - 1];
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Configure data pins */
for (int i=0; i<num_data; i++) {
GPIO_InitStruct.Pin = pin_mask(data[i]->number);
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Alternate = self->data[i]->altfn_index;
HAL_GPIO_Init(pin_port(data[i]->port), &GPIO_InitStruct);
}
/* Configure command pin */
GPIO_InitStruct.Alternate = self->command->altfn_index;
GPIO_InitStruct.Pin = pin_mask(command->number);
HAL_GPIO_Init(pin_port(command->port), &GPIO_InitStruct);
/* Configure clock */
GPIO_InitStruct.Alternate = self->clock->altfn_index;
GPIO_InitStruct.Pin = pin_mask(clock->number);
HAL_GPIO_Init(pin_port(clock->port), &GPIO_InitStruct);
__HAL_RCC_SDIO_CLK_ENABLE();
self->handle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;
self->handle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
self->handle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
self->handle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
self->handle.Init.BusWide = SDIO_BUS_WIDE_1B;
self->handle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
self->handle.Instance = SDIOx;
HAL_StatusTypeDef r = HAL_SD_Init(&self->handle);
if (r != HAL_OK) {
mp_raise_ValueError_varg(translate("SDIO Init Error %d"), (int)r);
}
HAL_SD_CardInfoTypeDef info;
r = HAL_SD_GetCardInfo(&self->handle, &info);
if (r != HAL_OK) {
mp_raise_ValueError_varg(translate("SDIO GetCardInfo Error %d"), (int)r);
}
self->num_data = 1;
if (num_data == 4) {
if ((r = HAL_SD_ConfigWideBusOperation(&self->handle, SDIO_BUS_WIDE_4B)) == HAL_SD_ERROR_NONE) {
self->handle.Init.BusWide = SDIO_BUS_WIDE_4B;
self->num_data = 4;
} else {
}
}
self->capacity = info.BlockNbr * (info.BlockSize / 512);
self->frequency = 25000000;
reserved_sdio[periph_index - 1] = true;
common_hal_mcu_pin_claim(clock);
common_hal_mcu_pin_claim(command);
for (int i=0; i<num_data; i++) {
common_hal_mcu_pin_claim(data[i]);
}
return;
}
uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t *self) {
return self->capacity;
}
uint32_t common_hal_sdioio_sdcard_get_frequency(sdioio_sdcard_obj_t *self) {
return self->frequency;
}
uint8_t common_hal_sdioio_sdcard_get_width(sdioio_sdcard_obj_t *self) {
return self->num_data;
}
STATIC void check_whole_block(mp_buffer_info_t *bufinfo) {
if (bufinfo->len % 512) {
mp_raise_ValueError(translate("Buffer must be a multiple of 512 bytes"));
}
}
STATIC void wait_write_complete(sdioio_sdcard_obj_t *self) {
if (self->state_programming) {
HAL_SD_CardStateTypedef st = HAL_SD_CARD_PROGRAMMING;
// This waits up to 60s for programming to complete. This seems like
// an extremely long time, but this is the timeout that micropython's
// implementation uses
for (int i=0; i < 60000 && st == HAL_SD_CARD_PROGRAMMING; i++) {
st = HAL_SD_GetCardState(&self->handle);
HAL_Delay(1);
};
self->state_programming = false;
}
}
STATIC void check_for_deinit(sdioio_sdcard_obj_t *self) {
if (common_hal_sdioio_sdcard_deinited(self)) {
raise_deinited_error();
}
}
int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
check_for_deinit(self);
check_whole_block(bufinfo);
wait_write_complete(self);
self->state_programming = true;
common_hal_mcu_disable_interrupts();
HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000);
common_hal_mcu_enable_interrupts();
if (r != HAL_OK) {
return -EIO;
}
return 0;
}
int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) {
check_for_deinit(self);
check_whole_block(bufinfo);
wait_write_complete(self);
common_hal_mcu_disable_interrupts();
HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000);
common_hal_mcu_enable_interrupts();
if (r != HAL_OK) {
return -EIO;
}
return 0;
}
bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) {
check_for_deinit(self);
return true;
}
bool common_hal_sdioio_sdcard_deinited(sdioio_sdcard_obj_t *self) {
return self->command == NULL;
}
STATIC void never_reset_mcu_periph(const mcu_periph_obj_t *periph) {
if (periph) {
never_reset_pin_number(periph->pin->port,periph->pin->number);
}
}
STATIC void reset_mcu_periph(const mcu_periph_obj_t *periph) {
if (periph) {
reset_pin_number(periph->pin->port,periph->pin->number);
}
}
void common_hal_sdioio_sdcard_deinit(sdioio_sdcard_obj_t *self) {
if (common_hal_sdioio_sdcard_deinited(self)) {
return;
}
reserved_sdio[self->command->periph_index - 1] = false;
never_reset_sdio[self->command->periph_index - 1] = false;
reset_mcu_periph(self->command);
self->command = NULL;
reset_mcu_periph(self->clock);
self->command = NULL;
for (size_t i=0; i<MP_ARRAY_SIZE(self->data); i++) {
reset_mcu_periph(self->data[i]);
self->data[i] = NULL;
}
}
void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self) {
if (common_hal_sdioio_sdcard_deinited(self)) {
return;
}
if (never_reset_sdio[self->command->periph_index] - 1) {
return;
}
never_reset_sdio[self->command->periph_index - 1] = true;
never_reset_mcu_periph(self->command);
never_reset_mcu_periph(self->clock);
for (size_t i=0; i<MP_ARRAY_SIZE(self->data); i++) {
never_reset_mcu_periph(self->data[i]);
}
}
void sdioio_reset() {
for (size_t i=0; i<MP_ARRAY_SIZE(reserved_sdio); i++) {
if (!never_reset_sdio[i]) {
reserved_sdio[i] = false;
}
}
}

View File

@ -0,0 +1,50 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_SDIO_H
#define MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_SDIO_H
#include "common-hal/microcontroller/Pin.h"
#include "peripherals/periph.h"
#include "py/obj.h"
typedef struct {
mp_obj_base_t base;
SD_HandleTypeDef handle;
uint8_t num_data:3, state_programming:1;
bool has_lock;
const mcu_periph_obj_t *command;
const mcu_periph_obj_t *clock;
const mcu_periph_obj_t *data[4];
uint32_t frequency;
uint32_t capacity;
} sdioio_sdcard_obj_t;
void sdioio_reset(void);
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_SDIO_H

View File

View File

View File

@ -61,7 +61,7 @@
#define HAL_RTC_MODULE_ENABLED
// #define HAL_SAI_MODULE_ENABLED
// #define HAL_SDRAM_MODULE_ENABLED
// #define HAL_SD_MODULE_ENABLED
#define HAL_SD_MODULE_ENABLED
// #define HAL_SMARTCARD_MODULE_ENABLED
// #define HAL_SMBUS_MODULE_ENABLED
// #define HAL_SPDIFRX_MODULE_ENABLED

View File

@ -6,6 +6,7 @@ USB_SERIAL_NUMBER_LENGTH ?= 24
ifeq ($(MCU_VARIANT),STM32F405xx)
CIRCUITPY_FRAMEBUFFERIO ?= 1
CIRCUITPY_RGBMATRIX ?= 1
CIRCUITPY_SDIOIO ?= 1
endif
ifeq ($(MCU_SERIES),F4)

View File

@ -194,3 +194,25 @@ const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN] = {
TIM(8, 3, 2, &pin_PI06),
TIM(8, 3, 3, &pin_PI07),
};
//SDIO
SDIO_TypeDef * mcu_sdio_banks[1] = {SDIO};
const mcu_periph_obj_t mcu_sdio_clock_list[1] = {
PERIPH(1, 12, &pin_PC12),
};
const mcu_periph_obj_t mcu_sdio_command_list[1] = {
PERIPH(1, 12, &pin_PD02),
};
const mcu_periph_obj_t mcu_sdio_data0_list[1] = {
PERIPH(1, 12, &pin_PC08),
};
const mcu_periph_obj_t mcu_sdio_data1_list[1] = {
PERIPH(1, 12, &pin_PC09),
};
const mcu_periph_obj_t mcu_sdio_data2_list[1] = {
PERIPH(1, 12, &pin_PC10),
};
const mcu_periph_obj_t mcu_sdio_data3_list[1] = {
PERIPH(1, 12, &pin_PC11),
};

View File

@ -61,4 +61,15 @@ extern const mcu_periph_obj_t mcu_uart_rx_list[UART_RX_ARRAY_LEN];
TIM_TypeDef * mcu_tim_banks[TIM_BANK_ARRAY_LEN];
const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN];
//SDIO
extern SDIO_TypeDef * mcu_sdio_banks[1];
extern const mcu_periph_obj_t mcu_sdio_clock_list[1];
extern const mcu_periph_obj_t mcu_sdio_command_list[1];
extern const mcu_periph_obj_t mcu_sdio_data0_list[1];
extern const mcu_periph_obj_t mcu_sdio_data1_list[1];
extern const mcu_periph_obj_t mcu_sdio_data2_list[1];
extern const mcu_periph_obj_t mcu_sdio_data3_list[1];
#endif // MICROPY_INCLUDED_STM32_PERIPHERALS_STM32F405XX_PERIPH_H

View File

@ -43,6 +43,9 @@
#include "common-hal/pulseio/PulseIn.h"
#include "timers.h"
#endif
#if CIRCUITPY_SDIOIO
#include "common-hal/sdioio/SDCard.h"
#endif
#include "clocks.h"
#include "gpio.h"
@ -224,6 +227,9 @@ void reset_port(void) {
spi_reset();
uart_reset();
#endif
#if CIRCUITPY_SDIOIO
sdioio_reset();
#endif
#if CIRCUITPY_PULSEIO
timers_reset();
pwmout_reset();

View File

@ -222,6 +222,9 @@ endif
ifeq ($(CIRCUITPY_SDIOIO),1)
SRC_PATTERNS += sdioio/%
endif
ifeq ($(CIRCUITPY_SHARPDISPLAY),1)
SRC_PATTERNS += sharpdisplay/%
endif
ifeq ($(CIRCUITPY_STAGE),1)
SRC_PATTERNS += _stage/%
endif
@ -409,6 +412,8 @@ SRC_SHARED_MODULE_ALL = \
random/__init__.c \
rgbmatrix/RGBMatrix.c \
rgbmatrix/__init__.c \
sharpdisplay/SharpMemoryFramebuffer.c \
sharpdisplay/__init__.c \
socket/__init__.c \
storage/__init__.c \
struct/__init__.c \

View File

@ -499,13 +499,6 @@ extern const struct _mp_obj_module_t pixelbuf_module;
#define PIXELBUF_MODULE
#endif
#if CIRCUITPY_RGBMATRIX
extern const struct _mp_obj_module_t rgbmatrix_module;
#define RGBMATRIX_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rgbmatrix),(mp_obj_t)&rgbmatrix_module },
#else
#define RGBMATRIX_MODULE
#endif
#if CIRCUITPY_PULSEIO
extern const struct _mp_obj_module_t pulseio_module;
#define PULSEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module },
@ -520,6 +513,13 @@ extern const struct _mp_obj_module_t ps2io_module;
#define PS2IO_MODULE
#endif
#if CIRCUITPY_RGBMATRIX
extern const struct _mp_obj_module_t rgbmatrix_module;
#define RGBMATRIX_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rgbmatrix),(mp_obj_t)&rgbmatrix_module },
#else
#define RGBMATRIX_MODULE
#endif
#if CIRCUITPY_RANDOM
extern const struct _mp_obj_module_t random_module;
#define RANDOM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module },
@ -562,6 +562,13 @@ extern const struct _mp_obj_module_t sdioio_module;
#define SDIOIO_MODULE
#endif
#if CIRCUITPY_SHARPDISPLAY
extern const struct _mp_obj_module_t sharpdisplay_module;
#define SHARPDISPLAY_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_sharpdisplay),(mp_obj_t)&sharpdisplay_module },
#else
#define SHARPDISPLAY_MODULE
#endif
#if CIRCUITPY_STAGE
extern const struct _mp_obj_module_t stage_module;
#define STAGE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module },
@ -737,6 +744,7 @@ extern const struct _mp_obj_module_t watchdog_module;
SAMD_MODULE \
SDCARDIO_MODULE \
SDIOIO_MODULE \
SHARPDISPLAY_MODULE \
STAGE_MODULE \
STORAGE_MODULE \
STRUCT_MODULE \

View File

@ -95,7 +95,11 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO)
CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
ifeq ($(CIRCUITPY_DISPLAYIO),1)
CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD)
else
CIRCUITPY_FRAMEBUFFERIO ?= 0
endif
CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO)
CIRCUITPY_VECTORIO ?= $(CIRCUITPY_DISPLAYIO)
@ -144,7 +148,6 @@ CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS)
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
# Only for SAMD boards for the moment
CIRCUITPY_RGBMATRIX ?= 0
CFLAGS += -DCIRCUITPY_RGBMATRIX=$(CIRCUITPY_RGBMATRIX)
@ -176,6 +179,9 @@ CFLAGS += -DCIRCUITPY_SDCARDIO=$(CIRCUITPY_SDCARDIO)
CIRCUITPY_SDIOIO ?= 0
CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO)
CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO)
CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY)
# Currently always off.
CIRCUITPY_STAGE ?= 0
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)

View File

@ -137,6 +137,7 @@ STATIC const byte *find_qstr(qstr q) {
while (q < pool->total_prev_len) {
pool = pool->prev;
}
assert(q - pool->total_prev_len < pool->len);
return pool->qstrs[q - pool->total_prev_len];
}

View File

@ -352,7 +352,8 @@ STATIC void rgbmatrix_rgbmatrix_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *
// These version exists so that the prototype matches the protocol,
// avoiding a type cast that can hide errors
STATIC void rgbmatrix_rgbmatrix_swapbuffers(mp_obj_t self_in) {
STATIC void rgbmatrix_rgbmatrix_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) {
(void)dirty_row_bitmap;
common_hal_rgbmatrix_rgbmatrix_refresh(self_in);
}

View File

@ -0,0 +1,92 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/objarray.h"
#include "py/runtime.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
STATIC mp_obj_t sharpdisplay_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_spi_bus, ARG_chip_select, ARG_width, ARG_height, ARG_baudrate, NUM_ARGS };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_spi_bus, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} },
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} },
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 2000000} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS );
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj);
busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi_bus].u_obj);
sharpdisplay_framebuffer_obj_t* self = &allocate_display_bus_or_raise()->sharpdisplay;
self->base.type = &sharpdisplay_framebuffer_type;
common_hal_sharpdisplay_framebuffer_construct(self, spi, chip_select, args[ARG_baudrate].u_int, args[ARG_width].u_int, args[ARG_height].u_int);
return MP_OBJ_FROM_PTR(self);
}
STATIC mp_int_t sharpdisplay_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
sharpdisplay_framebuffer_obj_t *self = (sharpdisplay_framebuffer_obj_t*)self_in;
// a readonly framebuffer would be unusual but not impossible
if ((flags & MP_BUFFER_WRITE) && !(self->bufinfo.typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW)) {
return 1;
}
*bufinfo = self->bufinfo;
return 0;
}
STATIC mp_obj_t sharpdisplay_framebuffer_deinit(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = (sharpdisplay_framebuffer_obj_t*)self_in;
common_hal_sharpdisplay_framebuffer_deinit(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(sharpdisplay_framebuffer_deinit_obj, sharpdisplay_framebuffer_deinit);
STATIC const mp_rom_map_elem_t sharpdisplay_framebuffer_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sharpdisplay_framebuffer_deinit_obj) },
};
STATIC MP_DEFINE_CONST_DICT(sharpdisplay_framebuffer_locals_dict, sharpdisplay_framebuffer_locals_dict_table);
const mp_obj_type_t sharpdisplay_framebuffer_type = {
{ &mp_type_type },
.name = MP_QSTR_SharpMemoryFramebuffer,
.buffer_p = { .get_buffer = sharpdisplay_framebuffer_get_buffer, },
.make_new = sharpdisplay_framebuffer_make_new,
.protocol = &sharpdisplay_framebuffer_proto,
.locals_dict = (mp_obj_dict_t*)&sharpdisplay_framebuffer_locals_dict,
};

View File

@ -0,0 +1,34 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
// #include "shared-module/framebufferio/FramebufferDisplay.h"
#include "py/objtype.h"
extern const mp_obj_type_t sharpdisplay_framebuffer_type;

View File

@ -0,0 +1,47 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdint.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h"
//| """Support for Sharp Memory Display framebuffers"""
//|
STATIC const mp_rom_map_elem_t sharpdisplay_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sharpdisplay) },
{ MP_ROM_QSTR(MP_QSTR_SharpMemoryFramebuffer), MP_ROM_PTR(&sharpdisplay_framebuffer_type) },
};
STATIC MP_DEFINE_CONST_DICT(sharpdisplay_module_globals, sharpdisplay_module_globals_table);
const mp_obj_module_t sharpdisplay_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&sharpdisplay_module_globals,
};

View File

View File

@ -6,11 +6,16 @@ Support Matrix
The following table lists the available built-in modules for each CircuitPython
capable board.
.. csv-table::
.. list-table::
:header-rows: 1
:widths: 7, 50
"Board", "Modules Available"
{% for key, value in support_matrix|dictsort -%}
"{{ key }}", "{{ '`' ~ value|join("`, `") ~ '`' }}"
{% endfor -%}
* - Board
- Modules Available
{% for key, value in support_matrix|dictsort %}
{{ '.. _' ~ key|replace(" ", "-") ~ ':' }}
* - {{ key }}
- {{ '`' ~ value|join("`, `") ~ '`' }}
{% endfor %}

View File

@ -19,14 +19,19 @@
#include "supervisor/spi_flash_api.h"
#include "py/mpconfig.h"
#if CIRCUITPY_SHARPDISPLAY
#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h"
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
#endif
primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
#if CIRCUITPY_RGBMATRIX
STATIC bool any_display_uses_this_rgbmatrix(rgbmatrix_rgbmatrix_obj_t* pm) {
#if CIRCUITPY_RGBMATRIX || CIRCUITPY_SHARPDISPLAY
STATIC bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) {
if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) {
framebufferio_framebufferdisplay_obj_t* display = &displays[i].framebuffer_display;
if (display->framebuffer == pm) {
if (display->framebuffer == obj) {
return true;
}
}
@ -102,9 +107,13 @@ void common_hal_displayio_release_displays(void) {
common_hal_displayio_i2cdisplay_deinit(&displays[i].i2cdisplay_bus);
} else if (bus_type == &displayio_parallelbus_type) {
common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus);
#if CIRCUITPY_FRAMEBUFFERIO
#if CIRCUITPY_RGBMATRIX
} else if (bus_type == &rgbmatrix_RGBMatrix_type) {
common_hal_rgbmatrix_rgbmatrix_deinit(&displays[i].rgbmatrix);
#endif
#if CIRCUITPY_SHARPDISPLAY
} else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
common_hal_sharpdisplay_framebuffer_deinit(&displays[i].sharpdisplay);
#endif
}
displays[i].fourwire_bus.base.type = &mp_type_NoneType;
@ -170,9 +179,18 @@ void reset_displays(void) {
#if CIRCUITPY_RGBMATRIX
} else if (displays[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) {
rgbmatrix_rgbmatrix_obj_t * pm = &displays[i].rgbmatrix;
if(!any_display_uses_this_rgbmatrix(pm)) {
if(!any_display_uses_this_framebuffer(&pm->base)) {
common_hal_rgbmatrix_rgbmatrix_deinit(pm);
}
#endif
#if CIRCUITPY_SHARPDISPLAY
} else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
sharpdisplay_framebuffer_obj_t * sharp = &displays[i].sharpdisplay;
if(any_display_uses_this_framebuffer(&sharp->base)) {
common_hal_sharpdisplay_framebuffer_reset(sharp);
} else {
common_hal_sharpdisplay_framebuffer_deinit(sharp);
}
#endif
} else {
// Not an active display bus.
@ -203,6 +221,11 @@ void displayio_gc_collect(void) {
rgbmatrix_rgbmatrix_collect_ptrs(&displays[i].rgbmatrix);
}
#endif
#if CIRCUITPY_SHARPDISPLAY
if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
common_hal_sharpdisplay_framebuffer_collect_ptrs(&displays[i].sharpdisplay);
}
#endif
if (displays[i].display.base.type == NULL) {
continue;

View File

@ -36,18 +36,28 @@
#include "shared-bindings/displayio/Group.h"
#include "shared-bindings/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/ParallelBus.h"
#if CIRCUITPY_RGBMATRIX
#include "shared-bindings/rgbmatrix/RGBMatrix.h"
#endif
#if CIRCUITPY_SHARPDISPLAY
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
#endif
typedef struct {
union {
mp_obj_base_t bus_base;
displayio_fourwire_obj_t fourwire_bus;
displayio_i2cdisplay_obj_t i2cdisplay_bus;
displayio_parallelbus_obj_t parallel_bus;
#if CIRCUITPY_RGBMATRIX
rgbmatrix_rgbmatrix_obj_t rgbmatrix;
#endif
#if CIRCUITPY_SHARPDISPLAY
sharpdisplay_framebuffer_obj_t sharpdisplay;
#endif
};
union {
mp_obj_base_t display_base;
displayio_display_obj_t display;
displayio_epaperdisplay_obj_t epaper_display;
#if CIRCUITPY_FRAMEBUFFERIO

View File

@ -40,6 +40,11 @@
#include <stdint.h>
#include <string.h>
#define fb_getter_default(method, default_value) \
(self->framebuffer_protocol->method \
? self->framebuffer_protocol->method(self->framebuffer) \
: (default_value))
void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self,
mp_obj_t framebuffer,
uint16_t rotation,
@ -51,7 +56,7 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu
uint16_t ram_width = 0x100;
uint16_t ram_height = 0x100;
uint16_t depth = fb_getter_default(get_color_depth, 16);
displayio_display_core_construct(
&self->core,
NULL,
@ -62,16 +67,29 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu
0,
0,
rotation,
self->framebuffer_protocol->get_color_depth(self->framebuffer),
false,
false,
self->framebuffer_protocol->get_bytes_per_cell(self->framebuffer),
false,
false);
depth,
fb_getter_default(get_grayscale, (depth < 8)),
fb_getter_default(get_pixels_in_byte_share_row, false),
fb_getter_default(get_bytes_per_cell, 2),
fb_getter_default(get_reverse_pixels_in_byte, false),
fb_getter_default(get_reverse_pixels_in_word, false)
);
self->first_pixel_offset = fb_getter_default(get_first_pixel_offset, 0);
self->row_stride = fb_getter_default(get_row_stride, 0);
if (self->row_stride == 0) {
self->row_stride = self->core.width * self->core.colorspace.depth/8;
}
self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo);
size_t framebuffer_size = self->first_pixel_offset + self->row_stride * self->core.height;
if (self->bufinfo.len < framebuffer_size) {
mp_raise_IndexError_varg(translate("Framebuffer requires %d bytes"), framebuffer_size);
}
self->first_manual_refresh = !auto_refresh;
self->native_frames_per_second = self->framebuffer_protocol->get_native_frames_per_second(self->framebuffer);
self->native_frames_per_second = fb_getter_default(get_native_frames_per_second, 60);
self->native_ms_per_frame = 1000 / self->native_frames_per_second;
supervisor_start_terminal(self->core.width, self->core.height);
@ -109,7 +127,7 @@ bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebuffer
}
mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self) {
if (self->framebuffer_protocol->set_brightness) {
if (self->framebuffer_protocol->get_brightness) {
return self->framebuffer_protocol->get_brightness(self->framebuffer);
}
return -1;
@ -138,7 +156,8 @@ STATIC const displayio_area_t* _get_refresh_areas(framebufferio_framebufferdispl
return NULL;
}
STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const displayio_area_t* area) {
#define MARK_ROW_DIRTY(r) (dirty_row_bitmask[r/8] |= (1 << (r & 7)))
STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const displayio_area_t* area, uint8_t *dirty_row_bitmask) {
uint16_t buffer_size = 128; // In uint32_ts
displayio_area_t clipped;
@ -147,6 +166,14 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
return true;
}
uint16_t subrectangles = 1;
// If pixels are packed by row then rows are on byte boundaries
if (self->core.colorspace.depth < 8 && self->core.colorspace.pixels_in_byte_share_row) {
int div = 8 / self->core.colorspace.depth;
clipped.x1 = (clipped.x1 / div) * div;
clipped.x2 = ((clipped.x2 + div - 1) / div) * div;
}
uint16_t rows_per_buffer = displayio_area_height(&clipped);
uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth;
uint16_t pixels_per_buffer = displayio_area_size(&clipped);
@ -187,6 +214,7 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
.x2 = clipped.x2,
.y2 = clipped.y1 + rows_per_buffer * (j + 1)
};
if (remaining_rows < rows_per_buffer) {
subrectangle.y2 = subrectangle.y1 + remaining_rows;
}
@ -197,12 +225,18 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer);
// COULDDO: this arithmetic only supports multiple-of-8 bpp
uint8_t *dest = self->bufinfo.buf + (subrectangle.y1 * self->core.width + subrectangle.x1) * (self->core.colorspace.depth / 8);
uint8_t *buf = (uint8_t *)self->bufinfo.buf, *endbuf = buf + self->bufinfo.len;
(void)endbuf; // Hint to compiler that endbuf is "used" even if NDEBUG
buf += self->first_pixel_offset;
size_t rowstride = self->row_stride;
uint8_t *dest = buf + subrectangle.y1 * rowstride + subrectangle.x1 * self->core.colorspace.depth / 8;
uint8_t *src = (uint8_t*)buffer;
size_t rowsize = (subrectangle.x2 - subrectangle.x1) * (self->core.colorspace.depth / 8);
size_t rowstride = self->core.width * (self->core.colorspace.depth/8);
size_t rowsize = (subrectangle.x2 - subrectangle.x1) * self->core.colorspace.depth / 8;
for (uint16_t i = subrectangle.y1; i < subrectangle.y2; i++) {
assert(dest >= buf && dest < endbuf && dest+rowsize <= endbuf);
MARK_ROW_DIRTY(i);
memcpy(dest, src, rowsize);
dest += rowstride;
src += rowsize;
@ -216,15 +250,23 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
}
STATIC void _refresh_display(framebufferio_framebufferdisplay_obj_t* self) {
displayio_display_core_start_refresh(&self->core);
self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo);
if(!self->bufinfo.buf) {
return;
}
displayio_display_core_start_refresh(&self->core);
const displayio_area_t* current_area = _get_refresh_areas(self);
while (current_area != NULL) {
_refresh_area(self, current_area);
current_area = current_area->next;
if (current_area) {
uint8_t dirty_row_bitmask[(self->core.height + 7) / 8];
memset(dirty_row_bitmask, 0, sizeof(dirty_row_bitmask));
self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo);
while (current_area != NULL) {
_refresh_area(self, current_area, dirty_row_bitmask);
current_area = current_area->next;
}
self->framebuffer_protocol->swapbuffers(self->framebuffer, dirty_row_bitmask);
}
displayio_display_core_finish_refresh(&self->core);
self->framebuffer_protocol->swapbuffers(self->framebuffer);
}
void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t* self, int rotation){
@ -307,11 +349,7 @@ void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) {
common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, false);
release_display_core(&self->core);
self->framebuffer_protocol->deinit(self->framebuffer);
}
void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) {
common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, true);
common_hal_framebufferio_framebufferdisplay_show(self, NULL);
self->base.type = &mp_type_NoneType;
}
void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisplay_obj_t* self) {
@ -320,6 +358,12 @@ void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisp
}
void framebufferio_framebufferdisplay_reset(framebufferio_framebufferdisplay_obj_t* self) {
common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, true);
common_hal_framebufferio_framebufferdisplay_show(self, NULL);
mp_obj_type_t *fb_type = mp_obj_get_type(self->framebuffer);
if(fb_type != NULL && fb_type != &mp_type_NoneType) {
common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, true);
common_hal_framebufferio_framebufferdisplay_show(self, NULL);
self->core.full_refresh = true;
} else {
release_framebufferdisplay(self);
}
}

View File

@ -48,44 +48,65 @@ typedef struct {
uint64_t last_refresh_call;
uint16_t native_frames_per_second;
uint16_t native_ms_per_frame;
uint16_t first_pixel_offset;
uint16_t row_stride;
bool auto_refresh;
bool first_manual_refresh;
} framebufferio_framebufferdisplay_obj_t;
void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self);
void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self);
void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self);
void framebufferio_framebufferdisplay_reset(framebufferio_framebufferdisplay_obj_t* self);
void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisplay_obj_t* self);
mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebufferio_framebufferdisplay_obj_t* self);
typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo);
typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t);
typedef void (*framebuffer_deinit_fun)(mp_obj_t);
typedef bool (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t);
typedef mp_float_t (*framebuffer_get_brightness_fun)(mp_obj_t);
typedef bool (*framebuffer_set_auto_brightness_fun)(mp_obj_t, bool);
typedef bool (*framebuffer_get_auto_brightness_fun)(mp_obj_t);
typedef int (*framebuffer_get_width_fun)(mp_obj_t);
typedef int (*framebuffer_get_height_fun)(mp_obj_t);
typedef int (*framebuffer_get_color_depth_fun)(mp_obj_t);
typedef bool (*framebuffer_get_reverse_pixels_in_byte_fun)(mp_obj_t);
typedef bool (*framebuffer_get_reverse_pixels_in_word_fun)(mp_obj_t);
typedef bool (*framebuffer_set_auto_brightness_fun)(mp_obj_t, bool);
typedef bool (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t);
typedef int (*framebuffer_get_bytes_per_cell_fun)(mp_obj_t);
typedef int (*framebuffer_get_color_depth_fun)(mp_obj_t);
typedef int (*framebuffer_get_first_pixel_offset_fun)(mp_obj_t);
typedef int (*framebuffer_get_grayscale_fun)(mp_obj_t);
typedef int (*framebuffer_get_height_fun)(mp_obj_t);
typedef int (*framebuffer_get_native_frames_per_second_fun)(mp_obj_t);
typedef bool (*framebuffer_get_pixels_in_byte_share_row_fun)(mp_obj_t);
typedef int (*framebuffer_get_row_stride_fun)(mp_obj_t);
typedef int (*framebuffer_get_width_fun)(mp_obj_t);
typedef mp_float_t (*framebuffer_get_brightness_fun)(mp_obj_t);
typedef void (*framebuffer_deinit_fun)(mp_obj_t);
typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo);
typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t, uint8_t *dirty_row_bitmask);
typedef struct _framebuffer_p_t {
MP_PROTOCOL_HEAD // MP_QSTR_protocol_framebuffer
// Mandatory
framebuffer_get_bufinfo_fun get_bufinfo;
framebuffer_swapbuffers_fun swapbuffers;
framebuffer_deinit_fun deinit;
framebuffer_get_width_fun get_width;
framebuffer_get_height_fun get_height;
framebuffer_get_color_depth_fun get_color_depth;
framebuffer_get_bytes_per_cell_fun get_bytes_per_cell;
framebuffer_get_native_frames_per_second_fun get_native_frames_per_second;
// Optional getters
framebuffer_get_bytes_per_cell_fun get_bytes_per_cell; // default: 2
framebuffer_get_color_depth_fun get_color_depth; // default: 16
framebuffer_get_first_pixel_offset_fun get_first_pixel_offset; // default: 0
framebuffer_get_grayscale_fun get_grayscale; // default: grayscale if depth < 8
framebuffer_get_native_frames_per_second_fun get_native_frames_per_second; // default: 60
framebuffer_get_pixels_in_byte_share_row_fun get_pixels_in_byte_share_row; // default: false
framebuffer_get_reverse_pixels_in_byte_fun get_reverse_pixels_in_byte; // default: false
framebuffer_get_reverse_pixels_in_word_fun get_reverse_pixels_in_word; // default: false
framebuffer_get_row_stride_fun get_row_stride; // default: 0 (no extra row padding)
// Optional -- default is no brightness control
framebuffer_get_brightness_fun get_brightness;
framebuffer_set_brightness_fun set_brightness;
// Optional -- default is no automatic brightness control
framebuffer_get_auto_brightness_fun get_auto_brightness;
framebuffer_set_auto_brightness_fun set_auto_brightness;
} framebuffer_p_t;

View File

@ -0,0 +1,277 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "py/gc.h"
#include "shared-bindings/board/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h"
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
#include "supervisor/memory.h"
#define SHARPMEM_BIT_WRITECMD_LSB (0x80)
#define SHARPMEM_BIT_VCOM_LSB (0x40)
static inline void *hybrid_alloc(size_t sz) {
if (gc_alloc_possible()) {
return m_malloc(sz + sizeof(void*), true);
} else {
supervisor_allocation *allocation = allocate_memory(align32_size(sz), false);
if (!allocation) {
return NULL;
}
memset(allocation->ptr, 0, sz);
return allocation->ptr;
}
}
static inline void hybrid_free(void *ptr_in) {
supervisor_allocation *allocation = allocation_from_ptr(ptr_in);
if (allocation) {
free_memory(allocation);
}
}
STATIC uint8_t bitrev(uint8_t n) {
uint8_t r = 0;
for(int i=0;i<8;i++) r |= ((n>>i) & 1)<<(7-i);
return r;
}
int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self) {
return self->width;
}
int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self) {
return self->height;
}
int common_hal_sharpdisplay_framebuffer_get_row_stride(sharpdisplay_framebuffer_obj_t *self) {
return (self->width + 7) / 8 + 2;
}
int common_hal_sharpdisplay_framebuffer_get_first_pixel_offset(sharpdisplay_framebuffer_obj_t *self) {
return 2;
}
bool common_hal_sharpdisplay_framebuffer_get_reverse_pixels_in_byte(sharpdisplay_framebuffer_obj_t *self) {
return true;
}
bool common_hal_sharpdisplay_framebuffer_get_pixels_in_byte_share_row(sharpdisplay_framebuffer_obj_t *self) {
return true;
}
void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self) {
if (!allocation_from_ptr(self->bufinfo.buf)) {
self->bufinfo.buf = NULL;
}
if (self->bus != &self->inline_bus
#if BOARD_SPI
&& self->bus != common_hal_board_get_spi()
#endif
) {
memcpy(&self->inline_bus, self->bus, sizeof(busio_spi_obj_t));
self->bus = &self->inline_bus;
}
}
void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self) {
}
void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo) {
if (!self->bufinfo.buf) {
int row_stride = common_hal_sharpdisplay_framebuffer_get_row_stride(self);
int height = common_hal_sharpdisplay_framebuffer_get_height(self);
self->bufinfo.len = row_stride * height + 2;
self->bufinfo.buf = hybrid_alloc(self->bufinfo.len);
uint8_t *data = self->bufinfo.buf;
*data++ = SHARPMEM_BIT_WRITECMD_LSB;
for(int y=0; y<height; y++) {
*data = bitrev(y+1);
data += row_stride;
}
self->full_refresh = true;
}
*bufinfo = self->bufinfo;
}
void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self) {
if (self->base.type != &sharpdisplay_framebuffer_type) {
return;
}
if (self->bus == &self->inline_bus) {
common_hal_busio_spi_deinit(self->bus);
}
common_hal_reset_pin(self->chip_select.pin);
hybrid_free(self->bufinfo.buf);
memset(self, 0, sizeof(*self));
}
void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, mcu_pin_obj_t *chip_select, int baudrate, int width, int height) {
common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select);
common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL);
common_hal_never_reset_pin(chip_select);
self->bus = spi;
common_hal_busio_spi_never_reset(self->bus);
self->width = width;
self->height = height;
self->baudrate = baudrate;
int row_stride = common_hal_sharpdisplay_framebuffer_get_row_stride(self);
self->bufinfo.len = row_stride * height + 2;
self->bufinfo.buf = gc_alloc(self->bufinfo.len, false, true);
uint8_t *data = self->bufinfo.buf;
*data++ = SHARPMEM_BIT_WRITECMD_LSB;
for(int y=0; y<self->height; y++) {
*data = bitrev(y+1);
data += row_stride;
}
self->full_refresh = true;
}
void common_hal_sharpdisplay_framebuffer_swapbuffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask) {
// claim SPI bus
if (!common_hal_busio_spi_try_lock(self->bus)) {
return;
}
common_hal_busio_spi_configure(self->bus, self->baudrate, 0, 0, 8);
// set chip select high
common_hal_digitalio_digitalinout_set_value(&self->chip_select, true);
// output the toggling signal
uint8_t *data = self->bufinfo.buf;
data[0] ^= SHARPMEM_BIT_VCOM_LSB;
common_hal_busio_spi_write(self->bus, data++, 1);
// output each changed row
size_t row_stride = common_hal_sharpdisplay_framebuffer_get_row_stride(self);
for(int y=0; y<self->height; y++) {
if(self->full_refresh || (dirty_row_bitmask[y/8] & (1 << (y & 7)))) {
common_hal_busio_spi_write(self->bus, data, row_stride);
}
data += row_stride;
}
// output a trailing zero
common_hal_busio_spi_write(self->bus, data, 1);
// set chip select low
common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
// release SPI bus
common_hal_busio_spi_unlock(self->bus);
self->full_refresh = false;
}
STATIC void sharpdisplay_framebuffer_deinit(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = self_in;
common_hal_sharpdisplay_framebuffer_deinit(self);
}
STATIC void sharpdisplay_framebuffer_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) {
sharpdisplay_framebuffer_obj_t *self = self_in;
common_hal_sharpdisplay_framebuffer_get_bufinfo(self, bufinfo);
}
STATIC int sharpdisplay_framebuffer_get_color_depth(mp_obj_t self_in) {
return 1;
}
STATIC int sharpdisplay_framebuffer_get_height(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = self_in;
return common_hal_sharpdisplay_framebuffer_get_height(self);
}
STATIC int sharpdisplay_framebuffer_get_width(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = self_in;
return common_hal_sharpdisplay_framebuffer_get_width(self);
}
STATIC int sharpdisplay_framebuffer_get_first_pixel_offset(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = self_in;
return common_hal_sharpdisplay_framebuffer_get_first_pixel_offset(self);
}
STATIC bool sharpdisplay_framebuffer_get_pixels_in_byte_share_row(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = self_in;
return common_hal_sharpdisplay_framebuffer_get_pixels_in_byte_share_row(self);
}
STATIC bool sharpdisplay_framebuffer_get_reverse_pixels_in_byte(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = self_in;
return common_hal_sharpdisplay_framebuffer_get_reverse_pixels_in_byte(self);
}
STATIC int sharpdisplay_framebuffer_get_row_stride(mp_obj_t self_in) {
sharpdisplay_framebuffer_obj_t *self = self_in;
return common_hal_sharpdisplay_framebuffer_get_row_stride(self);
}
STATIC void sharpdisplay_framebuffer_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmask) {
sharpdisplay_framebuffer_obj_t *self = self_in;
common_hal_sharpdisplay_framebuffer_swapbuffers(self, dirty_row_bitmask);
}
const framebuffer_p_t sharpdisplay_framebuffer_proto = {
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer)
.deinit = sharpdisplay_framebuffer_deinit,
.get_bufinfo = sharpdisplay_framebuffer_get_bufinfo,
.get_color_depth = sharpdisplay_framebuffer_get_color_depth,
.get_height = sharpdisplay_framebuffer_get_height,
.get_width = sharpdisplay_framebuffer_get_width,
.swapbuffers = sharpdisplay_framebuffer_swapbuffers,
.get_first_pixel_offset = sharpdisplay_framebuffer_get_first_pixel_offset,
.get_pixels_in_byte_share_row = sharpdisplay_framebuffer_get_pixels_in_byte_share_row,
.get_reverse_pixels_in_byte = sharpdisplay_framebuffer_get_reverse_pixels_in_byte,
.get_row_stride = sharpdisplay_framebuffer_get_row_stride,
};
void common_hal_sharpdisplay_framebuffer_collect_ptrs(sharpdisplay_framebuffer_obj_t *self) {
gc_collect_ptr(self->framebuffer);
gc_collect_ptr(self->bus);
gc_collect_ptr(self->bufinfo.buf);
}

View File

@ -0,0 +1,60 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include "py/obj.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-module/framebufferio/FramebufferDisplay.h"
typedef struct {
mp_obj_base_t base;
mp_obj_t framebuffer;
busio_spi_obj_t* bus;
busio_spi_obj_t inline_bus;
digitalio_digitalinout_obj_t chip_select;
mp_buffer_info_t bufinfo;
uint16_t width, height;
uint32_t baudrate;
bool full_refresh:1;
} sharpdisplay_framebuffer_obj_t;
void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, mcu_pin_obj_t *chip_select, int baudrate, int width, int height);
void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask);
void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self);
void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo);
int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self);
int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self);
void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask);
void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self);
void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self);
extern const framebuffer_p_t sharpdisplay_framebuffer_proto;
void common_hal_sharpdisplay_framebuffer_collect_ptrs(sharpdisplay_framebuffer_obj_t*);

View File

View File

View File

@ -38,6 +38,12 @@
#include "shared-module/displayio/__init__.h"
#endif
#if CIRCUITPY_SHARPDISPLAY
#include "shared-module/displayio/__init__.h"
#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h"
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
#endif
extern size_t blinka_bitmap_data[];
extern displayio_bitmap_t blinka_bitmap;
extern displayio_group_t circuitpython_splash;
@ -116,15 +122,21 @@ void supervisor_display_move_memory(void) {
grid->inline_tiles = false;
}
MP_STATE_VM(terminal_tilegrid_tiles) = NULL;
#if CIRCUITPY_RGBMATRIX
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) {
rgbmatrix_rgbmatrix_obj_t * pm = &displays[i].rgbmatrix;
#if CIRCUITPY_RGBMATRIX
if (displays[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) {
rgbmatrix_rgbmatrix_obj_t * pm = &displays[i].rgbmatrix;
common_hal_rgbmatrix_rgbmatrix_reconstruct(pm, NULL);
}
}
#endif
#if CIRCUITPY_SHARPDISPLAY
if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
sharpdisplay_framebuffer_obj_t * sharp = &displays[i].sharpdisplay;
common_hal_sharpdisplay_framebuffer_reconstruct(sharp);
}
#endif
}
#endif
#endif
}
size_t blinka_bitmap_data[32] = {

View File

@ -28,6 +28,7 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "rgb_led_status.h"
#include "supervisor/shared/tick.h"
#include "py/obj.h"
#ifdef MICROPY_HW_NEOPIXEL
uint8_t rgb_status_brightness = 63;
@ -365,6 +366,11 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
status->safe_mode = safe_mode;
status->found_main = found_main;
status->total_exception_cycle = 0;
status->ok = result->return_code != PYEXEC_EXCEPTION;
if (status->ok) {
// If this isn't an exception, skip exception sorting and handling
return;
}
status->ones = result->exception_line % 10;
status->ones += status->ones > 0 ? 1 : 0;
status->tens = (result->exception_line / 10) % 10;
@ -382,11 +388,12 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
}
line /= 10;
}
status->ok = result->return_code != PYEXEC_EXCEPTION;
if (!status->ok) {
status->total_exception_cycle = EXCEPTION_TYPE_LENGTH_MS * 3 + LINE_NUMBER_TOGGLE_LENGTH * status->digit_sum + LINE_NUMBER_TOGGLE_LENGTH * num_places;
}
if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) {
if (!result->exception_type) {
status->exception_color = OTHER_ERROR;
} else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) {
status->exception_color = INDENTATION_ERROR;
} else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_SyntaxError)) {
status->exception_color = SYNTAX_ERROR;

View File

@ -45,7 +45,10 @@ def find_stub_issues(tree):
if isinstance(node.value, ast.Constant) and node.value.value == Ellipsis:
yield ("WARN", f"Unnecessary Ellipsis assignment (= ...) on line {node.lineno}.")
elif isinstance(node, ast.arguments):
for arg_node in (node.args + node.posonlyargs + node.kwonlyargs):
allargs = list(node.args + node.kwonlyargs)
if sys.version_info >= (3, 8):
allargs.extend(node.posonlyargs)
for arg_node in allargs:
if not is_typed(arg_node.annotation) and (arg_node.arg != "self" and arg_node.arg != "cls"):
yield ("WARN", f"Missing argument type: {arg_node.arg} on line {arg_node.lineno}")
if node.vararg and not is_typed(node.vararg.annotation, allow_any=True):