Help resetting signal to reuse prussdrv_pru_send_event(ARM_PRU0_INTERRUPT);

I’m trying to reuse the prussdrv_pru_send_event(ARM_PRU0_INTERRUPT); function, but I can’t reset the register for WBS r31,30

This is my PRU code:

Enter code here...// Origin 0 defines the start of the program in the
// PRU’s instruction RAM, entrypoint is for debugging
#define CONST_PRUCFG C4
#define CONST_PRUSHAREDRAM C28

#define PRU0_CTRL 0x22000
#define PRU1_CTRL 0x24000

#define CTPPR0 0x28

#define OWN_RAM 0x000
#define OTHER_RAM 0x020
#define SHARED_RAM 0x00012000

.origin 0 // offset of the start of the code in PRU memory
.entrypoint START // program entry point, used by debugger only

#define PRU0_R31_VEC_VALID (1<<5)
#define SIGNUM 3 // corresponds to PRU_EVTOUT_0

START:
// initialize loop counter
WBS r31,30 //Wait for signal
MOV R16, SHARED_RAM
lbbo r1,r16,0,8
add r3,r1,r2
sbbo R3, R16, 8, 4
MOV r15,30
clr r31,r15
WBS r31,30 //Wait for signal
MOV R31.b0, PRU0_R31_VEC_VALID | SIGNUM
HALT

And this is the c:

Enter code here...#include <stdio.h>
#include <stdio.h>
#include <prussdrv.h>
#include <pruss_intc_mapping.h>
#include <unistd.h>

#define PRU_SHARED_MEM_ADDR 0x00012000
#define SHM_OFFSET 2048

static int pru_cleanup(void) {
int rtn = 0;

/* clear the event (if asserted) */
if(prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT)) {
fprintf(stderr, “prussdrv_pru_clear_event() failed\n”);
rtn = -1;
}

/* halt and disable the PRU (if running) */
if((rtn = prussdrv_pru_disable(0)) != 0) {
fprintf(stderr, “prussdrv_pru_disable() failed\n”);
rtn = -1;
}

/* release the PRU clocks and disable prussdrv module */
if((rtn = prussdrv_exit()) != 0) {
fprintf(stderr, “prussdrv_exit() failed\n”);
rtn = -1;
}

return rtn;
}

static int pru_setup(const char * const path) {
int rtn;
tpruss_intc_initdata intc = PRUSS_INTC_INITDATA;

if(!path) {
fprintf(stderr, “pru_setup(): path is NULL\n”);
return -1;
}

/* initialize PRU */
if((rtn = prussdrv_init()) != 0) {
fprintf(stderr, “prussdrv_init() failed\n”);
return rtn;
}

/* open the interrupt */
if((rtn = prussdrv_open(PRU_EVTOUT_0)) != 0) {
fprintf(stderr, “prussdrv_open() failed\n”);
return rtn;
}

/* initialize interrupt */
if((rtn = prussdrv_pruintc_init(&intc)) != 0) {
fprintf(stderr, “prussdrv_pruintc_init() failed\n”);
return rtn;
}

/* load and run the PRU program */
if((rtn = prussdrv_exec_program(0, path)) < 0) {
fprintf(stderr, “prussdrv_exec_program() failed\n”);
return rtn;
}

return rtn;
}

volatile int32_t* init_prumem()
{
volatile int32_t* p;
prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, (void**)&p);
return p+SHM_OFFSET;
}

int main()
{
printf(“Init PRU…\n”);
int ret = pru_setup(“PRUTest.bin”);
if(ret == -1) return -1;
volatile int* shared_mem = init_prumem();
//usleep(1000000);
printf(“Waiting for message…\n”);
shared_mem[0] = 5;
shared_mem[1] = 10;
prussdrv_pru_send_event(ARM_PRU0_INTERRUPT);
int n = prussdrv_pru_wait_event(PRU_EVTOUT_0);
printf(“Pru ended. Event: %i\n”, n);
printf(“Got number %d\n”, shared_mem[2]);
pru_cleanup();
return 0;
}

In this example, the c code should never exit because the PRU code should be waiting for a second signal, but it does exit. How do I reset the signal so that I can reuse the interrupt?

Hi,

I’m not sure if you can clear the interrupt flag by writing to R31. You may check the TI RPMSG examples which also rely on interrupts: https://git.ti.com/pru-software-support-package/pru-software-support-package/blobs/master/labs/lab_5/solution/PRU_RPMsg_Echo_Interrupt1/main.c#line85

Check the initialization, but also note how they clear the flag:

`

/* Check bit 30 of register R31 to see if the ARM has kicked us /
if (__R31 & HOST_INT) {
/
Clear the event status */
CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;

`

Regards,

Dimitar