This commit adds support for generating named pin mappings for all pins
including CPU, board-defined, LED and externally controlled pins. CPU pins
are mapped to `pin_GPIO<n>`, externally-controlled pins are mapped to
`pin_EXT_GPIO<n>`, and defined conditionally (up to 10 pins, and can be
expanded in the future), and they are non-const to allow `machine-pin.c` to
write the pin object fields. Both CPU and externally controlled pins are
generated even if there's no board CSV file; if one exists it will just be
added to board pins.
Handle externally controlled GPIO pins more generically, by removing all
CYW43-specific code from `machine_pin.c`, and adding hooks to initialise,
configure, read and write external pins. This allows any driver for an
on-board module which controls GPIO pins (such as CYW43 or NINA), to
provide its own implementation of those hooks and work seamlessly with
`machine_pin.c`.
These are for working with the filesystem when using pyboard.py as a
library, rather than at the command line.
- fs_listdir returns a list of tuples, in the same format as os.ilistdir().
- fs_readfile returns the contents of a file as a bytes object.
- fs_writefile allows writing a bytes object to a file.
- fs_stat returns an os.statresult.
All raise FileNotFoundError (or OSError(ENOENT) on Python 2) if the file is
not found (or PyboardError on other errors).
Updated fs_cp and fs_get to use fs_stat to compute file size.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This is useful when using pyboard.py as a library rather than at the
command line.
pyb.eval("1+1") --> b"2"
pyb.eval("{'a': '\x00'}") --> b"{'a': '\\x00'}"
Now you can also do
pyb.eval("1+1", parse=True) --> 2
pyb.eval("{'a': '\x00'}", parse=True) --> {'a': '\x00'}
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit uses the REGION_ALIAS GNU linker command to simplify the linker
snippets and consolidate the duplication.
Signed-off-by: Damien George <damien@micropython.org>
To adhere to the contract of mp_map_lookup, namely:
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND behaviour:
- returns slot, with key non-null and value=MP_OBJ_NULL if it was added
This ensures the same number of cycles are used for LED on and LED off in
the PIO 1Hz example. It's also possible to swap the first set() and the
irq() to avoid using an extra instruction, but this tutorial is a good
example of how to calculate the cycles.
Signed-off-by: Stig Bjørlykke <stig@bjorlykke.org>
To allow the USB to work in cases where there is a lot of filesystem
access, in particular on boot.
For example, registering of the USB CDC interface may fail if:
- the board file system is lfs2 (default), and
- sys.path contains entries for the local file system (default), and
- files are imported by boot.py or main.py from frozen bytecode of the file
system (common) and the file system contains many files, like 100.
In that case the board is very busy with scanning LFS, and registering the
USB interface seems to time out. This commit fixes this by allowing the
USB to make progress during filesystem reads.
Also switch existing MICROPY_EVENT_POLL_HOOK uses in this file to
MICROPY_EVENT_POLL_HOOK_FAST now that the latter macro exists.
When switching from a special function like SPI to an input or output,
there was a brief period after the function was disabled but before the
pin's I/O state was configured, in which the state would be poorly defined.
This fixes the problem by switching off the special function after fully
configuring the I/O state.
Fixes#10226.
Signed-off-by: Paul Grayson <pdg@alum.mit.edu>
There were several places where 32-bit integer could overflow with
frequencies of 2^28 Hz or above (~268 MHz). This fixes those overflows and
also introduces rounding for more accurate duty_ns computations.
Signed-off-by: Paul Grayson <pdg@alum.mit.edu>
This changes the freq() and duty_u16() functions to use more simpler, more
accurate formulas, in particular increasing the frequency accuracy from a
few percent to a fraction of a percent in many cases.
Signed-off-by: Paul Grayson <pdg@alum.mit.edu>
MicroPython overrides the axTLS port configuration file, but fails to
include <arpa/inet.h> (needed for htonl) and <sys/time.h> (needed for
gettimeofday). This results in build failures with compilers which do not
support implicit function declarations (which were removed from C in 1999).
This commit adds back the needed headers that were removed in this commit:
bd08017309
Signed-off-by: Damien George <damien@micropython.org>
Prior to this commit, the default security=-1 would be passed directly
through to the cyw43 driver to auto-detect the security type, but that
driver did not correctly handle the case of open security.
The cyw43 driver has now been changed to no longer support auto-detection,
rather it is up to the caller to always select the security type. The
defaults are now implemented in the Python bindings and are:
- if no key is given then it selects open security
- if a key is given then it selects WPA2_MIXED_PSK
Calling `wlan.connect(<ssid>)` will now connect to an open network, on
both rp2 and stm32 ports. The form `wlan.connect(<ssid>, <key>)` will
connect to a WPA2 network.
Fixes issue #9016.
Signed-off-by: Damien George <damien@micropython.org>
Changes since the previous version:
- remove mDNS
- implement lwIP IGMP MAC filter callback
- implement IPv6 support
- allow building with IGMP disabled
- fix handshake meggase WAIT_G1 event value
- increase EAPOL timeout from 2500ms to 500ms
- add function to get RSSI
- fix handling of open security networks
- remove support for automatically setting auth type
Signed-off-by: Damien George <damien@micropython.org>
This commit prevents the device from "hanging" when using lightsleep while
the WiFi chip is active.
Whenever the WiFi chip wants to interrupt the microcontroller to notify it
for a new package, it sets the CYW43_PIN_WL_HOST_WAKE pin to high,
triggering an IRQ. However, as polling the chip cannot happen in an
interrupt handler, it subsequently notifies the pendsv-service to do a poll
as soon as the interrupt handler ended. In order to prevent a new
interrupt from happening immediately afterwards, even before the poll has
run, the IRQ handler disables interrupts from the pin.
The first problem occurs, when a WiFi package arrives while the main loop
is in cyw43-code. In order to prevent concurrent access of the hardware,
the network code blocks pendsv from running again while entering lwIP code.
The same holds for direct cyw43 code (like changing the cyw43-gpios, i.e.
the LED on the Pico W). While the pendsv is disabled, interrupts can still
occur to schedule a poll (and disable further interrupts), but it will not
run. This can happen while the microcontroller is anywhere in rp2040 code.
In order to preserve power while waiting for cyw43 responses,
cyw43_configport.h defines CYW43_DO_IOCTL_WAIT and
CYW43_SDPCM_SEND_COMMON_WAIT to __WFI(). While this might work in most
cases, there are 2 edge cases where it fails:
- When an interrupt has already been received by the cyw43 stack, for
example due to an incoming ethernet packet.
- When the interrupt from the cyw43 response comes before the
microcontroller entered the __WFI() instruction.
When that happens, wfi will just block forever as no further interrupts are
received. The only way to safely use wfi to wake up from an interrupt is
inside a critical section, as this delays interrupts until the wfi is
entered, possibly resuming immediately until interrupts are reenabled and
the interrupt handler is run. Additionally this critical section needs to
check whether the interrupt has already been disabled and pendsv was
triggered, as in such a case, wfi can never be woken up, and needs to be
skipped, because there is already a package from the network chip waiting.
Note that this turns cyw43_yield into a nop (and thereby the cyw43-loops
into busy waits) from the second time onwards, as after the first call, a
pendsv request will definitely be pending. More logic could be added, to
explicitly enable the interrupt in this case.
Regarding lightsleep, this code has a similar problem. When an interrupt
occurs during lightsleep, the IRQ and pendsv handler and thereby poll are
run immediately, with the clocks still disabled, causing the SPI transfers
to fail. If we don't want to add complex logic inside the IRQ handler we
need to protect the whole lightsleep procedure form interrupts with a
critical section, exiting out early if an interrupt is pending for whatever
reason. Only then we can start to shut down clocks and only enable
interrupts when the system is ready again. Other interrupt handlers might
also be happy, that they are only run when the system is fully operational.
Tested on a Pico W, calling machine.lightsleep() within an endless loop and
pinging from the outside.
This modifies the automated code size comment to edit an existing comment
if one already exists instead of always creating a new comment. This
reduces noise on pull requests that are repeatedly updated.
Signed-off-by: David Lechner <david@pybricks.com>
In @micropython.native code the types of variables and expressions are
always Python objects, so they can be initialised as such. This prevents
problems with compiling optimised code like while-loops where a local may
be referenced before it is assigned to.
Signed-off-by: Damien George <damien@micropython.org>
During the initial handshake or subsequent renegotiation, the protocol
might need to read in order to write (or conversely to write in order
to read). It might be blocked from doing so by the state of the
underlying socket (i.e. there is no data to read, or there is no space
to write).
The library indicates this condition by returning one of the errors
`MBEDTLS_ERR_SSL_WANT_READ` or `MBEDTLS_ERR_SSL_WANT_WRITE`. When that
happens, we need to enforce that the next poll operation only considers
the direction that the library indicated.
In addition, mbedtls does its own read buffering that we need to take
into account while polling, and we need to save the last error between
read()/write() and ioctl().
This required to add two functions down the stack to uart.c and ra.sci.c.
- One for telling, whther the transmission is busy.
- One for reporting the size of the TX buffer.
Tested with a EK-RA6M2 board.
This was previously used for the definition of NIC types, but they have
been updated to use a protocol instead.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
See the previous commit, except in this case the customisation didn't
actually do anything so can just be removed.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This was previously implemented by adding additional members to the
mp_obj_type_t defined for each NIC, which is difficult to do cleanly with
the new object type slots mechanism. The way this works is also not
supported on GCC 8.x and below.
Instead replace it with the type protocol, which is a much simpler way of
achieving the same thing.
This affects the WizNet (in non-LWIP mode) and Nina NIC drivers.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Changes in this commit:
- Clear and mask D2 EXTIs.
- Set correct voltage scaling level for standby mode.
- Disable debug MCU (if debugging is disabled), for all MCU series.
It keeps compatibility with the XIAO bootloader by:
- using Soft Device 7.3.0
- reserving 48k memory for the bootloader.
So on double reset a drive pops for uploading an uf2 image or a nrfutil zip
pkg file. Instructions to create it from a hex file are included. The
bootloader can as well be activated with the touch 1200 option of nrfutil.
The script download_ble_stack.sh has been adapted to get the version 7.3.0
soft device files. It may have to be executed once before building.
The file system is set to 256k and the pin definitions are adapted.
Besides that, it has the common functionality and omissions. The on-board
sensors and additional flash can be supported by Python scripts.
This was introduced by 35fb90bd57, but
it is much simpler and essentially the same to just use
`tud_cdc_n_connected()`.
The only difference is that tud_cdc_n_connected() only checks for DTR,
but this is correct anyway: DTR indicates device presence, RTS indicates
that the host wants to receive data.
Signed-off-by: Damien Tournoud <damien@platform.sh>
usocket_events_deinit will only be available if MICROPY_PY_USOCKET_EVENTS
is enabled (which is only enabled when webrepl is enabled).
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This adds a concurrency section to all github workflows to cancel any
in progress workflow when a branch is updated. This should cancel any
ongoing or queued workflows, e.g. when a pull request is updated.
Signed-off-by: David Lechner <david@pybricks.com>
The compiler is not picky right now, but these are actually all syntax
errors:
- await is only valid in an async function
- async functions that use yield are actually async generators (a construct
not supported by the compiler right now)
ADC: The argument of vref=num is an integer. Values for num are:
SAMD21:
0 INT1V 1.0V voltage reference
1 INTVCC0 1/1.48 Analog voltage supply
2 INTVCC1 1/2 Analog voltage supply (only for VDDANA > 2.0V)
3 VREFA External reference
4 VREFB External reference
SAMD51:
0 INTREF internal bandgap reference
1 INTVCC1 Analog voltage supply
2 INTVCC0 1/2 Analog voltage supply (only for VDDANA > 2.0v)
3 AREFA External reference A
4 AREFB External reference B
5 AREFC External reference C (ADC1 only)
DAC: The argument of vref=num is an integer. Suitable values:
SAMD21:
0 INT1V Internal voltage reference
1 VDDANA Analog voltage supply
2 VREFA External reference
SAMD51:
0 INTREF Internal bandgap reference
1 VDDANA Analog voltage supply
2 VREFAU Unbuffered external voltage reference (not buffered in DAC)
4 VREFAB Buffered external voltage reference (buffered in DAC).
Changes in this commit:
- Do not deinit IRQ when uart.deinit() is called with an inactive object.
- Remove using it for the finaliser. There is another machanism for soft
reset, and it is not needed otherwise.
- Do not tag the UART buffers with MP_STATE_PORT, it is not required.
Clearing the DRE flag for the transmit interrupt at the end of a
uart.write() also cleared the RXC flag disabling the receive interrupt.
This commit also changes the flag set/clear mechanism in the driver for SPI
as well, even if it did not cause a problem there. But at least it saves a
few bytes of code.
Applies to both SPI and I2C. The underflow caused high baudrate settings
resulting in the lowest possible baudrate. The overflow resulted in
erratic baudrates, not just the lowest possible.