Message ID | 20201030080420.28016-1-michael.wu@vatics.com |
---|---|
Headers | show |
Series | Designware I2C slave confusing IC_INTR_STOP_DET handle | expand |
On 10/30/20 10:04 AM, Michael Wu wrote: > Sometimes we would get the following flow when doing an i2cset: > > 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4 > I2C_SLAVE_WRITE_RECEIVED > 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x714 : INTR_STAT=0x204 > I2C_SLAVE_WRITE_REQUESTED > I2C_SLAVE_WRITE_RECEIVED > > Documentation/i2c/slave-interface.rst says that I2C_SLAVE_WRITE_REQUESTED, > which is mandatory, should be sent while the data did not arrive yet. It > means in a write-request I2C_SLAVE_WRITE_REQUESTED should be reported > before any I2C_SLAVE_WRITE_RECEIVED. > > By the way, I2C_SLAVE_STOP didn't be reported in the above case because > DW_IC_INTR_STAT was not 0x200. > > dev->status can be used to record the current state, especially Designware > I2C controller has no interrupts to identify a write-request. This patch > makes not only I2C_SLAVE_WRITE_REQUESTED been reported first when > IC_INTR_RX_FULL is rising and dev->status isn't STATUS_WRITE_IN_PROGRESS > but also I2C_SLAVE_STOP been reported when a STOP condition is received. > > Signed-off-by: Michael Wu <michael.wu@vatics.com> > --- > drivers/i2c/busses/i2c-designware-slave.c | 45 +++++++++-------------- > 1 file changed, 18 insertions(+), 27 deletions(-) > Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Hi Michael, > Documentation/i2c/slave-interface.rst says that I2C_SLAVE_WRITE_REQUESTED, > which is mandatory, should be sent while the data did not arrive yet. It > means in a write-request I2C_SLAVE_WRITE_REQUESTED should be reported > before any I2C_SLAVE_WRITE_RECEIVED. Correct. > dev->status can be used to record the current state, especially Designware > I2C controller has no interrupts to identify a write-request. This patch Just double-checking: the designware HW does not raise an interrupt when its own address + RW bit has been received? Kind regards, Wolfram
Hi Wolfram, > > dev->status can be used to record the current state, especially Designware > > I2C controller has no interrupts to identify a write-request. This patch > > Just double-checking: the designware HW does not raise an interrupt when > its own address + RW bit has been received? Not exactly. There're an interrupt state name "RD_REQ" but no one named like "WR_REQ". For read-request, the slave will get a RD_REQ interrupt. For write-request, the slave won't be interrupted until data arrived to trigger interrupt "RX_FULL". I tried to use GPIO to simulate an I2C master. I only sent its own address + W bit without any data and then I got only a STOP_DET interrupt. If I sent its own address + W bit + one byte data and then I got one RX_FULL and a STOP_DET. It seems the controller doesn't interrupt when RW bit is W, but R does. What do you think, Jarkko? Sincerely, Michael Wu
> Not exactly. There're an interrupt state name "RD_REQ" but no one named > like "WR_REQ". > > For read-request, the slave will get a RD_REQ interrupt. > For write-request, the slave won't be interrupted until data arrived to > trigger interrupt "RX_FULL". > > I tried to use GPIO to simulate an I2C master. I only sent its own > address + W bit without any data and then I got only a STOP_DET interrupt. > If I sent its own address + W bit + one byte data and then I got one > RX_FULL and a STOP_DET. > > It seems the controller doesn't interrupt when RW bit is W, but R does. Thanks for the detailed explanation! Okay, then what you do looks correct to me (from a high level perspective without really knowing the HW): when RX is full, you first send the state WRITE_REQUESTED when there is no other transfer on-going. Then you send WRITE_RECEIVED immediately. I think this is the way to do it.
Hi Wolfram, > Thanks for the detailed explanation! Okay, then what you do looks > correct to me (from a high level perspective without really knowing the > HW): when RX is full, you first send the state WRITE_REQUESTED when > there is no other transfer on-going. Then you send WRITE_RECEIVED > immediately. I think this is the way to do it. Bingo!! Thanks for your understanding. I think I should have a habit of writing comments... X-P Best regards, Michael Wu
On 11/4/20 12:17 PM, Michael.Wu@vatics.com wrote: > Hi Wolfram, > >>> dev->status can be used to record the current state, especially Designware >>> I2C controller has no interrupts to identify a write-request. This patch >> >> Just double-checking: the designware HW does not raise an interrupt when >> its own address + RW bit has been received? > > Not exactly. There're an interrupt state name "RD_REQ" but no one named > like "WR_REQ". > > For read-request, the slave will get a RD_REQ interrupt. > For write-request, the slave won't be interrupted until data arrived to > trigger interrupt "RX_FULL". > > I tried to use GPIO to simulate an I2C master. I only sent its own > address + W bit without any data and then I got only a STOP_DET interrupt. > If I sent its own address + W bit + one byte data and then I got one > RX_FULL and a STOP_DET. > > It seems the controller doesn't interrupt when RW bit is W, but R does. > What do you think, Jarkko? > Yes, the datasheet has a flowchart for slave mode and it shows for a write only RX_FULL interrupt followed by read from IC_DATA_CMD to retrieve received byte. Which I believe won't occur if there is no incoming data byte and only STOP_DET happens as you have observed. The flowchart however doesn't include the STOP_DET flow. Jarkko