Accessing Cortex8 peripherals from PRU

I’ve successfully written ASM code for the PRU to read/write it’s own memory and written processor code to write into that memory as well.

I want to control the 3 I2C peripherals from the PRU but when I try to write to the host’s I2C peripherals (using SBBO) from the PRU registers nothing happens.

I’ve tried to understand the ‘PRU_access_const_table’ example but it doesn’t make much sense to me.

Any tips would be appreciated.

Thx

You need to use the proper addresses and make sure you clear the
standby_init bit to enable the OCP master port (one of the first things
done in most example PRU code).

Otherwise, you just write to the memory location using something like
the SBBO instruction.

Post your code if you're really stuck. I've got PRU code that writes to
the GPIO registers, which use the same interconnect resource (L4_PER) as
the I2C controller:

https://github.com/cdsteinkuehler/MachineKit/blob/MachineKit/src/hal/drivers/hal_pru_generic/pru_wait.p#L102

Here's a bit more self-contained (and simpler) code example:

https://github.com/cdsteinkuehler/MachineKit/blob/MachineKit-ubc/configs/ARM/PRU-Debugger/pruexample.p

This uses the GPIO set/clear registers to create an interesting pattern
on the LEDs, and shows a few coding options, and includes pointers to
the PRU reference guide for various features (like using structures, the
IEP timer, etc).

Charles,

Success! Thanks very much. To be clear all I did was to write:

#define CONST_PRUCFG C4

LBCO r0, CONST_PRUCFG, 4, 4

CLR r0, r0, 4

SBCO r0, CONST_PRUCFG, 4, 4

From what I’ve read this clears a bit in R30, yes? If so does that conflict w/ R30.w0 when used as a return from a CALL?

Thx,

Chip

Where are you getting R30 from?

Grab your book (SPRUHF8A "AM335x PRU-ICSS Reference Guide") and follow
along in-line.

Charles,

Success! Thanks very much. To be clear all I did was to write:

#define CONST_PRUCFG C4

This is creating a human-readable version of a constant table entry.

The constants are defined in table 9 section 5.2.1, page 25.

#define is documented in section 5.3.2.2.3, page 41.

LBCO r0, CONST_PRUCFG, 4, 4

According to section 5.3.4.2.6 on page 64, this will copy 4 bytes into
Register 0, starting with the address C4 + 4. From the constant table,
above, we know that C4 = 0x0002_6000 or the start of the PRU_ICSS_CFG
registers (section 10).

Section 10.1 on page 272 indicates that offset 4 into the PRU_ICSS_CFG
register bank is the SYSCFG register.

CLR r0, r0, 4

Section 10.1.2 on page 274 indicates bit 4 is the STANDBY_INIT bit for
the initiator (the hardware that lets the PRU read and write data from
the SoC). Clearing this bit enables the interface.

SBCO r0, CONST_PRUCFG, 4, 4

This is the corollary to the LBCO instruction, above, and writes 4 bytes
from R0 into the SYSCFG register, enabling the desired change.

From what I've read this clears a bit in R30, yes? If so does that
conflict w/ R30.w0 when used as a return from a CALL?

You do have to be careful about messing with R30 (or whichever register
you use as the CALL register...see section 5.3.2.1.4 if you want to
change it). Remember there's no stack (unless you make one), so you
can't nest calls and returns.

Nothing in the above code modifies R30, however.