No GPIO access from PRU's - GPIO toggle example - device tree overlay/pinmux problem?

Hi,

We are trying to get the GPIO toggle example running on the beaglebone black.

At this point we succeeded in the following: running the RProc echo example from the TI hands on lab which works. Writing and loading a custom device tree overlay to set the pinmux although we are not sure whether the pins get configured correctly.

We did some tests by setting the pinmode with pull-up and pull-down resistors which we measured using a multimeter. So we are sure the device tree overlay is loaded correctly. But we are not able to toggle pins from the PRU.

The device tree overlay code (PRU cape dtsi file adapted to overlay):

`

/dts-v1/;
/plugin/;

/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”;

part-number = “EMS-PRU-CUSTOM”;
version = “00A0”;

/* This overlay uses the following resources */
exclusive-use =
“P9.30”,
“P9.31”,
“P9.27”,
“P9.25”,
“P9.29”,
“P9.28”,
“P8.44”,
“P8.41”,
“P8.42”,
“pru0”,
“pru1”,
“pruss”;

fragment@0 {
target = <&am33xx_pinmux>;
overlay {
pru_pru_pins: pinmux_pru_pru_pins { // The PRU pin modes
pinctrl-single,pins = <
0x1a4 0x2e /* mcasp0_fsr, OMAP_MUX_MODE6 | AM33XX_PIN_INPUT, PRU CAPE SW1 /
0x1ac 0x2e /
mcasp0_ahclkx, OMAP_MUX_MODE6 | AM33XX_PIN_INPUT, PRU CAPE SW2 /
0x19c 0x05 /
mcasp0_ahclkr, OMAP_MUX_MODE5 | AM33XX_PIN_OUTPUT, PRU CAPE Red LED /
0x198 0x05 /
mcasp0_axr0, OMAP_MUX_MODE5 | AM33XX_PIN_OUTPUT, PRU CAPE Orange LED /
0x190 0x05 /
mcasp0_aclkx, OMAP_MUX_MODE5 | AM33XX_PIN_OUTPUT, PRU CAPE Blue LED /
0x194 0x05 /
mcasp0_fsx, OMAP_MUX_MODE5 | AM33XX_PIN_OUTPUT, PRU CAPE Green LED /
0x0ac 0x05 /
lcd_data3, OMAP_MUX_MODE5 | AM33XX_PIN_OUTPUT, PRU CAPE RGB_0 LED, HDMI Conf. /
0x0b0 0x05 /
lcd_data4, OMAP_MUX_MODE5 | AM33XX_PIN_OUTPUT, PRU CAPE RGB_1 LED, HDMI Conf. /
0x0b4 0x05 /
lcd_data5, OMAP_MUX_MODE5 | AM33XX_PIN_OUTPUT, PRU CAPE RGB_2 LED, HDMI Conf. */

;
};
};
};

fragment@1 { // Enable the PRUSS
target = <&pruss>;
overlay {
status = “okay”;
pinctrl-names = “default”;
pinctrl-0 = <&pru_pru_pins>;
};
};

};

`

The code of the GPIO toggle example remained the same (toggling some bits of R30 ). The outfile was moved to /lib/firmware and symlinked to am335x-pru0-fw which was then loaded by removing and reloading pru_rproc.

Is there a way to check how the pinmux is configured? Also using the uEnv.txt we prevented any universal capes from loading on boot (cmdline=coherent_pool=1M net.ifnames=0 quiet cape_universal=disable) and are using dtb=am335x-boneblack-overlay.dtb

We are running out of ideas why the GPIO’s are not toggling. Perhaps something is missing in the dts file? Are we overlooking something?

Thanks in advance

Small update:

If we load cape-universala and run the following command in terminal the PRU seems to be able to toggle the pins in question:

config-pin P9_31 pruout

This is only a temporary solution until a final solution for the device tree can be found, It should be possible to use the overlay to configure the GPIO pinmux correctly no?

Based on this I think we can conclude there is still some issue with the device tree overlay settings. But we have no clue what it would be at this point.

If the config-pin works, why not put the command(s) in a start-up file and be done with it?

Just my opinion, don’t touch the device tree blobs unless you absolutely have to.
And if you have to, use Robert’s scripts to rebuild them.

Regards,
Greg

I understand the sentiment of throwing them in a startup script, but I feel like that is giving away some control about the pin use. Although it can temporarly serve as a solution until we are able to fix the configuration in the overlays. Furthermore, I havent found any good documentation about that command(set) (config-pin) so far. And as far as I know pin muxing and configuration is usually set trough device tree overlays.

I’m not rebuilding the device tree blobs. I’m using the dtc command to build device tree overlays, and using the capemanager to load them at runtime.

Regards
Thomas

