The HPS prototype board revision 2 (“proto2”) is an external board with the HPS circuit, plus additional components which are useful for development. The board is not publicly available. Googlers can refer to go/hps-care for more details about the hardware.
The proto2 board uses an FTDI FT4232H chip to provide UART and power control to the host over USB, and an MCP2221 chip for I2C over USB. It needs some extra packages and configuration on the host (your gLinux workstation) before you can use it.
Run the setup script inside the ChromiumOS chroot:
scripts/setup
Also run the accompanying setup script outside the chroot. This script grants permission for your user account to access the relevant USB devices:
scripts/setup-proto2-on-host
If your user account cannot access the FT4232H USB device, the helper scripts may print an error like:
ValueError: The device has no langid (permission issue, no string descriptors supported or device error)
or:
Error: libusb_open() failed with LIBUSB_ERROR_ACCESS Error: no device found Error: unable to open ftdi device with vid 0403, pid 6011, description '*', serial '*' at bus location '*'
If your user account cannot access the MCP2221 USB device, the helper scripts may print an error like:
Error: Failed to open HPS via I2C: USB error: Access denied (insufficient permissions)
Start OpenOCD:
scripts/proto2-openocd
Example output:
** Programming Started ** ** Programming Finished ** ** Verify Started ** ** Verified OK ** ** Resetting Target ** Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections
Leave the script running OpenOCD in one terminal, and continue working in another terminal. Scripts such as mcu-run
and fpga-rom-run
interact with OpenOCD over port 4444.
To build and run the MCU program, run:
scripts/mcu-run
This helper script builds the MCU application with development features enabled, then programs it onto the MCU flash and runs it. It then shows output from the MCU program and allows further interaction.
scripts/proto2-power-cycle.py
, then run scripts/mcu-run
again.When the MCU application is built with development features enabled, it accepts debugging commands using the RTT (Real-Time Transfer) protocol.
Use the monitor program to interact with the MCU over RTT. In the terminal that's running scripts/mcu-run
, press enter to activate the console, then type a command. The monitor prints messages it receives over RTT. Example output:
>> reset_mcu MCU> INFO: Found expected flash chip MCU> INFO: Default HM01B0 configuration applied MCU> INFO: MCU application started. CPU is running at 60MHz >> launch_app Command LaunchApp running Command LaunchApp complete MCU> INFO: FPGA reported boot #1 FPGA> Hello from the Rust FPGA FPGA> Classifier status: InitOk
You can also program the FPGA bitstream and FPGA application image via the MCU using the write_gateware
and write_soc_rom
commands. The script assumes you have already built the bitstream and application using the scripts/build-fpga-bitstream
and scripts/build-fpga-rom-dev
helper scripts.
Check help
for a complete list of monitor commands.
On a real HPS peripheral, the stage0 boot loader is permanently programmed at the beginning of flash, and it executes the stage1 application from an offset in flash after verifying its signature. When working with proto2, we typically skip the stage0 boot loader because it’s not necessary for development. The scripts/mcu-run
helper script mentioned above writes the application to the beginning of flash; the stage0 boot loader is not involved.
However, if you are testing a change to the stage0 boot loader, you may want to run it on proto2. There is a corresponding helper script for stage0:
scripts/proto2-stage0-run
There is no monitor command for stage0. It does not support RTT. You can interact with stage0 using the hps-util
Rust tool or the C++ hps
tool from platform2.
On proto2 the WP (Write Protect) line is controlled by a GPIO pin on the FT4232H. If you want to test stage0 signature verification, you can assert WP:
scripts/proto2-power-cycle.py --write-protect
By default the script deasserts WP.
Note that although proto2 has UART connections, HPS firmware does not have any code or FPGA logic for interacting with the UART. You will not see any output on the UART. However, the proto2 UART connections are still useful with CFU-Playground, where the code does interact with the UART.
To connect your terminal to the UART, run:
scripts/proto2-term
This script wraps the Litex terminal interface. Press Control-C twice in quick succession to disconnect.
On proto2 the MLB interrupt line (signal from HPS to the main logic board to request its attention) is connected to an ATmega16u4 USB-capable MCU. Its UART is connected to FT4232H port D and its USB interface is connected to proto2's USB hub.
In order to observe the interrupt line, you need to program the ATmega16u4:
scripts/avr-prog
You can then run the helper script to watch the UART output from the ATmega16u4:
scripts/avr-term
The UART output will show !
when the interrupt line goes high and .
when it goes low.
The hps-mon
and hps-util
tools can also monitor the interrupt line state via the ATmega16U4 UART. Pass --interrupt=avr-ftdi-proxy
to enable support.
If you use hps-factory
to write stage0 to proto2, it will also configure readout protect (RDP) level 1 to protect the MCU flash. OpenOCD (and all the helper scripts) will then be unable to program flash in that case:
[...] Error: stm32x device protected Error: failed erasing sectors 0 to 28 embedded:startup.tcl:530: Error: ** Programming Failed ** in procedure 'program' in procedure 'program_error' called at file "embedded:startup.tcl", line 595 at file "embedded:startup.tcl", line 530
To remove RDP and unlock the flash, first start the OpenOCD helper script:
scripts/proto2-openocd
In another terminal, use GDB to issue the necessary register writes:
arm-none-eabi-gdb \ --ex 'target extended-remote localhost:3333' \ --ex 'set {int}0x40022008 = 0x45670123' \ --ex 'set {int}0x40022008 = 0xCDEF89AB' \ --ex 'set {int}0x4002200c = 0x08192A3B' \ --ex 'set {int}0x4002200c = 0x4C5D6E7F' \ --ex 'set {int}0x4002202c = 0x3f' \ --ex 'set {int}0x40022020 = 0xfffffeaa' \ --ex 'set {int}0x40022014 = 0x20000'