Merge branch 'main' into hid_devices-gc

This commit is contained in:
Dan Halbert 2021-05-24 18:17:52 -04:00 committed by GitHub
commit 0f66832829
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 792 additions and 1294 deletions

View File

@ -190,6 +190,7 @@ jobs:
- "arduino_mkrzero"
- "arduino_nano_33_ble"
- "arduino_nano_33_iot"
- "arduino_nano_rp2040_connect"
- "arduino_zero"
- "bast_pro_mini_m0"
- "bastble"

@ -1 +1 @@
Subproject commit 9b4a5241d8c3310b31a7925a4f2160743890a2e4
Subproject commit e5b149599d14a8841167fe552846ca36925b87a0

View File

@ -45,11 +45,11 @@ This error occurs when importing a module that is stored as a ``mpy`` binary fil
(rather than a ``py`` text file) that was generated by a different version of
CircuitPython than the one it's being loaded into. Most versions are compatible
but, rarely they aren't. In particular, the ``mpy`` binary format changed between
CircuitPython versions 1.x and 2.x, and will change again between 2.x and 3.x.
CircuitPython versions 1.x and 2.x, 2.x and 3.x, and will change again between 6.x and 7.x.
So, for instance, if you just upgraded to CircuitPython 2.x from 1.x you'll need to download a
So, for instance, if you just upgraded to CircuitPython 7.x from 6.x you'll need to download a
newer version of the library that triggered the error on ``import``. They are
all available in the
`Adafruit bundle <https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest>`_
and the `Community bundle <https://github.com/adafruit/CircuitPython_Community_Bundle/releases/latest>`_.
Make sure to download a version with 2.0.0 or higher in the filename.
Make sure to download a version with 7.0.0 or higher in the filename.

View File

@ -1719,7 +1719,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1672,6 +1672,10 @@ msgstr ""
msgid "Only edge detection is available on this hardware"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only int or string supported for ip"
msgstr ""
#: shared-module/displayio/OnDiskBitmap.c
#, c-format
msgid ""
@ -1693,10 +1697,6 @@ msgstr ""
msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
msgstr ""

View File

@ -1697,7 +1697,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1721,7 +1721,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1694,7 +1694,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1713,8 +1713,8 @@ msgid "Only one color can be transparent at a time"
msgstr "Only one colour can be transparent at a time"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
@ -4393,6 +4393,9 @@ msgstr "zi must be of float type"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi must be of shape (n_section, 2)"
#~ msgid "Only raw int supported for ip"
#~ msgstr "Only raw int supported for ip"
#~ msgid ""
#~ "CircuitPython is in safe mode because you pressed the reset button during "
#~ "boot. Press again to exit safe mode.\n"

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2021-05-15 15:52+0000\n"
"PO-Revision-Date: 2021-05-22 17:58+0000\n"
"Last-Translator: Alvaro Figueroa <alvaro@greencore.co.cr>\n"
"Language-Team: \n"
"Language: es\n"
@ -1246,7 +1246,7 @@ msgstr "AuthMode invalido"
#: ports/nrf/common-hal/_bleio/__init__.c
msgid "Invalid BLE parameter"
msgstr ""
msgstr "Parámetro BLE invalido"
#: shared-module/displayio/OnDiskBitmap.c
msgid "Invalid BMP file"
@ -1737,8 +1737,8 @@ msgid "Only one color can be transparent at a time"
msgstr "Solo un color puede ser transparente a la vez"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr "Solo se aceptan enteros crudos para ip"
msgid "Only raw int or string supported for ip"
msgstr "Para ip solo puede con un entero o una cadena"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
@ -4448,6 +4448,9 @@ msgstr "zi debe ser de tipo flotante"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi debe ser una forma (n_section,2)"
#~ msgid "Only raw int supported for ip"
#~ msgstr "Solo se aceptan enteros crudos para ip"
#~ msgid ""
#~ "CircuitPython is in safe mode because you pressed the reset button during "
#~ "boot. Press again to exit safe mode.\n"

View File

@ -1712,7 +1712,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2021-05-20 13:02+0000\n"
"Last-Translator: Noel Gaetan <gaetan.noel@viacesi.fr>\n"
"PO-Revision-Date: 2021-05-21 17:47+0000\n"
"Last-Translator: Hugo Dahl <hugo@code-jedi.com>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
@ -116,7 +116,7 @@ msgstr "%q doit être >= 1"
#: shared-bindings/usb_hid/Device.c
msgid "%q must be None or 1-255"
msgstr "%q doit être NULL ou compris entre 1 et 255"
msgstr "%q doit être None ou compris entre 1 et 255"
#: shared-module/vectorio/Polygon.c
msgid "%q must be a tuple of length 2"
@ -1745,8 +1745,8 @@ msgid "Only one color can be transparent at a time"
msgstr "Une seule couleur peut être transparente à la fois"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr "IP n'accepte que les chiffres entiers bruts"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
@ -4459,6 +4459,9 @@ msgstr "zi doit être de type float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi doit être de forme (n_section, 2)"
#~ msgid "Only raw int supported for ip"
#~ msgstr "IP n'accepte que les chiffres entiers bruts"
#~ msgid ""
#~ "CircuitPython is in safe mode because you pressed the reset button during "
#~ "boot. Press again to exit safe mode.\n"

View File

@ -1694,7 +1694,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1726,7 +1726,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1707,7 +1707,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1697,7 +1697,7 @@ msgid "Only one color can be transparent at a time"
msgstr ""
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -1712,8 +1712,8 @@ msgid "Only one color can be transparent at a time"
msgstr "Er kan maar één kleur per keer transparant zijn"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr "Alleen raw int ondersteund voor IP"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
@ -4404,6 +4404,9 @@ 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 "Only raw int supported for ip"
#~ msgstr "Alleen raw int ondersteund voor IP"
#~ msgid ""
#~ "CircuitPython is in safe mode because you pressed the reset button during "
#~ "boot. Press again to exit safe mode.\n"

View File

@ -1705,7 +1705,7 @@ msgid "Only one color can be transparent at a time"
msgstr "W danym momencie przezroczysty może być tylko jeden kolor"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c

View File

@ -6,7 +6,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2021-05-20 13:02+0000\n"
"PO-Revision-Date: 2021-05-22 17:58+0000\n"
"Last-Translator: Wellington Terumi Uemura <wellingtonuemura@gmail.com>\n"
"Language-Team: \n"
"Language: pt_BR\n"
@ -1735,8 +1735,8 @@ msgid "Only one color can be transparent at a time"
msgstr "Apenas uma cor pode ser transparente de cada vez"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr "Apenas o int bruto é compatível para o ip"
msgid "Only raw int or string supported for ip"
msgstr "Apenas int ou string bruto é compatível para o ip"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
@ -4458,6 +4458,9 @@ msgstr "zi deve ser de um tipo float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi deve estar na forma (n_section, 2)"
#~ msgid "Only raw int supported for ip"
#~ msgstr "Apenas o int bruto é compatível para o ip"
#~ msgid ""
#~ "CircuitPython is in safe mode because you pressed the reset button during "
#~ "boot. Press again to exit safe mode.\n"

View File

@ -6,7 +6,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2021-05-20 13:02+0000\n"
"PO-Revision-Date: 2021-05-22 17:58+0000\n"
"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: sv\n"
@ -1719,8 +1719,8 @@ msgid "Only one color can be transparent at a time"
msgstr "Bara en färg kan vara genomskinlig i taget"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr "Endast raw int stöds för ip"
msgid "Only raw int or string supported for ip"
msgstr "Enbart int eller string stöds för ip"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
@ -4417,6 +4417,9 @@ 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 "Only raw int supported for ip"
#~ msgstr "Endast raw int stöds för ip"
#~ msgid ""
#~ "CircuitPython is in safe mode because you pressed the reset button during "
#~ "boot. Press again to exit safe mode.\n"

View File

@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2021-05-12 21:48+0000\n"
"PO-Revision-Date: 2021-05-21 17:47+0000\n"
"Last-Translator: hexthat <hexthat@gmail.com>\n"
"Language-Team: Chinese Hanyu Pinyin\n"
"Language: zh_Latn_pinyin\n"
@ -857,6 +857,7 @@ msgstr "Guǎnggào bāo de shùjù tài dà"
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
msgid "Deep sleep pins must use a rising edge with pulldown"
msgstr ""
"shēn dù shuì mián bié zhēn bì xū shǐ yòng xià lā shàng shēng de biān yuán"
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
@ -1234,7 +1235,7 @@ msgstr "wú xiào AuthMode"
#: ports/nrf/common-hal/_bleio/__init__.c
msgid "Invalid BLE parameter"
msgstr ""
msgstr "wú xiào BLE cān shù"
#: shared-module/displayio/OnDiskBitmap.c
msgid "Invalid BMP file"
@ -1695,7 +1696,7 @@ msgstr ""
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
msgid "Only edge detection is available on this hardware"
msgstr ""
msgstr "cǐ yìng jiàn shàng jǐn tí gòng biān yuán jiǎn cè"
#: shared-module/displayio/OnDiskBitmap.c
#, c-format
@ -1721,8 +1722,8 @@ msgid "Only one color can be transparent at a time"
msgstr "Yīcì zhǐ néng yǒuyī zhǒng yánsè shì tòumíng de"
#: shared-bindings/ipaddress/__init__.c
msgid "Only raw int supported for ip"
msgstr "Ip jǐn zhīchí raw int"
msgid "Only raw int or string supported for ip"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
@ -1791,7 +1792,7 @@ msgstr "Quánxiàn bèi jùjué"
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
msgid "Pin cannot wake from Deep Sleep"
msgstr ""
msgstr "yǐn jiǎo wú fǎ cóng shēn dù shuì mián zhōng huàn xǐng"
#: ports/raspberrypi/bindings/rp2pio/StateMachine.c
msgid "Pin count must be at least 1"
@ -1814,7 +1815,7 @@ msgstr "Pin méiyǒu ADC nénglì"
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
#: ports/stm/common-hal/pulseio/PulseIn.c
msgid "Pin interrupt already in use"
msgstr ""
msgstr "yǐn jiǎo zhōng duàn yǐ zài shǐ yòng zhōng"
#: shared-bindings/adafruit_bus_device/SPIDevice.c
#: shared-bindings/digitalio/DigitalInOut.c
@ -2057,7 +2058,7 @@ msgstr "bù zhī chí dà xiǎo"
#: ports/stm/common-hal/alarm/SleepMemory.c
msgid "Sleep Memory not available"
msgstr ""
msgstr "shuì mián jì yì bù kě yòng"
#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c
msgid "Slice and value different lengths."
@ -2119,12 +2120,16 @@ msgid ""
"The CircuitPython heap was corrupted because the stack was too small.\n"
"Increase the stack size if you know how. If not:"
msgstr ""
"diàn lù dàn duī bèi sǔn huài, yīn wéi duī zhàn tài xiǎo.\n"
"rú guǒ nín zhī dào rú hé zēng jiā duī zhàn dà xiǎo. rú guǒ méi yǒu"
#: supervisor/shared/safe_mode.c
msgid ""
"The `microcontroller` module was used to boot into safe mode. Press reset to "
"exit safe mode."
msgstr ""
"`wēi kòng zhì qì` mó kuài yòng yú qǐ dòng dào ān quán mó shì. àn chóng zhì "
"tuì chū ān quán mó shì."
#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30"
@ -2136,6 +2141,9 @@ msgid ""
"enough power for the whole circuit and press reset (after ejecting "
"CIRCUITPY)."
msgstr ""
"wēi kòng zhì qì de gōng lǜ xià jiàng. què bǎo diàn yuán tí gòng\n"
"zú gòu de gōng lǜ yòng yú zhěng gè diàn lù hé àn chóng zhì (tán chū "
"CIRCUITPY hòu)."
#: shared-module/audiomixer/MixerVoice.c
msgid "The sample's bits_per_sample does not match the mixer's"
@ -2201,7 +2209,7 @@ msgstr "yào biān xiě de zǒng shù jù dà yú %q"
#: ports/stm/common-hal/alarm/touch/TouchAlarm.c
msgid "Touch alarms not available"
msgstr ""
msgstr "bù kě yòng chù mō bào jǐng qì"
#: py/obj.c
msgid "Traceback (most recent call last):\n"
@ -2442,12 +2450,14 @@ msgstr "Tèzhēng bù zhīchí xiě rù"
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode because:\n"
msgstr ""
msgstr "nín chǔ yú ān quán mó shì shì yīn wéi:\n"
#: supervisor/shared/safe_mode.c
msgid ""
"You pressed the reset button during boot. Press again to exit safe mode."
msgstr ""
"zài qǐ dòng guò chéng zhōng, nín àn xià le chóng zhì àn niǔ. zài cì àn xià "
"yǐ tuì chū ān quán mó shì."
#: supervisor/shared/safe_mode.c
msgid "You requested starting safe mode by "
@ -4404,6 +4414,9 @@ msgstr "zi bìxū wèi fú diǎn xíng"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)"
#~ msgid "Only raw int supported for ip"
#~ msgstr "Ip jǐn zhīchí raw int"
#~ msgid ""
#~ "CircuitPython is in safe mode because you pressed the reset button during "
#~ "boot. Press again to exit safe mode.\n"

