I have a project where I am trying to use both PRUs. PRU0 loops until the ARM_PRU0_INTERRUPT (bit 31 of PRU0 r31) is received, and PRU1 loops until the ARM_PRU1_INTERUPT (bit 31 of PRU1 r31) is received. Once the loops terminate, they send a PRU0_ARM_INTERRUPT or PRU1_ARM_INTERRUPT, respectively.
This works. However, if the PRU0 code to sends a PRU0_PRU1_INTERRUPT then the PRU0 loop terminates because bit 31 of PRU0 r31 is set… even though ARM_PRU0_INTERUPT has not been sent.
Can anyone see a bug in the code below or otherwise know how to fix this problem? The code runs indefinitely until ctrl-c is hit. With the problematic code commented out, “00002222” is printed out once a second indicating that PRU0 is looping. If the problematic line is executied, then “80000000” is printed out once a second indicating that PRU0 is no longer looping and bit 31 of PRU0 r31 is set.
Thanks!
PRU0 Code:
`
.origin 0
.entrypoint PRUCODE0
#include “prucode.hp”
PRUCODE0:
// Enable OCP master port
LBCO r0, CONST_PRUCFG, 4, 4
CLR r0, r0, 4 // Clear SYSCFG[STANDBY_INIT] to enable OCP master port
SBCO r0, CONST_PRUCFG, 4, 4
// Set C28 to shared ram
MOV r0, SHARED_RAM
MOV r1, PRU0_CTRL + CTPPR0
SBBO r0, r1, 0, 4
MOV r20, 0x1111
SBCO r20, CONST_PRUSHAREDRAM, 0, 4
MAIN_LOOP:
MOV r20, 0x2222
SBCO r20, CONST_PRUSHAREDRAM, 0, 4
// Send notification to PRU1
//MOV r31.b0, PRU0_PRU1_INTERRUPT+16 // CAUSES LOOP TO TERMINATE
// Loop unless bit 31 of r31 is set (ARM to PRU0 event)
QBBC MAIN_LOOP, r31, 31
END:
MOV r20, r31
SBCO r20, CONST_PRUSHAREDRAM, 0, 4
// Send notification to ARM
MOV r31.b0, PRU0_ARM_INTERRUPT+16
// Halt the processor
HALT
`
PRU1 Code:
`
.origin 0
.entrypoint PRUCODE1
#include “prucode.hp”
PRUCODE1:
// Enable OCP master port
LBCO r0, CONST_PRUCFG, 4, 4
CLR r0, r0, 4 // Clear SYSCFG[STANDBY_INIT] to enable OCP master port
SBCO r0, CONST_PRUCFG, 4, 4
// Set C28 to shared ram
MOV r0, SHARED_RAM
MOV r1, PRU1_CTRL + CTPPR0
SBBO r0, r1, 0, 4
MAIN_LOOP:
// Loop unless bit 31 of r31 is set (ARM to PRU1 event)
QBBC MAIN_LOOP, r31, 31
END:
// Send notification to ARM
MOV r31.b0, PRU1_ARM_INTERRUPT+16
// Halt the processor
HALT
`
Header:
`
#ifndef _PRUCODE_HP
#define _PRUCODE_HP
#define PRU0_PRU1_INTERRUPT 17
#define PRU1_PRU0_INTERRUPT 18
#define PRU0_ARM_INTERRUPT 19
#define PRU1_ARM_INTERRUPT 20
#define ARM_PRU0_INTERRUPT 21
#define ARM_PRU1_INTERRUPT 22
#define CONST_PRUSSINTC C0
#define CONST_PRUCFG C4
#define CONST_PRUDRAM C24
#define CONST_PRUDRAM_OTHER C25
#define CONST_PRUSHAREDRAM C28
#define CONST_DDR C31
#define PRU0_CTRL 0x22000
#define PRU1_CTRL 0x24000
#define CTBIR 0x20
#define CTPPR0 0x28
#define CTPPR1 0x2c
#define OWN_RAM 0x000
#define OTHER_RAM 0x020
#define SHARED_RAM 0x100
#define GER_OFFSET 0x10
#define HIESR_OFFSET 0x34
#define SICR_OFFSET 0x24
#define EISR_OFFSET 0x28
#define INTC_CHNMAP_REGS_OFFSET 0x0400
#define INTC_HOSTMAP_REGS_OFFSET 0x0800
#define INTC_HOSTINTPRIO_REGS_OFFSET 0x0900
#define INTC_HOSTNEST_REGS_OFFSET 0x1100
#endif //_PRUCODE_HP
`
ARM Code:
`
/******************************************************************************
- Header Files *
******************************************************************************/
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <prussdrv.h>
#include <pruss_intc_mapping.h>
/******************************************************************************
- Literal Constants *
******************************************************************************/
#define PRU0_NUM 0
#define PRU1_NUM 1
#define PRUSS0_SHARED_DATARAM 4
/******************************************************************************
- Typedefs *
******************************************************************************/
typedef char boolean;
/******************************************************************************
- Local Variables *
******************************************************************************/
static volatile boolean done;
/******************************************************************************
- Function Definitions *
******************************************************************************/
void sighandle(int signum)
{
done = 1;
}
int main (void)
{
unsigned int *buf; // PRU shared buffer
unsigned int ret;
tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
done = 0;
signal(SIGINT, sighandle);
printf("\nStarting…\r\n");
/* Initialize the PRUs */
prussdrv_init();
/* Open PRU Interrupts */
ret = prussdrv_open(PRU_EVTOUT_1);
if (ret)
{
fprintf(stderr,“ERROR: PRU1 Interrupt Failure\n\n”);
return (ret);
}
ret = prussdrv_open(PRU_EVTOUT_0);
if (ret)
{
fprintf(stderr,“ERROR: PRU0 Interrupt Failure\n\n”);
return (ret);
}
/* Get the interrupt initialized */
prussdrv_pruintc_init(&pruss_intc_initdata);
/* Allocate Shared PRU memory. /
prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, (void)&buf);
/* Execute PRU code */
prussdrv_exec_program (PRU1_NUM, “./prucode1.bin”);
prussdrv_exec_program (PRU0_NUM, “./prucode0.bin”);
while(!done)
{
sleep(1);
printf("%08x \n", buf[0] );
}
sleep(1);
prussdrv_pru_send_event( ARM_PRU1_INTERRUPT );
prussdrv_pru_wait_event (PRU_EVTOUT_1);
prussdrv_pru_clear_event (PRU_EVTOUT_1, PRU1_ARM_INTERRUPT);
prussdrv_pru_send_event( ARM_PRU0_INTERRUPT );
prussdrv_pru_wait_event (PRU_EVTOUT_0);
prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
printf("%08x \n", buf[0] );
prussdrv_pru_disable(PRU1_NUM);
prussdrv_pru_disable(PRU0_NUM);
prussdrv_exit ();
printf("\nDone.\n");
return(0);
}
`