When you want to use an I2C device with Raspberry Pi or Jetson nano, RasPi has libraries such as pigpio and WiringPi, but Jetson has only Jetson.GPIO, and you may have trouble when you want to write in C / C ++. (Are you in trouble ??)
For such a case, I wrote an article about how to communicate with an I2C device using a general-purpose Linux I2C driver.
There seem to be several ways to communicate with the I2C device, but this code uses the ioctl I2C_RDWR.
i2c_example.c
#include <stdint.h>
// ...
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
static const char* dev_name = "/dev/i2c-1";
/*!Read data from I2C slave device.
* @param[in] dev_addr device address.
* @param[in] reg_addr register address.
* @param[out]data A pointer to the storage location of the data to be read.
* @param[in]length Length of data to read.
*/
int8_t i2c_read(
uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t length) {
/*Open the I2C device. */
int32_t fd = open(dev_name, O_RDWR);
if (fd == -1) {
fprintf(stderr, "i2c_read: failed to open: %s\n", strerror(errno));
return -1;
}
/* I2C-Create a Read message. */
struct i2c_msg messages[] = {
{ dev_addr, 0, 1, ®_addr }, /*Set register address. */
{ dev_addr, I2C_M_RD, length, data }, /*Read length bytes into data. */
};
struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 };
/* I2C-Read. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 2) {
fprintf(stderr, "i2c_read: failed to ioctl: %s\n", strerror(errno));
close(fd);
return -1;
}
close(fd);
return 0;
}
/*!Write data to I2C slave device.
* @param[in] dev_addr device address.
* @param[in] reg_addr register address.
* @param[in]data A pointer to the storage location of the data to be written.
* @param[in]length Length of data to write.
*/
int8_t i2c_write(
uint8_t dev_addr, uint8_t reg_addr, const uint8_t* data, uint16_t length) {
/*Open the I2C device. */
int32_t fd = open(dev_name, O_RDWR);
if (fd == -1) {
fprintf(stderr, "i2c_write: failed to open: %s\n", strerror(errno));
return -1;
}
/* I2C-Prepare a buffer for Write. */
uint8_t* buffer = (uint8_t*)malloc(length + 1);
if (buffer == NULL) {
fprintf(stderr, "i2c_write: failed to memory allocate\n");
close(fd);
return -1;
}
buffer[0] = reg_addr; /*Set the register address in the 1st byte. */
memcpy(&buffer[1], data, length); /*Set data after the second byte. */
/* I2C-Create a Write message. */
struct i2c_msg message = { dev_addr, 0, length + 1, buffer };
struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
/* I2C-Write. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 1) {
fprintf(stderr, "i2c_write: failed to ioctl: %s\n", strerror(errno));
free(buffer);
close(fd);
return -1;
}
free(buffer);
close(fd);
return 0;
}
First of all, the header include and the device name definition.
python
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
static const char* dev_name = "/dev/i2c-1";
The pin assignments for the RasPi and Jetson nano I2C Bus1 are the same, and the device name is the same for / dev / i2c-1
.
python
/* I2C-Create a Read message. */
struct i2c_msg messages[] = {
{ dev_addr, 0, 1, ®_addr }, /*Set register address. */
{ dev_addr, I2C_M_RD, length, data }, /*Read length bytes into data. */
};
struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 };
/* I2C-Read. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 2) {
Two i2c_msg structures are required for Read. Set the register address first, The size to be read second and the storage location of the data are specified.
python
/* I2C-Prepare a buffer for Write. */
uint8_t* buffer = (uint8_t*)malloc(length + 1);
buffer[0] = reg_addr; /*Set the register address in the 1st byte. */
memcpy(&buffer[1], data, length); /*Set data after the second byte. */
/* I2C-Create a Write message. */
struct i2c_msg message = { dev_addr, 0, length + 1, buffer };
struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
/* I2C-Write. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 1) {
At the time of Write, a buffer of "length of data to be written + 1" is required. Set the register address in the 1st byte, Set the data after the second byte.
The i2c_msg structure will be one.
I was able to communicate with the I2C device on both the RasPi and Jetson Nano with this code, but please note that the code and content may be incorrect.
Recommended Posts