Required dependencies:
#include <ti/drivers/i2c/I2C.h>
Also need to link these files in you're project:
libi2c_xwr68xx.aer4f
${COM_TI_MMWAVE_SDK_INSTALL_DIR}/packages/ti/drivers/i2c/lib
Pin Multiplexing
Using these pins which are already exposed on the development board:
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);
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);
I2C Initialization Configuration
I2C functions are divided into master and slave modes. This example uses master mode functionality.
First, call this function:
I2C_init();
Then, similar to other peripheral initialization:
I2C_Params i2cParams;
I2C_Params_init(&i2cParams);
i2cParams.bitRate = I2C_400kHz;
i2cParams.transferMode = I2C_MODE_BLOCKING;
RadarSystem.I2C_Handle = I2C_open(0, &i2cParams);
if (RadarSystem.I2C_Handle == NULL)
{
System_printf("Error: Unable to open I2C instance\n");
return;
}
Data Transmission
Define the I2C_Transaction structure and use I2C_transfer function:
I2C_Transaction i2cTransaction;
i2cTransaction.readCount = 0;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = NULL;
i2cTransaction.writeBuf = NULL;
i2cTransaction.slaveAddress = data;
I2C_transfer(RadarSystem.I2C_Handle, &i2cTransaction);
Either writeCount or readCount must not be zero. If no ACK is received after sending the slave address, transmission will be automatically cancelled.
Note: The address past is 7-bit. If an 8-bit address is provided, the 7th bit will be discarded.
Although we configured 400kHz, actual speed may be lower due to thread scheduling.
Simulating UART Data Output Using SDA
Due to the characteristics of the transmission function, we can use data bits for 7-bit UART data transmission. For standard 8-bit UART, we can define this data format: if the 7th bit is 1, send 0x01 first, otherwise send 0x00, then send stop bit and pull high twice, followed by the lower 7 bits.
Here's the implementation:
void I2C_Send(uint8_t data)
{
I2C_Transaction i2cTransaction;
i2cTransaction.readCount = 0;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = NULL;
i2cTransaction.writeBuf = NULL;
uint8_t highNibble = data >> 7;
uint8_t lowNibble = data & 0x7F;
i2cTransaction.slaveAddress = highNibble;
I2C_transfer(RadarSystem.I2C_Handle, &i2cTransaction);
i2cTransaction.slaveAddress = lowNibble;
I2C_transfer(RadarSystem.I2C_Handle, &i2cTransaction);
}
Important: UART protocol typically uses LSB, while I2C uses MSB. The receiver needs to adjust configuration or perform conversion.
For sending arrays:
void I2C_Send_Buf(uint8_t* buffer, uint8_t size)
{
uint8_t i = 0;
for(i = 0; i < size; i++)
{
I2C_Send(buffer[i]);
}
}
For sending large data:
I2C_Send_Buf(&data[0], 2);
I2C_Send_Buf((uint8_t*)&RadarSystem.frameNumber, 4);
I2C_Send_Buf((uint8_t*)&RadarSystem.HeartRate_Out, 4);
I2C_Send_Buf((uint8_t*)&RadarSystem.BreathingRate_Out, 4);
I2C_Send_Buf((uint8_t*)&RadarSystem.OutputStats, 128);
I2C_Send_Buf(&data[2], 2);