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.

IWR6843AOPEVM: using mmwave SDK i2c library to write bare-metal code

Part Number: IWR6843AOPEVM
Other Parts Discussed in Thread: IWR6843, IWR6843AOP

Hi all,

It is possible to run the i2c function from TI mmwave SDK and use it to write a bare-metal code?

I'm not familiar with TI SDK and this is my first time writing a code, I'm trying to use the i2c library and get "stuck" on the I2C_transfer function.

I prefer the bare-metal code if any of you have a solution for me, please advise?

Thanks to all,

Yishai,

  • Yishai:

    Can you please please define more explicitly what you mean by bare metal? Additionally, can you please detail what you are trying to accomplish with this type of implementation.

    Best regards,

    Connor Desmond

  • Hi Connor,

    Sorry for the delayed answer, thank you for your reply,

    By meaning bare-metal, I refer to using the mmWave SDK library to write the FW code for IWR6348AOP SoC, without using TI-RTOS OS (SYS/BIOS), without running semaphore and tasks.

    My Goals are:

    1. to learn how to program the SoC

    2. to write a small FW for my BU, I have designed a board around this SoC, and I wanted to check all the HW connectivity

    Currently, I have succeeded to run a GPIO and UART small program, but, when I run the i2c the program is got "stuck" at < retVal = I2C_transfer(i2c Handle, & i2c Transaction); > i2c function.

    For better understanding, I attached the small case which I have started to write.

    Regards,

    Yishai A,

    
    /* Standard Include Files. */
    #include <stdint.h>
    #include <stdlib.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.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>
    
    /* mmWaveSDK Include Files */
    #include <ti/common/sys_common.h>
    #include <ti/drivers/esm/esm.h>
    #include <ti/drivers/soc/soc.h>
    #include <ti/drivers/uart/UART.h>
    #include <ti/utils/cli/cli.h>
    #include <ti/drivers/i2c/I2C.h>
    #include <ti/drivers/gpio/gpio.h>
    #include <ti/drivers/pinmux/pinmux.h>
    #include <ti/drivers/osal/MemoryP.h>
    #include <ti/utils/testlogger/logger.h>
    
    
    /**************************************************************************
     *************************** Global Definitions ***************************
     **************************************************************************/
    /** \brief Number of messages sent */
    #define I2C_TEST_MESSAGE_COUNT          100
    #define I2C_TEST_BLOCKING_MODE          1
    #define I2C_TEST_SCAN_MODE              2
    
    #define UART_BAUD_RATE                  115200
    
    
    /* Global Variables */
    volatile uint32_t       testSelection = 0;
    volatile uint32_t       gTransferDone = 0;
    volatile uint32_t       gTransferErrors = 0, gTransferCount = 0;
    uint8_t                 rxData[16];
    uint8_t                 txData[16];
    uint32_t                rxTicks[I2C_TEST_MESSAGE_COUNT];
    uint32_t                txTicks[I2C_TEST_MESSAGE_COUNT];
    uint32_t                minRxTicks;
    uint32_t                maxRxTicks;
    uint32_t                minTxTicks;
    uint32_t                maxTxTicks;
    uint32_t                totalTxTicks;
    uint32_t                totalRxTicks;
    I2C_Transaction         i2cTransaction;
    
    /* Global Variable which holds the CPU Clock Frequency */
    uint32_t gCPUClockFrequency = (200 * 1000000);
    
    
    /**************************************************************************
     *************************** Extern Definitions ***************************
     **************************************************************************/
    /*
    void uartInit(){
    
        //UART_Handle      handle;
        //UART_Params      params;
    
        //UART_Params_init(&params);
        params.clockFrequency = gCPUClockFrequency;
        params.baudRate  = UART_BAUD_RATE;
        params.writeDataMode = UART_DATA_TEXT;
        params.readDataMode = UART_DATA_TEXT;
        params.readReturnMode = UART_RETURN_FULL;
        params.readEcho = UART_ECHO_OFF;
        //handle = UART_open(0, &params);
    
    }
    */
    void sysInit(){
    
        /* Initialize the GPIO */
           GPIO_init();
    
        /* Initialize the UART */
           UART_init();
    
        /* Initializa the I2C driver */
           I2C_init();
    
        /* Initialize the ESM: Dont clear errors as TI RTOS does it */
           //ESM_init(0U);
    }
    
    static int32_t pinCfg(void){
    
        /* Test the GPIO Input: Configure pin J13 as GPIO_1 input */
           Pinmux_Set_OverrideCtrl(SOC_XWR68XX_PINJ13_PADAC, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
           Pinmux_Set_FuncSel(SOC_XWR68XX_PINJ13_PADAC, SOC_XWR68XX_PINJ13_PADAC_GPIO_1);
           GPIO_setConfig(SOC_XWR68XX_GPIO_2, GPIO_CFG_INPUT);
    
        /* Test the GPIO Output: Configure pin K13 as GPIO_2 output */
           Pinmux_Set_OverrideCtrl(SOC_XWR68XX_PINK13_PADAZ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
           Pinmux_Set_FuncSel(SOC_XWR68XX_PINK13_PADAZ, SOC_XWR68XX_PINK13_PADAZ_GPIO_2);
           GPIO_setConfig(SOC_XWR68XX_GPIO_2, GPIO_CFG_OUTPUT);
    
        /* Setup the PINMUX to bring out the MSS UART-1 */
           Pinmux_Set_OverrideCtrl(SOC_XWR68XX_PINN5_PADBE, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
           Pinmux_Set_FuncSel(SOC_XWR68XX_PINN5_PADBE, SOC_XWR68XX_PINN5_PADBE_MSS_UARTA_TX);
           //GPIO_setConfig(SOC_XWR68XX_PINN5_PADBE_MSS_UARTA_TX, GPIO_CFG_OUTPUT);
    
           Pinmux_Set_OverrideCtrl(SOC_XWR68XX_PINN4_PADBD, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
           Pinmux_Set_FuncSel(SOC_XWR68XX_PINN4_PADBD, SOC_XWR68XX_PINN4_PADBD_MSS_UARTA_RX);
           //GPIO_setConfig(SOC_XWR68XX_PINN4_PADBD_MSS_UARTA_RX, GPIO_CFG_INPUT);
    
        /* Setup the PINMUX to bring out the MSS UART-3 */
           //Pinmux_Set_OverrideCtrl(SOC_XWR68XX_PINF14_PADAJ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
           //Pinmux_Set_FuncSel(SOC_XWR68XX_PINF14_PADAJ, SOC_XWR68XX_PINF14_PADAJ_MSS_UARTB_TX);
    
        /* Setup the PINMUX to bring out the XWR68xx I2C pins */
           Pinmux_Set_OverrideCtrl(SOC_XWR68XX_PINF13_PADAH, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
           Pinmux_Set_FuncSel(SOC_XWR68XX_PINF13_PADAH, SOC_XWR68XX_PINF13_PADAH_I2C_SDA);
    
           Pinmux_Set_OverrideCtrl(SOC_XWR68XX_PING14_PADAI, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
           Pinmux_Set_FuncSel(SOC_XWR68XX_PING14_PADAI, SOC_XWR68XX_PING14_PADAI_I2C_SCL);
    
    
           return 0;
    }
    
    /**
     *  @b Description
     *  @n
     *      Performs a read from a given slave device.
     *
     *  @param[in]  i2cHandle
     *      Handle to the I2C Driver.
     *  @param[in]  i2cSlaveAddress
     *      Address of I2C Slave to read from.
     *  @param[in]  i2cSlaveRegAddress
     *      Address of the register to be read.
     *
     *  @retval
     *      Success     - 0.
     *  @retval
     *      Error       - -1
     */
    
    static int32_t i2cReadAddress(I2C_Handle i2cHandle, uint8_t i2cSlaveAddress, uint8_t i2cSlaveRegAddress)
    {
        bool            retVal = false;
        int32_t         errCode = 0;
    
        /* Reset the transmit and receive buffer */
        memset(&rxData, 0, sizeof (rxData));
    
        /* Scan for the slave address */
        /*txData[0] = i2cSlaveRegAddress;
        i2cTransaction.slaveAddress = i2cSlaveAddress;
        i2cTransaction.writeBuf = txData;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = rxData;
        i2cTransaction.readCount = 0;*/
    
        //uint8_t confTxData[] = {0x01U, 0x60U, 0xA0U};
        i2cTransaction.slaveAddress = i2cSlaveAddress;; //I2C_TEMPERATURE_SENSOR_ADDRESS;
        i2cTransaction.writeBuf = txData;;  //confTxData;
        i2cTransaction.writeCount = 3U;
        i2cTransaction.readBuf = rxData;    //NULL;
        i2cTransaction.readCount = 0U;
        i2cTransaction.timeout = 100U;
    
    
        /* Writing to slave address */
        retVal = I2C_transfer(i2cHandle, &i2cTransaction);
    
        if (retVal == false)
        {
            errCode = -1;
        }
        else
        {
            /* Read from slave */
            i2cTransaction.slaveAddress = i2cSlaveAddress;
            i2cTransaction.writeBuf = txData;
            i2cTransaction.writeCount = 0;
            i2cTransaction.readBuf = rxData;
            i2cTransaction.readCount = 4;
            i2cTransaction.timeout = 100U;
    
            retVal = I2C_transfer(i2cHandle, &i2cTransaction);
            if (retVal == false)
            {
                errCode = -1;
            }
            else
            {
                errCode = 0;
            }
        }
        return errCode;
    }
    
    
    /**
     * main
     */
    int main(void)
    {
        // sys clock hander
        Task_Params     taskParams;
        SOC_Handle      socHandle;
        SOC_Cfg         socCfg;
        int32_t         errCode;
    
        // uart_a handler
        UART_Handle      uartHandle;
        UART_Params      uartParams;
        unsigned char rxBuffer[20];
        const unsigned char hello[] = "Hello World\n";
        int32_t status;
    
    
        // i2c_handler
        I2C_Handle      i2cHandle;
        I2C_Params      i2cParams;
        //I2C_Transaction i2cTransaction;
        uint32_t        index = 0;
        uint8_t         i2cSlaveAddress;
        uint8_t         i2cSlaveRegAddress;
        int32_t         retVal = 0;
        uint32_t        slaveFound = 0;
    
        unsigned char buff[80];
    
    
     /* Initialize the SOC confiugration: */
        memset ((void *)&socCfg, 0, sizeof(SOC_Cfg));
    
     /* Populate the SOC configuration: */
        socCfg.clockCfg = SOC_SysClock_INIT;
    
     /* Initialize the SOC Module: This is done as soon as the application is started
      * to ensure that the MPU is correctly configured. */
        socHandle = SOC_init (&socCfg, &errCode);
      if (socHandle == NULL)
      {
          System_printf ("Error: SOC Module Initialization failed [Error code %d]\n", errCode);
          return -1;
      }
    
    
        sysInit();
        //uartInit();
        pinCfg();
    
    
    
        UART_Params_init(&uartParams);
    
        uartParams.clockFrequency  = MSS_SYS_VCLK;
        uartParams.baudRate        = 115200;
        uartParams.writeDataMode   = UART_DATA_BINARY;  //UART_DATA_TEXT;
        uartParams.readDataMode    = UART_DATA_BINARY;
        uartParams.readEcho        = UART_ECHO_OFF; //UART_RETURN_FULL;
        uartParams.isPinMuxDone    = 1U;
        uartParams.writeTimeout    = 100;
        /*
        uartParams.clockFrequency = gCPUClockFrequency;
        uartParams.baudRate       = UART_BAUD_RATE;
        uartParams.writeDataMode  = UART_DATA_TEXT;
        uartParams.readDataMode   = UART_DATA_TEXT;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho       = UART_ECHO_OFF;
        */
        uartHandle = UART_open(0, &uartParams);
        //handle = UART_open(0, NULL);
    
    
        I2C_Params_init(&i2cParams);
        i2cParams.transferMode = I2C_MODE_BLOCKING;
        i2cParams.bitRate = I2C_100kHz;
    
     /* Open the I2C driver */
        i2cHandle = I2C_open(0, &i2cParams);
    
        if (i2cHandle == NULL){
            printf ("Error: I2C Driver Open failed\n");
            return -1;
        }
    
        index = 1;
     /* Read register address 0x0 */
        i2cSlaveRegAddress = 0x0;
    
    
        printf("Hello World!\n");
        //CLI_write("Hello World!\n");
    
    
        for(;;){
    
            if((index < 0x7F)&&(slaveFound<=0)){
    
                i2cSlaveAddress = (uint8_t)index;
                //sprintf(buff, "Pinging Device at slave address: 0x%x ...", i2cSlaveAddress);
                //printf ("Debug: Pinging Device at slave address: 0x%x ...", i2cSlaveAddress);
                //UART_writePolling(uartHandle, "Pinging Device at slave address: 0x%x ...", sizeof("Pinging Device at slave address: 0x%x ..."));
                //UART_writePolling(uartHandle, buff, sizeof(buff));
                printf("Pinging Device at slave address: 0x%x ...", i2cSlaveAddress);
                retVal = i2cReadAddress(i2cHandle, i2cSlaveAddress, i2cSlaveRegAddress);
                if (retVal == -1){
                    //printf ("Failed \n");
                    UART_writePolling(uartHandle, "Failed ", sizeof("Failed "));
                }
                else{
                    //printf ("Passed (0x%x%x%x%x) \n", rxData[3], rxData[2], rxData[1], rxData[0]);
                    sprintf(buff, "Passed ", &rxData);
                    //UART_writePolling(uartHandle, "Passed ", sizeof("Passed "));
                    //UART_writePolling(uartHandle, rxData, sizeof(rxData));
                    UART_writePolling(uartHandle, buff, sizeof(buff));
                    slaveFound++;
                }
                index++;
            }
            if(slaveFound == 0)
                retVal = -1;
            else
                retVal = 0;
    
    
            //GPIO_write  (SOC_XWR68XX_GPIO_2, 1U);
            GPIO_toggle (SOC_XWR68XX_GPIO_2);
            /* Delay: */
            SOC_microDelay (100000U);
            //__delay_ms(500);
    
            UART_writePolling(uartHandle, hello, sizeof(hello));
    
        }
    
        //return 0;
    
    }
    

  • Yishai:

    You may have already looked here, but here is the test code for the I2C driver for mmwave devices. From what I could gather this has no RTOS dependencies. Try using this and compare to your implementation. We had a teammate who recently used this resource to implement I2C functionality, so I am confident that this will get up and running.

    <MMWAVE_SDK_INSTALL_PATH>\packages\ti\drivers\i2c\test

    Best,

    Connor Desmond

  • Yes, I have already done that, and I have compared the codes; unfortunately, in my code, it "stuck", I have tried to manage the interrupts to solve this issue without success.
    Are you sure that this test code no RTOS dependencies? I think that the OS handles the task. See below, task handler by SYS/BIOS in the main function.

    Thank you,

    Kind Regards,

    Yishai,

    /* Initialize the Task Parameters. */
    Task_Params_init(&taskParams);
    taskParams.stackSize = 6*1024;
    Task_create(Test_initTask, &taskParams, NULL);

    /* Start BIOS */
    BIOS_start();
    return 0;
    }

  • Yishai:

    Nice catch. That is indeed an RTOS dependency. I am going to ask a driver expert on feasibility of this. I will get back to you in the next couple of days.

    Best,

    Connor Desmond

  • Thank you very much, I appreciate it, I'll wait.

    Regards,

    Yishai,

  • Yishai:

    The provided TI driver for I2C is meant to be implemented in TI RTOS applications. See below:

    This documentation can be found here:

    <MMWAVE_SDK_INSTALL_PATH>\packages\ti\drivers\i2c\docs\doxygen\html\index.html

    Best regards,

    Connor Desmond

  • Thank you,

    Without RTOS, I can't use these library files?

    Instead of that, are there other libraries?

    At this opportunity, I'll ask one more question related to mmWave SDK.

    I'm using mmwave_sdk_03_05_00_04 library, I have noted that the pimux files are not compatible with IWR6843AOP only with IWR6843.

    There is some more GPIO in the AOP version, which not relevant for the non-AOP version. There is a pinmux file that supports the AOP?

    If so, in which SDK version and how can I download it? As I know, I'm using the last mmWave SDK version.

    Regards,

    Yishai,

  • Yishai:

    This is a known issue with AOP pinmux. I would suggest using the mux values per the AOP datasheet instead of the pinmux macros defined in pinmux_xwr68xx.h.

    Best regards,

    Connor Desmond

  • Yes, that what I'm doing, but it easier when we are using a predefined header file.

    Thanks,

    Regards,

    Yishai,

  • Hi Connor,

    I don't know if it's ok to share files here, but I was editing the pinmux for iwr6843AOP based on the pinmux_xwr68xx.h header file.

    The names and pin control addresses are according to the iwr6843AOP datasheet, maybe it will help others.

    Regards,

    Yishai,

    pinmux_xwr68xxAOP.h