| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## master #19617 +/- ##
==========================================
+ Coverage 98.55% 98.58% +0.03%
==========================================
Files 182 182
Lines 23320 23322 +2
Branches 5 5
==========================================
+ Hits 22984 22993 +9
+ Misses 335 328 -7
Partials 1 1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness.
|
Sorry, something went wrong.
Some drivers need to register a GPIO interrupt from C rather than through the machine.Pin.irq() Python method -- for example a network driver that wakes on a transceiver's IRQ line. Add mp_hal_pin_interrupt(), matching the stm32 and rp2 ports, plus mp_hal_pin_interrupt_enable() to mask and unmask an already-registered interrupt, which is useful for interrupt coalescing. The registered interrupt is given the lowest priority, as eth.c already does for the Ethernet IRQs: it only schedules work and must not preempt USB or DMA. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Some drivers need to register a GPIO interrupt from C rather than through the machine.Pin.irq() Python method. Factor the IRQ-object allocation out of machine_pin_irq() into a shared helper, then build mp_hal_pin_interrupt() and mp_hal_pin_interrupt_enable() on top of it. The latter masks and unmasks an already-registered interrupt, which is useful for interrupt coalescing. The registered interrupt is given the same low priority this port already uses for the cyw43 host-wake IRQ, since it only schedules work. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Add mp_hal_pin_interrupt_enable() to mask and unmask an already-registered pin interrupt, matching the mimxrt and alif ports. A driver can use it for interrupt coalescing: mask on the edge, unmask once the work is done. It wraps the port's existing extint_enable() / extint_disable(). Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Carries morselib -- the vendor's prebuilt WLAN library -- and the transceiver firmware that the 802.11ah driver is built on. Pinned at release 2.12.3. morselib is distributed as a prebuilt archive under the Morse Micro Binary License; the rest of the SDK is Apache-2.0. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
|
Code size report: Reference: stm32/mpu: Reuse MPU_ATTRIBUTES_NUMBER0 for all non-cacheable uses. [1827631]
Comparison: alif/boards/OPENMV_AE3: Enable HaLow. [merge of 23a14ee]
mpy-cross: +0 +0.000%
bare-arm: +0 +0.000%
minimal x86: +0 +0.000%
unix x64: +0 +0.000% standard
stm32: +0 +0.000% PYBV10
esp32: +0 +0.000% ESP32_GENERIC
mimxrt: -16 -0.004% TEENSY40
rp2: +0 +0.000% RPI_PICO_W
samd: +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
qemu rv32: +0 +0.000% VIRT_RV32
|
Sorry, something went wrong.
The portable core that the network.HALOW binding is built on, sitting between morselib and the MicroPython runtime: - a cooperative scheduler that runs morselib's tasks on their own stacks, pumped from the network poll; - an OSAL providing the RTOS primitives morselib expects -- tasks, mutexes, semaphores, queues and timers -- on top of that scheduler; - a HAL driving the transceiver over SPI, with an optional pin interrupt for low-latency receive; - packet memory and the lwIP interface, allocated from the MicroPython heap so the driver keeps no static pool of its own; - build rules that link the prebuilt morselib archive and the firmware blobs. Scheduler and allocator come with qemu and host unit tests. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
The MicroPython network interface on top of the drivers/halow core: a station-mode network.HALOW class with connect/disconnect, scan, config and status accessors, and an ioctl passthrough for certification tooling, plus the SEC_/TWT_/DUTY_CYCLE_/PM_/STAT_ constants. The constants are fixed to literals and static-asserted against the morselib enums, so a future SDK renumbering fails the build here rather than silently changing what a user's stored value means. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Documents the network.HALOW 802.11ah station interface: its methods, the config and status parameters, the security/power/duty-cycle/TWT constants and the link states, with notes on the ways 802.11ah differs from 2.4GHz Wi-Fi -- no WPA2-PSK, a mandatory country/channel plan, and a transmit-only power-save mode. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Two hardware suites for the network.HALOW interface. network_halow.py needs only the transceiver: it checks the constants, active() cycling, config validation and out-of-range rejection, scan, and that use-after-deinit and config-after-deactivate are refused rather than fatal. network_halow_sta.py needs a HaLow access point and credentials in a halow_config module, and covers association, a socket round trip, and the association-only settings. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Wire the drivers/halow driver into the alif port: include its build rules, tear it down on soft reset, and service it. The transceiver is polled from a dedicated 1ms soft timer -- more often than lwIP's 64ms tick, because morselib always has timers due and this poll is what notices a received frame -- and halow_schedule_poll() raises a PendSV dispatch so a queued transmit does not wait for the next tick. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Wire the drivers/halow driver into the mimxrt port: include its build rules, tear it down on soft reset, and service the transceiver from the network poll each systick, with halow_schedule_poll() raising a PendSV dispatch so a queued transmit does not wait for the next tick. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Wire the drivers/halow driver into the stm32 port: include its build rules, tear it down on soft reset, and service the transceiver from the network poll each systick, with halow_schedule_poll() raising a PendSV dispatch so a queued transmit does not wait for the next tick. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
At the port's 16K MEM_SIZE, sustained TCP exhausts the lwIP heap: it returns ENOMEM and throughput collapses, recovers, and collapses again in a repeating pattern. Raise it to 64K, matching the stm32 port, which holds steady. Measured on an AE3 driving a HaLow uplink: tens of ENOMEM failures per 20-minute soak at 16K, none at 64K. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Enable the Morse Micro MM8108 802.11ah shield on the N6: SPI2 on P0/P1/P2, the shield's control lines on the expansion header, and the pin interrupt for low-latency receive. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
Enable the Morse Micro MM8108 802.11ah shield on the AE3's HP core: SPI0 on P0/P1/P2, with the shield's control lines sharing the JTAG pins on the header. The transceiver is polled -- the IRQ line is mapped but the pin interrupt is left off, as it gives no throughput gain on this port. Signed-off-by: Kwabena W. Agyeman <kwagyeman@live.com>
|
@dpgeorge - I added this to OpenMV's feature list tracker. I understand it will take a while for this to be reviewed and that the review will be lengthy. However, it's now working. Note that the entire PR is AI-generated and verified on real hardware. I drove the AI to max performance and fixed all encountered bugs. Any issues we encountered during bring-up were not overlooked; they were resolved. Original performance when the driver was complete was like < 100KB/s. Scan and association were also problematic along with crashing all over. All that has been fixed and driven to be good. Whatever changes you want to make that are possible given the limitations of the Morse microdriver can be done quickly and reverified thanks to the HIL I set up to test this code. I have a test system for the RT1062, N6, and AE3. You need to buy this to actually test against the shields I sent you. Let me know when I should send you one: https://www.mouser.com/en/ProductDetail/Morse-Micro/MM-HL2-EXT-A-AU?qs=sGAEpiMZZMv0DJfhVcWlK%2FsNvTRZof5PRDeHTp4nalmrn%252B38j3g9qA%3D%3D # Set COUNTRY / SSID / KEY below to match your access point.
import time
import network
# --- Access point -----------------------------------------------------------
COUNTRY = "US" # your regulatory domain, e.g. "US", "AU", "EU", "JP"
SSID = "ssid-halow"
KEY = "your-password"
# --- Bring up HaLow ---------------------------------------------------------
network.country(COUNTRY)
wlan = network.HALOW()
wlan.active(True)
wlan.connect(SSID, KEY)
print("HaLow: associating with %r ..." % SSID)
deadline = time.ticks_add(time.ticks_ms(), 30000)
while not wlan.isconnected():
if time.ticks_diff(deadline, time.ticks_ms()) < 0:
raise RuntimeError("HaLow association timed out")
time.sleep_ms(200)
ip = wlan.ifconfig()[0]
print("HaLow: connected ip=%s rssi=%d dBm channel=%d bandwidth=%d MHz"
% (ip, wlan.status("rssi"), wlan.config("channel"), wlan.config("bandwidth")))
|
Sorry, something went wrong.
|
@kwagyeman super interesting work, thanks! Which hardware do you test with on the MicroPython side? I have such a HalowLink 2 gateway coming in for a project. |
Sorry, something went wrong.
|
@jonnor - The OpenMV N6, OpenMV AE3, and RT1062. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary
This PR adds network.HALOW, a MicroPython network interface for the Morse Micro MM6108/MM8108 802.11ah (Wi-Fi HaLow) sub-GHz Wi-Fi transceivers, and wires it into the stm32, alif and mimxrt ports.
HaLow trades raw throughput for range and power, so the API follows the existing network.WLAN/cyw43 station model — active(), connect(), isconnected(), ifconfig(), config(), status() — plus the HaLow-specific pieces: regulatory network.country(), S1G channel/bandwidth reporting, OPEN/OWE/SAE (WPA3) security, and TWT-based power save.
What's included:
The driver is only compiled when a board sets MICROPY_PY_NETWORK_HALOW=1; it has zero impact on other boards.
Testing
Tested on hardware against a HaLow AP — association plus 20-minute TCP/UDP throughput soaks (hundreds of connect/transfer cycles, no leaks or asserts). All three integrated ports (stm32/alif/mimxrt) compile.
Throughput (bench soak means, station→AP, channel 28, 2 MHz bandwidth):
UDP-up is the cleanest capability figure (no retransmit/pacing); ~8 Mbit/s on the N6 is close to the practical ceiling for 2 MHz bandwidth. TCP is lower across the board due to link-level loss/retransmit behaviour.
OPENMV_N6 and OPENMV_AE3 are enabled in this PR. The mimxrt port integration is included and compiles; it's exercised on hardware by an out-of-tree board (the OpenMV RT1060, an i.MX RT1062, numbers above), but no in-tree board enables HaLow on mimxrt yet.
Trade-offs and Alternatives
Generative AI
I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the code and the description above.