Skip to content

Redesign/reimplement firmware and add revD support - #1181

Merged
whitequark merged 22 commits into
GlasgowEmbedded:mainfrom
whitequark:firmware-revd
Jul 23, 2026
Merged

Redesign/reimplement firmware and add revD support#1181
whitequark merged 22 commits into
GlasgowEmbedded:mainfrom
whitequark:firmware-revd

Conversation

@whitequark

@whitequark whitequark commented Jun 18, 2026

Copy link
Copy Markdown
Member

The new FX2 firmware has complete feature parity with the old FX2 firmware,
with the following major changes:

  • reimplement board/port/FPGA management USB protocol to be network transparent
  • reimplement handling of USB endpoint buffering to significantly increase
    throughput on Windows and open the door for e.g. all-OUT/all-IN configurations
  • reimplement port management commands to take a mask and four distinct values
    (documented in firmware/fx2/glasgow_mgmt.h)
  • add support for ECP5 SRAM bitstream loading
  • add support for using ports C, D on revD0
  • extend I/O voltage range to 1.2-5.5 V on revD0 (from 1.8-5.0 V on revABC)
  • implement a more robust fault system:
    • faults are distinguished by the port they occurred on, and on their type
      (Isupply over-current, Vsense over-voltage, Vsense under-voltage)
    • faults can be cleared in a fine-grained manner
    • unsolicited fault reports are sent by the firmware
    • unsolicited fault reports are logged by the software
  • add support for FPGA reporting interrupts via I2C and the FX2
    • uses the same mechanism as supply fault reporting
    • fully implemented and tested in FX2 firmware
    • not yet integrated in software from either FPGA or host side
  • implement supply disconnection on over-current on revC23D
  • add CLI for current limiting: glasgow voltage AB 3.3 0.125 (3.3 V, 125 mA)
  • implement glasgow flash --advertise-webusb to get rid of the notification
  • disable Vsense range alert on revABC01 due to suspected ADC silicon erratum
    (see firmware/fx2/port.c)

The following revD-only features are not implemented for the time being:

  • STM32 bootloader in FX2
  • NAFE bridge commands via the STM32
  • ECP5 non-volatile bitstream programming/loading and STM32-based strapping
  • OctoSPI memory controller

To do:

  • ensure default Ilimit of 0.1 A can be turned off
  • Ilimit overflow not detected
  • ERR LED active after boot on revD
  • health check fails, only on Windows

To test:

  • review firmware and gateware to make sure there is never contention on PORTB
  • performance on Windows
  • any applet that may have been indirectly affected by the changes
`glasgow run benchmark` on Windows
I: glasgow.hardware.device: device already has bitstream ID 99dba768d228a693
I: glasgow.cli: running handler for applet 'benchmark'
I: glasgow.applet.internal.benchmark: running benchmark mode source for 8.000 MiB
I: glasgow.applet.internal.benchmark: mode source: 40.83 MiB/s (326.62 Mb/s)
I: glasgow.applet.internal.benchmark: running benchmark mode sink for 8.000 MiB
I: glasgow.applet.internal.benchmark: mode sink: 40.35 MiB/s (322.80 Mb/s)
I: glasgow.applet.internal.benchmark: running benchmark mode loopback for 8.000 MiB
I: glasgow.applet.internal.benchmark: mode loopback: 41.03 MiB/s (328.26 Mb/s)
I: glasgow.applet.internal.benchmark: running benchmark mode latency for 8.000 MiB
I: glasgow.applet.internal.benchmark: mode latency: mean: 377.36 µs stddev: 95.82 µs worst: 3415.90 µs

@whitequark
whitequark requested a review from purdeaandrei as a code owner June 18, 2026 11:57
@whitequark
whitequark force-pushed the firmware-revd branch 7 times, most recently from 6f4b75c to 13aa799 Compare June 23, 2026 16:06
@whitequark
whitequark force-pushed the firmware-revd branch 3 times, most recently from af4df3e to b20d903 Compare June 28, 2026 21:20
@whitequark whitequark changed the title [WIP] Reimplement firmware and management protocol; add revD support [WIP] Redesign/reimplement firmware and add revD support Jun 28, 2026
@whitequark
whitequark force-pushed the firmware-revd branch 6 times, most recently from 43c4457 to b374255 Compare June 29, 2026 21:07

