Hello all!
I have been working on a code where in which I use the interrupt PRU_EVTOUT_1 as a heartbeat from the PRU to the host. Currently, however, I have not been able to clear the interrupt so that it can be sent again. A (partial) minimal example is found below. As it is, the code does not work (for me at least… maybe I’m doing something stupid). This code works when PRU_EVTOUT_1 is replaced by PRU_EVTOUT_0 or when PRU0_ARM_INTERRUPT is replaced by PRU1_ARM_INTERRUPT.
I edited prussdrv.c to find out where the issue is coming from and it seems that the wrong bit is cleared in SECR1 using the values below. That is:
- when I send
PRU0_R31_VEC_VALID | PRU_EVTOUT_0
, I getSERC1 = 0x80000
, which is correctly cleared byPRU0_ARM_INTERRUPT = 19
- when I send
PRU0_R31_VEC_VALID | PRU_EVTOUT_1
, I getSERC1 = 0x100000
, which is correctly cleared byPRU1_ARM_INTERRUPT = 20
That makes sense given that PRU0_R31_VEC_VALID | PRU_EVTOUT_1 = ``PRU1_ARM_INTERRUPT + 16
. The second form is found in the example codes for prussdrv, whereas the first one is used in Derek Molloy’s EBB (ultrasonic example, chapter 13).
Is PRU_EVTOUT_1 from PRU0 the same as sending PRU_EVTOUT_0 from PRU1? That seems odd, but I wasn’t able to figure it out from the reference guide. I must be doing something wrong, I just don’t know what!
Any help is appreciated! I am using the latest version of the am335x_pru_package (built directly from the repository).
Cheers!
prumain.p:
`
.origin 0 // start of program in PRU memory
.entrypoint START // program entry point
#define PRU0_R31_VEC_VALID 32
#define PRU_EVTOUT_0 3
#define PRU_EVTOUT_1 4
START:
// Send interrupt to host
MOV R31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_1
// Wait for 1 second
MOV r3, DELAY_MS
DELAY:
SUB r3, r3, 1
QBNE DELAY, r3, 0
// Send interrupt to host
MOV R31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_1
// Halt
HALT
`
main.c:
`
/* Wait for PRU_EVTOUT_1 */
n = prussdrv_pru_wait_event(PRU_EVTOUT_1);
printf(“This is the PRU_EVTOUT_1 number %d.\n”, n);
prussdrv_pru_clear_event(PRU_EVTOUT_1, PRU0_ARM_INTERRUPT);
/* Wait for PRU_EVTOUT_0 (will go through this one instead of waiting for the delay in prumain.p */
n = prussdrv_pru_wait_event(PRU_EVTOUT_1);
printf(“This is the PRU_EVTOUT_1 number %d.\n”, n);
prussdrv_pru_clear_event(PRU_EVTOUT_1, PRU0_ARM_INTERRUPT);
`