198
main.c
View File

@ -53,7 +53,6 @@
#include "supervisor/port.h"
#include "supervisor/serial.h"
#include "supervisor/shared/autoreload.h"
#include "supervisor/shared/rgb_led_status.h"
#include "supervisor/shared/safe_mode.h"
#include "supervisor/shared/stack.h"
#include "supervisor/shared/status_leds.h"
@ -114,7 +113,6 @@ static void reset_devices(void) {
}
STATIC void start_mp(supervisor_allocation* heap) {
reset_status_led();
autoreload_stop();
supervisor_workflow_reset();
@ -251,7 +249,6 @@ STATIC void cleanup_after_vm(supervisor_allocation* heap) {
#endif
reset_port();
reset_board();
reset_status_led();
}
STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
@ -286,8 +283,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
bool found_main = false;
if (safe_mode == NO_SAFE_MODE) {
new_status_color(MAIN_RUNNING);
static const char * const supported_filenames[] = STRING_LIST(
"code.txt", "code.py", "main.py", "main.txt");
#if CIRCUITPY_FULL_BUILD
@ -317,6 +312,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
serial_write_compressed(translate("WARNING: Your code filename has two extensions\n"));
}
}
#else
(void) found_main;
#endif
// Finished executing python code. Cleanup includes a board reset.
@ -334,42 +331,62 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
}
// Program has finished running.
bool printed_press_any_key = false;
#if CIRCUITPY_DISPLAYIO
bool refreshed_epaper_display = false;
size_t time_to_epaper_refresh = 1;
#endif
rgb_status_animation_t animation;
prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
// Setup LED blinks.
#if CIRCUITPY_STATUS_LED
uint32_t color;
uint8_t blink_count;
bool led_active = false;
#if CIRCUITPY_ALARM
if (result.return_code & PYEXEC_DEEP_SLEEP) {
color = BLACK;
blink_count = 0;
} else
#endif
if (result.return_code != PYEXEC_EXCEPTION) {
if (safe_mode == NO_SAFE_MODE) {
color = ALL_DONE;
blink_count = ALL_DONE_BLINKS;
} else {
color = SAFE_MODE;
blink_count = SAFE_MODE_BLINKS;
}
} else {
color = EXCEPTION;
blink_count = EXCEPTION_BLINKS;
}
size_t pattern_start = supervisor_ticks_ms32();
size_t single_blink_time = (OFF_ON_RATIO + 1) * BLINK_TIME_MS;
size_t blink_time = single_blink_time * blink_count;
size_t total_time = blink_time + LED_SLEEP_TIME_MS;
#endif
#if CIRCUITPY_ALARM
bool fake_sleeping = false;
#endif
bool skip_repl = false;
while (true) {
RUN_BACKGROUND_TASKS;
// If a reload was requested by the supervisor or autoreload, return
if (reload_requested) {
#if CIRCUITPY_ALARM
if (fake_sleeping) {
board_init();
}
#endif
reload_requested = false;
return true;
skip_repl = true;
break;
}
// If interrupted by keyboard, return
if (serial_connected() && serial_bytes_available()) {
#if CIRCUITPY_ALARM
if (fake_sleeping) {
board_init();
}
#endif
// Skip REPL if reload was requested.
bool ctrl_d = serial_read() == CHAR_CTRL_D;
if (ctrl_d) {
skip_repl = serial_read() == CHAR_CTRL_D;
if (skip_repl) {
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
}
return ctrl_d;
break;
}
// Check for a deep sleep alarm and restart the VM. This can happen if
@ -378,9 +395,9 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
#if CIRCUITPY_ALARM
if (fake_sleeping && common_hal_alarm_woken_from_sleep()) {
serial_write_compressed(translate("Woken up by alarm.\n"));
board_init();
supervisor_set_run_reason(RUN_REASON_STARTUP);
return true;
skip_repl = true;
break;
}
#endif
@ -403,26 +420,21 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
printed_press_any_key = false;
}
// Refresh the ePaper display if we have one. That way it'll show an error message.
#if CIRCUITPY_DISPLAYIO
// Don't refresh the display if we're about to deep sleep.
#if CIRCUITPY_ALARM
refreshed_epaper_display = refreshed_epaper_display || result.return_code & PYEXEC_DEEP_SLEEP;
#endif
if (!refreshed_epaper_display) {
refreshed_epaper_display = maybe_refresh_epaperdisplay();
}
#endif
// Sleep until our next interrupt.
#if CIRCUITPY_ALARM
if (result.return_code & PYEXEC_DEEP_SLEEP) {
// Make sure we have been awake long enough for USB to connect (enumeration delay).
int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks(NULL);
// Until it's safe to decide whether we're real/fake sleeping, just run the RGB
if (connecting_delay_ticks < 0 && !fake_sleeping) {
fake_sleeping = true;
new_status_color(BLACK);
// Until it's safe to decide whether we're real/fake sleeping
if (fake_sleeping) {
// This waits until a pretend deep sleep alarm occurs. They are set
// during common_hal_alarm_set_deep_sleep_alarms. On some platforms
// it may also return due to another interrupt, that's why we check
// for deep sleep alarms above. If it wasn't a deep sleep alarm,
// then we'll idle here again.
common_hal_alarm_pretending_deep_sleep();
} else if (connecting_delay_ticks < 0) {
// Entering deep sleep (may be fake or real.)
board_deinit();
if (!supervisor_workflow_active()) {
// Enter true deep sleep. When we wake up we'll be back at the
@ -431,27 +443,85 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
// Does not return.
} else {
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
fake_sleeping = true;
}
} else {
// Loop while checking the time. We can't idle because we don't want to override a
// time alarm set for the deep sleep.
}
}
} else
#endif
{
// Refresh the ePaper display if we have one. That way it'll show an error message.
#if CIRCUITPY_DISPLAYIO
if (time_to_epaper_refresh > 0) {
time_to_epaper_refresh = maybe_refresh_epaperdisplay();
}
if (!fake_sleeping) {
tick_rgb_status_animation(&animation);
} else {
// This waits until a pretend deep sleep alarm occurs. They are set
// during common_hal_alarm_set_deep_sleep_alarms. On some platforms
// it may also return due to another interrupt, that's why we check
// for deep sleep alarms above. If it wasn't a deep sleep alarm,
// then we'll idle here again.
#if CIRCUITPY_ALARM
common_hal_alarm_pretending_deep_sleep();
#else
port_idle_until_interrupt();
#if !CIRCUITPY_STATUS_LED
port_interrupt_after_ticks(time_to_epaper_refresh);
#endif
#endif
#if CIRCUITPY_STATUS_LED
uint32_t tick_diff = supervisor_ticks_ms32() - pattern_start;
// By default, don't sleep.
size_t time_to_next_change = 0;
if (tick_diff < blink_time) {
uint32_t blink_diff = tick_diff % (single_blink_time);
if (blink_diff >= BLINK_TIME_MS) {
if (led_active) {
new_status_color(BLACK);
status_led_deinit();
led_active = false;
}
time_to_next_change = single_blink_time - blink_diff;
} else {
if (!led_active) {
status_led_init();
new_status_color(color);
led_active = true;
}
time_to_next_change = BLINK_TIME_MS - blink_diff;
}
} else if (tick_diff > total_time) {
pattern_start = supervisor_ticks_ms32();
} else {
if (led_active) {
new_status_color(BLACK);
status_led_deinit();
led_active = false;
}
time_to_next_change = total_time - tick_diff;
}
#if CIRCUITPY_DISPLAYIO
if (time_to_epaper_refresh > 0 && time_to_next_change > 0) {
time_to_next_change = MIN(time_to_next_change, time_to_epaper_refresh);
}
#endif
// time_to_next_change is in ms and ticks are slightly shorter so
// we'll undersleep just a little. It shouldn't matter.
port_interrupt_after_ticks(time_to_next_change);
#endif
port_idle_until_interrupt();
}
}
// Done waiting, start the board back up.
#if CIRCUITPY_STATUS_LED
if (led_active) {
new_status_color(BLACK);
status_led_deinit();
}
#endif
#if CIRCUITPY_ALARM
if (fake_sleeping) {
board_init();
}
#endif
return skip_repl;
}
FIL* boot_output_file;
@ -468,7 +538,6 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
bool skip_boot_output = false;
if (ok_to_run) {
new_status_color(BOOT_RUNNING);
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
FIL file_pointer;
@ -578,13 +647,27 @@ STATIC int run_repl(void) {
#endif
autoreload_suspend();
// Set the status LED to the REPL color before running the REPL. For
// NeoPixels and DotStars this will be sticky but for PWM or single LED it
// won't. This simplifies pin sharing because they won't be in use when
// actually in the REPL.
#if CIRCUITPY_STATUS_LED
status_led_init();
new_status_color(REPL_RUNNING);
status_led_deinit();
#endif
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
exit_code = pyexec_raw_repl();
} else {
exit_code = pyexec_friendly_repl();
}
cleanup_after_vm(heap);
#if CIRCUITPY_STATUS_LED
status_led_init();
new_status_color(BLACK);
status_led_deinit();
#endif
autoreload_resume();
return exit_code;
}
@ -593,9 +676,8 @@ int __attribute__((used)) main(void) {
// initialise the cpu and peripherals
safe_mode_t safe_mode = port_init();
// Turn on LEDs
init_status_leds();
rgb_led_status_init();
// Turn on RX and TX LEDs if we have them.
init_rxtx_leds();
// Wait briefly to give a reset window where we'll enter safe mode after the reset.
if (safe_mode == NO_SAFE_MODE) {

View File

@ -6,13 +6,14 @@
// Rev E
#define MICROPY_HW_LED_STATUS (&pin_PA23)
#define MICROPY_HW_NEOPIXEL (&pin_PB03)
#define MICROPY_HW_NEOPIXEL (&pin_PB02)
#define CIRCUITPY_STATUS_LED_POWER (&pin_PB03)
// These are pins not to reset.
// QSPI Data pins
#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
// QSPI CS, QSPI SCK and NeoPixel pin
#define MICROPY_PORT_B (PORT_PB03 | PORT_PB10 | PORT_PB11)
#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)

View File

@ -12,7 +12,7 @@
// QSPI Data pins
#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
// QSPI CS, QSPI SCK and NeoPixel pin
#define MICROPY_PORT_B (PORT_PB03 | PORT_PB10 | PORT_PB11)
#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)

View File

@ -33,10 +33,9 @@
#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 CIRCUITPY_RGB_STATUS_R (&pin_PA06)
// #define CIRCUITPY_RGB_STATUS_G (&pin_PA05)
// #define CIRCUITPY_RGB_STATUS_B (&pin_PA07)
// #define CIRCUITPY_RGB_STATUS_INVERTED_PWM
#define MICROPY_HW_LED_STATUS (&pin_PA06)

View File

@ -25,15 +25,8 @@
*/
#include "supervisor/board.h"
#include "common-hal/microcontroller/Pin.h"
#include "supervisor/shared/board.h"
#include "hal/include/hal_gpio.h"
void board_init(void) {
gpio_set_pin_function(PIN_PA15, GPIO_PIN_FUNCTION_OFF);
gpio_set_pin_direction(PIN_PA15, GPIO_DIRECTION_OUT);
gpio_set_pin_level(PIN_PA15, true); // Turn on neopixel by default
never_reset_pin_number(PIN_PA15);
}
bool board_requests_safe_mode(void) {

View File

@ -2,6 +2,7 @@
#define MICROPY_HW_MCU_NAME "samd21e18"
#define MICROPY_HW_NEOPIXEL (&pin_PA18)
#define CIRCUITPY_STATUS_LED_POWER (&pin_PA15)
#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)

View File

@ -25,15 +25,8 @@
*/
#include "supervisor/board.h"
#include "common-hal/microcontroller/Pin.h"
#include "supervisor/shared/board.h"
#include "hal/include/hal_gpio.h"
void board_init(void) {
gpio_set_pin_function(PIN_PA15, GPIO_PIN_FUNCTION_OFF);
gpio_set_pin_direction(PIN_PA15, GPIO_DIRECTION_OUT);
gpio_set_pin_level(PIN_PA15, true); // Turn on neopixel by default
never_reset_pin_number(PIN_PA15);
}
bool board_requests_safe_mode(void) {

View File

@ -2,6 +2,7 @@
#define MICROPY_HW_MCU_NAME "samd21e18"
#define MICROPY_HW_NEOPIXEL (&pin_PA18)
#define CIRCUITPY_STATUS_LED_POWER (&pin_PA15)
#define MICROPY_PORT_A (0)
#define MICROPY_PORT_B (0)

View File

@ -36,7 +36,6 @@
#include "hal/include/hal_gpio.h"
#include "hal/include/hal_spi_m_sync.h"
#include "hal/include/hpl_spi_m_sync.h"
#include "supervisor/shared/rgb_led_status.h"
#include "samd/dma.h"
#include "samd/sercom.h"
@ -72,11 +71,6 @@ void reset_sercoms(void) {
if (never_reset_sercoms[i]) {
continue;
}
#ifdef MICROPY_HW_APA102_SERCOM
if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) {
continue;
}
#endif
// SWRST is same for all modes of SERCOMs.
sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1;
}
@ -122,15 +116,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
continue;
}
Sercom *potential_sercom = sercom_insts[sercom_index];
if (
#if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !CIRCUITPY_BITBANG_APA102
(potential_sercom->SPI.CTRLA.bit.ENABLE != 0 &&
potential_sercom != status_apa102.spi_desc.dev.prvt &&
!apa102_sck_in_use)
#else
potential_sercom->SPI.CTRLA.bit.ENABLE != 0
#endif
) {
if (potential_sercom->SPI.CTRLA.bit.ENABLE != 0) {
continue;
}
clock_pinmux = PINMUX(clock->number, (i == 0) ? MUX_C : MUX_D);
@ -181,10 +167,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
// Set up SPI clocks on SERCOM.
samd_peripherals_sercom_clock_init(sercom, sercom_index);
#if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !CIRCUITPY_BITBANG_APA102
// if we're re-using the dotstar sercom, make sure it is disabled or the init will fail out
hri_sercomspi_clear_CTRLA_ENABLE_bit(sercom);
#endif
if (spi_m_sync_init(&self->spi_desc, sercom) != ERR_NONE) {
mp_raise_OSError(MP_EIO);
}

View File

@ -32,15 +32,7 @@
#include "hal/include/hal_gpio.h"
#include "samd/pins.h"
#include "supervisor/shared/rgb_led_status.h"
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
bool apa102_sck_in_use;
bool apa102_mosi_in_use;
#endif
#ifdef SPEAKER_ENABLE_PIN
bool speaker_enable_in_use;
#endif
@ -90,14 +82,6 @@ void reset_all_pins(void) {
gpio_set_pin_function(PIN_PA31, GPIO_PIN_FUNCTION_G);
#endif
#ifdef MICROPY_HW_NEOPIXEL
neopixel_in_use = false;
#endif
#ifdef MICROPY_HW_APA102_MOSI
apa102_sck_in_use = false;
apa102_mosi_in_use = false;
#endif
// After configuring SWD because it may be shared.
#ifdef SPEAKER_ENABLE_PIN
speaker_enable_in_use = false;
@ -122,25 +106,6 @@ void reset_pin_number(uint8_t pin_number) {
never_reset_pins[GPIO_PORT(pin_number)] &= ~(1 << GPIO_PIN(pin_number));
#ifdef MICROPY_HW_NEOPIXEL
if (pin_number == MICROPY_HW_NEOPIXEL->number) {
neopixel_in_use = false;
rgb_led_status_init();
return;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin_number == MICROPY_HW_APA102_MOSI->number ||
pin_number == MICROPY_HW_APA102_SCK->number) {
apa102_mosi_in_use = apa102_mosi_in_use && pin_number != MICROPY_HW_APA102_MOSI->number;
apa102_sck_in_use = apa102_sck_in_use && pin_number != MICROPY_HW_APA102_SCK->number;
if (!apa102_sck_in_use && !apa102_mosi_in_use) {
rgb_led_status_init();
}
return;
}
#endif
if (pin_number == PIN_PA30
#ifdef SAM_D5X_E5X
) {
@ -176,20 +141,6 @@ void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
}
void claim_pin(const mcu_pin_obj_t* pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
neopixel_in_use = true;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
apa102_mosi_in_use = true;
}
if (pin == MICROPY_HW_APA102_SCK) {
apa102_sck_in_use = true;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin == SPEAKER_ENABLE_PIN) {
speaker_enable_in_use = true;
@ -223,26 +174,6 @@ bool pin_number_is_free(uint8_t pin_number) {
}
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
// Special case for Metro M0 where the NeoPixel is also SWCLK
#ifndef IGNORE_PIN_PA30
if (MICROPY_HW_NEOPIXEL == &pin_PA30 && DSU->STATUSB.bit.DBGPRES == 1) {
return false;
}
#endif
return !neopixel_in_use;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
return !apa102_mosi_in_use;
}
if (pin == MICROPY_HW_APA102_SCK) {
return !apa102_sck_in_use;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin == SPEAKER_ENABLE_PIN) {
return !speaker_enable_in_use;

View File

@ -31,14 +31,6 @@
#include "peripherals/samd/pins.h"
#ifdef MICROPY_HW_NEOPIXEL
extern bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
extern bool apa102_sck_in_use;
extern bool apa102_mosi_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

@ -60,7 +60,7 @@ static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMa
" movs r6, #3; d2: sub r6, #1; bne d2;" // delay 3
#endif
#ifdef SAM_D5X_E5X
" movs r6, #3; d2: subs r6, #1; bne d2;" // delay 3
" movs r6, #16; d2: subs r6, #1; bne d2;" // delay 3
#endif
" tst r4, r5;" // mask&r5
" bne skipclr;"
@ -70,7 +70,7 @@ static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMa
" movs r6, #6; d0: sub r6, #1; bne d0;" // delay 6
#endif
#ifdef SAM_D5X_E5X
" movs r6, #6; d0: subs r6, #1; bne d0;" // delay 6
" movs r6, #16; d0: subs r6, #1; bne d0;" // delay 6
#endif
" str r1, [r0, #0];" // clr (possibly again, doesn't matter)
#ifdef SAMD21
@ -85,10 +85,13 @@ static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMa
" movs r6, #2; d1: sub r6, #1; bne d1;" // delay 2
#endif
#ifdef SAM_D5X_E5X
" movs r6, #2; d1: subs r6, #1; bne d1;" // delay 2
" movs r6, #15; d1: subs r6, #1; bne d1;" // delay 2
#endif
" b loopBit;"
"nextbyte:"
#ifdef SAM_D5X_E5X
" movs r6, #12; d3: subs r6, #1; bne d3;" // delay 2
#endif
" cmp r2, r3;"
" bcs neopixel_stop;"
" b loopLoad;"
@ -114,42 +117,12 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
// Turn off interrupts of any kind during timing-sensitive code.
mp_hal_disable_all_interrupts();
#ifdef SAM_D5X_E5X
// When this routine is positioned at certain addresses, the timing logic
// below can be too fast by about 2.5x. This is some kind of (un)fortunate code
// positioning with respect to a cache line.
// Theoretically we should turn on off the CMCC caches and the
// NVM caches to ensure consistent timing. Testing shows the the NVMCTRL
// cache disabling seems to make the difference. But turn both off to make sure.
// It's difficult to test because additions to the code before the timing loop
// below change instruction placement. (though this should be less true now that
// the main code is in the cache-aligned function neopixel_send_buffer_core)
// Testing was done by adding cache changes below the loop (so only the
// first time through is wrong).
//
// Turn off instruction, data, and NVM caches to force consistent timing.
// Invalidate existing cache entries.
hri_cmcc_set_CFG_reg(CMCC, CMCC_CFG_DCDIS | CMCC_CFG_ICDIS);
hri_cmcc_write_MAINT0_reg(CMCC, CMCC_MAINT0_INVALL);
hri_nvmctrl_set_CTRLA_CACHEDIS0_bit(NVMCTRL);
hri_nvmctrl_set_CTRLA_CACHEDIS1_bit(NVMCTRL);
#endif
uint32_t pin = digitalinout->pin->number;
port = &PORT->Group[GPIO_PORT(pin)]; // Convert GPIO # to port register
pinMask = (1UL << (pin % 32)); // From port_pin_set_output_level ASF code.
volatile uint32_t *clr = &(port->OUTCLR.reg);
neopixel_send_buffer_core(clr, pinMask, pixels, numBytes);
#ifdef SAM_D5X_E5X
// Turn instruction, data, and NVM caches back on.
hri_cmcc_clear_CFG_reg(CMCC, CMCC_CFG_DCDIS | CMCC_CFG_ICDIS);
hri_nvmctrl_clear_CTRLA_CACHEDIS0_bit(NVMCTRL);
hri_nvmctrl_clear_CTRLA_CACHEDIS1_bit(NVMCTRL);
#endif
// Update the next start.
next_start_raw_ticks = port_get_raw_ticks(NULL) + 4;

View File

@ -51,21 +51,10 @@
#include "hal/include/hal_flash.h"
#include "supervisor/flash.h"
#include "supervisor/shared/rgb_led_status.h"
static struct flash_descriptor supervisor_flash_desc;
void supervisor_flash_init(void) {
// Activity LED for flash writes.
#ifdef MICROPY_HW_LED_MSC
struct port_config pin_conf;
port_get_config_defaults(&pin_conf);
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
port_pin_set_config(MICROPY_HW_LED_MSC, &pin_conf);
port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
#endif
#ifdef SAM_D5X_E5X
hri_mclk_set_AHBMASK_NVMCTRL_bit(MCLK);
#endif
@ -114,10 +103,6 @@ bool supervisor_flash_read_block(uint8_t *dest, uint32_t block) {
}
bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) {
#ifdef MICROPY_HW_LED_MSC
port_pin_set_output_level(MICROPY_HW_LED_MSC, true);
#endif
temp_status_color(ACTIVE_WRITE);
// non-MBR block, copy to cache
int32_t dest = convert_block_to_flash_addr(block);
if (dest == -1) {
@ -136,10 +121,6 @@ bool supervisor_flash_write_block(const uint8_t *src, uint32_t block) {
if (error_code != ERR_NONE) {
return false;
}
clear_temp_status();
#ifdef MICROPY_HW_LED_MSC
port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
#endif
return true;
}

View File

@ -462,6 +462,8 @@ static uint32_t _get_count(uint64_t *overflow_count) {
return count;
}
volatile bool _woken_up;
static void _port_interrupt_after_ticks(uint32_t ticks) {
uint32_t current_ticks = _get_count(NULL);
if (ticks > 1 << 28) {
@ -473,9 +475,16 @@ static void _port_interrupt_after_ticks(uint32_t ticks) {
return;
}
#endif
RTC->MODE0.COMP[0].reg = current_ticks + (ticks << 4);
uint32_t target = current_ticks + (ticks << 4);
RTC->MODE0.COMP[0].reg = target;
#ifdef SAM_D5X_E5X
while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COMP0)) != 0) {
}
#endif
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0;
current_ticks = _get_count(NULL);
_woken_up = current_ticks >= target;
}
void RTC_Handler(void) {
@ -485,15 +494,18 @@ void RTC_Handler(void) {
// Our RTC is 32 bits and we're clocking it at 16.384khz which is 16 (2 ** 4) subticks per
// tick.
overflowed_ticks += (1L << (32 - 4));
}
#ifdef SAM_D5X_E5X
} else if (intflag & RTC_MODE0_INTFLAG_PER2) {
if (intflag & RTC_MODE0_INTFLAG_PER2) {
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_PER2;
// Do things common to all ports when the tick occurs
supervisor_tick();
}
#endif
} else if (intflag & RTC_MODE0_INTFLAG_CMP0) {
if (intflag & RTC_MODE0_INTFLAG_CMP0) {
// Clear the interrupt because we may have hit a sleep and _ticks_enabled
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
_woken_up = true;
#ifdef SAMD21
if (_ticks_enabled) {
// Do things common to all ports when the tick occurs.
@ -565,7 +577,7 @@ void port_idle_until_interrupt(void) {
}
#endif
common_hal_mcu_disable_interrupts();
if (!tud_task_event_ready() && !hold_interrupt) {
if (!tud_task_event_ready() && !hold_interrupt && !_woken_up) {
__DSB();
__WFI();
}

View File

@ -30,6 +30,7 @@
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21)
#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0)

View File

@ -30,6 +30,7 @@
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21)
#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0)

View File

@ -30,6 +30,8 @@
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO1)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21)
#define CIRCUITPY_STATUS_LED_POWER_INVERTED (1)
#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0)

View File

@ -44,6 +44,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO33) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO34) },
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER_INVERTED), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO1) },

