IMX6ULL I2C

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMX6ULL I2C

506 Views
Lizh
Contributor I

hello:

  When I was using imx6ull's I2C feature recently, I noticed a strange problem with I2C continuous writing: When IMX6ULL continuously writes data to the slave machine, IMX6ULL waits for more than 20 us after each byte is written, and then writes another byte. I recently in the use of imx6ull's I2C function, I found that I2C continuous write has a very strange problem: when IMX6ULL continuous to write data to the slave machine, IMX6ULL every write a byte will wait for more than 20 us, and then write a byte. My request is: is there a way to put this more than 20 us without waiting, have been continuously written. Is that OK? Wait, keep writing. Is that OK?

Lizh_0-1714682035496.png

 

0 Kudos
Reply
2 Replies

469 Views
Chavira
NXP TechSupport
NXP TechSupport

Hi @Lizh!

Thank you for contacting NXP Support!

 

Maybe the problem is in your code.

How you are writing on the i2c bus?

I recommend trying with i2c-tools

 

Best Regards!

Chavira

0 Kudos
Reply

425 Views
Lizh
Contributor I
int cs_i2c_byte_read(struct haptic *cs_haptic, uint8_t reg_addr, uint8_t * buf, uint32_t len)
{
int ret = -1;
int i = CS_RETRY_TIMES;
struct i2c_msg msg[2];
struct i2c_adapter *adapter = cs_haptic->i2c->adapter;
 
if (buf == NULL || len == 0) {
log_err(" input param is invalid");
return -1;
}
/*send reg addr*/
msg[0].addr = cs_haptic->i2c->addr;
msg[0].flags = 0;
msg[0].buf = &reg_addr;
msg[0].len = 1;
/*read reg*/
msg[1].addr = cs_haptic->i2c->addr;
msg[1].flags = I2C_M_RD;
msg[1].buf = buf;
msg[1].len = len;
mutex_lock(&i2c_rw_lock);
do {
ret = i2c_transfer(adapter, msg, sizeof(msg) / sizeof(struct i2c_msg));
if (ret < 0)
log_err("read failed: %d", ret);
else
break;
i--;
} while (i > 0);
mutex_unlock(&i2c_rw_lock);
return ret;
}
 
int cs_i2c_byte_write(struct haptic *cs_haptic, uint8_t reg_addr, uint8_t * buf, uint32_t len)
{
int32_t ret = 0;
uint8_t *data = NULL;
int i = CS_RETRY_TIMES;
struct i2c_msg msg;
struct i2c_adapter *adapter = cs_haptic->i2c->adapter;
 
if (buf == NULL || len == 0) {
log_err("input param is invalid");
return -1;
}
data = kmalloc(len + 1, GFP_KERNEL);
if (data == NULL) {
return -ENOMEM;
}
data[0] = reg_addr;
memcpy(&data[1], buf, len);
 
msg.addr = cs_haptic->i2c->addr;
msg.flags = 0;
msg.buf = data;
msg.len = len + 1;
mutex_lock(&i2c_rw_lock);
do {
ret = i2c_transfer(adapter, &msg, 1);
if (ret < 0)
log_err("write failed: %d", ret);
else
break;
i--;
} while (i > 0);
mutex_unlock(&i2c_rw_lock);
kfree(data);
return ret;
}
 
int cs_i2c_one_byte_write(struct haptic *cs_haptic, uint8_t reg_addr, uint8_t data)
{
uint8_t temp = 0;
 
temp = data;
return cs_i2c_byte_write(cs_haptic,reg_addr, &temp, 0x01);
}
 
int cs_write_sram(struct haptic *cs_haptic, uint8_t reg_addr, uint8_t *buf, uint32_t len){
uint8_t *data = NULL;
int ret = -1;
 
if (buf == NULL || len == 0) {
log_err("input param is invalid");
return -1;
}
 
data = kmalloc(len + 1, GFP_KERNEL);
data[0] = reg_addr;
memcpy(&data[1], buf, len);
ret = i2c_master_send(cs_haptic->i2c, data, len + 1);
if (ret < 0)
log_err("i2c write sram err:%d",ret);
kfree(data);
return ret;
}


The i2c_transfer function is actually implemented by your I2C controller driver,It's not my code. I'm calling your underlying interface. The i2c_transfer function actually calls your driver function i2c_imx_xfer, so this should not be my code problem, please help to look at it, thank you.
0 Kudos
Reply