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.

C6678 IPC without SYS/BIOS

I'm trying to get the cores on C6678 to send interrupts to each other using IPCGRx registers.

The setup code ran on each core looks like this:


void set_interrupt_table()
{
    volatile uint32_t *uiptr_table, *uiptr_function;
    int ii;

    CSR &= 0xFFFFFFFE;            // Turn off interrupts globally
    ICR = 0x0000FFF0;             // mask all maskable interrupts

    if (DNUM == 1) {
        uiptr_table = (uint32_t *) 0x02620038;
        *uiptr_table++ = 0x83e70b13; // KICK0    SPRS691B - 6678 Data Manual - 3.3.4 Kicker Mechanism
        *uiptr_table   = 0x95a4f1e0; // KICK1    make memory containing IPCGRx writable
    }

    uiptr_table = (uint32_t *) ISTP;                   // copy the contents of interrupt table function to ISTP
    uiptr_function = (uint32_t *) &interrupt_table;    // interrupt_table is written in assembly with .nocmp directive
    ii = 32;                                           // skip the 4 restricted interrupts (RESET, NMI, 2 reserved)
    while (ii--) {                                     // ...
        uiptr_table++;                                 // ...
        uiptr_function++;                              // ...
    }
    ii = 96;                                           // 12 interrupts, 8 32-bit instructions per interrupt = 96;
    while (ii--) {
        *uiptr_table++ = *uiptr_function++;
    }

    uiptr_table = (uint32_t *) 0x01800104;             // SPRUGW0B - CorePac User Guide, table 9-3 - Interrupt mux register
                                                   
                                          //
SPRS691B - 6678 Data Manual - table 7-38 CorePac Primary Interrupts
    *uiptr_table++ = 0x0706055b;          // int4 = 91 (IPC_LOCAL), int5 = 5, int6 = 6, int 7 = 7
    *uiptr_table++ = 0x0B0A0908;          // int8 = 8, int9 = 9, int10 = 10, int11 = 11;
    *uiptr_table = 0x0F0E0D0C;            // int12 = 12, int13 = 13, int14 = 14, int15 = 15;

    ISR = 0x00000010;                     // enable interrupt 4
    CSR |= 0x00000001;                    // write to CSR
}


Then each core besides 1 sends an interrupt using IPCGR1 with this function:

void signal_cpu(uint32_t cpu_num, uint32_t source)
{
    volatile uint32_t *uiptr_register = (uint32_t *) 0x02620240; // SPRS691B - 6678 Data Manual - table 3-2 - IPCGR0
    if (cpu_num <= 7) {
        uiptr_register += cpu_num;
        *uiptr_register |= (source << 4);     // set source
        *uiptr_register |= 1;                // interrupt
    }

}


Running this code on on hardware using a XDS560 emulator yields no results (the function handling interrupt 4 is not ran). After some investigation it turned out that for whatever reaseon the kicker registers (KICK0 and KICK1) didn't register any writes and have the default values of 0. Am I missing something? Should those registers be written to in a specific manner? Is it something that can be corrected with switches on the Evaluation Board? (TMDXEVM6678L)

  • Okay, after going over the code sevaral more times I managed to find my mistakes:

    1. It looks like KICK0 and KICK1 are write-only to the debugger, and this mislead me into thinking they aren't set properly

    2. I mixed up ISR/ICR registers with IER register (I cleared and set the interrupt instead of disabling/enabling it - it didn't execute as it wasn't enabled)

  • Karol,

    Glad to see you were able to quickly resolve. Thanks for taking the time to update your post to acknowledge.

    Best regards,

    Dave