Reading ADC with both PRUs

I have asked this of TI but haven’t really gotten a firm answer and I can’t seem to find a clear discussion in the Technical Reference Manual.

I would like to set up PRU1 to monitor two analog input lines and take an action on two GPIOs depending on the values it reads. It would just be started by either the host program through remoteproc or by PRU0.

Simultaneously, I need PRU0 to read three other analog lines and do more complex control work with those.

I can have PRU1 do all the ADC configuration including setting up steps 1, 2 and 3 to read three analog lines in one-shot mode while steps 4 & are set up to read the other two analog lines in continous mode. I’ll write data from steps 1, 2 and 3 into FIFO0 and 4 & 5 into FIFO1.

The question is can PRU0 read FIFO0 while PRU1 might try to read FIFO1 at the same time?

Given that each PRU is capable of accessing the other's data RAM (as I
recall, each PRU sees its RAM at address 0, and sees the other's RAM at
some fixed offset), I'd probably use a few words of PRU0's RAM and have
PRU1 write into that space, along with a timestamp value -- PRU0 would look
for a change in the timestamp, then grab the ADC values (allowing PRU1 to
write new values while PRU0 processes the previous set -- Or PRU0 clears
the timestamp [which is no longer a timestamp] which PRU1 sees as "okay to
write new values", PRU1 then sets the timestamp byte to tell PRU0 "okay to
read". Closest I can come to a shared semaphore/mutex (are there any
synchronization primitives in the PRU runtime?).

I’m going to hold on to this as a backup option. I’m already using the shared memory space so that’s another option but writing to PRU0’s local RAM may be faster. I don’t know. The monitor/control that PRU1 is doing doesn’t would be just fine with a 1-second read interval I think. The three lines that PRU0 is already reading in this application require at least 3ms intervals or better.

Thanks for the good idea on this.

Walter

Hello Walter

Two ansychronous processor’s it’s entirely possible eventually ones writing and other is reading and gets bad Data that’s why they invented hardware dual port ram.

Ping pong circular buffer’s work on one processor systems you disable interrupts in critical regions or lock it with a mutex controlled by RTOS.

Perhaps it’s not critical

How long have you been waiting on an answer just curious?

Mark

… setting up steps 1, 2 and 3 to read three analog lines in one-shot mode while steps 4 & are set up to read the other two analog lines in continous mode. I’ll write data from steps 1, 2 and 3 into FIFO0 and 4 & 5 into FIFO1.

Yes. You can use the FIFO_select bit (26) in the STEPCONFIGx registers to spread the samples. And when the Mode bits (1-0) are cleared (one-shot) the sequencer will disable that step after operation (in STEPENABLE register). Next turn the sequencer will again consider only enabled steps.

The question is can PRU0 read FIFO0 while PRU1 might try to read FIFO1 at the same time?

Not at the same time, but one after the other (L3 access control). AFAIR PRU-1 waits until PRU-0 is done. And both PRUSS are waiting until ARM is done.

#The question is can PRU0 read FIFO0 while PRU1 #might try to read FIFO1 at the same time?

If these FIFOS are in Data RAM it’s recommended to use shared memory. What’s confusing is as I understood it there’s a PRU shared RAM and another larger shared memory so sample code must be inspected carefully if that’s true to understand exactly what’s being referred to as Shared. I think the larger RAM is called OCM.

Below and following link is the relavent blurb to support my comment I found here

