Date: Sun, 10 Nov 2019 08:16:03 -0700 From: Ian Lepore <ian@freebsd.org> To: mishin@mh.san.ru, freebsd-arm@freebsd.org Subject: Re: Can't write to IIC by I2CRDWR with two records 'struct iic_msg' Message-ID: <1dff42bdef54d3eca4791e5da729ee479b386731.camel@freebsd.org> In-Reply-To: <7ace6346d97d0bfe95cfab3cb6fa820b@mh.san.ru>
index | next in thread | previous in thread | raw e-mail
On Sun, 2019-11-10 at 16:55 +0400, mishin@mh.san.ru wrote:
> 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}
> };
Some i2c hardware controller drivers don't properly support the NOSTOP
and NOSTART flags. Sometimes it's a bug, and sometimes it's because
hardware limitations prevent it. In the allwinner case, I think it's a
bug, but manu would know for sure.
-- Ian
> 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);
> }
> _______________________________________________
> freebsd-arm@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-arm
> To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org
> "
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1dff42bdef54d3eca4791e5da729ee479b386731.camel>
