Help resetting signal to reuse prussdrv_pru_send_event(ARM_PRU0_INTERRUPT);

93 views
Skip to first unread message

Joseph Foster

unread,
Dec 2, 2017, 12:02:54 AM12/2/17
to BeagleBoard

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?

din...@gmail.com

unread,
Dec 2, 2017, 6:04:36 AM12/2/17
to BeagleBoard
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
Reply all
Reply to author
Forward
0 new messages