View File

@ -30,6 +30,7 @@
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO1)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO2)
#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0)
#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n")

View File

@ -29,7 +29,6 @@
#include "py/runtime.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/rgb_led_status.h"
static bool spi_never_reset[SOC_SPI_PERIPH_NUM];

View File

@ -27,23 +27,15 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "supervisor/shared/rgb_led_status.h"
#include "py/mphal.h"
#include "components/driver/include/driver/gpio.h"
#include "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];
bool apa102_mosi_in_use;
bool apa102_sck_in_use;
STATIC void floating_gpio_reset(gpio_num_t pin_number) {
// This is the same as gpio_reset_pin(), but without the pullup.
// Note that gpio_config resets the iomatrix to GPIO_FUNC as well.
@ -78,14 +70,6 @@ void reset_pin_number(gpio_num_t pin_number) {
in_use[pin_number / 32] &= ~(1 << pin_number % 32);
floating_gpio_reset(pin_number);
#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) {
@ -106,19 +90,10 @@ 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) {
@ -126,12 +101,6 @@ void common_hal_mcu_pin_claim(const mcu_pin_obj_t *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;
uint32_t mask = 1 << (pin_number % 32);
return (in_use[offset] & mask) == 0;

View File

@ -31,13 +31,6 @@
#include "peripherals/pins.h"
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

@ -27,15 +27,6 @@
*/
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/rgb_led_status.h"
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
bool apa102_sck_in_use;
bool apa102_mosi_in_use;
#endif
STATIC bool claimed_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT];
STATIC bool never_reset_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT];
@ -54,14 +45,6 @@ void reset_all_pins(void) {
IOMUXC->SW_PAD_CTL_PAD[i] = ((mcu_pin_obj_t *)(mcu_pin_globals.map.table[i].value))->pad_reset;
}
}
#ifdef MICROPY_HW_NEOPIXEL
neopixel_in_use = false;
#endif
#ifdef MICROPY_HW_APA102_MOSI
apa102_sck_in_use = false;
apa102_mosi_in_use = false;
#endif
}
// Since i.MX pins need extra register and reset information to reset properly,
@ -74,25 +57,6 @@ void common_hal_reset_pin(const mcu_pin_obj_t *pin) {
claimed_pins[pin->mux_idx] = false;
*(uint32_t *)pin->mux_reg = pin->mux_reset;
*(uint32_t *)pin->cfg_reg = pin->pad_reset;
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
neopixel_in_use = false;
rgb_led_status_init();
return;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin->mux_idx == MICROPY_HW_APA102_MOSI->mux_idx ||
pin->mux_idx == MICROPY_HW_APA102_SCK->mux_idx) {
apa102_mosi_in_use = apa102_mosi_in_use && pin->mux_idx != MICROPY_HW_APA102_MOSI->mux_idx;
apa102_sck_in_use = apa102_sck_in_use && pin->mux_idx != MICROPY_HW_APA102_SCK->mux_idx;
if (!apa102_sck_in_use && !apa102_mosi_in_use) {
rgb_led_status_init();
}
return;
}
#endif
}
void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) {
@ -100,20 +64,6 @@ void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) {
}
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
return !neopixel_in_use;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
return !apa102_mosi_in_use;
}
if (pin == MICROPY_HW_APA102_SCK) {
return !apa102_sck_in_use;
}
#endif
return !claimed_pins[pin->mux_idx];
}
@ -123,20 +73,6 @@ uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t *pin) {
void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) {
claimed_pins[pin->mux_idx] = true;
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
neopixel_in_use = true;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
apa102_mosi_in_use = true;
}
if (pin == MICROPY_HW_APA102_SCK) {
apa102_sck_in_use = true;
}
#endif
}
void claim_pin(const mcu_pin_obj_t *pin) {

View File

@ -32,14 +32,6 @@
#include "pins.h"
#ifdef MICROPY_HW_NEOPIXEL
extern bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
extern bool apa102_sck_in_use;
extern bool apa102_mosi_in_use;
#endif
void reset_all_pins(void);
void claim_pin(const mcu_pin_obj_t *pin);

View File

@ -31,9 +31,9 @@
#define MICROPY_HW_MCU_NAME "nRF52840"
// 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 CIRCUITPY_RGB_STATUS_R (&pin_P0_30)
#define CIRCUITPY_RGB_STATUS_G (&pin_P0_29)
#define CIRCUITPY_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

@ -32,10 +32,10 @@
#define MICROPY_HW_LED_STATUS (&pin_P1_07)
#define CP_RGB_STATUS_INVERTED_PWM
#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 CIRCUITPY_RGB_STATUS_INVERTED_PWM
#define CIRCUITPY_RGB_STATUS_R (&pin_P0_30)
#define CIRCUITPY_RGB_STATUS_G (&pin_P0_29)
#define CIRCUITPY_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

@ -32,9 +32,9 @@
#define MICROPY_HW_LED_STATUS (&pin_P1_12)
#define CP_RGB_STATUS_R (&pin_P0_13)
#define CP_RGB_STATUS_G (&pin_P0_14)
#define CP_RGB_STATUS_B (&pin_P0_15)
#define CIRCUITPY_RGB_STATUS_R (&pin_P0_13)
#define CIRCUITPY_RGB_STATUS_G (&pin_P0_14)
#define CIRCUITPY_RGB_STATUS_B (&pin_P0_15)
#if QSPI_FLASH_FILESYSTEM
#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20)

View File

@ -31,15 +31,7 @@
#include "py/mphal.h"
#include "nrf/pins.h"
#include "supervisor/shared/rgb_led_status.h"
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
bool apa102_sck_in_use;
bool apa102_mosi_in_use;
#endif
#ifdef SPEAKER_ENABLE_PIN
bool speaker_enable_in_use;
#endif
@ -73,14 +65,6 @@ void reset_all_pins(void) {
nrf_gpio_cfg_default(pin);
}
#ifdef MICROPY_HW_NEOPIXEL
neopixel_in_use = false;
#endif
#ifdef MICROPY_HW_APA102_MOSI
apa102_sck_in_use = false;
apa102_mosi_in_use = false;
#endif
// After configuring SWD because it may be shared.
reset_speaker_enable_pin();
}
@ -95,25 +79,6 @@ void reset_pin_number(uint8_t pin_number) {
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) {
neopixel_in_use = false;
rgb_led_status_init();
return;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin_number == MICROPY_HW_APA102_MOSI->number ||
pin_number == MICROPY_HW_APA102_SCK->number) {
apa102_mosi_in_use = apa102_mosi_in_use && pin_number != MICROPY_HW_APA102_MOSI->number;
apa102_sck_in_use = apa102_sck_in_use && pin_number != MICROPY_HW_APA102_SCK->number;
if (!apa102_sck_in_use && !apa102_mosi_in_use) {
rgb_led_status_init();
}
return;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin_number == SPEAKER_ENABLE_PIN->number) {
reset_speaker_enable_pin();
@ -144,20 +109,6 @@ void claim_pin(const mcu_pin_obj_t *pin) {
// Set bit in claimed_pins bitmask.
claimed_pins[nrf_pin_port(pin->number)] |= 1 << nrf_relative_pin_number(pin->number);
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
neopixel_in_use = true;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
apa102_mosi_in_use = true;
}
if (pin == MICROPY_HW_APA102_SCK) {
apa102_sck_in_use = true;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin == SPEAKER_ENABLE_PIN) {
speaker_enable_in_use = true;
@ -171,20 +122,6 @@ bool pin_number_is_free(uint8_t pin_number) {
}
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
return !neopixel_in_use;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
return !apa102_mosi_in_use;
}
if (pin == MICROPY_HW_APA102_SCK) {
return !apa102_sck_in_use;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin == SPEAKER_ENABLE_PIN) {
return !speaker_enable_in_use;

View File

@ -31,14 +31,6 @@
#include "peripherals/nrf/pins.h"
#ifdef MICROPY_HW_NEOPIXEL
extern bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
extern bool apa102_sck_in_use;
extern bool apa102_mosi_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

@ -26,14 +26,7 @@
#include "supervisor/board.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
void board_init(void) {
common_hal_never_reset_pin(&pin_GPIO16);
gpio_init(16);
gpio_set_dir(16, GPIO_OUT);
gpio_put(16, true);
}
bool board_requests_safe_mode(void) {

View File

@ -2,6 +2,7 @@
#define MICROPY_HW_MCU_NAME "rp2040"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO17)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO16)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2)

View File

@ -26,14 +26,7 @@
#include "supervisor/board.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
void board_init(void) {
common_hal_never_reset_pin(&pin_GPIO11);
gpio_init(11);
gpio_set_dir(11, GPIO_OUT);
gpio_put(11, true);
}
bool board_requests_safe_mode(void) {

View File

@ -2,6 +2,7 @@
#define MICROPY_HW_MCU_NAME "rp2040"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO12)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO11)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO25)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO24)

View File

@ -0,0 +1,37 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 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 "supervisor/board.h"
void board_init(void) {
}
bool board_requests_safe_mode(void) {
return false;
}
void reset_board(void) {
}

View File

@ -0,0 +1,14 @@
#define MICROPY_HW_BOARD_NAME "Arduino Nano RP2040 Connect"
#define MICROPY_HW_MCU_NAME "rp2040"
// #define MICROPY_HW_LED_STATUS (&pin_GPIO6)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO12)
#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6)
#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO7)
#define DEFAULT_SPI_BUS_MISO (&pin_GPIO4)
#define DEFAULT_UART_BUS_RX (&pin_GPIO1)
#define DEFAULT_UART_BUS_TX (&pin_GPIO0)

View File

@ -0,0 +1,12 @@
USB_VID = 0x239A
USB_PID = 0x00CF
USB_PRODUCT = "Arduino Nano RP2040 Connect"
USB_MANUFACTURER = "Arduino"
CHIP_VARIANT = RP2040
CHIP_FAMILY = rp2
EXTERNAL_FLASH_DEVICES = "AT25SF128A"
CIRCUITPY__EVE = 1

View File

@ -0,0 +1,63 @@
#include "shared-bindings/board/__init__.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_GPIO2) }, // ESP32 FW boot state pin (confusingly named GPIO0)
{ MP_ROM_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_GPIO9) },
// Primary SPI
{ MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO5) },
// Secondary SPI connected to ESP32
{ MP_ROM_QSTR(MP_QSTR_MISO1), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_MOSI1), MP_ROM_PTR(&pin_GPIO11) },
{ MP_ROM_QSTR(MP_QSTR_SCK1), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_CS1), MP_ROM_PTR(&pin_GPIO9) },
// Primary I2C
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO12) }, // Note these are not actually analog!
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO12) },
{ MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO13) }, // Note these are not actually analog!
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO15) },
{ MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO19) },
{ MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO21) },
// PDM onboard mic
{ MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_GPIO22) },
{ MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_GPIO23) },
// Sensor IRQ
{ MP_ROM_QSTR(MP_QSTR_INT1), MP_ROM_PTR(&pin_GPIO24) },
{ MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO25) },
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);

