PRU Pin Mux

Has anyone used the Pin Mux Utility? I’m trying to enable R30 and R31 on my PRUs. I’ve had a rough time enabling device trees so I decided to try and use the Pin Mux Utility. It seems relatively easy to use and it produces nice .h files but the compiler has an issue with some of the code.

`

#define MUX_VAL(OFFSET,VALUE)
writel((VALUE), AM335X_CTRL_BASE + (OFFSET));

`

Neither GCC or G++ know what to make of writel(). They say it’s not defined and such. I’ve read something about linux/io.h but I haven’t been able to find it. Am I barking up a tree with this utility?

Those who have successfully done Pin Muxing, by what means? I’ve tried doing the hipster circuit tutorial but debian doesn’t like the tree so says dmesg. I’m not sold on the tree method anyways because I wouldn’t mind being able to alter the muxing between compiles not restarts.

Here's a dts file that works for me for r30/31
You can comment out or in pins you need or don't need.

All pins are configured for r30 (output), to use r31 (input) change the
0x05 to 0x06 respectively.

Note that this uses pins used by hdmi/lcd and mmc1 (the onboard emmc of
the BBB).
You need to disable the capes for these first if you want to use these
pins as well:
http://www.logicsupply.com/blog/2013/07/18/disabling-the-beaglebone-black-hdmi-cape/

I tested all pins with my oscilloscope, they appear to work in this
configuration.

Florian

ledmatrix-00A0.dts (14 KB)

Inputs won't work using 0x06, you need to select the proper pinmux
setting *AND* enable the input buffer. Also, with the provided device
tree it is still necessary to reboot if you want to change anything.

I have a universal device tree (available pre-installed on current
Debian based BeagleBone images) that allows dynamic reconfiguration of
the I/O pins without rebooting. Simply use the config-pin utility to
setup the I/O pins as needed:

config-pin -a P8.15 pruin # The -a automatically loads the overlay
config-pin P8.20 pruout

Once the overlay is loaded you can reconfigure the pin muxing as much as
needed without having to reboot.

When you’ve software running on the PRUSS, you neither need a device tree overlay nor any other tools to change the pinmuxing.

Just enable the OCP master port and write the desired configurations in to the registers of the Control Module (0x44E10800 on AM33xx).

Device tree overlays can get created later when you finished the development.

I use the Debian image and never ran across config-pin. I’m going to start with this and see how it goes.

Inputs won’t work using 0x06, you need to select the proper pinmux
setting AND enable the input buffer. Also, with the provided device
tree it is still necessary to reboot if you want to change anything.

I have a universal device tree (available pre-installed on current
Debian based BeagleBone images) that allows dynamic reconfiguration of
the I/O pins without rebooting. Simply use the config-pin utility to
setup the I/O pins as needed:

config-pin -a P8.15 pruin # The -a automatically loads the overlay
config-pin P8.20 pruout

Once the overlay is loaded you can reconfigure the pin muxing as much as
needed without having to reboot.

Here’s a dts file that works for me for r30/31
You can comment out or in pins you need or don’t need.

All pins are configured for r30 (output), to use r31 (input) change the
0x05 to 0x06 respectively.

Note that this uses pins used by hdmi/lcd and mmc1 (the onboard emmc of
the BBB).
You need to disable the capes for these first if you want to use these
pins as well:
http://www.logicsupply.com/blog/2013/07/18/disabling-the-beaglebone-black-hdmi-cape/

I tested all pins with my oscilloscope, they appear to work in this
configuration.

Florian

Has anyone used the Pin Mux Utility? I’m trying to enable R30 and R31
on my PRUs. I’ve had a rough time enabling device trees so I decided
to try and use the Pin Mux Utility. It seems relatively easy to use
and it produces nice .h files but the compiler has an issue with some
of the code.

#define MUX_VAL(OFFSET,VALUE)
writel((VALUE), AM335X_CTRL_BASE + (OFFSET));

