Since most of this week has been a refactoring slog on the HDL compiler, I'll instead talk about the engineering for the source-measure unit (SMU, HDL here) and multimeter (HDL here) example design boards that were built last year, but only started to get brought up. As a recap, a SMU is a combination DC power supply, DC load (think programmable variable resistor), and voltage and current meters. A pretty versatile piece of lab equipment, but also expensive (commercial units are thousands of dollars - even used), big, and bulky.
The idea behind the SMU example design was to make a minimal functional unit, at low cost, and as a physically compact unit. The low cost comes from using inexpensive parts and sacrificing high precision (possibly calibrating it out in software), while the compactness comes from using an external power supply (using the now ubiquitous USB Type-C PD) and giving zero thought to thermal design (needs to be addressed in a future revision). The analog stage is largely based off the PS-Load project, which has one of the more clear and understandable circuits that also decomposes nicely into functional blocks for this HDL system.
In any case, firmware work to bring up these boards have been happening over the past two months. The SMU code largely went as expected, given familiarity with the LPC1549 microcontroller. It consists of a few device-specific software components, like the USB PD driver and the analog stage controller that tries to provide soft-start capability (and avoid startup transients from integrator windup). And in testing, these mostly seem to work.
There are also a few more general software components, including protobuf-based nonvolatile configuration and USB interface. Protobuf (protocol buffers) are an interface-definition language (think C structs) that provides cross-language (de)serialization (because writing parsers is a waste of time for non-specialty applications). Protobuf-based nonvolatile configuration allows for backward compatibility - as the schema evolves, it will continue to read old versions of the schema. It also works with all the tooling around protocol buffers - for example, strong typing and human-friendly printing - which would otherwise have to be written from scratch.
Similarly, there is a layer that provides a protobuf abstraction for USB communications. This uses USB HID as the underlying transport layer (because it's driver-free and requires no additional installation, and hid4java provides cross-OS host support in JVM languages), but instead of needing to work with USB HID's very low-level 64-byte packet structure, it presents the higher-level and structured protobuf interface and handles the underlying (de)serialization and (de)packetization.
The SMU communication and config protocols are all on GitHub.
It's worth noting that USB provides a class for instruments as USB TMC (Test and Measurement Class). The downside for that is that would need driver installation, so setup (and user experience) becomes a lot more complicated. There also aren't as much device-side libraries for USB TMC, whereas USB HID is included with mbed.
This entire stack does work, with a Scala program sending commands to the SMU, here for calibration purposes by sweeping through commanded voltages and currents. Referencing against a Fluke multimeter, it's surprisingly linear!
The multimeter board bringup was much less straightforward, since on the nRF52840 several pins are not configured to be GPIOs by default and need additional code to be used as GPIOs. In particular, SWO must be disabled with NRF_CLOCK->TRACECONFIG = 0;
and NFC must be disabled with a compiler flag -DCONFIG_NFCT_PINS_AS_GPIOS
But otherwise, the main functional blocks are tested (not shown: blue wire fixes to get the USB working and correct the voltage divider reference) - and what better way to test custom test equipment ... with custom test equipment! It hasn't been tested for linearity yet (calibration to come soonTM), and at some point I'll test dropping in a MCP3553 (22b ADC, sigma-delta type) to replace the MCP3201 (12b ADC, SAR type - annoyingly it's ALMOST pin compatible except they inexplicably swapped the SCK and CS pins - whyyy).