View File

@ -14,9 +14,10 @@
#define MICROPY_HW_BACKLIGHT (&pin_GPIO12)
#define MICROPY_HW_VBUS_DETECT (&pin_GPIO2)
#define MICROPY_HW_LED_G (&pin_GPIO13)
#define MICROPY_HW_LED_R (&pin_GPIO14)
#define MICROPY_HW_LED_B (&pin_GPIO15)
#define CIRCUITPY_RGB_STATUS_INVERTED_PWM
#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO13)
#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO14)
#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO15)
#define MICROPY_HW_SW_Y (&pin_GPIO16)
#define MICROPY_HW_SW_X (&pin_GPIO17)

View File

@ -1,9 +1,10 @@
#define MICROPY_HW_BOARD_NAME "Pimoroni Tiny 2040"
#define MICROPY_HW_MCU_NAME "rp2040"
#define MICROPY_HW_LED_R (&pin_GPIO18)
#define MICROPY_HW_LED_G (&pin_GPIO19)
#define MICROPY_HW_LED_B (&pin_GPIO20)
#define CIRCUITPY_RGB_STATUS_INVERTED_PWM
#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO18)
#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO19)
#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO20)
#define MICROPY_HW_USER_SW (&pin_GPIO23)

View File

@ -32,7 +32,6 @@
#include "supervisor/board.h"
#include "common-hal/microcontroller/Pin.h"
#include "supervisor/shared/rgb_led_status.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "src/rp2_common/hardware_dma/include/hardware/dma.h"

View File

@ -29,21 +29,8 @@
#include "common-hal/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/rgb_led_status.h"
#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
bool apa102_sck_in_use;
bool apa102_mosi_in_use;
#endif
#ifdef SPEAKER_ENABLE_PIN
bool speaker_enable_in_use;
#endif
STATIC uint32_t never_reset_pins;
void reset_all_pins(void) {
@ -77,31 +64,6 @@ void reset_pin_number(uint8_t pin_number) {
PADS_BANK0_GPIO0_PUE_BITS |
PADS_BANK0_GPIO0_PDE_BITS);
hw_set_bits(&padsbank0_hw->io[pin_number], PADS_BANK0_GPIO0_OD_BITS);
#ifdef MICROPY_HW_NEOPIXEL
if (pin_number == MICROPY_HW_NEOPIXEL->number) {
neopixel_in_use = false;
rgb_led_status_init();
return;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin_number == MICROPY_HW_APA102_MOSI->number ||
pin_number == MICROPY_HW_APA102_SCK->number) {
apa102_mosi_in_use = apa102_mosi_in_use && pin_number != MICROPY_HW_APA102_MOSI->number;
apa102_sck_in_use = apa102_sck_in_use && pin_number != MICROPY_HW_APA102_SCK->number;
if (!apa102_sck_in_use && !apa102_mosi_in_use) {
rgb_led_status_init();
}
return;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin_number == SPEAKER_ENABLE_PIN->number) {
speaker_enable_in_use = false;
}
#endif
}
void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) {
@ -113,25 +75,7 @@ void common_hal_reset_pin(const mcu_pin_obj_t *pin) {
}
void claim_pin(const mcu_pin_obj_t *pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
neopixel_in_use = true;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
apa102_mosi_in_use = true;
}
if (pin == MICROPY_HW_APA102_SCK) {
apa102_sck_in_use = true;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin == SPEAKER_ENABLE_PIN) {
speaker_enable_in_use = true;
}
#endif
// Nothing to do because all changes will set the GPIO settings.
}
bool pin_number_is_free(uint8_t pin_number) {
@ -145,26 +89,6 @@ bool pin_number_is_free(uint8_t pin_number) {
}
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
return !neopixel_in_use;
}
#endif
#ifdef MICROPY_HW_APA102_MOSI
if (pin == MICROPY_HW_APA102_MOSI) {
return !apa102_mosi_in_use;
}
if (pin == MICROPY_HW_APA102_SCK) {
return !apa102_sck_in_use;
}
#endif
#ifdef SPEAKER_ENABLE_PIN
if (pin == SPEAKER_ENABLE_PIN) {
return !speaker_enable_in_use;
}
#endif
return pin_number_is_free(pin->number);
}