Neither GCC or G++ know what to make of writel(). They say it’s not
defined and such. I’ve read something about linux/io.h but I haven’t
been able to find it. Am I barking up a tree with this utility?

Those who have successfully done Pin Muxing, by what means? I’ve
tried doing the hipster circuit tutorial but debian doesn’t like the
tree so says dmesg. I’m not sold on the tree method anyways because I
wouldn’t mind being able to alter the muxing between compiles not
restarts.


Charles Steinkuehler
cha...@steinkuehler.net

I am also interested in this method. It might help the end product to be able to adjust muxing on the fly. I’ll have to look into this.

The pin mux registers require privileged memory access, which is why the kernel space is usually required. The pru can write these!?

Of course. The PRU is directly wired into the on-chip bus, and bypasses
all ARM side sanity checks like memory page access restrictions. You
have 100% full control over anything the PRU can access, which is just
about every significant chunk of hardware on the die except for:

* SGX-530 GPU
* AES & SHA crypto accelerator
* USB
* MMC

Details are in the Interconnects section of the TRM (section 10), and
remember:

  With great power comes great responsibility!

I tried running this and:

`

debian@beaglebone:~/Desktop/riot/pru_test$ config-pin -a P8.15 pruincape-universal overlay not found
Loading cape-universal overlay
bash: line 0: echo: write error: File exists
Error loading device tree overlay file: cape-universal

`
Whats going on here?

What does your slots file look like?

The overlay tries to claim all available pins, so if you loaded anything
else previously it won't work. If you leave the HDMI (with audio)
enabled, there's a universaln overlay that doesn't try to grab the audio
pins.

Try loading the overlay manually and see if that helps, the -a switch
was recently added, so might have some issues.

`

debian@beaglebone:~/Desktop/riot/pru_test$ cat /sys/devices/bone_capemgr.9/slots

0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
debian@beaglebone:~/Desktop/riot/pru_test$ config-pin overlay cape-universal

Loading cape-universal overlay
bash: line 0: echo: write error: File exists
Error loading device tree overlay file: cape-universal
debian@beaglebone:~/Desktop/riot/pru_test$

`

I am not concerned with HDMI at all so I am more than willing to turn that off if need be but I’m not 100% on where to do that.

debian@beaglebone:~/Desktop/riot/pru_test$ cat
/sys/devices/bone_capemgr.9/slots

0: 54:PF---
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
debian@beaglebone:~/Desktop/riot/pru_test$ config-pin overlay cape-universal

Loading cape-universal overlay
bash: line 0: echo: write error: File exists
Error loading device tree overlay file: cape-universal
debian@beaglebone:~/Desktop/riot/pru_test$

You have the full HDMI interface enabled, which includes the audio
signals. You either need to load the cape-universaln overlay that
doesn't try to grab the audio lines, or disable HDMI (which allows the
HDMIN overlay without audio to load, leaving the audio pins free for
your use).

I need to make the code smarter so it looks to see if HDMI or HDMIN is
loaded and selects the proper overlay automatically.

I am not concerned with HDMI at all so I am more than willing to turn that
off if need be but I'm not 100% on where to do that.

Edit /boot/uboot/uEnv.txt, and look for the optargs= line.

That did it.

Helpful as always Charles.

Code never seems to work out of the box for me on these things. Now that I have operational code looking at R31 I have issues putting the results int datamemory which is just absurd. Here’s the code:

`
#define CONST_PRUDRAM C3
#define TOOTH_COUNTER R5

lpe:
ADD TOOTH_COUNTER, TOOTH_COUNTER, 1
QBEQ lpe, r31, 0

SBCO TOOTH_COUNTER, CONST_PRUDRAM, 0, 4

`

I have also done this with SBBO pointed to 0x0 with no success. In prudebugger R5 has a non zero value but the memory comes up as 0x0 in the debugger. The C program I have agrees with the bugger’s reported values on that value and surrounding values. Is there a setup for the pru to access DM? That feels absurd. It is it’s own local ram.

