This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Setting up the PRU and ARM for PRU to generate ARM system interrupt (20)

 

I'm running uCOSII RTOS (not Linux) on the Beaglebone and am trying to generate an interrupt back from PRU0
to the ARM (Interrupt 20).

My PRU code is functional, blinking lights, logic etc. other than not getting the interrupt generated I want back to the ARM.

I've gone through the Linux examples that use the prussdrv and have I think gone through the set up steps for the
Generation of an interrupt but no luck yet.

Basically reproducing what's done in prussdrv_pruintc_init().

I'm missing some step somehow of setting things up.

As in many of the examples I see, I'm leaving the system event for PRU0 to ARM at "19"


I'm using HOST-2, Channel 2, and mapping event 19 to Channel 2.

Steps in my set up:

 

    // Set Polarity of incoming events to active high
    HWREG( PRU_INTC_BASE + PRU_INTC_SIPR0_REG )= 0xFFFFFFFF;
    HWREG( PRU_INTC_BASE + PRU_INTC_SIPR1_REG )= 0xFFFFFFFF;
   
    // Set type of incoming events to "pulse"
    HWREG( PRU_INTC_BASE + PRU_INTC_SITR0_REG )= 0;
    HWREG( PRU_INTC_BASE + PRU_INTC_SITR1_REG )= 0;
   
    // Map system event number 19 to Channel  ( PRU generated interrupt to ARM )
    HWREG( PRU_INTC_BASE + PRU_INTC_CMR4_REG )= 0x02000000;// CMR4 has events 16-19, 19 in highest byte (I start at CMR0 per spec names)
    
    // Map Channel2 to Host 2
    HWREG( PRU_INTC_BASE + PRU_INTC_HMR0_REG )= 0x00020000; // HMR0 has HOST map for channel2 in bits 16-19, select HOST-2
    
    // Turn OFF Ethercat events
    HWREG( PRU_CFG_BASE + PRU_CFG_MII_RT )= 0; // not sure about this but seems like a good idea as Im not using ethercat
    
    // Clear Event 19 interrupt (SECR0)
    HWREG( PRU_INTC_BASE + PRU_INTC_SECR0_REG )= (1 << 19); // bit 19    
    // Enable set Event 16 interrupt (ESR0)
    HWREG( PRU_INTC_BASE + PRU_INTC_ESR0_REG )= (1 << 19); // bit 19    
    // Enable host channel (HIEISR)
    HWREG( PRU_INTC_BASE + PRU_INTC_HIEISR_REG )= 0x4; // HOST-2 bit position (0x4)
    
    // Enable system interrupt (EISR)
    HWREG( PRU_INTC_BASE + PRU_INTC_EISR_REG )= 0x4; // HOST-2 bit position (0x4)
        
    // Register the PRU_EVTOUT0 interrupt vector (set up INTC on ARM side for my service)
    IntRegister(SYS_INT_PRUSS1_EVTOUT0, pru0_int_handler); // interrupt "20" stuffs vector map
    IntSystemEnable(SYS_INT_PRUSS1_EVTOUT0); // interrupt "20" enable bit in
    IntPrioritySet(SYS_INT_PRUSS1_EVTOUT0, 0, AINTC_HOSTINT_ROUTE_IRQ);  // interrupt "20"
   
    // Finally, set Global Enable in INTC GER register
    HWREG( PRU_INTC_BASE + PRU_INTC_GER_REG )= 1;
   
   
    ------------
   
    On the PRU code side, to trigger the PRU_EVT0,  I want to write to R31, where bit 5 is strobe, and
    bits 3:0 map to events 16 - 32, so want to :
   
    MOV R31.b0, 19 + 16        // sets bit 5 strobe + address 3:0 = 35, = system event 19
    
    This is not generating an interrupt on the ARM side so I'm missing a set up step somewhere or misunderstanding a
    setup parameter.
   
    Using the emulator I verify I'm executing this instruction but I must be missing some enable somewhere.
   
    Thanks for any insight.
   
    Ken.

  • Solved my own issue,

    Misunderstanding of the PRU specification as it pertains to indexing to selected interrupts in the 10 bit fields of the following registers:

    SISR

    SICR

    EISR

    EICR

    HIEISR

    The fact that there are 10 host interrupts and 10 bits for these registers do NOT mean each bit represents the enable of ONE of these (i.e. HOST-0 ....HOST-9)

    For these you write the "system event number" for EACH event event you want to address with a separate access.

    The exection to this is register HIDISR .     In this case you can individually disable HOST 0 through 9 with individual bits.

    Regards.