PRU , getting a pin for output on PRU0 and PRU1 to the expansion header

I am slowly mulling through being able to actually have my BBB do things that are useful. The next hurdle is getting a pin on P8/P9 that I can output from the two PRUs. I have written a PRU code and “think” i have run it ok on the first PRU. FYI, I am enabling the PRU with the BB-BONE-PRU-01.dtbo that is in /lib/firmware. It is the only cape I have added.

I have reviewed example code, and I can not figure out how one maps a PRU register bit to a Header pin. I attempted to just loop and toggle a pin which I think is P8.3, using code I found in the Light control project on the TI wiki. But that doesn’t appear to be working (it looks like very so often, something else is writing to that pin).

This is what I have:

`

// Make DMX pin mask
MOV r6, DMX_PIN //DMX_PIN set to 6
LBCO r2, CONST_PRUDRAM, r6, 1
MOV r4, 1
LSL r4, r4, r2.b0
TOGGLE:
// 1. Bring low for 92 us
MOV r6, GPIO1 | GPIO_CLEARDATAOUT
SBBO r4, r6, 0, 4
SLEEPUS 92, 1, START_LOW_SLEEP

// 2. Bring high for 12 us
MOV r6, GPIO1 | GPIO_SETDATAOUT
SBBO r4, r6, 0, 4
SLEEPUS 12, 1, START_HIGH_SLEEP
JMP TOGGLE

`

And in the c code, I have the following export:

`

// This is called with pin = 6
static void LOCAL_export_pin (int pin) {

FILE *file;

char dir_file_name[50];

// Export the GPIO pin

file = fopen("/sys/class/gpio/export", “w”);

fprintf(file, “%d”, pin);

fclose(file);

// Let GPIO know what direction we are writing

sprintf(dir_file_name, “/sys/class/gpio/gpio%d/direction”, pin);

file = fopen(dir_file_name, “w”);

fprintf(file, “out”);

fclose(file);

}

`

But I don’t really understand how to map and setup the mux (I know I will need to do something for the other PRU).

Are there recommended examples which focus on this mapping a bit more (using the standard device tree overlays)?

Thanks

Charles

Hi Charles,

P8_03 is used as gpmc_ad6 by the board. Free pins start at P8_07 ff.

You can find examples in the source code of libpruio on how to use a PRUSS to do pinmuxing and how to change the state of an output pin (or read the state of input pins). You’ll find code to change any pin there. (You don’t need any sysfs operations nor device tree overlays - just an overlay that starts the PRUSS.)

In your case it may be easier to start with the pins directly connected to the PRU registers R30 / R31 (which is faster and easier, since you don’t need to access the GPIO devices).

Thank you so much! That provided to be extremely helpful. I guess I hadn’t appreciated that to just write out a data stream, with minimal memory interaction with the ARM, I was going to have to learn not just the PRU assembly, but also device tree overlays, the pinmux, and then how to compile and load. Quite a bit to take in for one who is use to just writing PIC code standalone.

I was able to toggle a pin , so I can at least move to the next phase. I don’t find a lot of examples that have two PRUs running (I am wonder about the pruss_waitevent call, as it doesn’t take a pru number), but I think I can muddy through that!

Thank you again.

To me, this is the best starting document: http://www.element14.com/community/community/designcenter/single-board-computers/next-gen_beaglebone/blog/2013/05/22/bbb--working-with-the-pru-icssprussv2

If I remember right, to set p8_12:

SET r30.t14 // p8_12 set
and to clear:
CLR r30.t14 // p8_12 clear

Like shabaz says from Element 14, the 0 from r30 looks like an “O” for output, while the 1 from r31 looks like an “i” for input. So, r30 is generally for output and r32 is generally input (bits 0…29). There are other things you can do with r30/31, but for gpio, they’re input and output.

The pinmux for the dts file is
0x034 0x6 // p8_12, mode 6, pulldown
if I remember right. For pinmux/device tree info, you could see Derek Molloy’s information on dts: https://github.com/derekmolloy/boneDeviceTree/tree/master/docs.

Regards,
Rene