This allows a simple way to run the existing asyncio tests under the
webassembly port, which doesn't support `asyncio.run()`.
Signed-off-by: Damien George <damien@micropython.org>
This commit adds a significant portion of the existing MicroPython asyncio
module to the webassembly port, using parts of the existing asyncio code
and some custom JavaScript parts.
The key difference to the standard asyncio is that this version uses the
JavaScript runtime to do the actual scheduling and waiting on events, eg
Promise fulfillment, timeouts, fetching URLs.
This implementation does not include asyncio.run(). Instead one just uses
asyncio.create_task(..) to start tasks and then returns to the JavaScript.
Then JavaScript will run the tasks.
The implementation here tries to reuse as much existing asyncio code as
possible, and gets all the semantics correct for things like cancellation
and asyncio.wait_for. An alternative approach would reimplement Task,
Event, etc using JavaScript Promise's. That approach is very difficult to
get right when trying to implement cancellation (because it's not possible
to cancel a JavaScript Promise).
Signed-off-by: Damien George <damien@micropython.org>
When a Promise is rejected on the JavaScript side, the reject reason should
be thrown into the encapsulating generator on the Python side.
Signed-off-by: Damien George <damien@micropython.org>
An exception on the Python side should be passed to the Promise reject
callback on the JavaScript side.
Signed-off-by: Damien George <damien@micropython.org>
Otherwise Emscripten allocates it on the Emscripten C stack, which will
overflow for large amounts of code.
Fixes issue #14307.
Signed-off-by: Damien George <damien@micropython.org>
In modularize mode, the `_createMicroPythonModule()` constructor must be
await'ed on, before `Module` is ready to use.
Signed-off-by: Damien George <damien@micropython.org>
When `lightsleep()` is called from within a thread the interrupts may not
be enabled on current core, and thus the call to `lightsleep()` never
completes.
Fixes issue #14092.
Signed-off-by: Simon Wood <simon@mungewell.org>
This optimises the case where a Python function is, for example, stored to
a JavaScript attribute and then later retrieved from Python. The Python
function no longer needs to be a proxy with double proxying needed for the
call from Python -> JavaScript -> Python.
Signed-off-by: Damien George <damien@micropython.org>
Change provided by @ironss-iotec.
Tested with Adafruit, SEEED and MiniFig boards for non-interference.
Fixes issue #14190.
Signed-off-by: robert-hh <robert@hammelrath.com>
Using a define for MICROPY_HW_SPIFLASH_BAUDRATE in mpconfigboard.h. If not
defined the default is 24MHz.
Signed-off-by: robert-hh <robert@hammelrath.com>
For all MCUs: run the test for USB clock recovery mode fallback after USB
has been started.
For samd21: change DFLL48 config from the open loop mode variant to sync
with the XOSC32KULP. Matches better the 48MHz value.
Signed-off-by: robert-hh <robert@hammelrath.com>
The default CYW43 WiFi AP settings were missing the security mode, leaving
the AP in open mode by default. That's changed by this commit to use
WPA/WPA2 by default.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
When PWM constructor was created without specifying a device or setting
both freq and duty rate, it was not tagged as used, and further calls to
get a PWM object may get the same PWM device assigned.
Fixes#13494.
Signed-off-by: robert-hh <robert@hammelrath.com>
Exceptions in pin interrupt handlers would end up crashing MicroPython with
a "FATAL: uncaught exception".
In addition, MicroPython would get stuck trying to output this error
message, or generally any print output from inside a pin interrupt handler,
through the UART after the first character, so that only "F" was visible.
The reason was a matching interrupt priority between the running pin
interrupt and the UARTE interrupt signaling completion of the output
operation. Fix that by increasing the UARTE interrupt priority.
Code taken from the stm32 port and adapted.
Signed-off-by: Christian Walther <cwalther@gmx.ch>
Under some circumstances, after a hard reset, the low-frequency clock would
not be running. This caused time.ticks_ms() to return 0, time.sleep_ms()
to get stuck, and other misbehavior. A soft reboot would return it to a
working state.
The cause was a race condition that was hit when the bootloader would
itself turn LFCLK on, but turn it off again shortly before launching the
main application (this apparently happens with the Adafruit bootloader
from https://github.com/fanoush/ds-d6/tree/master/micropython). Stopping
the clock is an asynchronous operation and it continues running for a short
time after the stop command is given. When MicroPython checked whether to
start it by looking at the LFCLKSTAT register (nrf_clock_lf_is_running)
during that time, it would mistakenly not be started again. What
MicroPython should be looking at is not whether the clock is running at
this time, but whether a start/stop command has been given, which is
indicated by the LFCLKRUN register (nrf_clock_lf_start_task_status_get).
It is not clearly documented, but empirically LFCLKRUN is not just set when
the LFCLKSTART task is triggered, but also cleared when the LFCLKSTOP task
is triggered, which is exactly what we need.
The matter is complicated by the fact that the nRF52832 has an anomaly
(see [errata](https://infocenter.nordicsemi.com/topic/errata_nRF52832_Rev3/ERR/nRF52832/Rev3/latest/anomaly_832_132.html?cp=5_2_1_0_1_33))
where starting the LFCLK will not work between 66µs and 138µs after it last
stopped. Apply a workaround for that. See nrfx_clock_lfclk_start() in
micropython/lib/nrfx/drivers/src/nrfx_clock.c for reference, but we are not
using that because it also does other things and makes the code larger.
Signed-off-by: Christian Walther <cwalther@gmx.ch>
It destroys a few manual alignments, but these seem minor compared to
the benefit of automated code style consistency.
Signed-off-by: Christian Walther <cwalther@gmx.ch>
Trying to use an external board definition according to
https://github.com/micropython/micropython-example-boards on the nrf port
failed with "Invalid BOARD specified". Replacing all ocurrences of
"boards/$(BOARD)" with "$(BOARD_DIR)" following the example of
stm32/Makefile fixes that.
Signed-off-by: Christian Walther <cwalther@gmx.ch>
If the heap allocation fails we will crash if we continue, so at least we
can show a clear error message so one can figure out memory allocation was
the problem (instead of just seeing some arbitrary null pointer error
later).
Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
This adds a QEMU-based bare metal RISC-V 32 bits port. For the time
being only QEMU's "virt" 32 bits board is supported, using the ilp32 ABI
and the RV32IMC architecture.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit adds a pyscript variant for use in https://pyscript.net/.
The configuration is:
- No ASYNCIFY, in order to keep the WASM size down and have good
performance.
- MICROPY_CONFIG_ROM_LEVEL_FULL_FEATURES to enable most features.
- Custom manifest that includes many of the python-stdlib libraries.
- MICROPY_GC_SPLIT_HEAP_AUTO to increase GC heap size instead of doing a
collection when memory is exhausted. This is needed because ASYNCIFY is
disabled. Instead the GC collection is run at the top-level before
executing any Python code.
- No MICROPY_VARIANT_ENABLE_JS_HOOK because there is no asynchronous
keyboard input to interrupt a running script.
Signed-off-by: Damien George <damien@micropython.org>
With this commit, `interpreter.runPythonAsync(code)` can now be used to run
Python code that uses `await` at the top level. That will yield up to
JavaScript and produce a thenable, which the JavaScript runtime can then
resume. Also implemented is the ability for Python code to await on
JavaScript promises/thenables. For example, outer JavaScript code can
await on `runPythonAsync(code)` which then runs Python code that does
`await js.fetch(url)`. The entire chain of calls will be suspended until
the fetch completes.
Signed-off-by: Damien George <damien@micropython.org>
This commit improves the webassembly port by adding:
- Proxying of Python objects to JavaScript with a PyProxy type that lives
on the JavaScript side. PyProxy implements JavaScript Proxy traps such
as has, get, set and ownKeys, to make Python objects have functionality
on the JavaScript side.
- Proxying of JavaScript objects to Python with a JsProxy type that lives
on the Python side. JsProxy passes through calls, attributes,
subscription and iteration from Python to JavaScript.
- A top-level API on the JavaScript side to construct a MicroPython
interpreter instance via `loadMicroPython()`. That function returns an
object that can be used to execute Python code, access the Python globals
dict, access the Emscripten filesystem, and other things. This API is
based on the API provided by Pyodide (https://pyodide.org/). As part of
this, the top-level file is changed from `micropython.js` to
`micropython.mjs`.
- A Python `js` module which can be used to access all JavaScript-side
symbols, for example the DOM when run within a browser.
- A Python `jsffi` module with various helper functions like
`create_proxy()` and `to_js()`.
- A dedenting lexer which automatically dedents Python source code if every
non-empty line in that source starts with a common whitespace prefix.
This is very helpful when Python source code is indented within a string
within HTML or JavaScript for formatting reasons.
Signed-off-by: Damien George <damien@micropython.org>
This commit cleans up and generalises the Makefile, adds support for
variants (following the unix port) and adds the "standard" variant as the
default variant.
Signed-off-by: Damien George <damien@micropython.org>