I think the solution that Greg offered would probably work, but is also in
my own mind a hack at best. The problem with config-pin is that you have to
wait for the system to be up and running, along with cape-mgr, and god know
what else. With an overlay, you can configure your pin through the second
stage boot loader much sooner, and you can configure the pins on your board
all at once, and exactly to your specification. Hi, low, etc. So I tend to
agree with you, that yes, the best solution is to go with an overlay.

There are also other aspects to this situation that may be less than
desirable. Such as knowing the script you're using ( config-pin ), and
potential legal issues using that software in a commercial application.
Blah blah blah. . . So I'm not saying these are real problems, just that
it's other information one needs to know before using third party software
to feel OK with using that third party software. Something that software
engineers do not necessarily want, or need to deal with.

Anyway Thomas, I think your problem may stem from universal overlays being
enabled by default. You want your cmdline= line in /boot/uEnv.txt to look
somethign like this:

cmdline=coherent_pool=1M net.ifnames=0 quiet

Initially, it'll look like this:

cmdline=coherent_pool=1M net.ifnames=0 quiet cape_universal=enable

Remove the cape_universal=enable bit from that line.

Additionally, you'll want to know which board overlay file you're loading
at boot. Again, at the top of the /boot/uEnv.txt file you'll see some
commented out entries like these:

##BeagleBone Black/Green dtb's for v4.1.x (BeagleBone White just works..)

##BeagleBone Black: HDMI (Audio/Video) disabled:
#dtb=am335x-boneblack-emmc-overlay.dtb

##BeagleBone Black: eMMC disabled:
#dtb=am335x-boneblack-hdmi-overlay.dtb

##BeagleBone Black: HDMI Audio/eMMC disabled:
#dtb=am335x-boneblack-nhdmi-overlay.dtb

##BeagleBone Black: HDMI (Audio/Video)/eMMC disabled:
#dtb=am335x-boneblack-overlay.dtb

##BeagleBone Black: wl1835
#dtb=am335x-boneblack-wl1835mod.dtb

##BeagleBone Green: eMMC disabled
#dtb=am335x-bonegreen-overlay.dtb

You can comment out one of these which is applicable to you. So let's say
the pin your using is a part of hdmi audio, or video. You're going ot need
to disable that by selecting the correct board overlay file from the listed
above. Sp if you wanted to get back your pins from hdmi video and audio you
would uncomment this like so:

##BeagleBone Black: HDMI (Audio/Video) disabled:
dtb=am335x-boneblack-emmc-overlay.dtb

In addition to that, if you're using uboot overlay loading I do believe you
can simply ignore the line which I just mentioned. Then use uncomment the
following lines instead:

*From:*
###Disable auto loading of virtual capes (emmc/video/wireless)
#disable_uboot_overlay_emmc=1
#disable_uboot_overlay_video=1
#disable_uboot_overlay_audio=1
#disable_uboot_overlay_wireless=1
*To:*
###Disable auto loading of virtual capes (emmc/video/wireless)
#disable_uboot_overlay_emmc=1
disable_uboot_overlay_video=1
disable_uboot_overlay_audio=1
#disable_uboot_overlay_wireless=1

So I do not know what peripherals can be muxed on the pin you're using
there. I do not have my muxing table PDF files handy at the moment, but you
can check that for yourself. Make sure nothing else is conflicting with
that pin for the "normal" default setting on your given image. Chances are
pretty good that since it seems to work with config-pin, but not without,
that the universal IO overlay is conflicting with your own overlay. You
could attempt to load your custom overlay from teh command line to see if
you get a "file already exists" error, and if you do, then there is a 99.9%
chance that universal IO being loaded at boot is your problem. If by some
odd chance it's not, there is another overlay overlay conflicting with that
which you desire.

Thanks for your reply.

using uEnv.txt no capes are loaded on boot since we had pin conflicts with the emmc virtual cape.

