Skip to content

RegSpec Interface Update and Touchups#76

Open
Poofjunior wants to merge 15 commits intoharp-tech:mainfrom
AllenNeuralDynamics:main
Open

RegSpec Interface Update and Touchups#76
Poofjunior wants to merge 15 commits intoharp-tech:mainfrom
AllenNeuralDynamics:main

Conversation

@Poofjunior
Copy link
Copy Markdown
Collaborator

@Poofjunior Poofjunior commented Apr 3, 2026

Note

Full disclosure! We've started using this branch on devices (quad-dac) we're developing now.

Summary

This PR is a rewrite of how we define registers to consolidate all register-related info into one location based on some related discussion in #47 . This looks simple, but it's a huge readability cleanup for creating/maintaining harp devices with a few bugfixes along the way. It's also not necessarily the way we'll do things long-term, but the pico core project is versioned, so we can always make changes later.

(This is a breaking change because we changed some function signatures and made some previously-exposed functions private.)

Here's the breakdown:

  • RegSpecs and RegFnPair are now combined into RegSpec, reducing the bookkeeping we needed to do between arrays of these elements, which was cumbersome and error-prone for more than a couple registers.
  • Custom named constructors exist to cleanup the creation of RegSpecs. These include one per every primitive Harp data type (i.e: RegSpec::U8, RegSpec::U8Array, etc), and they reduce the boilerplate and bookkeeping to create custom registers.
  • get rid of the need to cast register data to (uint8_t*)
  • Example has now been rewritten too.

Fixes

Example

Common:

// Harp App Register Setup.
const size_t app_reg_count = 2;

// Define register contents.
struct app_regs_t
{
    volatile uint8_t test_byte;  // app register 0
    volatile uint32_t test_uint; // app register 1
} app_regs;

Old:

// Define register "specs."
RegSpecs app_reg_specs[app_reg_count]
{
    {(uint8_t*)&app_regs.test_byte, sizeof(app_regs.test_byte), U8}, // lol wut
    {(uint8_t*)&app_regs.test_uint, sizeof(app_regs.test_uint), U32}
};

// Define register read-and-write handler functions.
RegFnPair reg_handler_fns[app_reg_count]
{
    {&HarpCore::read_reg_generic, &HarpCore::write_reg_generic},
    {&HarpCore::read_reg_generic, &HarpCore::write_to_read_only_reg_error}
};

New:

// Define register "specs."
RegSpec app_reg_specs[app_reg_count]
{
    RegSpec::U8(&app_regs.test_byte,
        HarpCore::read_reg_generic, HarpCore::write_reg_generic),
    RegSpec::U32(&app_regs.test_uint,
        HarpCore::read_reg_generic, HarpCore::write_to_read_only_reg_error)
};

Testing

This works when issuing a "DUMP" event of all registers from pyharp. I will follow-up by rewriting the interface to an existing device to clean it up.

Harp.device.quac examples also work after rewriting the Harp interface to represent the changes in the core API above.

@Poofjunior Poofjunior assigned Poofjunior and unassigned bruno-f-cruz Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants