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.

IWR1642BOOST: IWR slave write to the I2C bus results in critical error in the DSS: interrupts issue

Part Number: IWR1642BOOST
Other Parts Discussed in Thread: IWR1642

Hello, 

I am using an IWR1642 EVM as an I2C slave to send data to a master Arduino controller. 

Using the I2C driver and the Slave test provided in the SDK, I was able to make the IWR slave write data to the bus, and the data was received on the Arduino side. 

However, when I call the same write function, 

I2CSlave_write(I2CSlave_Handle handle, const void *buffer, size_t size)

on the MSS core during the execution of the mmwave demo, I get a failure in the DSS core. 

Here is the error on console output: 

{module#8}: "../dss_main.c", line 264: error {id:0x10000, args:[0x8139b4, 0x8139b4]}
xdc.runtime.Error.raise: terminating execution

This is the line:

    /* Check if previous chirp processing has completed */
    DebugP_assert(gMmwDssMCB.dataPathObj.interFrameProcToken == 0);

Here is the call stack during error: 

I am not sure at all why this would be happening since the i2c write function is running on a the MSS core. However, the call stack does point to something going wrong with the interrupts. Is it because when the DSS finishes processing a frame, it signals an interrupt to the MSS so MSS can receive it, but in the case of i2c, the i2c driver is blocking mode, so it makes MSS unresponsive to the interrupt originating from DSS? I will look into this further, and hopefully you can share your perspective.

Thank you, 

Herman

  • Hello Herman,

    The exception could be very well because of the blocking nature of the I2C call and also can be attributed to the I2C interface slow speed nature.
    We will have someone in the team reproduce the scenario and send you more details ASAP.

    -Raghu
  • Yes, as mentioned by Raghu it is likely that the I2C call on the MSS is causing it to miss a handshaking interrupt from the DSS. The I2C driver can be configured to run at 400Khz - did you try that, or run at the default 100KHz? You can also try reducing the amount of data being sent in order to test that it's a timing issue. If you can't run at 400KHz and send all the data you want to send, you may be able to break the transfer into smaller pieces to work around the interrupt schedule, or perhaps try another serial interface (such as UART or SPI).
  • Thanks for your replies.

    I have placed the I2CSlave_write function into a new task and this allows the code to run for about 1-2 minutes, until the same handshaking error appears. I've played around with the task priority but without success.

    Next, the I2CSlave_write function also returns FALSE when the 7-bit addressing mode is used. (I need to use the 7-bit address mode to work with the Wire library from Arduino.) However, the write function still writes to the I2C bus and I see the data printed to the console from the Arduino.

    I have tried 400kHz mode but it doesn't seem to work. I changed the default parameters in the I2C driver of mmWave SDK and have configured the Arduino Wire library in the 400kHz mode, but with no success. I am only sending 8 bytes at a time so the bit rate should not really matter.

    Originally I wanted to look at I2C because I want to run 4 IWR slaves. If I do not get this working soon, I'll definitely look into SPI.

    A bit more about my code:

    I call the I2CSlave_Main function from the MmwDemo_mssInitTask in mss_main.c. In this file, I also update txProxObjData array with some data, and then post the I2CSemHandle binary semaphore to let the I2C_task do the write. 

    Here is the I2C code only:

    /* Standard Include Files. */
    #include <stdint.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    
    /* BIOS/XDC Include Files. */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/IHeap.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/Memory.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/heaps/HeapBuf.h>
    #include <ti/sysbios/heaps/HeapMem.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/family/arm/v7a/Pmu.h>
    
    /* mmWave SK Include Files: */
    #include <ti/common/sys_common.h>
    #include <ti/drivers/soc/soc.h>
    #include <ti/drivers/i2c/I2CSlave.h>
    #include <ti/drivers/pinmux/pinmux.h>
    #include <ti/drivers/esm/esm.h>
    #include <ti/drivers/osal/HwiP.h>
    
    /**************************************************************************
     *************************** Global Definitions ***************************
     **************************************************************************/
    #define I2C_TEST_BLOCKING_MODE          1
    
    /* Global Variables */
    static   I2CSlave_Handle     i2cHandle;
            Semaphore_Handle     I2CSemHandle;
              uint8_t            txProxObjData[8];
              uint8_t            txData[8];
    
    int32_t I2CSlave_Main (void);
    
    
    static int32_t PlatformInit(void)
    {
    #if (defined(SOC_XWR14XX))
        /* Setup the PINMUX to bring out the XWR14xx I2C pins */
        Pinmux_Set_OverrideCtrl(SOC_XWR14XX_PINR3_PADAH, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
        Pinmux_Set_FuncSel(SOC_XWR14XX_PINR3_PADAH, SOC_XWR14XX_PINR3_PADAH_I2C_SDA);
        Pinmux_Set_OverrideCtrl(SOC_XWR14XX_PINP4_PADAI, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
        Pinmux_Set_FuncSel(SOC_XWR14XX_PINP4_PADAI, SOC_XWR14XX_PINP4_PADAI_I2C_SCL);
    #else
        /* Setup the PINMUX to bring out the XWR16xx I2C pins */
        Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINF13_PADAH, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
        Pinmux_Set_FuncSel(SOC_XWR16XX_PINF13_PADAH, SOC_XWR16XX_PINF13_PADAH_I2C_SDA);
    
        Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PING14_PADAI, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
        Pinmux_Set_FuncSel(SOC_XWR16XX_PING14_PADAI, SOC_XWR16XX_PING14_PADAI_I2C_SCL);
    #endif
    
        return 0;
    }
    
    static int32_t I2CSlave_Init(void)
    {
        I2CSlave_Params     i2cParams;
        int32_t             errCode = 0;
        uint32_t            arg;
        Semaphore_Params    semParams;
    
        Semaphore_Params_init(&semParams);
        semParams.mode = Semaphore_Mode_BINARY;
        I2CSemHandle = Semaphore_create(1, &semParams, NULL);
    
        PlatformInit();
    
        /* Set the transmit buffer */
        //memset(&rxData, 0, sizeof(rxData));
        memset(&txData, 0, sizeof(txData));
        memset(&txProxObjData, 0, sizeof(txProxObjData));
    
    
        /* Initialize the I2C Slave driver */
        I2CSlave_init();
    
        /* Initialize the I2C driver default parameters */
        I2CSlave_Params_init(&i2cParams);
    
        i2cParams.transferMode = I2CSLAVE_MODE_BLOCKING;
        i2cParams.slaveAddress = 0x48;
    
        /* Open the I2C Slave driver */
        i2cHandle = I2CSlave_open(0, &i2cParams);
    
        if (i2cHandle == NULL)
        {
            System_printf ("Error: I2C Driver Open failed\n");
            return -1;
        }
        //System_printf ("Debug: I2C Slave open passed\n");
    
        /* Configure the I2C device in expand address mode. */
        arg = 0;
        errCode = I2CSlave_control (i2cHandle, I2C_CMD_ADDR_MODE, (void* )&arg);
        if (errCode < 0)
        {
            System_printf ("Error: I2C control Set XA failed [Error code %d]\n", errCode);
            return -1;
        }
        //System_printf ("Debug: I2C Slave Control passed\n");
        return 0;
    }
    
    static void I2C_Task(UArg arg0, UArg arg1)
    {
    
    
        if(I2CSlave_Init() < 0);
        {
            System_printf ("Error: I2C Init failure \n");
        }
    
        while(1)
        {
            Semaphore_pend(I2CSemHandle, BIOS_WAIT_FOREVER);
            memcpy((void*)(&(txData[0])), (void*)(&(txProxObjData[0])), sizeof(txProxObjData));
            //System_printf ("Pre-Write\n");
            /* Slave Write */
            if (I2CSlave_write(i2cHandle, (void*)(&(txData[0])), sizeof(txData)) == false)
            {
                System_printf ("Error: I2C Slave write OK**\n");
                //return -1;
            }
            Task_sleep(10);
    
        }
    
    }
    
    int32_t I2CSlave_Main (void)
    {
        Task_Params     taskParams;
    
        /* Initialize the Task Parameters. */
        Task_Params_init(&taskParams);
        //taskParams.priority = 2;
        taskParams.stackSize = 6*1024;
        Task_create(I2C_Task, &taskParams, NULL);
    
        return 0;
    }

  • Hmm, you're only sending 8 bytes? That shouldn't be a problem.  Have you checked that your I2C tasks are lower priority than the MMW tasks?

  • The task where I update the txProxObjData[8] buffer is MmwDemo_mboxReadTask. This task's priority was set to 4. The I2C_Task priority was set to 1. This did not resolve the issue.
  • Any news about this issue? Thank you.