@ld-cd ld-cd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MGMT Comments

Comment thread firmware/fx2/glasgow_mgmt.h Outdated
Comment thread firmware/fx2/glasgow_mgmt.h

@q3k q3k left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 8051 code seems to do what it should do. But that's a given, because it has already been tested to work.

But that's only part of what a code review is for... For me it's also about having the code be understood and maintained by more than one person. So I approached it as an exercise in me getting into the code and trying to understand it pretty much fully, and this turned out to be more of a readability review than a correctness review.

Overall I do believe that it would really benefit from a quite deep documentation pass. This code is on an intersection between two hellish topics (8051 SDCC code and USB) and even the smallest amount of documentation is immensely helpful. It took me a while to get through all of this because I basically had to build a mental model of the codebase from scratch with almost nothing helping me along the way. There's a lot of concepts that jump out on a first read (ports? endpoints? configuration? fpga configuration? nvm? i2c? smbus?) and it's difficult to read the code subsystem-by-subsystem because of how intertwined everything ends up being. Some handholding of the concepts being clearly explained when first encountered (ie. at the top of files, eg. header files) would have really helped steer me from having to guess and test my assumptions vs. just being able to get on with reading things.

I've left a bunch of comments requesting such docs, which are just a reflection of a small subset of thoughts I've had pop into my head while reviewing the code at first and having trouble understanding what's going on. These could be a good jumping off point to add critical documentation points.

But more broadly I think that:

  1. All 'public' functions in headers need a documentation string, and a quite verbose one at that. Assume basic famililarity with how a Glasgow works, but not necessarily how the FIFO setup works, how endpoints get reconfigured as the device is used, etc.
  2. All 'public' structures/enums/types in headers need a documentation string.
  3. Documentation should clearly state when some is used and by what, are values/types some parts of some fixed protocol or are they just some local decisions/defines.
  4. Extra care should be put in to document 'hidden' argument variables that would usually be passed explicitly but end up being global variables due to 8051/SDCC constraints.

Comment thread firmware/fx2/Makefile Outdated
Comment thread firmware/fx2/nvmem.c Outdated
Comment thread firmware/fx2/nvmem.c Outdated
Comment thread firmware/fx2/glasgow.h Outdated
uint32_t bitstream_size;
char bitstream_id[CONFIG_SIZE_BITSTREAM_ID];
uint32_t unused;
uint16_t voltage_limit[4];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a good place to document what voltage limits are.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread firmware/fx2/glasgow.h Outdated
Comment thread firmware/fx2/fpga.c
Comment thread firmware/fx2/port.c
return smbus_run(get_vsupply_revabc_seq, dac_addr_revabc[chan]);
}

// ===== revABC01 ADC081C =========================================================================

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably split this back out into multiple files per ADC/generation?

@whitequark whitequark Jul 17, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it this way because there are no clear generations. We have a smooth transition from revA to revD that replaces bits piecemeal without ever having a clean break. So there is a clear case to be made for a ton of source files, or for a single file. I figured a single file makes more sense here, considering how it's all interdependent anyway.

(I did not originate the per-ADC split, it was done by someone else who implemented the INA233 support. That said, it made more sense with revC.)

Comment thread firmware/fx2/fpga.c
Comment thread firmware/fx2/fpga.c
Comment thread firmware/fx2/main.c Outdated
@whitequark

Copy link
Copy Markdown
Member Author

Thanks for the review! I essentially agree with your conclusions. I'll reply to some of the comments that relate to technical constraints first, then update the firmware sources to address review (which will be almost exclusively documentation work).

@ld-cd ld-cd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still need to look through the python changes

Comment thread firmware/fx2/fpga.c
Comment thread firmware/fx2/fpga.c
Comment thread firmware/fx2/nvmem.c
Comment thread firmware/fx2/glasgow.h
Comment thread firmware/fx2/main.c
Comment thread firmware/fx2/main.c
Comment thread firmware/fx2/fpga.c
Comment thread firmware/fx2/port.c
@whitequark whitequark changed the title [WIP] Redesign/reimplement firmware and add revD support Redesign/reimplement firmware and add revD support Jul 22, 2026
This is currently not well surfaced (in particular the types are not
updated for this case), but it's a useful escape hatch e.g. to talk
to the NAFE using the SPI controller applet:

    # ...
    afe_adc = assembly._platform.request("afe_adc", dir={
        "reset": "o",
        "cs":    "-",
        "clk":   "-",
        "copi":  "-",
        "cipo":  "-",
        "int":   "i",
        "sync":  "o",
        "drdy":  "i",
    })
    # ...
    spi_iface = SPIControllerInterface(logger, assembly,
        cs=~afe_adc.cs, sck=afe_adc.clk,
        copi=afe_adc.copi, cipo=afe_adc.cipo,
        mode=spi.Mode.from_cpol_cpha(cpol=0, cpha=1)
    )
    # ...
