pre-commit manages its own dependencies otherwise (including Black), but
this one is a C/C++ binary so needs to be installed independently.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
`esp_eth_ioctl(ETH_CMD_S_MAC_ADDR)` sets the MAC address of the hardware
device, but we also need to notify the upper layers of the change so that
e.g. DHCP work properly.
Add support for various SPI-based ethernet chips (W5500, KSZ8851SNL,
DM9051) to the ESP32 port. This leverages the existing support in ESP-IDF
for these chips -- which configures these chips in "MAC raw" mode -- and
the existing support for network.LAN in the ESP32 port. In particular,
this doesn't leverage the wiznet5k support that is used on the rp2 and
stm32 ports (because that's for native use of lwIP).
Tested on the POE Featherwing (with the SJIRQ solder jumper bridged) and a
ESP32-S3 feather.
A note about the interrupt pin: The W5500 implementation within ESP-IDF
relies on hardware interrupt, and requires the interrupt pin from the W5500
to be wired to a GPIO. This is not the case by default on the Adafruit
Ethernet FeatherWing, which makes it not directly compatible with this
implementation.
Both the direction and the Pin used for ref_clk can now be configured. It
Requires at least idf v4.4. The new keyword arguments to the constructor
are:
- ref_clk_mode=mode: with mode being Pin.IN or Pin.OUT. If it is not set,
then the default configuration is used, which may be configured by
kconfig settings.
- ref_clk=pin_obj: which defines the Pin used for ref_clk. This is either
Pin(0), Pin(16) or Pin(17). No check is done for the pin number. If it
is the wrong one, it simply will not work. Besides that, no harm.
LAN8710 uses the same drivers as LAN8720, so this commit just adds the
names. Alternatively, both could be summarised under LAN87xx, like the
esp-idf does.
Showing 8 digits instead of 5, supporting devices with more than 1 MByte of
RAM (which is common these days). The masking was never needed, and the
related commented-out line can go.
The intention of using `tee` is to both print the code size change in
the CI logs and save them to a file. Using redirection to a file
caused it to not print the changes.
Signed-off-by: David Lechner <david@pybricks.com>
Pin defines are:
- For Pico define board pins and the default LED pin (WL_GPIO25).
- For Pico-W define board pins, external pins and the default
LED pin (WL_GPIO0).
- For the Nano-RP2040, define board pins, external pins and
the default LED pin (GPIO25)
- For all other boards, the pins.csv defines the LED pin (if any)
for backwards compatibility with code that assumes there's always
an LED pin.
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>