Send data to the I2C device
Once you start the I2C driver, it exposes a path under /dev/i2c*. You can use the devctl() command to interface with the I2C driver and can find it's format in hw/i2c.h. The example uses the following sample I2C code to explain the interface: https://gitlab.com/qnx/projects/hardware-component-samples/-/tree/main/common/rpi_i2c
The following example reads a value from a slave device to explain the interface. Start with defining the read data structure in your application:
struct i2c_recv_data_msg_t
{
i2c_sendrecv_t hdr;
uint8_t bytes[0];
};Fill out the i2c_sendrecv_t structure with relevant data:
typedef struct {
i2c_addr_t slave; /* slave address */
_Uint32t send_len; /* length of send data in bytes */
_Uint32t recv_len; /* length of receive data in bytes */
_Uint32t stop; /* set stop when complete? */
} i2c_sendrecv_t;Fill out the i2c_addr_t structure, which is set up for the slave device:
typedef struct {
_Uint32t addr; /* I2C address */
_Uint32t fmt; /* 7- or 10-bit format */
} i2c_addr_t;Filling up the data may look like the following:
// Allocate memory for the message
struct i2c_recv_data_msg_t *msg = NULL;
msg = malloc(sizeof(struct i2c_recv_data_msg_t) + MIN_READ_BYTES); // allocate enough memory for both the calling information and received data
if (!msg)
{
perror("alloc failed");
return I2C_ERROR_ALLOC_FAILED;
}
// Assign which register
msg->bytes[0] = register_val;
// Assign the I2C device and format of message
msg->hdr.slave.addr = i2c_address;
msg->hdr.slave.fmt = I2C_ADDRFMT_7BIT;
msg->hdr.send_len = 1;
msg->hdr.recv_len = 1;
msg->hdr.stop = 1;Once you've filled out the data, you can finally send the data to the resource manager using the devctl() command:
int status; // status information about the devctl() call
int err = devctl(smbus_fd[bus_number], DCMD_I2C_SENDRECV, msg, sizeof(*msg) + 1, (&status)); // specify DCMD_I2C_SENDRECV to indicate that we are using the i2c_sendrecv_t data structureRefer to the smbus_read_data_byte() function in the i2c.c file for more detailed information. You can implement a similar approach for other devctl() DCMDs.
You can find a list of the devctl() commands in the "Resource manager interface" section of the Customizing a BSP guide.
