PRU I2C fails after first transaction

I am using this library to sample some sensors over the I2C bus using the PRUs on the Beaglebone Black. It seems as if only the first transaction works correctly, after which the library seems to only attempt to read from register address 0xFF, followed by the SCL line being pulled low (see attached image captures by logic analyzer). I have already opened an issue on their github, but am not expecting an answer there as the repository hasn’t been updated in years and the author hasn’t been active on GitHub since 2019.

While trying to find the problem myself, I decided to write the register address and received data in the shared memory to inspect using prudebug. For this test, I am attempting to read registers 0x00 and 0x03. Interestingly, it writes the correct register addresses into memory (see image), but only the first returned value is correct (0xEA). The value written into the received data buffer in shared memory is 0xFF, which does not make sense. As can be seen from the logic analyzer, 0xFF is the address it attempts to read from.


I don’t know what I am doing wrong here, but any help would be appreciated! My main code is shown below, and the library functions can be found in the linked repository here.

uint8_t curr_data_idx = 0;
uint8_t tmp = 0;
uint8_t reg = 0x00;
volatile uint8_t * buf = ((volatile uint8_t*)(RESERVED_SMEM_ADDR + 32));

int main(void)

    // enable OCP


    uint8_t res = 0;
    res = pru_i2c_driver_Init(1);
    uint8_t saddr = 0x68;

    pru_i2c_driver_ReadReg(1, saddr, reg, &tmp);
    buf[curr_data_idx] = tmp;

    reg = 0x03;
    pru_i2c_driver_ReadReg(1, saddr, reg, &tmp);
    buf[curr_data_idx] = tmp;
    return 0;

Looks like you are dealing with some very stale code.
Secondly, make sure you have the correct device tree, if you have bus conflicts you will have issues.

Are you sure the array is being properly traversed and indexed?
Does it need \0 null terminator?

My current uEnv.txt loads the following overlays:


where bbb-reserve-prumem.dtbo reserves some ddr3 memory.

Which array do you mean? volatile uint8_t * buf is only to load the read values and the corresponding register addresses for debugging purposes.

My main confusion is regarding the resulting I2C signal, which attempts to read register 0xFF without ever being told to read a register with that address. And to make matters more confusing, the debugged memory tells us that 0xFF is actually the read value obtained by the sensor.