Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Nov 2019 16:55:13 +0400
From:      mishin@mh.san.ru
To:        freebsd-arm@freebsd.org
Subject:   Can't write to IIC by I2CRDWR with two records 'struct iic_msg'
Message-ID:  <7ace6346d97d0bfe95cfab3cb6fa820b@mh.san.ru>

next in thread | raw e-mail | index | archive | help
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);
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7ace6346d97d0bfe95cfab3cb6fa820b>