`

#Docs: http://elinux.org/Beagleboard:U-boot_partitioning_layout_2.0

uname_r=4.4.54-ti-r93
#uuid=
#dtb=

##BeagleBone Black/Green dtb’s for v4.1.x (BeagleBone White just works…)

##BeagleBone Black: HDMI (Audio/Video) disabled:
#dtb=am335x-boneblack-emmc-overlay.dtb

##BeagleBone Black: eMMC disabled:
#dtb=am335x-boneblack-hdmi-overlay.dtb

##BeagleBone Black: HDMI Audio/eMMC disabled:
#dtb=am335x-boneblack-nhdmi-overlay.dtb

##BeagleBone Black: HDMI (Audio/Video)/eMMC disabled:
dtb=am335x-boneblack-overlay.dtb

##BeagleBone Black: wl1835
#dtb=am335x-boneblack-wl1835mod.dtb

##BeagleBone Green: eMMC disabled
#dtb=am335x-bonegreen-overlay.dtb

###U-Boot Overlays###
###Documentation: http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays
###Master Enable
#enable_uboot_overlays=1
###Overide capes with eeprom
#uboot_overlay_addr0=/lib/firmware/.dtbo
#uboot_overlay_addr1=/lib/firmware/.dtbo
#uboot_overlay_addr2=/lib/firmware/.dtbo
#uboot_overlay_addr3=/lib/firmware/.dtbo
###Custom Cape
#dtb_overlay=/lib/firmware/EBB-PRU-Custom-00A0.dtbo
###Disable auto loading of virtual capes (emmc/video/wireless)
disable_uboot_overlay_emmc=1
#disable_uboot_overlay_video=1
#disable_uboot_overlay_audio=1
#disable_uboot_overlay_wireless=1
###Cape Universal Enable
#enable_uboot_cape_universal=1
###U-Boot fdt tweaks…
#uboot_fdt_buffer=0x60000
###U-Boot Overlays###

cmdline=coherent_pool=1M net.ifnames=0 quiet cape_universal=disable

#In the event of edid real failures, uncomment this next line:
#cmdline=coherent_pool=1M net.ifnames=0 quiet cape_universal=enable video=HDMI-A-1:1024x768@60e

##Example v3.8.x
#cape_disable=capemgr.disable_partno=
#cape_enable=capemgr.enable_partno=

##Example v4.1.x
#cape_disable=bone_capemgr.disable_partno=
#cape_enable=bone_capemgr.enable_partno=

##enable Generic eMMC Flasher:
##make sure, these tools are installed: dosfstools rsync
#cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh

`

On boot the slots looks like this:

`

root@beaglebone:~# cat /sys/devices/platform/bone_capemgr/slots
0: PF---- -1
1: PF---- -1
2: PF---- -1
3: PF---- -1
root@beaglebone:~#

`

And then I can load my overlay to a slot, but no pins are toggeling. If I load cape-universal instead, and do the config-pin, the pin starts toggeling.

Also, we presume that when using the cape-universala with pin config we are doing the toggles trough software with the bone-pinmux-helper instead of connecting register 30 to the output pads. We only get a toggle speed of around 2MHz which should be way higher if it was the PRU controlling the pin directly.

Edit: This was wrong. Using the config-pin scripts we got everything working even at higher frequencies (30MHz). We are going to have a look at the overlays later.

You could view the implementation of overlays as an optimization pass.

Greg

So, there is another possible work around that you could try. Keep in mind that I have not tested this myself. But config-pin can load overlays too. So it is possible that you could do something like this:

config-pin overlay <your_overlay_name_ here>

Then your overlay would have to exist in /lib/firmware, as I seem to recall that config-pin for some reason does not handle pathing well, or at all. Still, I kind of via that as a hack as well, and it is possible that if universala conflicts with any overlays you want to use. That you’ll receive an “file already exists” error. One trick I could think of there is create a “blank” universala overlay file, or maybe just copy the contents of your existing overlay into a new universala, then compile it and replace the old one with your new one. . . . again, in my own mind, a HUGELY undesirable hack.

Anyway. I commend Charles S. for the time he’s spent on Universal IO, and I love the concept. But I kept running into problems using it in production systems. So I had to stop using it. It was constantly fighting me when all I really needed to do was get something done. The result I wound up with, was not using it . . . which is really unfortunate, but I mostly view it as a learning tool anyway. I learned a lot by reading through Charles’ config-pin script, and overlays he created.

You and I both are using similar kernels, I think the kernel I’m using is slightly newer, which also leaves me to believe that perhaps you’re one image behind the one I’m currently testing on. I’ve found some issues with capemgr, that are minor if you know how to work around those issues, and you’re very familiar with the beaglebone system in general. But . …relaying this information would take a tremendous amount of effort for both of us . . .

So my advice to you, for now would be to try and completely disable Universal IO, and load your overlays via uboot. Robert has made a couple of posts in the last week or so to a link on the elinux site that has instructions on how to do so. However, if you read the uEnv.txt file, you may be able to figure this out on your own. One thing I do not know for sure however, is how enabling specific board files the old way works when you’re using uboot overlay loading. However, I do think there is a new method, commented out for disabling the eMMC too.

A bit of additional information that I left out unintentionally. I think the debian image I am using is the first iamge where uboot overlay loading is enabled. So, if you decided to use uboot overlays you may have to go with a newer image.

The kernel im using is: uname_r=4.4.55-ti-r94

And the image I used is: bone-debian-8.7-console-armhf-2017-04-02-1gb.img.xz

Anything after this date I’m assuming has uboot overlay loading enabled. This is indeed a testing image, but so far aside from capemgr not working from the command line, and capmgr slots file not reporting what has been loaded. It seems to be very solid. I’m seriously considering putting this image to work in the field on 30ish live production systems. I’m that happy with it.