The loop

One prompt. Eight iterations. PASS.

Recreated from the bench flow, sped up. The loop it recreates runs today on Oracova development hardware, where unmodified Betaflight already flies against the same ECP5 fabric. Augur One puts that fabric on one board and is in fabrication.

oracova bench
$ oracova task "implement and test the gyro driver"
plan MPU6000 gyro/accel · SPI1 · DUT STM32F411, real silicon
world mpu6000 model v1.2, validated against real silicon
synth → bench FPGA ................ ok · 4 m 12 s
bench DUT board seated
 
netlist parse DUT board PCBA: SPI1 → PA5 SCK · PA6 MISO · PA7 MOSI · PA4 nCS
map DUT pins → base connector → FPGA balls ............ 4 nets routed
bench internal logic analyzer armed on SPI1
 
wiretest gpio loopback, no protocol: fabric drives each net, reads each pin back over SWD
PA5 PA6 PA7 PA4 4/4 nets toggle · 0 shorts · 0 opens
bench wiring is ground truth: every failure after this line is firmware
 
iter 1 write driver: spi init · read WHO_AM_I @ 12.5 MHz · t+7 min
build ok flash ok test running
who_am_i .................................. FAIL read 0x9C then 0xE3, expected 0x68
internal logic analyzer · spi1 · iter 1
nCSSCLKMISO12.5 MHz on a 1 MHz register bus
Config read clocked at 12.5 MHz. This part caps register reads at 1 MHz; 20 MHz is for sensor data only.
la register reads cap at 1 MHz on this part; data reads may run to 20 MHz
fix config clock → ÷128 = 0.78 MHz, under the cap · sensor burst 12.5 MHz → rebuild
 
iter 2 flash ok · test running · t+21 min
who_am_i .................................. PASS 0x68
gyro_x .................................... FAIL reads 0x0000, always
internal logic analyzer · spi1 · iter 2
MOSI00111011bit 7addr byte = 0x3B
bit 7 = 0 → that's a write, not a read. The 0x80 read flag is missing.
la addr 0x3B sent without the 0x80 read bit
fix set the 0x80 read flag in the burst path → rebuild
 
iter 3 flash ok · test running · t+34 min
gyro_x .................................... data flows
rate check: world spins the table 90 °/s, ground truth · driver reports 11.3
fix driver set FS_SEL=3 (±2000 °/s) but scaled with the ±250 default: 131 → 16.4
 
iter 4 flash ok · full suite · t+43 min
who_am_i .................................. PASS
self test ................................. PASS
rate step 90 °/s .......................... PASS
burst read @ 8 kHz sustained .............. PASS
 
iter 5 improve: burst reads over DMA, get the CPU out of the read path · t+49 min
flash ok · test running
burst read @ 8 kHz ........................ FAIL transfer never starts
regs NDTR frozen: driver armed DMA1, but SPI1 requests only route to DMA2
fix retarget SPI1 DMA → DMA2 streams 0/3 · CR2 TXDMAEN|RXDMAEN → rebuild
 
iter 6 flash ok · test running · t+58 min
burst read @ 8 kHz ........................ FAIL stream armed, zero requests
regs stream 0 CHSEL=0. SPI1_RX is channel 3 on this stream
fix CHSEL → 3 on both streams → rebuild
 
iter 7 flash ok · test running · t+65 min
gyro_x .................................... data flows, shifted by one byte
la 14 bytes clocked per frame, 15 needed (addr + 14 data): NDTR missed the address byte
fix NDTR = 15: count the address byte, discard rx[0] → rebuild
 
iter 8 flash ok · full suite · t+70 min
who_am_i .................................. PASS
self test ................................. PASS
rate step 90 °/s .......................... PASS
burst read @ 8 kHz over DMA ............... PASS
cpu cycles moving gyro bytes .............. 0
 
result gyro driver implemented · DMA-accelerated · tested · 8 iterations · 1 h 12 min unattended
checker deterministic, fixed thresholds. The agent never grades its own work
task · implement and test the gyro driver replay · recreated · sped up · not live video

Every board on the bench gets this same loop.

See the board built to play your world