Figure out how to configure correctly modules, pins, and PRU to blink a led

Can anyone help me to point me what I am missing of blinking a led via PRU, please?

I’d like to understand how to use PRUs in order to exploit them. So far, I’d be happy to start from blinking a led via PRU.

After some struggling, I was able to run righto blinking led example on an old 3.8 official image (i.e. bone-debian-7.8-lxde-4gb-armhf-2015-03-01-4gb) by following righto’s guide and EBB (i.e. Exploring Beaglebone). In that blinky moment, I believed that I was figuring something out.

However, since I moved to the latest official image (i.e. bone-debian-8.6-lxqt-4gb-armhf-2016-11-06-4gb), everything felt apart…
Fortunately, I found this interesting thread, from which I found Greg’s guide. Hence, I followed Greg’s guide to set up Remoteproc. While Greg’s guide proceed by building and running PRUADC project, I compiled with success PRU_gpioToggle of pru-software-support-package’s examples.
Then, I attached a led from p8.11 to gnd with a 700 Ohm resistance, and loaded the pru0 firmware as specified by Greg’s guide, but it did not blink :frowning:
I also tried to confirm the pinmux configuration by using config-pin as suggested by RobertCNelson (e.g. “config-pin P8.11 pruout”), but no blink was spotted.

Can anyone point me in the right direction, please?

Regards,
Lorenzo

P.S. I am still confused about Device Tree, Remoteproc, and PRU_Driver, each time that I believe how it should work, it does not… mumble…
P.P.S. How could I check if PRU’s firmware is running?

Hi Lorenzo-

An important file to view is the kernel log. At the command line:

dmesg

You should be able to find messages in this log which indicate success or failure of PRU firmware loading.

Did you successfully modify the Device tree in order to enable the RemoteProc kernel drivers? This is a relatively new requirement.
A more recent project includes the steps to enable RemoteProc:

https://github.com/Greg-R/pru-pid-motor

Regards,
Greg

Hi Greg,

Thank you for your reply!
Friday, I found what I was doing wrong: I was using am335X-boneblack.dts instead of am335X-boneblack-emmc-overlay.dts. This wrong dts was pinmuxing my target pin to HDMI, and I was not able to exploit config-pin.
Therefore, I edited am335X-boneblack-emmc-overlay.dts by enabling remoteproc as in your guide, then used config-pin to configure my target pin to pruout. Finally, everything was blinking :slight_smile:

To summarize:

  1. edit am335x-boneblack-emmc-overlay.dts to enable remoteproc;
  2. edit /boot/uEnv.txt to use as dtb “am335x-boneblack-emmc-overlay”;
  3. config pin as pruout via “config-pin”.

Now, in order to learn how to use the whole system, I am moving forward the examples :slight_smile:

Regards,
Lorenzo

Lorenzo, nice to hear you are making progress.
The Device Tree configuration is a significant barrier and once you break through that things will move quickly.
I think you will find the rest of the examples will work relatively easily.
Good luck and have fun with your project!

Regards,
Greg

Thank you, Greg!

Device Tree was really confusing to me, probably due to the fact that I was using also examples from 3.8.

By the way, I saw that you used an external ADC in your project, while I am scouting to use the internal ADC via PRU. May I ask why you did not use the internal ADC for your project? Do you know if it is feasible to use the internal one instead of an external?

Regards,
Lorenzo

There was nothing particularly practical about that PRU-ADC project. It was a means of learning PRU C programming, SPI bus, RemoteProc framework, and user-space C code (and others).
It was an extremely good learning experience! I want to apply the knowledge gained to robotic projects and also I am interested in Software Defined Radio.

I’m pretty sure that others have successfully accessed the internal ADCs from the PRU. If you do some searching I think you can find a specific instance.
I think it should be possible via the PRU’s OCP master port.

Several people have done external ADC's through the PRU via various means.
SPI for you, but I think for example DR Molloy used I2C ? It's been a while
since I've read any of his material. But I'd like to see someone talk about
the internal ADC *only* because it does not require additional circuitry,
or hardware to make work. Although, obviously one would still have to
"design" a circuit anyhow, for 1.8v or less. Not like you could just plug a
GPIO, PWM, or whatever to an ADC pin, and expect the ADC, or processor to
survive. Without some form of voltage scaling.

However, other than for touchscreens, I'm finding the on processor ADC is
not exactly that good. Having 8 input channels is cool, but only if the
pins aren't multiplexed. Which is the case with the on die ADC. e.g. it's
not a true 200ksps x8 ADC. Despite what many people out there think.

There was nothing particularly practical about that PRU-ADC project. It was a means of learning PRU C programming, SPI bus, RemoteProc framework, and user-space C code (and others).
It was an extremely good learning experience! I want to apply the knowledge gained to robotic projects and also I am interested in Software Defined Radio.

I’m pretty sure that others have successfully accessed the internal ADCs from the PRU. If you do some searching I think you can find a specific instance.
I think it should be possible via the PRU’s OCP master port.

That’s great! Additionally, it is cool that you wrote down the guides in order to simplify others.
Do you already have project in your mind?

I found this library, which is wrote for python and should allow developers to use the “internal” ADC ; I am scanning it, in order to understand how it was used.
Additionally, I found this discussion!

So far, I found examples that access the internal ADC from PRU, but none using C language. For example, this is taken from the previously linked python library. We are going to deep our understanding of this example, hopefully it is possible to write a working counterpart in C :slight_smile:

As far as I understood from the example, it should be enough to enable “OCP port” and point to TSC ADC registers (i.e. on-board/internal ADC registers) in order to configure and read values, am I right?

Hence, I wrote down a header file (i.e. sys_tscadcss.h) which contains the structure that represents the TSC ADC registers (e.g. sysTscadcss struct with register fields REVISION, SYSCONFIG, etc.). Then, I created also the TSCADCSS variable of type sysTscadcss in this header file.

In order to point to the right TSC ADC’s memory location (i.e. 0x44E0D000), I used two ways that I took from some examples of PRU software support package:

  1. #define TSCADCSS (((volatile sysTscadcss)0x44E0D000))” ;
  2. “volatile __far sysTscadcss TSCADCSS attribute((cregister(“TSCADCSS”, far), peripheral));” with its constant define “TSCADCSS ® : org = 0x44E0D000 len = 0x00000300 CREGISTER=27” in AM335x_PRU.cmd file.

In both cases, the pru firmware compiles, and runs. However, in the same both cases, when I try to read any register with a default value not equals to 0 (e.g. REVISION, ADCSTAT, etc. ), I read 0.

Any idea what I am missing, please?

I did some step forward and I putted my header file on github. I hope that it could be helpfull :slight_smile:
One note: it is mandatory to power the TSC_ADC via PRCM or DT (i.e. device tree, I used the uio_pdru_genirq as suggested by zmatt).

Now, I am experiencing that ADC returns incorrect values, but I’ll open a different thread.

P.S. for my experience, DT with drivers and modules was, still is, pretty hard to understand. Do you know if there is an updated and correct guide, please?