[https://elinux.org/Ti_AM33XX_PRUSSv2](https://elinux.org/Ti_AM33XX_PRUSSv2)
One PRU may access the memory of another for passing information but it is recommend to use scratch pad or shared memory, see below.
[Open Core Protocol](http://en.wikipedia.org/wiki/Open_Core_Protocol) (OCP) master port
Access to the data bus that interconnects all peripherals on the SoC, including the ARM Cortex-A8, used for data transfer directly to and from the PRU in Level 3 (L3) memory space.
### Shared Between PRUs
Scratch pad
3 banks of 30 32-bit registers (total 90 32-bit registers).
Single-cycle access, can be accessed from either PRU for data sharing and signalling or for individual use.
12KB data memory
Accessed over the 32-but bus, not single-cycle.
[Sent from Yahoo Mail on Android](https://go.onelink.me/107872968?pid=InProduct&c=Global_Internal_YGrowth_AndroidEmailSig__AndroidUsers&af_wl=ym&af_sub1=Internal&af_sub2=Global_YGrowth&af_sub3=EmailSignature)

I am thinking that I’ll have PRU0 do all the configuration and enabling of the TSC and have the values for the two sensors that I want PRU1 to monitor put in FIFO1. I’ll have PRU0 only read from FIFO0 and let PRU1 only read from FIFO1.
I will set up the three I want to read in one-shot mode and have PRU0 enable them to be read again. the other two will be in continuous mode so PRU0 won’t have to do anything as long as it doesn’t change their configuration.
If PRU-1 waits until PRU-0 is done then it can read FIFO1 as needed to get the data. I only need it to read these possibly as little as once per second so that alone will reduce the number of potential conflicts with PRU0.

If this will work it will eliminate having PRU0 read FIFO1 and write the data into shared memory space where PRU1 could read it. That in itself would have a potential conflict on PRU0 write/PRU1 read.

Good info. I’m going to set up some testing. Thank you!

Mark - I think I waited a day or maybe two. They’ve engaged and are answering my questions. It’s congruent with what is being shared here.

Walter

I don’t understand that concept. When you switch bits in the STEPENABLE register, you’d loose accurate ADC timing. What sampling rate are you talking about?

AFAIR your target is to controlling two eletromagnetic valves (water medium?). They’ve a latency of more than 10 ms → sampling rate & controller loop should be 1 kHz or above.

When sampling all 5 channels continguously in one FIFO and fetching them by one PRU in a ring buffer (SRam), you can do this with accurate timing up to 40 kHz (more than enough). Meanwhile the other PRU evaluates the ring buffer, computing the standard channels (4 &) continguously and the other channels (1, 2, 3) on demand. Note: There’re 1000 PRU cycles between two ADC samples, and 5000 PRU cycles between a sequencer loop (@ 40kHz). Both PRUs exchange the last ring buffer writing position by DRam (or scratch pad).

This alternative concept does not only guarantee accurate timing, it’s also easy to develop and maintain.

BTW: It doesn’t matter which PRU (or the ARM) does the configuration. Just starting the sequencer (CTRL register) should be done by the ADC-PRU.

Both PRUs exchange the last ring buffer writing position by DRam (or scratch pad).

Too many RAMS we need to be clear to avoid confusion please

DDR is DRAM

Internal RAM is SRAM and there are several

SBL ARM internal SRAM (fast from ARM)
PRU shared RAM
PRU data and instruction RAM( fastest for PRU)
The Shared SRAM between ARM and PRU and any DSP on other chips( used by rproc??)

Thanks

Slightly off subject but to me this AM64 looks big

https://training.ti.com/sitara-am64x-processors-combine-powerful-communication-and-real-time-performance

1Meg of SRAM split between the 4 Cortex R4 that can run bare metal or Free RTOS and in next release instead of waiting for Linux to boot to load the firmware by Rproc it’s loaded in about 500 mS.

Supports Linux on dual A53 has 2 PRU and a 5th R5 onboard JTAG and GUI creator for Linux side and supports BLE and WiFi ( not sure if that’s an add on)

$99 for starter kit. I’ve ordered one

Not sure if PRU has access to all that fast SRAM but anything done by the PRU can certainly be done by any of the R4 which has REAL interrupts and much easier to rapidly code and debug than the PRU.

No hocus pocus transferring large amounts of Data from PRU or R4 using slow DDR and spending months trying to squeeze a few bytes of memory for the PRU​:joy::ok_hand::face_with_hand_over_mouth:

Even Nick the TI resident PRU genius used 2 PRU to implement his FOC reference design.
The AM64 demo app uses one Cortex ARM R4 to do the same thing. On a SOC like AM64x the PRU would only be needed if you ran out of peripherals.
Amazing demo one R4 is running FFT no need to pass anything back to A53. The Application core(A53) is nothing more than a network gateway wired or wireless and a GUI Host. That turns Linux programmers into PC programmer’s :face_with_hand_over_mouth: and the Real Time programming is done in RTOS.
Maybe in next release with quick boot they will fix RPMSg make it faster. Perhaps they ported libprio :japanese_goblin: fixed it and documented it properly

Ooops I forgotten. I’m pretty sure the Matlab to implement FOC is already a possibility on Cortex R4 that’s never going to happen for PRU

Vector control, also called field-oriented control (FOC), is a variable-frequency drive (VFD) control method in which the stator currents of a three-phase AC or brushless DC electric motor are identified as two orthogonal components that can be visualized with a vector.

Hi Beagle Veterans,

I just ran across this old Jun '21 post from Mark_Lazarewicz about the TI SK-AM64. in the last 3 posts, Mark proposes using the Cortex-R5 instead of the PRU for easier real-time development. This is the exact same concept I’m hoping to get into with the recently released BBAI-64. Has anyone jumped into using a TI SoC with a Cortex-R5F like this yet? @Mark_Lazarewicz you out there???

I’ve had some limited Cortex-R5F success on the BBAI-64 as a newbie. I’ve gotten Whetstone and Coremark running doing the timing with the GTC and I can toggle an I/O pin with excellent stability. But, things get a bit more complex as I try to go into pinmuxing and peripheral configuration. Hoping to have an R5F run two DACs each connected to its own SPI channel (for “simultaneous” output update). Will likely need SPI configured with DMA, etc.

I don’t have any BBB/PRU or TI CCS experience. Would it be worth buying something like the SK-AM64 from TI to learn on before moving onto the BBAI64? Or should I keep on reading the TRM and the SDK source code? :face_with_head_bandage: Maybe the TI training videos are something I should be doing???

Any advice/guidance is greatly appreciated.

Thanks,
FredE

EDIT: Forget the DMA stuff. I would be happy just to get anything going.

@FredEckert I started with zero PRU experience and found Mark Yoder’s PRU Cookbook helpful. A Google search should locate it for you. It was helpful to peruse the TRM and TI’s PRU Optimizing C/C++ Compiler and their PRU Assembly Language Tools manuals. I don’t recall their training videos so I can’t comment on those. They do have examples that you can work through. I was generally a neophyte in the use of Linux when I started on this a few years ago. Many of the manuals, documents and posts assume a strong knowledge and experience with the OS, kernel, etc. I didn’t have that and it caused me confusion early on.

2 Likes

I did find it for the BBB, do you know if that will also work with the AI-64?

Sorry, I haven’t worked with the AI-64 at all.

1 Like

Walter,

Thanks for the reply.

After review, I am going to run through the PRU Cookbook. It seems like a good intro to some of the more advanced concepts I need to learn. Looks like Mark Yoder is just about to update the examples to remove the obsolete Cloud 9 stuff!! Good time to jump in…

I tried summoning @Mark_Lazarewicz though the ether. No luck there. His old posts are a hoot. Maybe If I type @Mark_Lazarewicz three times he will appear.

I totally understand how much confusion a newbie can have with this stuff. It’s a chore just figuring out where to start. Like a total noob, I bought a PRUCape and figured, I’ll just slap this on the AI-64 and learn everything :wink:

EDIT: @lazarman @lazarman @NiceGuy

Fred,
I compiled some tips after I’d spent months learning and working with the PRUs. Here they are for your reading pleasure.

  1. Working with the PRUs is not easy. Although it isn’t easy, once you get the hang of it you’ll be impressed with the expanded functionality and flexibility of this system on a chip (SOC) that you gain.
  2. If you are rusty on using ‘C’ or just sloppy with memory allocation, pointers and addresses, spend some time getting back up to speed on these concepts. This will save you hours in the long run.
  3. If your mental conversion from decimal to hex to binary gets foggy sometimes, use Excel and create a simple tool to help you convert one to the other. It has built in DEC2HEX, HEX2BIN, BIN2HEX, etc. functions.
  4. I did not use CCS or a debug probe. They probably make some things easier but I can’t say.
  5. Get used to not being able to output anything from the PRU code directly to a terminal unless you hook up a separate terminal or other output device. The PRUs don’t really run an OS like Linux so they don’t have stdout type functions to use.
  6. Get the PRU software development package from TI and download it to your Beagle using git.
  7. If you don’t need them, disable audio and video support in /boot/uEnv.txt
  8. Spend some time studying TI’s Sitarra Technical Reference Manual (TRM) for the am335x series. I mean really study it. Get familiar with the architecture of the chip and all the on-chip peripherals. In the interest of time, deep dive only on the ones you’ll be using.
  9. Note that floating point operations are not supported in PRU hardware and are discouraged by TI. If you must use them, know that they will use a lot of code and cycles and you may not have enough space to load your program. So use them sparingly.
  10. Get familiar with the utilities available with the TI Assembly Language tools. In particular, ofdpru will breakdown your object file and help you know how much memory you’ll be using and where.
  11. Spend time going through Mark Yoder’s PRU Cookbook. Do the examples.
  12. Spend time going through TI’s Hands On Labs. Although currently they are aimed at running on a Linux-based development platform, it’s not required. You can still learn from the hands on labs even if you are running a Windows machine as your platform. Also, although TI assumes you are using Code Compiler Studio (CCS), it is not required. I used a combination of the Cloud9 IDE that ships with the BB for development of my code for both the host and PRU side. It lets me run code on the host side in the IDE. I then use a PUTTY session to make and load my PRU code. I suppose I could use a terminal session in Cloud9 to do this but using the PuTTY session is a nice way to keep the two types of code differentiated in my mind.
  13. Understand the toolchain you are using and what it is doing but you don’t have to initially understand every intricacy of the Makefile.
  14. Get really comfortable with the registers that you’ll use. Be aware that sometimes TI splits the configuration value across a nibble. An example is the Touch Screen Controller’s four bits to set the analog channel input for a step. It uses bits 19-22. 19 is the MSB of the fifth nibble. Bits 20,21 and 22 are in the next nibble. So to configure to use analog input 5, the hex value for those two nibbles must be 28.
  15. Specifically, study pin muxing. It helps to understand why it is necessary.
  16. Recognize just how small 8k of RAM is really. Each PRU has only 8k of RAM for the firmware you download and your data. This means you’ll really need to pay attention to writing tight, efficient code. If you run out of memory to load your program, first eliminate all floating point operations that you can and then begin to refine your code.
  17. Study remoteproc thoroughly and get to know how it works like the back of your hand. Basically, it is bi-directional i/o between the main processor running under Linux and the PRUs based on a concept of virtual i/o (aka virtio). Once this sunk in for me, it became easier to use.
  18. Make sure when you compile the firmware that you’re using the right make file. Out of the box, Cloud9 will try to use gcc to compile and it won’t recognize some of the C extensions TI has built into the PRU’s compiler. For this reason, I compile my PRU code from a terminal session with PUTTY. There’s probably a way to write a make file so this would work in Cloud9 but I didn’t take the time to figure this out (yet).
  19. When you are compiling your firmware with the make file, make sure to use TARGET=yourfilename or else you’ll get errors because the make file is looking for the target. If you don’t you’ll get errors around problems with header files, etc. that don’t make sense and it could waste a lot of time. Believe me, it is easy to forget this sometimes.
  20. When learning remoteproc and RPMSG, I recommend starting with a very simple “round trip” message. Send something like “Hi” to the PRU and have it send “Hi Back” and display it from the host program. I keep this code in my program so I can use it to confirm things are running when they seem like they might not be.
  21. Whatever you have your PRU doing, when it is done, make sure to stop sending messages through RPMSG and stop all peripherals, otherwise you may just crash the whole SOC.
3 Likes