cipcmicrocontrollercommunicationtexas-instruments

TMS320F28379D Inter processor communication issue


I am working on TMS320F28379D in which I am trying to achieve inter processor communication. And its also working when I try to read data which is send by CPU1. CPU2 Reads same data from 2 location. which is really a second location data. for example if I read location 0x0003FC00U and 0x0003FC01U it will revert the data which is present in 0x0003FC01U for both the location.

currently in CPU1 I am just writing data and in CPU2 I am trying to read it.

So, in CPU1 I have called:

ipc_cpu1_write_data(ipc_address,&IPC_CPU1_DATA[0],ipc_data_length,IPC_FLG_IPC0);

And in CPU2 I have called:

ipc_cpu2_receive_data(IPC_FLG_IPC0,&IPC_CPU2_DATA[0]);

For trial I am adding all data in debug mode,

Keeping, ipc_data_lenght = 10 and ipc_address = 0 in array IPC_CPU1_DATA in 0-9 location I am writting 1-10

While I read it in CPU2 in IPC_CPU2_DATA array its reading 2 for both 0 and 1 location, 4 for both 2 and 3 location and so on...

/*
 * user_ipc.c
 *
 *  Created on: 24-Jun-2024
 *      Author: Admin
 */

#include "user_ipc.h"

#ifndef CPU2
uint16_t IPC_CPU1_DATA[100];
#else
uint16_t IPC_CPU2_DATA[100];
#endif

void ipc_init()
{
    HWREG(IPC_BASE + IPC_O_ACK) = 0XFFFFFFFF;
    DEVICE_DELAY_US(1);
}

void ipc_flag_ack(uint32_t flag)
{
    HWREG(IPC_BASE + IPC_O_ACK) = HWREG(IPC_BASE + IPC_O_ACK) | flag;
    DEVICE_DELAY_US(1);
}

bool ipc_flag_sts(uint32_t flag)
{
    uint32_t rd_flag;

    rd_flag = HWREG(IPC_BASE + IPC_O_STS);
    DEVICE_DELAY_US(1);

    if(rd_flag & flag == flag)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool ipc_flag_check(uint32_t flag)
{
    uint32_t rd_flag;

    rd_flag = HWREG(IPC_BASE + IPC_O_FLG);
    DEVICE_DELAY_US(1);

    if(rd_flag & flag == flag)
    {
        return true;
    }
    else
    {
        return false;
    }
}

void ipc_flag_set(uint32_t flag)
{
    HWREG(IPC_BASE + IPC_O_SET) = HWREG(IPC_BASE + IPC_O_SET) | flag;
    DEVICE_DELAY_US(1);
}

void ipc_flag_clr(uint32_t flag)
{
    HWREG(IPC_BASE + IPC_O_CLR) = HWREG(IPC_BASE + IPC_O_CLR) | flag;
    DEVICE_DELAY_US(1);
}

#ifndef CPU2

void ipc_cpu1_write_data(uint16_t ram_address,uint16_t *data_loc_pointer,uint16_t data_length,uint32_t flag)
{
    uint16_t data_pointer;

    for(data_pointer = 0; data_pointer < data_length; data_pointer++)
    {
        HWREG(CPU1_TO_CPU2_MSG_RAM_BASE + ram_address + data_pointer) = *data_loc_pointer++;
        DEVICE_DELAY_US(1);
    }

    HWREG(IPC_BASE + IPC_O_SENDCOM) = ipc_write_holding_reg;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDADDR) = ram_address;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDDATA) = data_length;
    DEVICE_DELAY_US(1);

    HWREG(IPC_BASE + IPC_O_SET) = HWREG(IPC_BASE + IPC_O_SET) | flag;
    DEVICE_DELAY_US(1);
}

