I’m using the PRU on a BeagleBone Black to interface to a digital to analog converter (DAC). The DAC generates a clock signal that I have connected to pin 16 of R31. Each time a transition on that pin is detected, I write new data to the DAC via R30. The quicker the PRU reacts to a clock transition and updates the DAC data lines, the faster I can run the DAC.
To start my testing, I’ve written the following simplified assembly code that just toggles the data lines when a DAC clock transition is detected.
// Start by waiting for a high to low transition on DCLKIO
// - DCLKIO is connected to pin 16 of R31
mov r0, 0x10000
// Dummy data values
mov r2, 0xffff
mov r3, 0
qbeq wait_one_to_zero, r0, r31
mov r30, r2
// Now, wait for a low to high transition.
mov r0, 0
qbeq wait_zero_to_one, r0, r31
mov r30, r3
// Now, wait for a high to low transition.
mov r0, 0x10000
This works fine but when I look at the data lines on my logic analyzer, I notice that there is an approximately 25ns delay between when a transition occurs on my DAC clock and when the data lines are updated. Since the PRU runs at 200 MHz, I was expecting something closer to 10ns (1 clock cycle for qbeq and 1 clock cycles for mov). I should mention that if I run some assembly code that just does “mov r30,0; mov r30, 0xffff; mov r30, 0” that I do see 5ns transitions on the output pins as advertised. I’ve also looked at the waveforms on an oscilloscope and they ring a bit but not enough to confuse where the logic transitions are occurring. I use “config-pin PX.XX pruin/pruout” to configure my pins for use by the PRU and I’m running 4.9.12-bone4.
I’ve read through the PRU section in the (massive) AM335x TI Reference Manual and it seems that both R30 and R31 should be operating in “direct input” and “direct output” modes by default. The diagrams and the documentation in the reference manual seem to indicate a direct connection between the R30/R31 registers and the I/O pins but my measurements seem to suggest there’s some kind of buffering with an additional clocking delay hiding in there somewhere. The fact that I can still toggle the output pins at 200 MHz with “mov r30,0; mov r30,0xffff, mov r30,0” perhaps means that the buffering is only on the input lines or that it exists on the output as well and the output transitions initiated by the assembly code move through that buffering in a pipelined manner.
Any comments on this problem would be greatly appreciated. As it stands now, this delay is going to mean I have to run my DAC quite a bit more slowly than I had hoped
Thanks in advance!