Can't write to IIC by I2CRDWR with two records 'struct iic_msg'
mishin at mh.san.ru
mishin at mh.san.ru
Sun Nov 10 12:55:26 UTC 2019
About a system:
1. FreeBSD betta 12.1-STABLE FreeBSD 12.1-STABLE r354236 OPI_ZERO arm
2. Allwinner H2+
3.
iichb0: <Allwinner Integrated I2C Bus Controller> mem
0x1c2ac00-0x1c2afff irq 35 on simplebus0
iicbus0: <OFW I2C bus> on iichb0
iic0: <I2C generic I/O> on iicbus0
I trying to send a data array following a register value to a SSD1306
display
from 'Allwinner H2+' by a following method (according to `i2c.c`):
char SSD1306::iic_write(uint8_t offset, uint8_t data[], uint16_t size)
const {
struct iic_msg msgs[2] =
{
{slave_addr, IIC_M_WR | IIC_M_NOSTOP, sizeof(offset), &offset},
{slave_addr, IIC_M_WR | IIC_M_NOSTART, size, data}
};
struct iic_rdwr_data xfer = {msgs, 2};
if ( ioctl(iic_handle, I2CRDWR, &xfer) == -1 ) {
perror("ioctl(I2CRDWR)");
return(-1);
};
return(0);
};
iic_write(0x40, buffer, buffer_size);
But something goes wrong and the display stills blank (no errors,
though). But when I use an 'one record' struct
with combined 'register+data' array (see below) or read by that 'two
records' scheme (see below), all is ok.
Have I made a mistake is flags or it is a feature or a bug?
Thanks
---
Next two methods works ok
Read following write:
char TEA5767::iic_read(uint8_t offset, uint8_t *data, uint16_t size)
const {
struct iic_msg msgs[2] =
{
{slave_addr, IIC_M_WR | IIC_M_NOSTOP, sizeof(offset), &offset},
{slave_addr, IIC_M_RD, size, data}
};
struct iic_rdwr_data xfer = {msgs, 2};
if ( ioctl(iic_handle, I2CRDWR, &xfer) == -1) {
perror("ioctl(I2CRDWR)");
return(-1);
};
return(0);
};
and write a combined 'register+data' array works too:
char SSD1306::iic_write(uint8_t data[], uint16_t size) const
{
struct iic_msg msgs[1] =
{
{slave_addr, IIC_M_WR, size, data}
};
struct iic_rdwr_data xfer = {msgs, 1};
if ( ioctl(iic_handle, I2CRDWR, &xfer) == -1) {
perror("ioctl(I2CRDWR)");
return(-1);
};
return(0);
}
More information about the freebsd-arm
mailing list