As an aside, a C program should be able to look down in dram and see registers at the 0x7000 offset right? It looks empty to the bugger and my C program. Or are those different registers than the R0-R31?

Code never seems to work out of the box for me on these things. Now that I
have operational code looking at R31 I have issues putting the results int
datamemory which is just absurd. Here's the code:

#define CONST_PRUDRAM C3
#define TOOTH_COUNTER R5

lpe:
ADD TOOTH_COUNTER, TOOTH_COUNTER, 1
QBEQ lpe, r31, 0

SBCO TOOTH_COUNTER, CONST_PRUDRAM, 0, 4

I have also done this with SBBO pointed to 0x0 with no success. In
prudebugger R5 has a non zero value but the memory comes up as 0x0 in the
debugger. The C program I have agrees with the bugger's reported values on
that value and surrounding values. Is there a setup for the pru to access
DM? That feels absurd. It is it's own local ram.

I suspect you are writing to the wrong address. Note that C3 which you
use above points to the local eCAP timer, I have no idea why you think
it should be writing to memory.

As an aside, a C program should be able to look down in dram and see
registers at the 0x7000 offset right? It looks empty to the bugger and my
C program. Or are those different registers than the R0-R31?

Read the PRU Reference Guide. The documentation for these registers
indicates they are valid while the PRU is disabled. See the RUNSTATE
and ENABLE bits in the CONTROL register (section 5.4.1 of the PRU
Reference Guide).

I got C3 from TI’s website:
http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit#PRU_Internal_Constants_Table_Entry_Register_n_.280x0480_.2B_4.2An.29

Use the real TRM and data sheet. The page you linked to is for an
earlier version of the PRU. At the top it says:

This arcticle is part of a collection of articles describing the PRU
subsystem included in OMAP-L1x8/C674m/AM18xx devices (where m is an even
number).

The PRU cores are upgraded in the AM335x parts vs. the AM18xx.

There we are. I got it working using C24. That’s incredibly confusing. What’s config pin’s deal here:

`

debian@beaglebone:~/Desktop/riot_bin$ sudo config-pin -q P8.15
P8_15 Mode: pruin
debian@beaglebone:~/Desktop/riot_bin$ sudo config-pin -q P8.45
Pin is not modifyable: P8_45 lcd_data0
debian@beaglebone:~/Desktop/riot_bin$ sudo config-pin -q P8.20
cape-univ-emmc overlay not found
run “config-pin overlay cape-univ-emmc” to load the cape
debian@beaglebone:~/Desktop/riot_bin$ config-pin overlay cape-univ-emmc
Loading cape-univ-emmc overlay
bash: line 0: echo: write error: File exists
Error loading device tree overlay file: cape-univ-emmc

`

I mean the muxing on P8.15 works splendedly but then P8.20 is inaccessible. Also most of the pins on PRU1 are covered up by lcd pins which will quickly become unacceptable in my project.

If you want to use P8.20, you need to disable the eMMC. If you want to
use P8.45 you need to disable the HDMI output (and someone needs to
finish the missing cape-univ-hdmi).

Note that you can access almost as many PRU0 pins (11 out, 10 in)
without needing to disable either eMMC or HDMI.

I thought we disabled the HDM in the first place… it’s disabled in my uENv.

“Note that you can access almost as many PRU0 pins (11 out, 10 in)
without needing to disable either eMMC or HDMI.”

Unfortuantely I need both processors. If I could even find two inputs on PRU1 I would just move that core over to it and make PRU0 the talkative one.

What’s the deal with STC/LFC? Its in the AM18xx instruction list but they talk about depreciating it. If one core could write to the other’s R30 it’s a wasted cycle but if I could free up the LCD pins and have all of the other PRU’s excess pins I could definitely use that.

I thought we disabled the HDM in the first place... it's disabled in
my uENv.

Yes, recall I said:

If you want to use P8.45 you need to disable the HDMI output (and
someone needs to finish the missing cape-univ-hdmi).

Feel free to send a pull request adding cape-uinv-hdmi! :slight_smile: