Evan McCord Morse

projects

The WHALE platform

Three and a half years of NSF EPSCoR funded research (the "Wisdom" team) into open technology for remote environmental sensing and infrastructure monitoring. The result is a complete open firmware platform for the RP2040: solar-powered sensor nodes on sodium-ion cells, RFM69 packet radio to a cellular gateway, MQTT out the far end. Deployed networks have 100% data retention, including through a gateway failure.

Everything is open source and open hardware (CERN-OHL-W), designed so other researchers can reproduce it from commonly available parts. There is no vendor SDK anywhere in the stack. Startup code, linker scripts, register definitions, build system, HAL, drivers, and transport are all first-party Zig, grown bottom-up as independent libraries. Each library has its own tests, its own documentation, and its own reason to exist.

munch codeberg.org/e-mo/munch
A lexer and parser toolkit for Zig. Grammars are plain Zig types and comptime declarations; parse results are ordinary structs, unions, and slices. 172 tests.
fig codeberg.org/e-mo/fig-zig
A small configuration format. Define the schema as a Zig type and fig parses a .fig file into that type, with typed errors and rendered file:line:col diagnostics. 305 tests.
jig codeberg.org/e-mo/jig
Generates thin Zig register-access modules from fig hardware manifests, wired directly into the build graph. 28 manifests describe the full RP2040 peripheral set. Hardware as data, not hand-maintained headers.
rp2040-build codeberg.org/e-mo/rp2040-build
Bare-metal build support for the RP2040: startup code, boot stage 2 CRC, vector tables, UF2 conversion, and firmware build APIs for the Zig build system.
rp2040-drivers codeberg.org/e-mo/rp2040-drivers
The HAL: 13 MCU peripheral modules and 8 device drivers (RFM69 radio, SIM7080G cellular modem, ultrasonic and temperature sensors, accelerometer, EEPROM, RTC, battery charger), with explicit ownership contracts. 324 tests.
loom codeberg.org/e-mo/loom
Reusable protocol frameworks. Currently a USB device stack with CDC ACM, split so loom owns protocol state and the HAL owns registers. The framework fell out of a driver the moment the seam became real.
rp2040-rfm69-ota codeberg.org/e-mo/rp2040-rfm69-ota
Over-the-air firmware updates across the RFM69 radio link: receiver boot firmware, transmitter relay, and a host REPL. 101 tests.
whale-build codeberg.org/WISDOM-Research/whale-build
The board-level platform for the Whale v7, including RUDP, a reliable transport for lossy low-power radio links: selective-repeat fragmentation, duplicate suppression across reboots, EEPROM-durable acknowledgments, and over-the-air wake of a dormant node in a measured 19 ms. Verified byte-for-byte at 40% injected bidirectional loss. Every number in its documentation names the bench firmware that produced it. 244 tests.
whale-examples codeberg.org/WISDOM-Research/whale-examples
26 standalone, documented example firmwares. Reference material that doubles as a standing audit of the platform's API ergonomics.
wisdom_node_hardware codeberg.org/WISDOM-Research/wisdom_node_hardware
Five revisions of custom sensor-node PCBs in KiCad, plus a 915 MHz Yagi antenna. The beautiful, hand-routed work of the Wisdom team's hardware engineer, designed in weekly collaboration. CERN-OHL-W.

This work won the Outstanding Student Presentation Award at the AGU Fall Meeting 2025.


limpet

codeberg.org/e-mo/limpet

An IO monitor that holds on. A tmux-style client/server tool in Go that watches many serial (USB CDC) and MQTT streams at once, survives disconnects and reconnects, names every stream uniformly (type:watch@unit), and formats output through pluggable formatters. Built as daily-driver tooling for sensor-network development. About 12k lines, with tests.


Fortran vs. C: an ECS performance study

The core of an entity component system, implemented twice: once in C, once in modern Fortran, a language I learned for the project. The goal was to test Fortran's claims of superior compiler auto-vectorization. Across hundreds of thousands of transformations of large data vectors, repeated thousands of times with randomized data, the Fortran implementation was consistently 10-15% faster than the C.