This error is reported by libusb if you stall a Set Interface request.

@ld-cd ld-cd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still got some more to work through

Comment thread software/glasgow/gateware/pll/__init__.py
Comment thread software/glasgow/gateware/pll/__init__.py Outdated
Comment thread software/glasgow/gateware/pll/bench.py
Comment thread software/glasgow/gateware/pll/ecp5.py
Comment thread software/glasgow/gateware/pll/ecp5.py
Comment thread software/glasgow/gateware/pll/ecp5.py
Comment thread software/glasgow/gateware/pll/ice40.py Outdated
Comment thread software/glasgow/gateware/pll/ecp5.py
Comment thread software/glasgow/hardware/assembly.py
Comment thread software/glasgow/gateware/pll/__init__.py Outdated
Comment thread software/glasgow/hardware/assembly.py
Comment thread software/glasgow/hardware/assembly.py
Comment thread software/glasgow/hardware/device.py Outdated
Comment thread software/glasgow/hardware/device.py

@ld-cd ld-cd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats everything I was worried about resolved

Comment thread software/glasgow/gateware/pll/ecp5.py
The new FX2 firmware has complete feature parity with the old FX2
firmware, with the following major changes:
- reimplement board/port/FPGA management USB protocol to be network
  transparent
- reimplement handling of USB endpoint buffering to significantly
  increase throughput on Windows and open the door for e.g. all-OUT or
  all-IN configurations
- reimplement port management commands to take a mask and four distinct
  values (documented in `firmware/fx2/glasgow_mgmt.h`)
- add support for ECP5 SRAM bitstream loading
- add support for using ports `C`, `D` on revD0
- extend I/O voltage range to 1.2-5.5 V on revD0 (from 1.8-5.0 V on
  revABC)
- implement a more robust fault system:
  - faults are distinguished by the port they occurred on, and on their
    type (Isupply over-current, Vsense overvoltage, Vsense undervoltage)
  - faults can be cleared in a fine-grained manner
  - unsolicited fault reports are sent by the firmware
  - unsolicited fault reports are logged by the software
- add support for FPGA reporting interrupts via I2C and the FX2
  - uses the same mechanism as supply fault reporting
  - fully implemented and tested in FX2 firmware
  - not yet integrated in software from either FPGA or host side
- implement supply disconnection on over-current on revC23D
- add CLI for current limiting: `glasgow voltage AB 3.3 0.125` (3.3 V,
  125 mA)
- implement `glasgow flash --advertise-webusb` to get rid of
  the notification
- disable Vsense range alert on revABC01 due to suspected ADC silicon
  erratum (see `firmware/fx2/port.c`)

The following revD-only features are not implemented for the time being:
- STM32 bootloader in FX2
- NAFE bridge commands via the STM32
- ECP5 non-volatile bitstream programming/loading and STM32-based
  strapping
The full functionality is implemented for both iCE40 and ECP5.
@whitequark
whitequark force-pushed the firmware-revd branch 2 times, most recently from 576fe83 to 234f5fe Compare July 23, 2026 01:15
See GlasgowEmbedded#1203. This is a temporary solution in lieu of something better
@whitequark

Copy link
Copy Markdown
Member Author

Wow, this monstrous PR is finally done! 🎉

Many thanks to @q3k and @ld-cd for the very thorough review.

@whitequark
whitequark enabled auto-merge July 23, 2026 01:56
@whitequark
whitequark added this pull request to the merge queue Jul 23, 2026
Merged via the queue into GlasgowEmbedded:main with commit 5c24219 Jul 23, 2026
14 checks passed
@whitequark
whitequark deleted the firmware-revd branch July 23, 2026 02:20
@whitequark whitequark mentioned this pull request Jul 23, 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

Development

Successfully merging this pull request may close these issues.

3 participants