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.

LAUNCHXL-F28379D: Data transfer using IPC without the drivers

Part Number: LAUNCHXL-F28379D

I am attempting to implement a data transfer of characters from CPU1 to CPU2 using IPC.  I found this example in the datasheet but I cannot get the process to work.  Here is what the data sheet is saying, and I am using:

Here is an example of how to use these features together. CPUx needs some data from CPUy's LS RAM. The data is at CPUy address 0x9400 and is 0x80 16-bit words long. The protocol could be implemented like this: – CPUx writes 0x1 to IPCSENDCOM, defined in software to mean "copy data from address".

It writes the address (0x9400) to IPCSENDADDR and the data length (0x80) to IPCSENDDATA.

– CPUx writes to IPCSET[3] and IPCSET[16]. Here, IPC flag 3 is configured to send an interrupt and IPCSET[16] is defined in software to indicate an incoming command. CPUx begins polling for IPCFLG[3] to go low.

– CPUy receives the interrupt. In the interrupt handler, it checks IPCSTS, finds that flag 16 is set, and runs a command processor.

– CPUy reads the command (0x1) from IPCRECVCOM, the address (0x9400) from IPCRECVADDR, and the data length (0x80) from IPCRECVDATA.

CPUy then copies the LS RAM data to an empty space in its writable shared memory starting at offset 0x210.

– CPUy writes the shared memory address (0x210) to its IPCLOCALREPLY register. It then writes to IPCACK[16] and IPCACK[3] to clear the flags and indicate completion of the command. CPUy's work is done. – CPUx sees IPCFLG[3] go low. It reads IPCREMOTEREPLY to get the shared memory offset of the

I am using this block of code to attempt to send data to shared ram then will read it on CPU2 but it is not working

SendIpcData((void*)ReceivedChar, 8, 22);
        IpcRegs.IPCSENDCOM = 0x1;
        IpcRegs.IPCSENDADDR = (void*)ReceivedChar;
        IpcRegs.IPCSENDDATA = (8*i);

Am I going about this correctly or am I using the wrong functions?

Thanks in advance.

  • Hi Christian,

    You have understood is correctly and it should work. What is the issue you are facing? E.g., IPC interrupt is not getting generated or data is not getting copied ? Are you using IPC MSG RAMs or GSxRAM? If using GSxRAM, please make sure you have set the ownership permission correctly in GSxMSEL.

    Regards,

    Vivek Singh

  • I am using msg and recv ram.  Here is my ISR, triggered by a toggle of IPC 3 (on CPU2):
    uint32_t length;
        void* dataLocation;
        if(IpcRegs.IPCSTS.bit.IPC22 == 1){
            IpcRegs.IPCRECVCOM = 1;
            dataLocation = (void*)IpcRegs.IPCRECVADDR;
            length = IpcRegs.IPCRECVDATA;
            memcpy(RECV_MSG_RAM, dataLocation, length);
    }
    I think I have ram offsets wrong for the memcpy or somewhere else, is there a mask that I need to reference CPU1 MSG RAM or the RECVADDR address on CPU2.  Also once the data is transferred to RECV_MSG_RAM on CPU2 can I use another memcpy to send that onto LRAM?

  • Vivek,

    I have just gotten back to the code.  As of today cpu2 does not receive an interrupt despite the fact that IPC2 is set on CPU1, here are what I believe to be relevant info:

     InitPieVectTable();
        IpcRegs.IPCCLR.bit.IPC2 = 1;
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    //enable PIE interrupts
        PieCtrlRegs.PIEIER1.bit.INTx14 = 1;  // Enable IPC2 ISR
    interrupt void IPC2_ISR(void)
    {
        uint32_t length;
        void* dataLocation;
            IpcRegs.IPCRECVCOM = 1;
            dataLocation = (void*)IpcRegs.IPCRECVADDR;
            length = IpcRegs.IPCRECVDATA;
            IpcRegs.IPCACK.bit.IPC22 = 1;
            memcpy(RECV_MSG_RAM, dataLocation, length);
            IpcRegs.IPCSET.bit.IPC31 = 1;
            IpcRegs.IPCACK.bit.IPC2 = 1;
    }
    I have enables group one interrupts, intM, and DBGM on CPU1 as well
  • Hi,

    Following code (acknowledging the interrupt) should be inside ISR because it needs to be done for each IPC interrupt.

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    Also you are expecting IPC2 interrupt where as you are enabling IPC1 interrupt (IPC2 is INT15). Right ?

    PieCtrlRegs.PIEIER1.bit.INTx14 = 1;  // Enable IPC2 ISR

    Please correct this and see if that helps.

    Regards,

    Vivek Singh