void ipc_cpu1_request_data(uint16_t ram_address,uint16_t data_length,uint32_t flag)
{
    HWREG(IPC_BASE + IPC_O_SENDCOM) = ipc_read_holding_reg;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDADDR) = ram_address;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDDATA) = data_length;
    DEVICE_DELAY_US(1);

    HWREG(IPC_BASE + IPC_O_SET) = HWREG(IPC_BASE + IPC_O_SET) | flag;
    DEVICE_DELAY_US(1);
}

void ipc_cpu1_receive_data(uint32_t flag,uint16_t *data_loc_pointer)
{
    uint16_t ram_address,data_length,data_pointer;

    if(ipc_flag_sts(flag) == 0)
    {
        if(HWREG(IPC_BASE + IPC_O_RECVCOM) == ipc_write_holding_reg)
        {
            ram_address = HWREG(IPC_BASE + IPC_O_RECVADDR);
            DEVICE_DELAY_US(1);
            data_length = HWREG(IPC_BASE + IPC_O_RECVDATA);
            DEVICE_DELAY_US(1);

            for(data_pointer = 0; data_pointer < data_length; data_pointer++)
            {
                *data_loc_pointer++ = HWREG(CPU2_TO_CPU1_MSG_RAM_BASE + ram_address + data_pointer);
                DEVICE_DELAY_US(1);
            }
        }
    }
}
#else

void ipc_cpu2_write_data(uint16_t ram_address,uint16_t *data_loc_pointer,uint16_t data_length,uint32_t flag)
{
    uint16_t data_pointer;

    for(data_pointer = 0; data_pointer < data_length; data_pointer++)
    {
        HWREG(CPU2_TO_CPU1_MSG_RAM_BASE + ram_address + data_pointer) = *data_loc_pointer++;
        DEVICE_DELAY_US(1);
    }

    HWREG(IPC_BASE + IPC_O_SENDCOM) = ipc_write_holding_reg;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDADDR) = ram_address;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDDATA) = data_length;
    DEVICE_DELAY_US(1);

    HWREG(IPC_BASE + IPC_O_SET) = HWREG(IPC_BASE + IPC_O_SET) | flag;
    DEVICE_DELAY_US(1);
}

void ipc_cpu2_request_data(uint16_t ram_address,uint16_t data_length,uint32_t flag)
{
    HWREG(IPC_BASE + IPC_O_SENDCOM) = ipc_read_holding_reg;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDADDR) = ram_address;
    DEVICE_DELAY_US(1);
    HWREG(IPC_BASE + IPC_O_SENDDATA) = data_length;
    DEVICE_DELAY_US(1);

    HWREG(IPC_BASE + IPC_O_SET) = HWREG(IPC_BASE + IPC_O_SET) | flag;
    DEVICE_DELAY_US(1);
}

void ipc_cpu2_receive_data(uint32_t flag,uint16_t *data_loc_pointer)
{
    uint16_t ram_address,data_length,data_pointer,recv_cmd;

    if(ipc_flag_sts(flag))
    {
        recv_cmd = HWREG(IPC_BASE + IPC_O_RECVCOM);
        DEVICE_DELAY_US(1);

        if(recv_cmd == ipc_write_holding_reg)
        {
            ram_address = HWREG(IPC_BASE + IPC_O_RECVADDR);
            DEVICE_DELAY_US(1);
            data_length = HWREG(IPC_BASE + IPC_O_RECVDATA);
            DEVICE_DELAY_US(1);

            for(data_pointer=0U;data_pointer<data_length;data_pointer++)
            {
                *data_loc_pointer++ = HWREG(CPU1_TO_CPU2_MSG_RAM_BASE + ram_address + data_pointer);
                DEVICE_DELAY_US(1);
            }

            ipc_flag_ack(flag);
        }
    }
}

#endif

I'm trying to use shared memory to be exchanging medium for both CPUs to exchange data as there is no need for interrupt. I haven't placed any ISR. Please guide me through.


Solution

  • Got this issue solved. using HWREGH instead of HWREG instruction was the catch. HWREGH instruction works for writing 16bit address while HWREG instruction works for writing 32 bit address. so, when RAM was being written there it was required to use HWREGH.