Hermetic Modular

10/Board Support

Under the Framework

Every surface in this documentation is optional except this layer. The BSP is a deliberately thin board class in the Daisy tradition: pins mapped, drivers wired, nothing decided for you. If you want the framework's UX you opt in; if you want raw hardware, it is all here.

The hw object

One class, AlchemyLab, is the whole board. Construct it statically, call Init(), and every peripheral is a member.

MemberWhat it is
seedthe Daisy Seed underneath, with every libDaisy API intact
pots[kNumPots]Processed normalized pot values, 0–1. V2 applies pot conditioning.
buttons[i]uniform debounced access to B1, B2, B3
j1, j2AC-coupled codec inputs with consumed RisingEdge() detection while the audio path runs.
j3 through j8Switchable CV jacks with calibrated voltage access and backend-dependent output update behavior.
j9, j10DC-coupled codec outputs that can be claimed for nominally scaled CV.
ledsthe LED panel: per-ring, per-pixel, raw 8-bit RGB
Layout() / Arc()geometry: which LEDs ring which pot

Life without the framework

A bare-metal Alchemy firmware is a normal Daisy program: init, start audio, then your own forever-loop polling controls and painting LEDs. examples/cv_playground is written exactly this way, no ControlLoop attached, and is the reference for the whole jack API: saws out of six analog jacks, edge detection on the codec inputs, live direction flips on B2.

minimal bare-metal shape
static AlchemyLab hw;

int main()
{
    hw.Init();
    hw.StartAudio(AudioCallback);

    for (;;)
    {
        hw.ProcessAllControls();
        const float p0 = hw.pots[0].Value();
        hw.leds.SetRingByHour(0, p0 * 12.f, {0xC9, 0xA8, 0x4C});
        hw.leds.Show();
        daisy::System::Delay(1);
    }
}

Starting the audio path without application DSP

On Alchemy Lab V2, hw.StartAudio() can run without an application callback:

hw.Init();
hw.StartAudio();

The SDK still processes J1/J2 trigger detection and fills J9/J10 channels claimed for CV output. Unclaimed audio outputs are cleared.

Use hw.StartAudio(AudioCallback) when the application processes audio. A claimed codec CV output is filled by the SDK after that callback returns, replacing the samples written to that channel. DisableCvOutput() returns the channel to the application callback.

The audio callback, control polling, and LED frame are separate schedules. At 48 kHz with 24-sample blocks, the audio callback runs 2,000 times per second. The default control loop polls approximately every millisecond and renders approximately every 16 ms.

Keep formatted diagnostics and blocking peripheral operations on the main/control thread. A diagnostics gauge can publish a scalar from the audio callback without formatting or transmitting USB data there.

The drivers

Everything under the board class is an ordinary header you can read, reuse, or replace: the WS2812 LED chain, the MCP4728 external DAC, the PCA9557 expander behind B3, the switchable-jack analog switches, trigger-jack edge detection, and the calibration store. They conform to the Electrosmith Daisy ecosystem's conventions, so experience with libDaisy transfers directly.