View File

@ -34,14 +34,6 @@
#include "peripherals/pins.h"
#ifdef MICROPY_HW_NEOPIXEL
extern bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
extern bool apa102_sck_in_use;
extern bool apa102_mosi_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

@ -62,7 +62,7 @@ void alarm_set_wakeup_reason(stm_sleep_source_t reason) {
true_deep_wake_reason = reason;
}
STATIC stm_sleep_source_t _get_wakeup_cause(void) {
stm_sleep_source_t alarm_get_wakeup_cause(void) {
// If in light/fake sleep, check modules
if (alarm_pin_pinalarm_woke_this_cycle()) {
return STM_WAKEUP_GPIO;
@ -71,20 +71,20 @@ STATIC stm_sleep_source_t _get_wakeup_cause(void) {
return STM_WAKEUP_RTC;
}
// Check to see if we woke from deep sleep (reason set in port_init)
if (true_deep_wake_reason) {
if (true_deep_wake_reason != STM_WAKEUP_UNDEF) {
return true_deep_wake_reason;
}
return STM_WAKEUP_UNDEF;
}
bool common_hal_alarm_woken_from_sleep(void) {
return _get_wakeup_cause() != STM_WAKEUP_UNDEF;
return alarm_get_wakeup_cause() != STM_WAKEUP_UNDEF;
}
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
// If woken from deep sleep, create a copy alarm similar to what would have
// been passed in originally. Otherwise, just return none
stm_sleep_source_t cause = _get_wakeup_cause();
stm_sleep_source_t cause = alarm_get_wakeup_cause();
switch (cause) {
case STM_WAKEUP_RTC: {
return alarm_time_timealarm_create_wakeup_alarm();
@ -115,7 +115,7 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
RUN_BACKGROUND_TASKS;
// Detect if interrupt was alarm or ctrl-C interrupt.
if (common_hal_alarm_woken_from_sleep()) {
stm_sleep_source_t cause = _get_wakeup_cause();
stm_sleep_source_t cause = alarm_get_wakeup_cause();
switch (cause) {
case STM_WAKEUP_RTC: {
wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms);
@ -149,6 +149,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
}
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
alarm_set_wakeup_reason(STM_WAKEUP_UNDEF);
alarm_pin_pinalarm_prepare_for_deep_sleep();
alarm_time_timealarm_prepare_for_deep_sleep();
port_disable_tick();
@ -175,6 +176,8 @@ void common_hal_alarm_pretending_deep_sleep(void) {
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
alarm_set_wakeup_reason(STM_WAKEUP_UNDEF);
port_idle_until_interrupt();
}

View File

@ -40,6 +40,7 @@ typedef enum {
#define STM_ALARM_FLAG (RTC->BKP0R)
extern void alarm_set_wakeup_reason(stm_sleep_source_t reason);
stm_sleep_source_t alarm_get_wakeup_cause(void);
extern void alarm_reset(void);
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM__INIT__H

View File

@ -27,19 +27,10 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "supervisor/shared/rgb_led_status.h"
#include "py/mphal.h"
#include "pins.h"
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
bool apa102_sck_in_use;
bool apa102_mosi_in_use;
#endif
#if defined(TFBGA216)
GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK};
#elif defined(LQFP144)
@ -66,14 +57,6 @@ void reset_all_pins(void) {
for (uint8_t i = 0; i < GPIO_PORT_COUNT; i++) {
HAL_GPIO_DeInit(ports[i], ~never_reset_pins[i]);
}
#ifdef MICROPY_HW_NEOPIXEL
neopixel_in_use = false;
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
apa102_sck_in_use = false;
apa102_mosi_in_use = false;
#endif
}
// Mark pin as free and return it to a quiescent state.
@ -89,25 +72,6 @@ void reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
claimed_pins[pin_port] &= ~(1 << pin_number);
never_reset_pins[pin_port] &= ~(1 << pin_number);
HAL_GPIO_DeInit(ports[pin_port], 1 << pin_number);
#ifdef MICROPY_HW_NEOPIXEL
if (pin_port == MICROPY_HW_NEOPIXEL->port && pin_number == MICROPY_HW_NEOPIXEL->number) {
neopixel_in_use = false;
rgb_led_status_init();
return;
}
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
if (
(pin_port == MICROPY_HW_APA102_MOSI->port && pin_number == MICROPY_HW_APA102_MOSI->number)
|| (pin_port == MICROPY_HW_APA102_SCK->port && pin_number == MICROPY_HW_APA102_MOSI->number)
) {
apa102_mosi_in_use = false;
apa102_sck_in_use = false;
rgb_led_status_init();
return;
}
#endif
}
void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number) {
@ -140,20 +104,6 @@ bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number) {
}
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) {
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
return !neopixel_in_use;
}
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
if (pin == MICROPY_HW_APA102_MOSI) {
return !apa102_mosi_in_use;
}
if (pin == MICROPY_HW_APA102_SCK) {
return !apa102_sck_in_use;
}
#endif
return pin_number_is_free(pin->port, pin->number);
}
@ -171,19 +121,6 @@ uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t *pin) {
void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) {
claim_pin(pin->port, pin->number);
#ifdef MICROPY_HW_NEOPIXEL
if (pin == MICROPY_HW_NEOPIXEL) {
neopixel_in_use = true;
}
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
if (pin == MICROPY_HW_APA102_MOSI) {
apa102_mosi_in_use = true;
}
if (pin == MICROPY_HW_APA102_SCK) {
apa102_sck_in_use = true;
}
#endif
}
void common_hal_mcu_pin_reset_number(uint8_t pin_no) {

View File

@ -31,14 +31,6 @@
#include "peripherals/pins.h"
#ifdef MICROPY_HW_NEOPIXEL
extern bool neopixel_in_use;
#endif
#ifdef MICROPY_HW_APA102_MOSI
extern bool apa102_sck_in_use;
extern bool apa102_mosi_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

@ -27,6 +27,9 @@
#include <math.h>
#include "py/runtime.h"
#if CIRCUITPY_ALARM
#include "common-hal/alarm/__init__.h"
#endif
#include "common-hal/microcontroller/Processor.h"
#include "shared-bindings/microcontroller/ResetReason.h"
#include "supervisor/shared/translate.h"
@ -143,5 +146,10 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
}
mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
#if CIRCUITPY_ALARM
if (alarm_get_wakeup_cause() != STM_WAKEUP_UNDEF) {
return RESET_REASON_DEEP_SLEEP_ALARM;
}
#endif
return RESET_REASON_UNKNOWN;
}

View File

@ -991,6 +991,10 @@ void supervisor_run_background_tasks_if_tick(void);
#define CIRCUITPY_PROCESSOR_COUNT (1)
#endif
#ifndef CIRCUITPY_STATUS_LED_POWER_INVERTED
#define CIRCUITPY_STATUS_LED_POWER_INVERTED (0)
#endif
#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
#define CIRCUITPY_VERBOSE_BLE 0

View File

@ -826,7 +826,7 @@ STATIC bool mp_raw_code_has_native(mp_raw_code_t *rc) {
void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print) {
// header contains:
// byte 'M'
// byte 'C'
// byte version
// byte feature flags
// byte number of bits in a small int

View File

@ -60,12 +60,13 @@ STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t
uint8_t *buf = NULL;
if (mp_obj_get_int_maybe(address, (mp_int_t *)&value)) {
// We're done.
buf = (uint8_t *)value;
buf = (uint8_t *)&value;
} else if (mp_obj_is_str(address)) {
GET_STR_DATA_LEN(address, str_data, str_len);
if (!ipaddress_parse_ipv4address((const char *)str_data, str_len, &value)) {
mp_raise_ValueError(translate("Not a valid IP string"));
}
buf = (uint8_t *)&value;
} else {
mp_buffer_info_t buf_info;
if (mp_get_buffer(address, &buf_info, MP_BUFFER_READ)) {

View File

@ -76,7 +76,7 @@ bool ipaddress_parse_ipv4address(const char *str_data, size_t str_len, uint32_t
return true;
}
//| def ip_address(obj: Union[int]) -> IPv4Address:
//| def ip_address(obj: Union[int, str]) -> IPv4Address:
//| """Return a corresponding IP address object or raise ValueError if not possible."""
//| ...
//|
@ -91,7 +91,7 @@ STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) {
mp_raise_ValueError(translate("Not a valid IP string"));
}
} else {
mp_raise_ValueError(translate("Only raw int supported for ip"));
mp_raise_ValueError(translate("Only int or string supported for ip"));
}
return common_hal_ipaddress_new_ipv4address(value);

View File

@ -29,7 +29,7 @@
#include "lib/utils/interrupt_char.h"
#include "supervisor/shared/autoreload.h"
#include "supervisor/shared/rgb_led_status.h"
#include "supervisor/shared/status_leds.h"
#include "supervisor/shared/stack.h"
#include "supervisor/shared/translate.h"
#include "supervisor/shared/workflow.h"
@ -79,7 +79,7 @@ STATIC mp_obj_t supervisor_set_rgb_status_brightness(mp_obj_t lvl) {
if (brightness_int < 0 || brightness_int > 255) {
mp_raise_ValueError(translate("Brightness must be between 0 and 255"));
}
set_rgb_status_brightness((uint8_t)brightness_int);
set_status_brightness((uint8_t)brightness_int);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_rgb_status_brightness_obj, supervisor_set_rgb_status_brightness);

View File

@ -143,7 +143,9 @@ void reset_board_busses(void) {
}
}
#endif
// make sure I2C lock is not held over a soft reset
if (i2c_singleton != NULL) {
common_hal_busio_i2c_unlock(i2c_singleton);
if (!display_using_i2c) {
common_hal_busio_i2c_deinit(i2c_singleton);
i2c_singleton = NULL;

View File

@ -409,7 +409,7 @@ void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t *self) {
gc_collect_ptr((void *)self->stop_sequence);
}
bool maybe_refresh_epaperdisplay(void) {
size_t maybe_refresh_epaperdisplay(void) {
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].epaper_display.base.type != &displayio_epaperdisplay_type ||
displays[i].epaper_display.core.current_group != &circuitpython_splash) {
@ -417,11 +417,16 @@ bool maybe_refresh_epaperdisplay(void) {
continue;
}
displayio_epaperdisplay_obj_t *display = &displays[i].epaper_display;
if (common_hal_displayio_epaperdisplay_get_time_to_refresh(display) != 0) {
return false;
size_t time_to_refresh = common_hal_displayio_epaperdisplay_get_time_to_refresh(display);
if (time_to_refresh > 0) {
return time_to_refresh;
}
return common_hal_displayio_epaperdisplay_refresh(display);
if (common_hal_displayio_epaperdisplay_refresh(display)) {
return 0;
}
// If we could refresh but it failed, then we want to retry.
return 1;
}
// Return true if no ePaper displays are available to pretend it was updated.
return true;
// Return 0 if no ePaper displays are available to pretend it was updated.
return 0;
}

View File

@ -61,7 +61,7 @@ typedef struct {
void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t *self);
void release_epaperdisplay(displayio_epaperdisplay_obj_t *self);
bool maybe_refresh_epaperdisplay(void);
size_t maybe_refresh_epaperdisplay(void);
void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t *self);

View File

