How to run the pin ID test on an Acorn on a Raspberry Pi 5¶
You have an Acorn wired to a Raspberry Pi 5 and want each P2 ball to send its own name.
The boot check names a wrong wire on the fpgas.online design: How to run the Acorn check on a Raspberry Pi 5. This page reads each ball’s own name instead. It needs that design in the card’s flash, because step 7 checks for 10ee:7021. On a Compute Blade the load differs: How to run the pin ID test on an Acorn on a Compute Blade.
This procedure is waiting for its run: test-designs issue #229.
Warning
Never drive a Pi GPIO against an FPGA output. With the pin-ID design loaded, every P2 ball is an FPGA output, J2 included. Setting GPIO14 to a4 (TXD0) or op while pin-ID runs is then output against output on the J2 wire, and it crashes the Pi. Probe with pinctrl set 14 ip pn (input, no pull). Restore pinctrl set 14 a4 only once a design that treats J2 as an input is loaded.
What you need¶
An Acorn wired as on Acorn wiring on a Raspberry Pi 5, in the M.2 HAT slot, where the card is at
0001:01:00.0.The fpgas.online design in the card’s flash:
lspci -nn -s 0001:01:00.0shows10ee:7021before you start. Step 7 checks the card by that ID.At a site, the site operator’s agreement first. The card is off the PCIe bus from step 2 to step 7, so nobody else can use it.
No other command using the card. In a second shell on the Pi, hold the Acorn lock that
fpgas-verifyandfpgas-acorn-flashtake. Go on only when it printslock held, and press Ctrl-C there after step 7.$ sudo flock /run/lock/fpgas-acorn.lock sh -c 'echo lock held; sleep infinity'
The pin-ID bitstream for your card, in
PINID. The file names saycle-101for a CLE-101,cle-215pfor a CLE-215+ andcle-215for a CLE-215. Nothing read from the card tells a CLE-215+ from a CLE-215: telling the variants apart.The loopback and pin-ID designs are in no package. CI builds them and attaches them to the releases of fpgas.online-test-designs as
pmod-loopback_acorn-<variant>_vivado-vivado_sqrl_acorn.bitandpmod-pin-id_acorn-<variant>_vivado-vivado_sqrl_acorn.bit, for example in the releasevivado-bitstreams-v0.0-496-gf162f60. Build the pin-ID design frommain, not from that release. Copy the file to the host and put its name inLOOPBACKorPINID.A card that runs the fpgas.online design needs none of these files for the wiring check: on a Compute Blade, on a Raspberry Pi 5.
A checkout of fpgas.online-test-designs on the Pi, for the pin-ID host scanner
designs/pmod-pin-id/host/identify_pmod_pins.pyanddesigns/acorn-pcie/host/pcie_match_mps.py. The steps run from the checkout’s top directory.openFPGALoaderwith thelibgpiodcable. The scanner also needspython3-libgpiod, which no Acorn package brings:sudo apt install python3-libgpiod.
Steps¶
On the Pi, note how the four scanned pins are set, before step 3 changes them. Step 7 puts them back from this.
$ sudo pinctrl get 3,4,14,15
On the Pi, detach the card’s PCIe endpoint before the load (why). Link the header’s GPIO chip as
gpiochip0, because thelibgpiodcable opensgpiochip0. The link stays afterwards: the Acorn tools expect it.$ echo 1 | sudo tee /sys/bus/pci/devices/0001:01:00.0/remove $ sudo gpiodetect $ ls -l /dev/gpiochip0
The header’s chip is the one
gpiodetectlists aspinctrl-rp1; its number varies from 11 to 15. If/dev/gpiochip0is already that chip, or a link to it, skip the link below. Otherwise put the number in place of 15:$ sudo ln -sfn /dev/gpiochip15 /dev/gpiochip0
On the Pi, make GPIO3, GPIO4 and GPIO14 inputs. The pin-ID design drives J5, H5 and J2, which are on them.
$ for p in 3 4 14; do sudo pinctrl set $p ip; done
On the Pi, load the pin-ID design; each ball then transmits its own name at 1200 baud.
$ sudo openFPGALoader --cable libgpiod --pins 10:9:11:8 "$PINID"
On the Pi, run the scanner for the Acorn and read the name each pin sends.
$ sudo python3 designs/pmod-pin-id/host/identify_pmod_pins.py --board acorn
The scanner decodes every pin in software, from edge timestamps, so no pin needs a UART. Its options are on Pin-id scanner options.
When it ends, the scanner sets back each pin that had an alternate function when it started. GPIO15 goes back to the serial port, which is safe because the Pi only reads it. GPIO3, GPIO4 and GPIO14 stay inputs, because step 3 came first; without step 3 the Pi would drive J2 against the design (test-designs issue #308).
On the Pi, reset the FPGA over JTAG, so that it loads its flash image again. A reboot of the Pi alone does not: the FPGA keeps running the pin-ID design.
$ sudo openFPGALoader --cable libgpiod --pins 10:9:11:8 --reset
If
openFPGALoaderprinted an error, run step 6 once more. If it fails again, the FPGA may still run the pin-ID design. Run only the first block of step 7 and keep GPIO3, GPIO4 and GPIO14 inputs. Ask the site operator, then power-cycle the card.On the Pi, put the card back first and the serial pins last.
Make the JTAG pins inputs with a pull-down, because
openFPGALoaderleaves them driven. Rescan the PCIe bus and check that the card is there.$ for p in 8 9 10 11; do sudo pinctrl set $p ip pd; done $ echo 1 | sudo tee /sys/bus/pci/rescan $ lspci -nn -s 0001:01:00.0
Go on only when
lspcishows10ee:7021, because that proves the FPGA has left the pin-ID design. Then match the card’s Max_Payload_Size to the root port’s, because a rescan leaves it at its reset value.$ sudo python3 designs/acorn-pcie/host/pcie_match_mps.py
Last, set the four pins back to the function and pull that step 1 printed, and copy nothing after the
|. Edit the lines below to match step 1 before you run them. They are for a Pi where step 1 printed14: a4 pn | hi // GPIO14 = TXD0and15: a4 pu | hi // GPIO15 = RXD0, andipfor GPIO3 and GPIO4. A pin that step 1 printed asipornostays as step 3 left it.$ sudo pinctrl set 14 a4 pn # only after lspci showed 10ee:7021 $ sudo pinctrl set 15 a4 pu
Check¶
A correctly wired card passes: the scanner’s last line is RESULT: PASS, and its table shows the same name under
Expect and Got on each row.
Pi GPIO |
Expect |
What the wire is |
|---|---|---|
GPIO15 |
K2 |
serial TX, on the Pi’s RXD0 |
GPIO14 |
J2 |
serial RX, on the Pi’s TXD0 |
GPIO3 |
J5 |
spare GPIO |
GPIO4 |
H5 |
spare GPIO |
If it fails¶
Check whether step 2 detached the card: lspci -nn -s 0001:01:00.0 then prints nothing. If it did, do steps 6 and 7 before you leave the Pi, whatever failed. If it did not, nothing was loaded: stop.
The Pi crashes when a GPIO is set to output: pin ID drives all four P2 balls, so a Pi output fights an FPGA output. Keep GPIO3, GPIO4 and GPIO14 inputs, as step 3 sets them, until
lspcishows the card in step 7. A reboot of the Pi does not reload the FPGA, but it drops the lock, thegpiochip0link and step 3’s inputs. After a reboot, take the lock again, then do step 3 at once, then the link from step 2, then steps 6 and 7.Got shows
(none)on one row: no signal reached that GPIO. The wire to that ball is open or on another pin: Acorn wiring faults on a Raspberry Pi 5.Got shows a name that starts with
?: a signal reached that GPIO but did not decode. The wire is noisy or shared with another: Acorn wiring faults on a Raspberry Pi 5.Got shows another row’s name: two wires are swapped: Acorn wiring faults on a Raspberry Pi 5.
Got shows
(none)on every row: the pin-ID design is not running. Run step 4 again and read its output for an error.lspcishows nothing in step 7: the link may not be up yet. Wait ten seconds and rescan again. If it is still missing, run step 6 again, then step 7. If it is missing after that, the FPGA is not running the fpgas.online image. Leave GPIO3, GPIO4 and GPIO14 inputs. Ask the site operator, then power-cycle the card.