Host - Pru synchronization

I am trying to understand how to take advantage of the pru to see if I can use it in my application.

I am trying to synchronize the pru execution from the host. I am using the c libraries, which could be a proble. What I am doing is simple enough that I don’t think this should be a problem unless it really just doesn’t work.

My pru code looks like this:

for (i = 0; i < 3; i++){
waitForHost()
// " CLR R31, R31, 30 \n"

// " WBS R31, 30 \n"
// " CLR R31, R31, 30 \n"

readInstruction();
// read from shared memory location
// do work for instruction

notifyHost()

// " LDI R31.b0, PRU0_ARM_INTERRUPT + 16 \n"

}

the host loop is:
// Initialize the pru

for (i = 0; i < 3; i++){
// write to shared memory location
writeInstruction();

// Tell the pru to read the instruction
notifyPru();

// prussdrv_pru_send_event(ARM_PRU0_INTERRUPT);

// Wait for pru to complete the operation
waitForPru();

// prussdrv_pru_wait_event(PRU_EVTOUT_0);
// prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);

}

For debugging the pru writes the loop index to shared memory location 0.

As is, the first time the host reads the debug location, its value is 2 and never is 0 or 1.
It is as if the first time the pru is notified, it runs to completion, not stoping for the waitForHost at the top of the loop.

If I comment out the notifyPru() in the host, the host hangs waiting for the pru because the pru is still waiting.

Any help would be appreciated.

My pru code looks like this:

for (i = 0; i < 3; i++){
    waitForHost()
    // " CLR R31, R31, 30 \n"
    // " WBS R31, 30 \n"
    // " CLR R31, R31, 30 \n"

<snip>

As is, the first time the host reads the debug location, its value is 2 and
never is 0 or 1.
It is as if the first time the pru is notified, it runs to completion, not
stoping for the waitForHost at the top of the loop.

You can't clear bits in the status register, you have to clear whatever
is generating the status bit directly. That's either an input pin or
(in your case) the interrupt from the local INTC.

So try clearing the actual interrupt bit, and the PRU code should then
wait as expected for the next "handshake". I suspect the PRU is
currently running to completion because you're never clearing the
interrupt that kicks things off, so waitForHost() doesn't actually do
anything after the first "wait" and simply falls through from then on.

Thank you very much.

I appreciate you taking time to help me figure this out.

Now I just have to figure out how to do what you just said.

Section 6.2.2.5 "Interrupt Status Clearing":

https://github.com/beagleboard/am335x_pru_package/blob/master/am335xPruReferenceGuide.pdf

Thanks for the reference document. I have been out of town all week and am just getting back at this. I don’t want to be told the answer, thats just no fun. I am trying to figure out how this works so if someone can tell me why I’m not thinking about this correctly that would be useful.

I have tried many permutations of the following and can’t seem to find something to start with.

#define ARM_PRU0_INTERRUPT 21
#define CONST_PRUSSINTC C0
#define SICR_OFFSET 0x24

// Load the interrupt number into register 17

LDI R17, ARM_PRU0_INTERRUPT
// Write 4 bytes from R17 into pruss intc offset by the sicr
SBCO R17, CONST_PRUSSINTC, SICR_OFFSET, 4

Are there tutorials somewhere for this assmebly language, I haven’t used assembler since the 8080 :slight_smile:

Some PRU code samples: https://github.com/jstampfl?tab=repositories

I believe the readme that comes with the PRU pckage has it pretty much covered, but i did see a website or something that had a listing of all the instructions . . .