@ -79,7 +79,7 @@ static const uint8_t usb_hid_descriptor_template[] = {
static supervisor_allocation *hid_report_descriptor_allocation;
static usb_hid_device_obj_t hid_devices[MAX_HID_DEVICES];
// If 0, USB HID is disabled.
static mp_int_t hid_devices_num;
static mp_int_t num_hid_devices;
// This tuple is store in usb_hid.devices.
static mp_obj_tuple_t *hid_devices_tuple;
@ -97,7 +97,7 @@ static mp_obj_tuple_t default_hid_devices_tuple = {
};
bool usb_hid_enabled(void) {
return hid_devices_num > 0;
return num_hid_devices > 0;
}
void usb_hid_set_defaults(void) {
@ -140,13 +140,13 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *desc
// Make up a fresh tuple containing the device objects saved in the static
// devices table. Save the tuple in usb_hid.devices.
static void usb_hid_set_devices_from_hid_devices(void) {
mp_obj_t tuple_items[hid_devices_num];
for (mp_int_t i = 0; i < hid_devices_num; i++) {
mp_obj_t tuple_items[num_hid_devices];
for (mp_int_t i = 0; i < num_hid_devices; i++) {
tuple_items[i] = &hid_devices[i];
}
// Remember tuple for gc purposes.
hid_devices_tuple = mp_obj_new_tuple(hid_devices_num, tuple_items);
hid_devices_tuple = mp_obj_new_tuple(num_hid_devices, tuple_items);
usb_hid_set_devices(hid_devices_tuple);
}
@ -160,13 +160,15 @@ bool common_hal_usb_hid_enable(const mp_obj_t devices) {
return false;
}
hid_devices_num = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(devices));
if (hid_devices_num > MAX_HID_DEVICES) {
const mp_int_t num_devices = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(devices));
if (num_devices > MAX_HID_DEVICES) {
mp_raise_ValueError_varg(translate("No more than %d HID devices allowed"), MAX_HID_DEVICES);
}
num_hid_devices = num_devices;
// Remember the devices in static storage so they live across VMs.
for (mp_int_t i = 0; i < hid_devices_num; i++) {
for (mp_int_t i = 0; i < num_hid_devices; i++) {
// devices has already been validated to contain only usb_hid_device_obj_t objects.
usb_hid_device_obj_t *device =
MP_OBJ_TO_PTR(mp_obj_subscr(devices, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL));
@ -183,7 +185,7 @@ void usb_hid_setup_devices(void) {
usb_hid_set_devices_from_hid_devices();
// Create report buffers on the heap.
for (mp_int_t i = 0; i < hid_devices_num; i++) {
for (mp_int_t i = 0; i < num_hid_devices; i++) {
usb_hid_device_create_report_buffers(&hid_devices[i]);
}
}
@ -191,12 +193,12 @@ void usb_hid_setup_devices(void) {
// Total length of the report descriptor, with all configured devices.
size_t usb_hid_report_descriptor_length(void) {
size_t total_hid_report_descriptor_length = 0;
for (mp_int_t i = 0; i < hid_devices_num; i++) {
for (mp_int_t i = 0; i < num_hid_devices; i++) {
total_hid_report_descriptor_length += hid_devices[i].report_descriptor_length;
}
// Don't need space for a report id if there's only one device.
if (hid_devices_num == 1) {
if (num_hid_devices == 1) {
total_hid_report_descriptor_length -= 2;
}
return total_hid_report_descriptor_length;
@ -210,10 +212,10 @@ void usb_hid_build_report_descriptor(uint8_t *report_descriptor_space, size_t re
uint8_t *report_descriptor_start = report_descriptor_space;
for (mp_int_t i = 0; i < hid_devices_num; i++) {
for (mp_int_t i = 0; i < num_hid_devices; i++) {
usb_hid_device_obj_t *device = &hid_devices[i];
// Copy the report descriptor for this device.
if (hid_devices_num == 1) {
if (num_hid_devices == 1) {
// There's only one device, so it shouldn't have a report ID.
// Copy the descriptor, but splice out the report id indicator and value (2 bytes).
memcpy(report_descriptor_start, device->report_descriptor, device->report_id_index - 1);
@ -258,9 +260,10 @@ void usb_hid_gc_collect(void) {
gc_collect_ptr(hid_devices_tuple);
// Mark possible heap pointers in the static device list as in use.
for (mp_int_t i = 0; i < hid_devices_num; i++) {
for (mp_int_t i = 0; i < num_hid_devices; i++) {
// Cast away the const for .report_descriptor. It could be in flash or on the heap.
// The const is necessary to have the bytes be placed only in flash.
// Constant report descriptors must be const so that they are used directly from flash
// and not copied into RAM.
gc_collect_ptr((void *)hid_devices[i].report_descriptor);
gc_collect_ptr(hid_devices[i].in_report_buffer);
gc_collect_ptr(hid_devices[i].out_report_buffer);
@ -268,7 +271,7 @@ void usb_hid_gc_collect(void) {
}
usb_hid_device_obj_t *usb_hid_get_device_with_report_id(uint8_t report_id) {
for (uint8_t i = 0; i < hid_devices_num; i++) {
for (uint8_t i = 0; i < num_hid_devices; i++) {
usb_hid_device_obj_t *device = &hid_devices[i];
if (device->report_id == report_id) {
return &hid_devices[i];

View File

@ -39,7 +39,6 @@
#include "lib/oofatfs/ff.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "supervisor/memory.h"
#include "supervisor/shared/rgb_led_status.h"
#define NO_SECTOR_LOADED 0xFFFFFFFF
@ -467,7 +466,6 @@ static void spi_flash_flush_keep_cache(bool keep_cache) {
#ifdef MICROPY_HW_LED_MSC
port_pin_set_output_level(MICROPY_HW_LED_MSC, true);
#endif
temp_status_color(ACTIVE_WRITE);
// If we've cached to the flash itself flush from there.
if (MP_STATE_VM(flash_ram_cache) == NULL) {
flush_scratch_flash();
@ -475,7 +473,6 @@ static void spi_flash_flush_keep_cache(bool keep_cache) {
flush_ram_cache(keep_cache);
}
current_sector = NO_SECTOR_LOADED;
clear_temp_status();
#ifdef MICROPY_HW_LED_MSC
port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
#endif

View File

@ -14,28 +14,17 @@
#define PURPLE COLOR(INTENSITY, 0, INTENSITY)
#define WHITE COLOR(INTENSITY, INTENSITY, INTENSITY)
#define BOOT_RUNNING BLUE
#define MAIN_RUNNING GREEN
#define SAFE_MODE YELLOW
#define ALL_DONE GREEN
#define EXCEPTION RED
#define SAFE_MODE YELLOW
#define REPL_RUNNING WHITE
#define ACTIVE_WRITE 0x200000
#define ALL_DONE_BLINKS 1
#define EXCEPTION_BLINKS 2
#define SAFE_MODE_BLINKS 3
#define ALL_GOOD_CYCLE_MS 2000u
#define OFF_ON_RATIO 3
#define LINE_NUMBER_TOGGLE_LENGTH 300u
#define EXCEPTION_TYPE_LENGTH_MS 1000u
#define LED_SLEEP_TIME_MS 5000u
#define THOUSANDS WHITE
#define HUNDREDS BLUE
#define TENS YELLOW
#define ONES CYAN
#define INDENTATION_ERROR GREEN
#define SYNTAX_ERROR CYAN
#define NAME_ERROR WHITE
#define OS_ERROR ORANGE
#define VALUE_ERROR PURPLE
#define MPY_ERROR BLUE
#define OTHER_ERROR YELLOW
#define BLINK_TIME_MS 100u

View File

@ -1,486 +0,0 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "mphalport.h"
#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;
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/neopixel_write/__init__.h"
static uint8_t status_neopixel_color[3];
static digitalio_digitalinout_obj_t status_neopixel;
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
uint8_t rgb_status_brightness = 50;
#define APA102_BUFFER_LENGTH 12
static uint8_t status_apa102_color[APA102_BUFFER_LENGTH] = {0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0xff};
#if CIRCUITPY_BITBANG_APA102
#include "shared-bindings/bitbangio/SPI.h"
static bitbangio_spi_obj_t status_apa102 = {
.base = {
.type = &bitbangio_spi_type,
},
};
#else
#include "shared-bindings/busio/SPI.h"
busio_spi_obj_t status_apa102 = {
.base = {
.type = &busio_spi_type,
},
};
#endif
#endif
#if defined(CP_RGB_STATUS_R) || defined(CP_RGB_STATUS_G) || defined(CP_RGB_STATUS_B)
#define CP_RGB_STATUS_LED
#include "shared-bindings/pwmio/PWMOut.h"
#include "shared-bindings/microcontroller/Pin.h"
pwmio_pwmout_obj_t rgb_status_r = {
.base = {
.type = &pwmio_pwmout_type,
},
};
pwmio_pwmout_obj_t rgb_status_g = {
.base = {
.type = &pwmio_pwmout_type,
},
};
pwmio_pwmout_obj_t rgb_status_b = {
.base = {
.type = &pwmio_pwmout_type,
},
};
uint8_t rgb_status_brightness = 0xFF;
uint16_t status_rgb_color[3] = {
0 /* red */, 0 /* green */, 0 /* blue */
};
#endif
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
static uint32_t current_status_color = 0;
#endif
static bool rgb_led_status_init_in_progress = false;
void rgb_led_status_init() {
if (rgb_led_status_init_in_progress) {
// Avoid recursion.
return;
}
rgb_led_status_init_in_progress = true;
#ifdef MICROPY_HW_NEOPIXEL
common_hal_digitalio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL);
// Pretend we aren't using the pins. digitalio.DigitalInOut
// will mark them as used.
neopixel_in_use = false;
common_hal_digitalio_digitalinout_switch_to_output(&status_neopixel, false, DRIVE_MODE_PUSH_PULL);
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_construct(&status_apa102,
MICROPY_HW_APA102_SCK,
MICROPY_HW_APA102_MOSI,
NULL);
#else
if (!common_hal_busio_spi_deinited(&status_apa102)) {
// This may call us recursively if common_hal_reset_pin() is called,
// The rgb_led_status_init_in_progress guard will prevent further recursion.
common_hal_busio_spi_deinit(&status_apa102);
}
common_hal_busio_spi_construct(&status_apa102,
MICROPY_HW_APA102_SCK,
MICROPY_HW_APA102_MOSI,
NULL);
common_hal_busio_spi_never_reset(&status_apa102);
#endif
// Pretend we aren't using the pins. bitbangio.SPI will
// mark them as used.
apa102_mosi_in_use = false;
apa102_sck_in_use = false;
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_try_lock(&status_apa102);
// Use 1MHz for clock rate. Some APA102's are spec'd 800kHz-1200kHz,
// though many can run much faster. bitbang will probably run slower.
shared_module_bitbangio_spi_configure(&status_apa102, 1000000, 0, 0, 8);
#else
common_hal_busio_spi_try_lock(&status_apa102);
common_hal_busio_spi_configure(&status_apa102, 1000000, 0, 0, 8);
#endif
#endif
#if defined(CP_RGB_STATUS_LED)
if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_R)) {
pwmout_result_t red_result = common_hal_pwmio_pwmout_construct(&rgb_status_r, CP_RGB_STATUS_R, 0, 50000, false);
if (PWMOUT_OK == red_result) {
common_hal_pwmio_pwmout_never_reset(&rgb_status_r);
}
}
if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_G)) {
pwmout_result_t green_result = common_hal_pwmio_pwmout_construct(&rgb_status_g, CP_RGB_STATUS_G, 0, 50000, false);
if (PWMOUT_OK == green_result) {
common_hal_pwmio_pwmout_never_reset(&rgb_status_g);
}
}
if (common_hal_mcu_pin_is_free(CP_RGB_STATUS_B)) {
pwmout_result_t blue_result = common_hal_pwmio_pwmout_construct(&rgb_status_b, CP_RGB_STATUS_B, 0, 50000, false);
if (PWMOUT_OK == blue_result) {
common_hal_pwmio_pwmout_never_reset(&rgb_status_b);
}
}
#endif
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
// Force a write of the current status color.
uint32_t rgb = current_status_color;
current_status_color = 0x1000000; // Not a valid color
new_status_color(rgb);
#endif
rgb_led_status_init_in_progress = false;
}
void reset_status_led() {
#ifdef MICROPY_HW_NEOPIXEL
common_hal_reset_pin(MICROPY_HW_NEOPIXEL);
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
common_hal_reset_pin(MICROPY_HW_APA102_MOSI);
common_hal_reset_pin(MICROPY_HW_APA102_SCK);
#endif
#if defined(CP_RGB_STATUS_LED)
// TODO: Support sharing status LED with user.
#endif
}
void new_status_color(uint32_t rgb) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
if (current_status_color == rgb) {
return;
}
uint32_t rgb_adjusted = color_brightness(rgb, rgb_status_brightness);
current_status_color = rgb;
#endif
#ifdef MICROPY_HW_NEOPIXEL
if (neopixel_in_use) {
return;
}
status_neopixel_color[0] = (rgb_adjusted >> 8) & 0xff;
status_neopixel_color[1] = (rgb_adjusted >> 16) & 0xff;
status_neopixel_color[2] = rgb_adjusted & 0xff;
common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3);
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
if (apa102_mosi_in_use || apa102_sck_in_use) {
return;
}
status_apa102_color[5] = rgb_adjusted & 0xff;
status_apa102_color[6] = (rgb_adjusted >> 8) & 0xff;
status_apa102_color[7] = (rgb_adjusted >> 16) & 0xff;
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH);
#else
common_hal_busio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH);
#endif
#endif
#if defined(CP_RGB_STATUS_LED)
uint8_t red_u8 = (rgb_adjusted >> 16) & 0xFF;
uint8_t green_u8 = (rgb_adjusted >> 8) & 0xFF;
uint8_t blue_u8 = rgb_adjusted & 0xFF;
#if defined(CP_RGB_STATUS_INVERTED_PWM)
status_rgb_color[0] = (1 << 16) - 1 - ((uint16_t)(red_u8 << 8) + red_u8);
status_rgb_color[1] = (1 << 16) - 1 - ((uint16_t)(green_u8 << 8) + green_u8);
status_rgb_color[2] = (1 << 16) - 1 - ((uint16_t)(blue_u8 << 8) + blue_u8);
#else
status_rgb_color[0] = (uint16_t)(red_u8 << 8) + red_u8;
status_rgb_color[1] = (uint16_t)(green_u8 << 8) + green_u8;
status_rgb_color[2] = (uint16_t)(blue_u8 << 8) + blue_u8;
#endif
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_r, status_rgb_color[0]);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_g, status_rgb_color[1]);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_b, status_rgb_color[2]);
#endif
}
void temp_status_color(uint32_t rgb) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
uint32_t rgb_adjusted = rgb;
rgb_adjusted = color_brightness(rgb, rgb_status_brightness);
#endif
#ifdef MICROPY_HW_NEOPIXEL
if (neopixel_in_use) {
return;
}
uint8_t colors[3] = {(rgb_adjusted >> 8) & 0xff, (rgb_adjusted >> 16) & 0xff, rgb_adjusted & 0xff};
common_hal_neopixel_write(&status_neopixel, colors, 3);
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
if (apa102_mosi_in_use || apa102_sck_in_use) {
return;
}
uint8_t colors[APA102_BUFFER_LENGTH] = {0, 0, 0, 0, 0xff, rgb_adjusted & 0xff, (rgb_adjusted >> 8) & 0xff, (rgb_adjusted >> 16) & 0xff, 0xff, 0xff, 0xff, 0xff};
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_write(&status_apa102, colors, APA102_BUFFER_LENGTH);
#else
common_hal_busio_spi_write(&status_apa102, colors, APA102_BUFFER_LENGTH);
#endif
#endif
#if defined(CP_RGB_STATUS_LED)
uint8_t red_u8 = (rgb_adjusted >> 16) & 0xFF;
uint8_t green_u8 = (rgb_adjusted >> 8) & 0xFF;
uint8_t blue_u8 = rgb_adjusted & 0xFF;
uint16_t temp_status_color_rgb[3] = {0};
#if defined(CP_RGB_STATUS_INVERTED_PWM)
temp_status_color_rgb[0] = (1 << 16) - 1 - ((uint16_t)(red_u8 << 8) + red_u8);
temp_status_color_rgb[1] = (1 << 16) - 1 - ((uint16_t)(green_u8 << 8) + green_u8);
temp_status_color_rgb[2] = (1 << 16) - 1 - ((uint16_t)(blue_u8 << 8) + blue_u8);
#else
temp_status_color_rgb[0] = (uint16_t)(red_u8 << 8) + red_u8;
temp_status_color_rgb[1] = (uint16_t)(green_u8 << 8) + green_u8;
temp_status_color_rgb[2] = (uint16_t)(blue_u8 << 8) + blue_u8;
#endif
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_r, temp_status_color_rgb[0]);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_g, temp_status_color_rgb[1]);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_b, temp_status_color_rgb[2]);
#endif
}
void clear_temp_status() {
#ifdef MICROPY_HW_NEOPIXEL
if (neopixel_in_use) {
return;
}
common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3);
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
if (apa102_mosi_in_use || apa102_sck_in_use) {
return;
}
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH);
#else
common_hal_busio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH);
#endif
#endif
#if defined(CP_RGB_STATUS_LED)
uint16_t red = 0;
uint16_t green = 0;
uint16_t blue = 0;
#if defined(CP_RGB_STATUS_INVERTED_PWM)
red = (1 << 16) - 1 - status_rgb_color[0];
green = (1 << 16) - 1 - status_rgb_color[1];
blue = (1 << 16) - 1 - status_rgb_color[2];
#else
red = status_rgb_color[0];
green = status_rgb_color[1];
blue = status_rgb_color[2];
#endif
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_r, red);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_g, green);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_b, blue);
#endif
}
uint32_t color_brightness(uint32_t color, uint8_t brightness) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
uint32_t result = ((color & 0xff0000) * brightness / 255) & 0xff0000;
result += ((color & 0xff00) * brightness / 255) & 0xff00;
result += ((color & 0xff) * brightness / 255) & 0xff;
return result;
#else
return color;
#endif
}
void set_rgb_status_brightness(uint8_t level) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
rgb_status_brightness = level;
uint32_t current_color = current_status_color;
// Temporarily change the current color global to force the new_status_color call to update the
// LED. Usually duplicate calls of the same color are ignored without regard to brightness
// changes.
current_status_color = 0;
new_status_color(current_color);
#endif
}
void prep_rgb_status_animation(const pyexec_result_t *result,
bool found_main,
safe_mode_t safe_mode,
rgb_status_animation_t *status) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
new_status_color(ALL_DONE);
status->pattern_start = supervisor_ticks_ms32();
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;
status->tens += status->tens > 0 ? 1 : 0;
status->hundreds = (result->exception_line / 100) % 10;
status->hundreds += status->hundreds > 0 ? 1 : 0;
status->thousands = (result->exception_line / 1000) % 10;
status->thousands += status->thousands > 0 ? 1 : 0;
status->digit_sum = status->ones + status->tens + status->hundreds + status->thousands;
uint8_t num_places = 0;
uint16_t line = result->exception_line;
for (int i = 0; i < 4; i++) {
if ((line % 10) > 0) {
num_places++;
}
line /= 10;
}
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 (!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;
} else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_NameError)) {
status->exception_color = NAME_ERROR;
} else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_OSError)) {
status->exception_color = OS_ERROR;
} else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_ValueError)) {
status->exception_color = VALUE_ERROR;
} else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_MpyError)) {
status->exception_color = MPY_ERROR;
} else {
status->exception_color = OTHER_ERROR;
}
#endif
}
bool tick_rgb_status_animation(rgb_status_animation_t *status) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
uint32_t tick_diff = supervisor_ticks_ms32() - status->pattern_start;
if (status->ok) {
// All is good. Ramp ALL_DONE up and down.
if (tick_diff > ALL_GOOD_CYCLE_MS) {
status->pattern_start = supervisor_ticks_ms32();
new_status_color(BLACK);
return true;
}
uint16_t brightness = tick_diff * 255 / (ALL_GOOD_CYCLE_MS / 2);
if (brightness > 255) {
brightness = 511 - brightness;
}
if (status->safe_mode == NO_SAFE_MODE) {
new_status_color(color_brightness(ALL_DONE, brightness));
} else {
new_status_color(color_brightness(SAFE_MODE, brightness));
}
} else {
if (tick_diff > status->total_exception_cycle) {
status->pattern_start = supervisor_ticks_ms32();
return true;
}
// First flash the file color.
if (tick_diff < EXCEPTION_TYPE_LENGTH_MS) {
if (status->found_main) {
new_status_color(MAIN_RUNNING);
} else {
new_status_color(BOOT_RUNNING);
}
// Next flash the exception color.
} else if (tick_diff < EXCEPTION_TYPE_LENGTH_MS * 2) {
new_status_color(status->exception_color);
// Finally flash the line number digits from highest to lowest.
// Zeroes will not produce a flash but can be read by the absence of
// a color from the sequence.
} else if (tick_diff < (EXCEPTION_TYPE_LENGTH_MS * 2 + LINE_NUMBER_TOGGLE_LENGTH * status->digit_sum)) {
uint32_t digit_diff = tick_diff - EXCEPTION_TYPE_LENGTH_MS * 2;
if ((digit_diff % LINE_NUMBER_TOGGLE_LENGTH) < (LINE_NUMBER_TOGGLE_LENGTH / 2)) {
new_status_color(BLACK);
} else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * status->thousands) {
if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH) {
new_status_color(BLACK);
} else {
new_status_color(THOUSANDS);
}
} else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds)) {
if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + 1)) {
new_status_color(BLACK);
} else {
new_status_color(HUNDREDS);
}
} else if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds + status->tens)) {
if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds + 1)) {
new_status_color(BLACK);
} else {
new_status_color(TENS);
}
} else {
if (digit_diff < LINE_NUMBER_TOGGLE_LENGTH * (status->thousands + status->hundreds + status->tens + 1)) {
new_status_color(BLACK);
} else {
new_status_color(ONES);
}
}
} else {
new_status_color(BLACK);
}
}
#endif
return false; // Animation is not finished.
}

