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.

Trouble configuring and using the INTC

Other Parts Discussed in Thread: SYSBIOS

Hello,

I am working with the ICE-Board using SYSBIOS and the Industrial SDK. My aim is to configure the PRUSS's INTC. I am able to load the PRU-Code to the IRAM using the pruss_drv.h but i do not get any interrupts to the ARM-processor.

This is the simplified ARM-Code: I am not sure about the eventnumbers because there are some things int pruss_drv.c i don't understand, for AM335x devices there is a subtraction of (i think) 20(0x14) from the given parameter so that i took 20 as event number instead of 2.


tpruss_intc_initdata intcInitData[] = {
         {32,0xFF},
         {{32,2,1,0},{0xFF,0xFF}},
         {{2,2}, {0xFF,0xFF}},
         {0xFF}
};

void taskFxn(UArg a0, UArg a1){

int succ;

led_init();
ICSS_Init();

// Initialize PRUSS interrupt controller
PRUSSDRVPruIntcInit(intcInitData);

PRUSSDRVRegisterIrqHandler(22, 1, irqHandler);


PRUSSDRVPruDisable(0);
PRUSSDRVPruDisable(1);

PRUSSDRVPruWriteMemory(PRUSS0_PRU0_IRAM, 0, (unsigned int*)PRUCode0, sizeof(PRUCode0));

PRUSSDRVPruEnable(0);

PRUSSDRVPruWaitEvent(22);
UARTPutString(5, "[Task] interrupt occurred!\n");

}


The PRU just writes the event to its own R31 and then HALT's.

I also have tried to do the initialization from the PRU but without success. Even the code from the PRU Software Development Package (PRU_PRUtoPRU_Interrupt) didn't worked for me. The first PRU did it's Initialization and generated an Event and polled then for the other PRU to generate an Interrupt but the second PRU did not received the Interrupt at all.

I also inserted an infinite loop in the PRU's Code after the Initialization and stopped it in the debugger: None of the INTC registers was set, they had all the value 0x00. I don't know whether this is because of the debugger or a mistake in my code.

I am grateful for any Help.  

  • Well,

    now i know why there is the subtraction of 0x14 from the given event number, but there is another thing confusing me: The file "pruss_defs.h" which is used by "pruss_drv.c" defines for AM33XX devices some curious adresses.

    E.g.

    #define INTC_PHYS_BASE                0x4a320000

    where does this value come from? The wiki says on this site that the global adress for the INTC registers starts at 0x01C34000 and the "Technical Reference Manual" for AM335x devices says on page 156 that they start at 0x48200000.

    Where does the 0x4a320000 come from???

  • Hi,

    0x4820_0000 is ARM INTC base address, there is a dedicated INTC withing PRU-ICSS which is used for event generation to host and PRUs. 0x4a32_0000 is the base address of PRU-ICSS INTC.

    You might find more details here, https://github.com/beagleboard/am335x_pru_package/blob/master/am335xPruReferenceGuide.pdf 

  • Hi Waldemar,
     
    From AM335X TRM, Table 2-4 PRU_ICSS start address is 0x4A30_0000.
    From AM335x PRU-ICSS Reference Guide (can be found here: https://github.com/beagleboard/am335x_pru_package), Table 5: INTC is at address 0x0002_0000.
     
    So global address is 0x4A30_0000 + 0x0002_0000 = 0x4A32_0000
  • Hi,

    Thank you two for your replies. I have already studied the reference guide form the GitHub, it seems that i have mixed something up there.

    So the INTC i have to use is the PRU-ICSS INTC, do i have to configure the ARM INTC also? And does the PRU has to initialize anything too if the Initialization is already done from the ARM side?

  • now i solved the problem, i don't know why but writing to the own R31 did not generated an Interrupt at all. So the Solution was to generate an Interrupt by using the PRUSS-INTC registers. The solution looks now as follows:

    ARM(SYSBIOS):


    tpruss_intc_initdata intcInitData = {

                    {32,33,0xFF},                                     // enable SysEvt_32, SysEvt_33

                    {              {32,2,1,0},                           // map SysEvt_32 to channel_2, active high|pulse-mode

                                   {33,1,1,0},                           // map SysEvt_33 to channel_1, active high|pulse-mode

                                   {0xFF,0xFF}},                     // EVT_to_CHNL mapping end

                    {              {2,2},                                    // map channel_2 to host_2

                                   {1,1},                                    // map channel_1 to host_1

                                   {0xFF,0xFF}},                     // CHNL_to_HOST mapping end

                    (1<<2)|(1<<1)                                  // enable host_2 and host_1

    };

     

     

    void irqHandler(void){

                    PRUSSDRVPruClearEvent(32); // clear the Event so that it is not generated anymore

    UARTPutString(5, "[ISR] interrupt occurred!\n\r");

    }

     

    void taskFxn(UArg a0, UArg a1){

                     led_init();

     ICSS_Init();

     PRUSSDRVPruDisable(0);

    PRUSSDRVPruDisable(1);

     

     PRUSSDRVPruIntcInit(&intcInitData);                                  // Initialize PRUSS interrupt controller

    // register irqHandler for interrupt 20(PRU_ICSS_EVTOUT0)

     PRUSSDRVRegisterIrqHandler(20, 1, irqHandler);

     PRUSSDRVPruClearEvent(33);

     

    PRUSSDRVPruWriteMemory(PRUSS0_PRU0_IRAM, 0, (unsigned int*)PRUCode0,

                                                                                  sizeof(PRUCode0));

     PRUSSDRVPruEnable(0);

     

     PRUSSDRVPruSendEvent(33);

    }


    PRU0


    START:

    // Poll for receipt of interrupt on host 0

    POLL:

        QBBS      GEN_EVT, eventStatus, #31

        JMP       POLL

     

    GEN_EVT:

        // Clear SYS_EVT32

        MOV32     r31, 0x00000000

     

           //Generate SYS_EVT32

           MOV32  r12, 0x01

           MOV32 r17, 0x204

           SBCO    r12, CONST_PRUSSINTC, r17, 4


    Maybe there is someone who can explain why r31 doesn't work for me(maybe there is a configuring problem, pinmuxing, etc.).

    Thanks for the help.

    unsigned
  • Hi,

    From section 5.2.2.2 of am335xPruReferenceGuide.pdf only 16 events can be generated from PRUs to hosts via INTC

    You also need to set Bit5 of R31 for vector strobe for interrupt generation.

    From section 6, Table 161, sys evt 16 to sys evt 31 [pr1_pru_mst_intr(0:15)_intr_req] is reserved for this purpose. So sys evt 32 can be used for R31 based event generation.