Precisely timing the packets from CYW43/WizNET interfaces, as they enter mircoPython 'sock' module. #19899
|
I am trying to accurately time the packets received from the CYW43 (or WizNET) devices, such as used on the Pico-1W and Pico-2W. I have a mostly working solution, using the rp2's PIO to monitor the IRQ line from the external device and trigger the DMA to read from the 1us counter, and then I can use this value after my However there are a couple of issues I have not found a solution to...
Thinking analogous to the timestamp shown in PCAP files, is there a way to (roughly) timestamp the packet as it enters the underlying microPython code? Even if I had to patch/recompile microPython... If I had a rough timestamp, I could compare and tie this to the list of (accurate) 1us timestamps. Code snippet, DMA previously stored the timestamp into an array of the last 8 timestamps. And on PC I do |
Replies: 2 comments 11 replies
|
Stock In current upstream, For a firmware patch, I'd capture a C timestamp at the receive callback and store it in that queue entry, then expose it together with the datagram when it is dequeued. A single global/latest timestamp, or even one timestamp per socket, loses the association when more than one datagram is queued. Keep the metadata coupled to the packet on queue-full drops, and don't consume it on That gives the rough timestamp you describe, earlier than the Python loop, but it is not a wire/RF arrival timestamp. It can help narrow down the DMA candidates; it doesn't make an IRQ index a unique packet identifier. Your observed extra interrupts already prevent a simple one-to-one mapping. Two details worth checking before implementing it:
Which MicroPython version and WizNET backend are you using? The queue details above are from commit |
High-Precision Packet Timestamping in MicroPython on RP2040/RP2350 (CYW43 / W5500)The root issue you are encountering stems from the architectural gap between the physical link layer (IRQ/DMA) and the lwIP socket queue in MicroPython. On the Pico W, the CYW43439 shares the wireless IRQ line (
Because of this, an IRQ burst does not guarantee a valid UDP packet arriving at Here are the two ways to solve this cleanly: Solution 1: Direct lwIP Ingress Timestamping via a MicroPython User C Module (Recommended)If you are willing to rebuild MicroPython (or compile as a dynamic In the RP2 port ( // Inside ports/rp2/cyw43_driver (or your custom lwIP hook)
#include "hardware/timer.h"
// In the packet input callback:
void my_packet_hook(struct pbuf *p) {
uint32_t hw_timestamp = timer_hw->timerawl; // 1us hardware counter
// Tag the custom payload or store in a 16-entry ring buffer keyed by (port, seq/id):
record_ingress_ts(p, hw_timestamp);
}How to expose this to Python without rewriting
|

As promised here's a slightly nicer patch to microPython to add the timestamps to CYW43 packets:
20261109_recvfrom_ts.zip
I don't have WizNet devices at present, but I expect I'll do another patch using the same technique.