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.

F2837xD interprocessor communication with interrupts

Other Parts Discussed in Thread: CONTROLSUITE

Using the F2837xD, I am trying set an IPC event in CPU1, which will generate an interrupt in CPU2. This code would appear to work if I was polling, but I need it to be interrupt driven.

On the CPU2 (event-reception) side, I see the IPC (event) flag bit set, the IER and IFR bits set, the PIEIER and PIEIFR bits set, and the vector-table properly points to my __interrupt-declared function, but the ISR is never called.

I am using the latest CCS6.1 and I also tried the cpu01_to_cpu02_ipcdrivers sample application in ControlSuite 1.60; in that application a breakpoint in either CPU..IPCHandler is never reached -- how do I know the sample application is actually working? Note neither CPU errorHandler function is called, so both CPUs are executing without error.

Thanks,

Jim

  • Jim,

    Not sure if this is the problem, but to get reliable IPC communications you'll need to set up a handshake between the IPCs so they come up in a known state before you use them.  You'll need to pause your CPU1 initialisation until CPU2 has initialised its IPC.  You can do this with an IPC flag.  For example, in CPU1 init:

    while (IpcRegs.IPCSTS.bit.IPC17 == 0) ; // Wait for CPU02 to set IPC17
    IpcRegs.IPCACK.bit.IPC17 = 1; // Acknowledge and clear IPC17

    ...in CPU2, just after init:

    IpcRegs.IPCSET.bit.IPC17 = 1; // Set IPC17 to release CPU1

    Take a look at the code with the Delfino 1-day workshop (lab 4) for an example of this:

    processors.wiki.ti.com/.../F2837xD_Workshop

    As I said I may be wrong about the cause, but your description sounds like something you get when you don't do the handshake.  Hope it helps.

    Regards,

    Richard

  • Jim,
    in addition to what Richard suggested above :

    can you also check if you have INTM cleared? is the application able to receive any other interrupts? to receive a PIE interrupt, the interrupts should be enabled at 3 places. At IER level, at PIEIER level and the global interrupt mask should be disabled (asm( " clrc INTM");

    Hope this helps.

    Best Regards
    Santosh
  • Santosh,
    Yes INTM is cleared and CPU1 is able to receive interrupts. I have not gotten CPU2 to receive any interrupts yet.

    Richard,
    I will try that, but I have been debugging this with the emulator, and I start running CPU2 before CPU1, so I know CPU2 is fully initialized before CPU1 sends the very first IPC event.

    Thanks,
    Jim
  • I added the startup CPU1/CPU2 synchronization, which appears to allow me to receive CPU2 IPC interrupts -- thanks.

    Now whenever I call a function from within my IPC ISR, the code flies off into invalid memory (address 0, or 0x1f0000, or other addresses).

    Even simple code like this (in the CPU2 IPC ISR):

    __interrupt void CPU01toCPU02IPC0IntHandler (void)
    {
    ipcMsgCount++;
    IPCRtoLFlagAcknowledge(IPC_FLAG0);

    // Acknowledge IPC INT0 Flag and PIE to receive more interrupts
    IpcRegs.IPCACK.bit.IPC0 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    if (++LowSpeedLoopWaitCounter == 8)
    {
    LowSpeedLoopWaitCounter = 0;
    EVOKE_5_KHZ_ISR();
    }
    }

    ipcMsgCount is ALWAYS zero, yet I am able to break within this function; this alone is concerning -- either that ipcMsgCount++ is not executing or the debugger is not showing me the correct memory location.

    Also LowSpeedLoopWaitCounter is ALWAYS zero, so my EVOKE_5_KHZ_ISR() macro is never called. However if I change the condition to "if (++LowSpeedLoopWaitCounter == 0)", then the macro is called every execution -- note if LowSpeedLoopWaitCounter was properly incremented, then my condition should never be true .

    It is almost as if this CPU2 compiler does not work, and/or this CPU2 debugger (using Spectrum Digital XDS510-USB) does not work, or CPU2 does not work. I know these are pre-production parts, so I expect to find some issues. Please let me know if I am trying something that is still not functional. I don't want to waste me time here.

    Thanks,
    Jim
  • try acknowledging the interrupt at the end of ISR instead of at the beginning of the ISR.

    I'm not sure why you aren't seeing ipcMsgCount being incremented even though you are able to hit a break point in ISR. That is wierd, are you using any optimizations?

    hope this helps.

    Best regards
    Santosh
  • Jim,

    IPC should be functional on all samples. Have you tried looking at the disassembly of the ISR and single-stepping to see what's going on?
  • I tried moving the interrupt-ACK to the end of the ISR, but no change. The disassembly looks very similar (same code) between CPU1 and CPU2, but those global variables do not increment in CPU2. Interesting though, that I can change those variables in the Expressions window in the debugger, but the run-time code doesn't change them.
    My boss had an idea -- is there any kind of CPU2 memory-enable or RAM-clock-enable, or anything that would prevent the CPU2 access to RAM? My behavior is consistent with the CPU2 not being able to write to RAM.
    Jim
  • Are your CPU2 variables in the GSx RAMs (addresses 0xC000 - 0x1BFFF)? If so, you'll need to give CPU2 mastership by having CPU1 write to the GSxMSEL register. See section 2.11.1.3 of the TRM (Global Shared RAM (GSx RAM)) for more information.
  • It was the GSxMSEL register -- thank you.

    Regarding the use of Local Shared RAM between CPUs, it looks like the system will arbitrate the use of that LS RAM between CPUs at run-time. Should I rely on that arbitration, or would it be better to separate the allocation of that RAM between CPUs in the linker command file?

    Jim

  • Hi Jim,

    Local Shared RAMs (LSxRAM) are not shared between CPUs. LSxRAMs are dedicated RAMs for each CPU sub-system and shared between CPU and it's CLA only.

    Regards,

    Vivek Singh

  • To clarify Vivek's answer, there are two sets of LSx RAMs, one for each CPU.