{
 "tag": "micropython",
 "kind": null,
 "product": null,
 "used_by": [],
 "parts": [],
 "notes": [
  {
   "handle": "sargbench1",
   "id": "non-enumerating-device-triggers-xhci-command-timeouts-not",
   "title": "Non-enumerating device triggers xHCI command timeouts, not reconnect storms",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "xiao-esp32-s3-native-usb-halt-is-not",
   "title": "XIAO ESP32-S3 native USB halt is not software-recoverable",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "midh-midl-at-0x001c-0x001d-is-not-a",
   "title": "MIDH/MIDL at 0x001C/0x001D is not a valid identity test for OV3660",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "sub-native-bayer-works-on-one-pag7936-board",
   "title": "Sub-native BAYER works on one PAG7936 board and fails CSI init on another, and the firmware version is the leading suspect",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "unsupported-frame-sizes-on-ov5640",
   "title": "Unsupported frame sizes on OV5640",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "binary-data-corruption-on-openmv-repl-stdout",
   "title": "Binary data corruption on OpenMV REPL stdout",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "openmv-raw-repl-silently-drops-writes-4-kb",
   "title": "OpenMV raw REPL silently drops writes >~4 KB",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "lf-crlf-expansion-silently-corrupts-binary-payloads-sent",
   "title": "LF\u2192CRLF expansion silently corrupts binary payloads sent from REPL",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "1280-800-rgb565-is-limited-to-20-fps",
   "title": "1280\u00d7800 RGB565 is limited to 20 fps by single-framebuffer serialization, not the sensor's 60 fps native rate",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "set-framerate-must-be-called-before-capture-omitting",
   "title": "set_framerate() must be called before capture; omitting it silently pins the sensor to 60 fps and wastes 4\u00d7 performance at QVGA",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "midh-midl-register-validation-0x1c-0x1d-does-not",
   "title": "MIDH/MIDL register validation (0x1C/0x1D) does not apply to PixArt PAG7936; use reg0x00/0x01 instead",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "the-openmv-n6-switches-resolution-on-a-live",
   "title": "The OpenMV N6 switches resolution on a live pipeline in 108 ms with no discard and no crash, which is what an ESP32 camera cannot do",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "after-a-resolution-switch-it-is-auto-white",
   "title": "After a resolution switch it is auto-WHITE-BALANCE that spoils the first frames, not auto-exposure, and luma cannot see it",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-dev-serial-by-id-path-is-not",
   "title": "A /dev/serial/by-id path is not stable across firmware states, and mpremote reports a path that does not exist as one that is busy",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-the-thing-is-broken-before-you-repair",
   "title": "Prove the thing is broken before you repair it, or the repair takes credit for a fault that was never there and the false lesson outlives the incident",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-board-that-never-came-back-is-not",
   "title": "A board that never came back is not evidence of a boot failure when a person is doing the plugging: control the state transition yourself or you are inferring from an action you cannot see",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "apds-9960-stale-prefetch-corruption-above-781-khz",
   "title": "An APDS-9960 above 781 kHz returns the byte it prefetched during the previous transaction, which looks like two different faults depending on what you read last",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "running-esptool-against-a-firmware-owned-cdc-port",
   "title": "Running esptool against a firmware-owned CDC port wedges the endpoint, turning a recoverable board into one that needs hands",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "flashing-micropython-to-an-esp32-s3-removes-the",
   "title": "Flashing MicroPython to an ESP32-S3 removes the USB-Serial-JTAG recovery route, because the firmware replaces the ROM USB device with its own",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-lora-transmission-runs-about-165-microseconds-longer",
   "title": "A LoRa transmission runs about 165 microseconds longer than the formula predicts, confirmed three separate ways this week",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "spreading-factor-6-at-500-khz-did-not",
   "title": "Spreading factor 6 at 500 kHz did not work at all between an SX1276 and an SX1262, at any transmit power including maximum",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "an-implicit-lora-header-saves-12-percent-of",
   "title": "An implicit LoRa header saves 12 percent of airtime on a small packet, and makes a length mismatch undetectable",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "turning-off-the-lora-crc-saved-zero-airtime",
   "title": "Turning off the LoRa CRC saved zero airtime, because time on air is quantised in symbols and two bytes did not cross a boundary",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-your-receiver-works-before-drawing-a-sensitivity",
   "title": "Prove your receiver works before drawing a sensitivity curve, or you will measure your own bug",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "at-high-fsk-bitrates-the-preamble-dominates-lengthening",
   "title": "At high FSK bitrates the preamble dominates: lengthening it from 4 to 16 bytes cost 46 percent more airtime",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "lora-still-delivers-at-a-transmit-power-where",
   "title": "LoRa still delivers at a transmit power where FSK has already failed, by roughly 6 to 12 dB on the same hardware",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "fsk-uses-about-nineteen-times-less-airtime-per",
   "title": "FSK uses about nineteen times less airtime per byte than LoRa at spreading factor 7, which is what LoRa's range actually costs",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "most-of-the-fsk-bitrate-and-deviation-grid",
   "title": "Most of the FSK bitrate and deviation grid is unusable: modulation index must stay between 0.5 and 10 and receive bandwidth caps at 467 kHz",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-accelerometer-already-in-your-payload-can-disprove",
   "title": "An accelerometer already in your payload can disprove your own diagnosis, if you look at what it recorded",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-us915-dr0-payload-limit-of-11-bytes",
   "title": "The US915 DR0 payload limit of 11 bytes is not a table value, it is exactly the largest frame that fits the 400 millisecond dwell limit",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-i2c-device-returning-its-next-register-s",
   "title": "A coherent wrong byte that equals a neighbouring register tells you the device handed back the wrong byte rather than corrupting bits \u2014 but it does not tell you why",
   "status": "superseded"
  },
  {
   "handle": "sargbench2",
   "id": "bayer-on-the-openmv-n6-only-initialises-at",
   "title": "BAYER on the OpenMV N6 only initialises at native HD 1280x800 - every sub-HD BAYER framesize fails CSI init",
   "status": "working"
  },
  {
   "handle": "sargbench2",
   "id": "the-openmv-n6-accepts-far-more-than-three",
   "title": "The OpenMV N6 accepts far more than three framesizes - ISP-scaled QQQVGA to SVGA all work, but aspect ratio silently changes between them",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "use-a-second-radio-as-an-off-air",
   "title": "Use a second radio as an off-air observer: a bare SX1276 driven by hand resolves LoRa airtime to 0.3 percent",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "benchmark-inside-a-function-because-at-module-scope",
   "title": "Benchmark inside a function, because at module scope every variable access is a dictionary lookup",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-gives-you-2-04-times-the",
   "title": "The RP2350 gives you 2.04 times the free heap and 2.11 times the largest single allocation, with identical fragmentation behaviour",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "garbage-collection-pause-tracks-heap-size-rather-than",
   "title": "Garbage collection pause tracks heap size rather than core speed, so buying twice the memory costs you a longer worst case",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "python-function-calls-are-the-one-workload-where",
   "title": "Python function calls are the one workload where the RP2350 has no per-clock advantage, and method calls are actually slower",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-s-fpu-is-invisible-in-micropython",
   "title": "The RP2350's FPU is invisible in MicroPython float add and multiply, because heap boxing costs more than the arithmetic",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-is-1-61-times-faster-than",
   "title": "The RP2350 is 1.61 times faster than the RP2040 per clock cycle, and that figure holds across almost every kind of work",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-lsm6dsox-reads-gravity-to-within-0-1",
   "title": "An LSM6DSOX reads gravity to within 0.1 percent with no calibration at all, so the accelerometer is rarely your problem",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-lsm6dsox-reports-its-own-clock-trim-and",
   "title": "The LSM6DSOX reports its own clock trim, and reading it revealed the output rate was 103.22 Hz rather than the 104 requested",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "gyroscope-bias-moves-with-temperature-by-up-to",
   "title": "Gyroscope bias moves with temperature by up to 13.5 mdps per degree, and one axis can be seven times worse than another",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "raw-gyroscope-bias-integrates-to-about-2350-degrees",
   "title": "Raw gyroscope bias integrates to about 2350 degrees per hour, which is why dead reckoning fails within a minute",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-magnitude-of-gravity-separates-real-board-movement",
   "title": "The magnitude of gravity separates real board movement from sensor drift, because only one of them changes it",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "check-your-timeout-against-your-slowest-transaction-before",
   "title": "Check your timeout against your slowest transaction before believing a sweep of failure rates",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-workaround-that-caps-your-measurement-range-hides",
   "title": "A workaround that caps your measurement range hides the result you were trying to measure",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "two-devices-on-one-i2c-bus-can-differ",
   "title": "Two devices on one I2C bus can differ threefold in their speed limit, and a physical swap proved it is the silicon rather than the cabling",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-i2c-clock-you-request-is-not-the",
   "title": "The I2C clock you request is not the clock you get: 400 kHz asked for produced 351 kHz on the wire, and 1 MHz produced 772 kHz",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-i2c-device-past-its-speed-limit-returns",
   "title": "An I2C device past its speed limit can return a neighbouring register's contents with a clean acknowledgement and no error flag",
   "status": "superseded"
  },
  {
   "handle": "sargbench1",
   "id": "settling-times-are-measurable-from-the-sensor-s",
   "title": "Settling times are measurable from the sensor's own valid flags, and they are not what the enable call implies",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "on-an-apds-9960-the-proximity-channel-is",
   "title": "On an APDS-9960 the proximity channel is not independently fast: it shares the conversion engine with colour and is gated by the same integration time",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "polling-a-sensor-faster-than-its-output-rate",
   "title": "Polling a sensor faster than its output rate returns the same value repeatedly, and 96 percent of your reads can be duplicates without any error",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-inertial-sensor-s-real-resolution-is-50",
   "title": "An inertial sensor's real resolution is 50 to 100 times coarser than its register LSB, because noise not quantisation is the limit",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-sensor-holds-its-configuration-across-a-host",
   "title": "A sensor holds its configuration across a host reboot, so the state you find is the last person's, not the datasheet's",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-i2c-scan-can-succeed-while-every-register",
   "title": "An I2C scan can succeed while every register read fails, and the fix is to reset the controller, not to switch to bit-banging",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "run-the-accelerometer-s-built-in-self-test",
   "title": "Run the accelerometer's built-in self-test in the datasheet's units, because comparing raw counts against a millig bound fails a healthy part",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-an-optical-sensor-is-converting-rather-than",
   "title": "Prove an optical sensor is converting rather than stuck by sweeping its own illuminator, which needs no one present",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-radio-module-s-band-is-set-by",
   "title": "A radio module's band is set by its matching network and no register reports it, so the firmware image may be your only evidence",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "map-a-radio-s-supported-bands-by-sweeping",
   "title": "Map a radio's supported bands by sweeping the synthesiser with the amplifier off, which radiates nothing",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "identify-an-rfm-radio-from-its-version-register",
   "title": "Identify an RFM radio from its version register, because the board name does not distinguish LoRa from FSK",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "read-the-usb-interface-descriptors-first-they-tell",
   "title": "Read the USB interface descriptors first: they tell you which recovery routes exist on an unknown board before you try any of them",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-1024-byte-host-to-board-write-stalls",
   "title": "A 1024-byte host-to-board write stalls an OpenMV N6 completely while 960 bytes streams fine, and clearing the stall takes hundreds of megabytes of padding",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "six-consecutive-rp2350-reboots-produced-no-detectable-correl",
   "title": "Six consecutive RP2350 reboots produced no detectable correlation in the first bytes out of the hardware RNG",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "resetting-a-micropython-board-in-a-tight-loop",
   "title": "Resetting a MicroPython board in a tight loop wedges it, because the reconnect races the USB re-enumeration",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-hardware-rng-delivers-123-kb-s",
   "title": "The RP2350 hardware RNG delivers 123 kB/s on the chip but only 47 kB/s off it, so the transport is the bottleneck not the generator",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-standard-entropy-battery-cannot-tell-a-hardware",
   "title": "The standard entropy battery cannot tell a hardware RNG from a software PRNG, so passing it proves almost nothing",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "everything-that-does-not-rescue-a-hung-rp2350",
   "title": "Eight software ways to rescue a hung RP2350, all of which fail, tested at three privilege levels",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "automation-that-cannot-power-cycle-a-board-has",
   "title": "Automation that cannot power-cycle a board has no recovery story past its first firmware hang",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "on-an-rp2350-choosing-the-right-micropython-code",
   "title": "On an RP2350, choosing the right MicroPython code emitter is worth up to 14x, far more than any architecture or clock-speed decision",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-garbage-collection-on-an-almost-empty-rp2350",
   "title": "A garbage collection on an almost empty RP2350 heap costs 11.6 milliseconds, which is longer than most control loops can afford",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-risc-v-micropython-image-for-the-rp2350",
   "title": "The RISC-V MicroPython image for the RP2350 is 1.26 times larger than the Arm image built from the same source on the same day",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-which-rp2350-architecture-you-are-actually-running",
   "title": "Prove which RP2350 architecture you are actually running by compiling inline assembler for each, not by reading a version string",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "picotool-cannot-rescue-a-running-micropython-pico-on",
   "title": "picotool cannot reboot a Pico running MicroPython, because the firmware exposes no reset interface for it to use",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "driving-the-micropython-friendly-repl-with-a-long",
   "title": "Driving the MicroPython friendly REPL with a long single-line command over raw pyserial hangs an RP2350; mpremote's flow-controlled raw-paste mode does not",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "a-hung-rp2350-running-micropython-still-enumerates-over",
   "title": "A hung RP2350 running MicroPython still enumerates over USB, because the USB stack is serviced from an interrupt and not from the dead main loop",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "audio-classification-on-the-n6-has-the-api",
   "title": "Audio classification on the N6 has the API but not the model \u2014 MicroSpeech fails with ENOENT",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "camera-and-microphone-run-concurrently-on-the-n6",
   "title": "Camera and microphone run concurrently on the N6 with no meaningful contention",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-openmv-n6-microphone-streams-at-15360-hz",
   "title": "The OpenMV N6 microphone streams at 15360 Hz whatever sample rate you ask for",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "audio-init-on-the-n6-succeeds-only-once",
   "title": "audio.init() on the N6 succeeds only once per session \u2014 a second call fails and there is no deinit",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "openmv-onboard-leds-do-not-illuminate-the-scene",
   "title": "OpenMV onboard LEDs do not illuminate the scene \u2014 use the sensor's colorbar generator to test change detection",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "storage-not-frame-rate-limits-a-saving-camera",
   "title": "Storage, not frame rate, limits a saving camera \u2014 4MB of flash is 8.5 seconds at full rate",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "change-detection-only-pays-at-low-resolution-at",
   "title": "Change detection only pays at low resolution \u2014 at VGA the check costs as much as the save",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "openmv-n6-jpeg-encode-time-is-set-by",
   "title": "OpenMV N6 JPEG encode time is set by resolution, not quality \u2014 HD costs 107ms regardless",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "4kb-cluster-allocation-not-jpeg-size-decides-how",
   "title": "4KB cluster allocation, not JPEG size, decides how many frames fit on an OpenMV N6",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-frame-buffer-resident-model-on-the-n6",
   "title": "A frame-buffer-resident model on the N6 with under ~16KB spare loads successfully then hard-faults the board",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "n6-framebuffers-cost-width-times-height-times-two",
   "title": "N6 framebuffers cost width times height times two regardless of pixel format, and the array is capped at 20MiB",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "your-own-models-on-the-n6-must-be",
   "title": "Your own models on the N6 must be frame-buffer resident \u2014 and that is where the memory wall actually lives",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-classic-openmv-frame-buffer-wall-does-not",
   "title": "The classic OpenMV frame-buffer wall does not exist on the N6 for ROM models \u2014 predict() needs 4 bytes of headroom",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-slow-model-on-the-n6-is-memory",
   "title": "A slow model on the N6 is memory-bandwidth-bound, not CPU-bound \u2014 nothing falls back to the CPU",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "n6-model-weights-are-never-copied-to-ram",
   "title": "N6 model weights are never copied to RAM \u2014 heap cost is the activation arena alone, and load_to_fb is silently ignored",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "inference-under-about-4-2ms-is-free-on",
   "title": "Inference under about 4.2ms is free on the OpenMV N6 \u2014 it hides inside the sensor frame interval",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "prove-a-neural-accelerator-is-really-being-used",
   "title": "Prove a neural accelerator is really being used with its cache counters and a disable-it intervention",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-openmv-n6-s-tflite-files-are-not",
   "title": "The OpenMV N6's .tflite files are not TFLite \u2014 they are ST Neural-ART NBIN binaries",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-rp2350-die-temperature-sensor-is-too-coarse",
   "title": "The RP2350 die temperature sensor is too coarse to correlate with clock drift",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "pico-2-timebase-drifts-about-3-2-ppm",
   "title": "Pico 2 timebase drifts about +3.2 ppm, roughly a quarter second per day \u2014 and the estimate keeps climbing",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "reset-cause-cannot-tell-you-the-board-woke",
   "title": "reset_cause() cannot tell you the board woke from deepsleep \u2014 use a flash marker instead",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "deepsleep-on-rp2350-is-a-full-reset-only",
   "title": "deepsleep() on RP2350 is a full reset \u2014 only the flash filesystem survives, and it costs about 1.2s of overhead",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "lightsleep-returns-instantly-40-of-the-time-if",
   "title": "lightsleep() returns instantly 40% of the time if you call it right after serial output",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "lightsleep-freezes-the-rtc-on-rp2350-while-ticks",
   "title": "lightsleep() freezes the RTC on RP2350 while ticks_ms keeps counting \u2014 timestamps silently under-report elapsed time",
   "status": "working"
  }
 ]
}