View File

@ -1,81 +0,0 @@
/*
* 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.
*/
#ifndef MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H
#define MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H
#include <stdint.h>
#include <stdbool.h>
#include "lib/utils/pyexec.h"
#include "supervisor/port.h"
#include "py/mpconfig.h"
#include "rgb_led_colors.h"
#include "supervisor/shared/safe_mode.h"
// Overall, the time module must be implemented.
// To work with a DotStar, one must have MICROPY_HW_APA102_SCK and
// MICROPY_HW_APA102_MOSI defined and bitbangio.SPI or busio.SPI implemented.
// To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and
// neopixel_write implemented.
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) && !CIRCUITPY_BITBANG_APA102
#include "common-hal/busio/SPI.h"
extern busio_spi_obj_t status_apa102;
#endif
void rgb_led_status_init(void);
void reset_status_led(void);
void new_status_color(uint32_t rgb);
void temp_status_color(uint32_t rgb);
void clear_temp_status(void);
uint32_t color_brightness(uint32_t color, uint8_t brightness);
void set_rgb_status_brightness(uint8_t level);
typedef struct {
bool ok;
uint32_t pattern_start;
uint32_t total_exception_cycle;
safe_mode_t safe_mode;
uint8_t digit_sum;
uint8_t ones;
uint8_t tens;
uint8_t hundreds;
uint8_t thousands;
uint32_t exception_color;
bool found_main;
} rgb_status_animation_t;
void prep_rgb_status_animation(const pyexec_result_t *result,
bool found_main,
safe_mode_t safe_mode,
rgb_status_animation_t *status);
bool tick_rgb_status_animation(rgb_status_animation_t *status);
#endif // MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H

View File

@ -36,7 +36,7 @@
#include "supervisor/serial.h"
#include "supervisor/shared/rgb_led_colors.h"
#include "supervisor/shared/rgb_led_status.h"
#include "supervisor/shared/status_leds.h"
#include "supervisor/shared/translate.h"
#include "supervisor/shared/tick.h"
@ -65,11 +65,9 @@ safe_mode_t wait_for_safe_mode_reset(void) {
}
port_set_saved_word(SAFE_MODE_DATA_GUARD | (MANUAL_SAFE_MODE << 8));
// Wait for a while to allow for reset.
temp_status_color(SAFE_MODE);
#ifdef MICROPY_HW_LED_STATUS
digitalio_digitalinout_obj_t status_led;
common_hal_digitalio_digitalinout_construct(&status_led, MICROPY_HW_LED_STATUS);
common_hal_digitalio_digitalinout_switch_to_output(&status_led, true, DRIVE_MODE_PUSH_PULL);
#if CIRCUITPY_STATUS_LED
status_led_init();
#endif
#ifdef CIRCUITPY_BOOT_BUTTON
digitalio_digitalinout_obj_t boot_button;
@ -78,22 +76,32 @@ safe_mode_t wait_for_safe_mode_reset(void) {
#endif
uint64_t start_ticks = supervisor_ticks_ms64();
uint64_t diff = 0;
bool boot_in_safe_mode = false;
while (diff < 1000) {
#ifdef MICROPY_HW_LED_STATUS
#ifdef CIRCUITPY_STATUS_LED
// Blink on for 100, off for 100, on for 100, off for 100 and on for 200
common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4);
bool led_on = diff > 100 && diff / 100 != 2 && diff / 100 != 4;
if (led_on) {
new_status_color(SAFE_MODE);
} else {
new_status_color(BLACK);
}
#endif
#ifdef CIRCUITPY_BOOT_BUTTON
if (!common_hal_digitalio_digitalinout_get_value(&boot_button)) {
return USER_SAFE_MODE;
boot_in_safe_mode = true;
break;
}
#endif
diff = supervisor_ticks_ms64() - start_ticks;
}
#ifdef MICROPY_HW_LED_STATUS
common_hal_digitalio_digitalinout_deinit(&status_led);
#if CIRCUITPY_STATUS_LED
new_status_color(BLACK);
status_led_deinit();
#endif
clear_temp_status();
if (boot_in_safe_mode) {
return USER_SAFE_MODE;
}
port_set_saved_word(SAFE_MODE_DATA_GUARD);
return NO_SAFE_MODE;
}

