How can I identify the SMBus device address on the terminal? Also, I would like to know how to set the clock frequency in the i2c.h
file.
I attempted to use i2cdetect -y 6
, but unfortunately, it did not work. Are there any alternative methods for detecting the SMBus device?
Normally, I2C runs at around 400KHz, while SMBus operates at 100KHz. I wish to set the clock frequency to 100KHz to match the SMBus protocol. How to set the clock frequency on i2c.h file?
My i2c6.h code is as follows
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <cstdlib>
#include <cstring>
#include <unistd.h> // For close() function
int i2cfd;
static const char *device_name = "/dev/i2c-6";
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
int opendevice(void)
{
i2cfd = open(device_name, O_RDWR);
if (i2cfd < 0) {
perror("Error opening I2C device");
} else {
// Set the I2C functionality flags to enable SMBus (which includes 100kHz clock frequency)
if (ioctl(i2cfd, I2C_FUNCS, I2C_FUNC_I2C) < 0) {
perror("Error setting I2C functionality");
close(i2cfd);
i2cfd = -1;
}
}
return i2cfd;
}
void closedevice(void)
{
if (i2cfd >= 0) {
close(i2cfd);
i2cfd = -1;
}
}
int do_rdwr(struct i2c_msg *msgs, int nmsgs)
{
struct i2c_rdwr_ioctl_data msgset = {
.msgs = msgs,
.nmsgs = static_cast<__u32>(nmsgs),
};
if (msgs == NULL || nmsgs <= 0)
return -1;
if (ioctl(i2cfd, I2C_RDWR, &msgset) < 0)
return -1;
return 0;
}
int read_i2c_device_16(uint8_t address, uint16_t offset, uint8_t *buf, uint16_t count)
{
uint8_t offset_data[] = {static_cast<uint8_t>(offset >> 8), static_cast<uint8_t>(offset & 0x00FF)};
struct i2c_msg msgs[] = {
{address, 0, ARRAY_SIZE(offset_data), static_cast<__u8 *>((void *) offset_data)},
{address, I2C_M_RD, count, static_cast<__u8 *>((void *) buf)}
};
if (do_rdwr(msgs, ARRAY_SIZE(msgs)))
return -1;
return 0;
}
int write_i2c_device_16(uint8_t address, uint16_t offset, const uint8_t *buf, int len)
{
uint8_t *data = (uint8_t *)malloc((2 + len) * sizeof(*data));
struct i2c_msg msgs[] = {
{address, 0, static_cast<__u16>((2 + len) * sizeof(*data)), static_cast<__u8 *>((void *) data)}
};
if (!data) {
len = -1;
goto err_malloc;
}
data[0] = offset >> 8;
data[1] = offset & 0xFF;
memcpy(data + 2, buf, len);
if (do_rdwr(msgs, ARRAY_SIZE(msgs))) {
len = -1;
goto err_do_rdwr;
}
err_do_rdwr:
free(data);
err_malloc:
return len;
}
int read_i2c_device_8(uint8_t address, uint8_t offset, uint8_t* buf)
{
struct i2c_msg msgs[] = {
{address, 0, 1, &offset},
{address, I2C_M_RD, 1, buf}
};
if (do_rdwr(msgs, ARRAY_SIZE(msgs))) {
return -1;
}
return 0;
}
int write_i2c_device_8(uint8_t address, uint8_t offset, uint8_t *data)
{
int retval = 2;
uint8_t *buffer = (uint8_t *)malloc(2 * sizeof(*data));
struct i2c_msg msgs[] = {
{address, 0, 2, buffer}
};
if (!buffer)
{
retval = -1;
return retval;
}
buffer[0] = offset;
memcpy(buffer + 1, data, 1);
if (do_rdwr(msgs, ARRAY_SIZE(msgs))) {
retval = -1;
}
free(buffer);
return retval;
}