View File

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
* Copyright (c) 2017-2021 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
@ -26,11 +26,81 @@
#include "supervisor/shared/status_leds.h"
#if CIRCUITPY_DIGITALIO
#include "common-hal/digitalio/DigitalInOut.h"
#include "mphalport.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/tick.h"
#include "py/obj.h"
#ifdef CIRCUITPY_STATUS_LED_POWER
#include "shared-bindings/digitalio/DigitalInOut.h"
static digitalio_digitalinout_obj_t _status_power;
#endif
#ifdef MICROPY_HW_NEOPIXEL
uint8_t rgb_status_brightness = 63;
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/neopixel_write/__init__.h"
static uint8_t status_neopixel_color[3];
static digitalio_digitalinout_obj_t status_neopixel;
#elif defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
uint8_t rgb_status_brightness = 50;
#define APA102_BUFFER_LENGTH 12
static uint8_t status_apa102_color[APA102_BUFFER_LENGTH] = {0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0xff};
#if CIRCUITPY_BITBANG_APA102
#include "shared-bindings/bitbangio/SPI.h"
static bitbangio_spi_obj_t status_apa102 = {
.base = {
.type = &bitbangio_spi_type,
},
};
#else
#include "shared-bindings/busio/SPI.h"
busio_spi_obj_t status_apa102 = {
.base = {
.type = &busio_spi_type,
},
};
#endif
#elif CIRCUITPY_PWM_RGB_LED
#include "shared-bindings/pwmio/PWMOut.h"
#include "shared-bindings/microcontroller/Pin.h"
pwmio_pwmout_obj_t rgb_status_r = {
.base = {
.type = &pwmio_pwmout_type,
},
};
pwmio_pwmout_obj_t rgb_status_g = {
.base = {
.type = &pwmio_pwmout_type,
},
};
pwmio_pwmout_obj_t rgb_status_b = {
.base = {
.type = &pwmio_pwmout_type,
},
};
uint8_t rgb_status_brightness = 0xFF;
uint16_t status_rgb_color[3] = {
0 /* red */, 0 /* green */, 0 /* blue */
};
#elif CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS)
#include "shared-bindings/digitalio/DigitalInOut.h"
digitalio_digitalinout_obj_t single_color_led;
uint8_t rgb_status_brightness = 0xff;
#endif
#if CIRCUITPY_DIGITALIO && (defined(MICROPY_HW_LED_RX) || defined(MICROPY_HW_LED_TX))
#include "shared-bindings/digitalio/DigitalInOut.h"
#ifdef MICROPY_HW_LED_RX
digitalio_digitalinout_obj_t rx_led;
#endif
@ -38,27 +108,220 @@ digitalio_digitalinout_obj_t rx_led;
#ifdef MICROPY_HW_LED_TX
digitalio_digitalinout_obj_t tx_led;
#endif
#endif
void init_status_leds(void) {
#ifdef MICROPY_HW_LED_RX
#if CIRCUITPY_STATUS_LED
static uint32_t current_status_color = 0;
#endif
static bool status_led_init_in_progress = false;
void status_led_init() {
if (status_led_init_in_progress) {
// Avoid recursion.
return;
}
status_led_init_in_progress = true;
#ifdef CIRCUITPY_STATUS_LED_POWER
common_hal_digitalio_digitalinout_construct(&_status_power, CIRCUITPY_STATUS_LED_POWER);
common_hal_digitalio_digitalinout_switch_to_output(&_status_power,
CIRCUITPY_STATUS_LED_POWER_INVERTED == 0, DRIVE_MODE_PUSH_PULL);
#endif
#ifdef MICROPY_HW_NEOPIXEL
common_hal_digitalio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL);
common_hal_digitalio_digitalinout_switch_to_output(&status_neopixel, false, DRIVE_MODE_PUSH_PULL);
#elif defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_construct(&status_apa102,
MICROPY_HW_APA102_SCK,
MICROPY_HW_APA102_MOSI,
NULL);
#else
if (!common_hal_busio_spi_deinited(&status_apa102)) {
common_hal_busio_spi_deinit(&status_apa102);
}
common_hal_busio_spi_construct(&status_apa102,
MICROPY_HW_APA102_SCK,
MICROPY_HW_APA102_MOSI,
NULL);
#endif
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_try_lock(&status_apa102);
// Use 1MHz for clock rate. Some APA102's are spec'd 800kHz-1200kHz,
// though many can run much faster. bitbang will probably run slower.
shared_module_bitbangio_spi_configure(&status_apa102, 1000000, 0, 0, 8);
#else
common_hal_busio_spi_try_lock(&status_apa102);
common_hal_busio_spi_configure(&status_apa102, 1000000, 0, 0, 8);
#endif
#elif CIRCUITPY_PWM_RGB_LED
if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_R)) {
pwmout_result_t red_result = common_hal_pwmio_pwmout_construct(&rgb_status_r, CIRCUITPY_RGB_STATUS_R, 0, 50000, false);
if (PWMOUT_OK == red_result) {
common_hal_pwmio_pwmout_never_reset(&rgb_status_r);
}
}
if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_G)) {
pwmout_result_t green_result = common_hal_pwmio_pwmout_construct(&rgb_status_g, CIRCUITPY_RGB_STATUS_G, 0, 50000, false);
if (PWMOUT_OK == green_result) {
common_hal_pwmio_pwmout_never_reset(&rgb_status_g);
}
}
if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_B)) {
pwmout_result_t blue_result = common_hal_pwmio_pwmout_construct(&rgb_status_b, CIRCUITPY_RGB_STATUS_B, 0, 50000, false);
if (PWMOUT_OK == blue_result) {
common_hal_pwmio_pwmout_never_reset(&rgb_status_b);
}
}
#elif defined(MICROPY_HW_LED_STATUS)
common_hal_digitalio_digitalinout_construct(&single_color_led, MICROPY_HW_LED_STATUS);
common_hal_digitalio_digitalinout_switch_to_output(&single_color_led, true, DRIVE_MODE_PUSH_PULL);
#endif
#if CIRCUITPY_DIGITALIO && CIRCUITPY_STATUS_LED
// Force a write of the current status color.
uint32_t rgb = current_status_color;
current_status_color = 0x1000000; // Not a valid color
new_status_color(rgb);
#endif
status_led_init_in_progress = false;
}
void status_led_deinit() {
#ifdef MICROPY_HW_NEOPIXEL
common_hal_reset_pin(MICROPY_HW_NEOPIXEL);
#elif defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_deinit(&status_apa102);
#else
common_hal_busio_spi_deinit(&status_apa102);
#endif
#elif CIRCUITPY_PWM_RGB_LED
if (!common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_R)) {
common_hal_pwmio_pwmout_deinit(&rgb_status_r);
}
if (!common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_G)) {
common_hal_pwmio_pwmout_deinit(&rgb_status_g);
}
if (!common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_B)) {
common_hal_pwmio_pwmout_deinit(&rgb_status_b);
}
#elif defined(MICROPY_HW_LED_STATUS)
common_hal_digitalio_digitalinout_deinit(&single_color_led);
#endif
#ifdef CIRCUITPY_STATUS_LED_POWER
common_hal_digitalio_digitalinout_deinit(&_status_power);
#endif
}
void new_status_color(uint32_t rgb) {
#if CIRCUITPY_STATUS_LED
if (current_status_color == rgb) {
return;
}
uint32_t rgb_adjusted = color_brightness(rgb, rgb_status_brightness);
current_status_color = rgb;
#endif
#ifdef MICROPY_HW_NEOPIXEL
status_neopixel_color[0] = (rgb_adjusted >> 8) & 0xff;
status_neopixel_color[1] = (rgb_adjusted >> 16) & 0xff;
status_neopixel_color[2] = rgb_adjusted & 0xff;
common_hal_neopixel_write(&status_neopixel, status_neopixel_color, 3);
#elif defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
status_apa102_color[5] = rgb_adjusted & 0xff;
status_apa102_color[6] = (rgb_adjusted >> 8) & 0xff;
status_apa102_color[7] = (rgb_adjusted >> 16) & 0xff;
#if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH);
#else
common_hal_busio_spi_write(&status_apa102, status_apa102_color, APA102_BUFFER_LENGTH);
#endif
#elif CIRCUITPY_PWM_RGB_LED
uint8_t red_u8 = (rgb_adjusted >> 16) & 0xFF;
uint8_t green_u8 = (rgb_adjusted >> 8) & 0xFF;
uint8_t blue_u8 = rgb_adjusted & 0xFF;
#ifdef CIRCUITPY_RGB_STATUS_INVERTED_PWM
status_rgb_color[0] = (1 << 16) - 1 - ((uint16_t)(red_u8 << 8) + red_u8);
status_rgb_color[1] = (1 << 16) - 1 - ((uint16_t)(green_u8 << 8) + green_u8);
status_rgb_color[2] = (1 << 16) - 1 - ((uint16_t)(blue_u8 << 8) + blue_u8);
#else
status_rgb_color[0] = (uint16_t)(red_u8 << 8) + red_u8;
status_rgb_color[1] = (uint16_t)(green_u8 << 8) + green_u8;
status_rgb_color[2] = (uint16_t)(blue_u8 << 8) + blue_u8;
#endif
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_r, status_rgb_color[0]);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_g, status_rgb_color[1]);
common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_b, status_rgb_color[2]);
#elif CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS)
common_hal_digitalio_digitalinout_set_value(&single_color_led, rgb_adjusted > 0);
#endif
}
uint32_t color_brightness(uint32_t color, uint8_t brightness) {
#if CIRCUITPY_STATUS_LED
uint32_t result = ((color & 0xff0000) * brightness / 255) & 0xff0000;
result += ((color & 0xff00) * brightness / 255) & 0xff00;
result += ((color & 0xff) * brightness / 255) & 0xff;
return result;
#else
return color;
#endif
}
void set_status_brightness(uint8_t level) {
#if CIRCUITPY_STATUS_LED
rgb_status_brightness = level;
uint32_t current_color = current_status_color;
// Temporarily change the current color global to force the new_status_color call to update the
// LED. Usually duplicate calls of the same color are ignored without regard to brightness
// changes.
current_status_color = 0;
new_status_color(current_color);
#endif
}
void init_rxtx_leds(void) {
#if CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_RX)
common_hal_digitalio_digitalinout_construct(&rx_led, MICROPY_HW_LED_RX);
common_hal_digitalio_digitalinout_switch_to_output(&rx_led, true, DRIVE_MODE_PUSH_PULL);
#endif
#ifdef MICROPY_HW_LED_TX
#if CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_TX)
common_hal_digitalio_digitalinout_construct(&tx_led, MICROPY_HW_LED_TX);
common_hal_digitalio_digitalinout_switch_to_output(&tx_led, true, DRIVE_MODE_PUSH_PULL);
#endif
}
void toggle_rx_led(void) {
#ifdef MICROPY_HW_LED_RX
#if CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_RX)
common_hal_digitalio_digitalinout_set_value(&rx_led, !common_hal_digitalio_digitalinout_get_value(&rx_led));
#endif
}
void toggle_tx_led(void) {
#ifdef MICROPY_HW_LED_TX
#if CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_TX)
common_hal_digitalio_digitalinout_set_value(&tx_led, !common_hal_digitalio_digitalinout_get_value(&tx_led));
#endif
}

View File

@ -27,10 +27,35 @@
#ifndef MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H
#define MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H
void init_status_leds(void);
#include <stdint.h>
#include <stdbool.h>
#include "lib/utils/pyexec.h"
#include "supervisor/port.h"
#include "py/mpconfig.h"
#include "rgb_led_colors.h"
#include "supervisor/shared/safe_mode.h"
// Overall, the time module must be implemented.
// To work with a DotStar, one must have MICROPY_HW_APA102_SCK and
// MICROPY_HW_APA102_MOSI defined and bitbangio.SPI or busio.SPI implemented.
// To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and
// neopixel_write implemented.
#define CIRCUITPY_PWM_RGB_LED defined(CIRCUITPY_RGB_STATUS_R) || defined(CIRCUITPY_RGB_STATUS_G) || defined(CIRCUITPY_RGB_STATUS_B)
#define CIRCUITPY_STATUS_LED (CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS)) || defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || CIRCUITPY_PWM_RGB_LED
void status_led_init(void);
void status_led_deinit(void);
void new_status_color(uint32_t rgb);
uint32_t color_brightness(uint32_t color, uint8_t brightness);
void set_status_brightness(uint8_t level);
void init_rxtx_leds(void);
void toggle_rx_led(void);
void toggle_tx_led(void);
#endif // MICROPY_INCLUDED_SUPERVISOR_STATUS_LEDS_H

View File

@ -9,7 +9,6 @@ SRC_SUPERVISOR = \
supervisor/shared/flash.c \
supervisor/shared/memory.c \
supervisor/shared/micropython.c \
supervisor/shared/rgb_led_status.c \
supervisor/shared/safe_mode.c \
supervisor/shared/stack.c \
supervisor/shared/status_leds.c \