I wanted to implement an I2C bus recovery during initialization. The
reason is well known in literature[1].
I read the function i2c_generic_recovery[2] of Linux kernel, but I don't understand one thing.
The bus recovery is necessary to bring a slave to the end of a byte transmission that could be interrupted for some reason.
However the slave could be transmitting 0xFF, so why the above function breaks the loop if SDA is detected high?
[Line 620] /* Break if SDA is high */
Maybe it's better to send 9 clock cycles whatever the level of SDA line.
And what about STOP condition at the end of the 9 clock cycles? Is it necessary? It should be (SCL is already high): set SDA low, pause, set
SDA high.
Do you use this sort of bus recovery?
[1] https://www.analog.com/media/en/technical-documentation/application-notes/54305147357414AN686_0.pdf
[2] https://elixir.bootlin.com/linux/v4.5/source/drivers/i2c/i2c-core.c#L604
pozz <pozzugno@gmail.com> wrote:
I wanted to implement an I2C bus recovery during initialization. The
reason is well known in literature[1].
I read the function i2c_generic_recovery[2] of Linux kernel, but I don't
understand one thing.
The bus recovery is necessary to bring a slave to the end of a byte
transmission that could be interrupted for some reason.
However the slave could be transmitting 0xFF, so why the above function
breaks the loop if SDA is detected high?
[Line 620] /* Break if SDA is high */
With normal devices start followed by stop should reset state of the bus. Howere, to send start we need SDA high. If this is bus with single
master SDA should be high at least at the end of byte (bus should
flat high as device waits for ACK).
Maybe it's better to send 9 clock cycles whatever the level of SDA line.
I am not sure if this helps: writer is supposed to stop seeing new
start, so it is not clear if extra clock give anything for writers.
OTOH, if bus is clocked reader could get wrong data, so it seem
better to reset bus as soon as possible (that is first time when
SDA is high).
And what about STOP condition at the end of the 9 clock cycles? Is it
necessary? It should be (SCL is already high): set SDA low, pause, set
SDA high.
Do you use this sort of bus recovery?
Well, I plan to do so. But I do not like to use untested code,
and to preperly test it I would need special driver to inject
various upsets to I2C bus.
[1]
https://www.analog.com/media/en/technical-documentation/application-notes/54305147357414AN686_0.pdf
[2] https://elixir.bootlin.com/linux/v4.5/source/drivers/i2c/i2c-core.c#L604
Il 08/11/2022 23:08, antispam@math.uni.wroc.pl ha scritto:
pozz <pozzugno@gmail.com> wrote:
I wanted to implement an I2C bus recovery during initialization. The
reason is well known in literature[1].
I read the function i2c_generic_recovery[2] of Linux kernel, but I don't >>> understand one thing.
The bus recovery is necessary to bring a slave to the end of a byte
transmission that could be interrupted for some reason.
However the slave could be transmitting 0xFF, so why the above function
breaks the loop if SDA is detected high?
[Line 620] /* Break if SDA is high */
With normal devices start followed by stop should reset state of the bus.
Howere, to send start we need SDA high. If this is bus with single
master SDA should be high at least at the end of byte (bus should
flat high as device waits for ACK).
Do you think that a slave transmitting 0xFF interrupts the transmission
in the middle as soon as it detects a falling transition on SDA (STOP)?
Anyway, in this case the STOP transmission is necessary after reading
SDA high. I couldn't find the STOP transmission in the Linux kernel
code, only a few clock cycles until SDA is detected high.
Maybe it's better to send 9 clock cycles whatever the level of SDA line.
I am not sure if this helps: writer is supposed to stop seeing new
start, so it is not clear if extra clock give anything for writers.
Yes, if the slave transmitting something stops after seeing a STOP (SDA
going low). I don't know it this is a well-known specification and if
all the I2C slaves implement this specification correctly.
OTOH, if bus is clocked reader could get wrong data, so it seem
better to reset bus as soon as possible (that is first time when
SDA is high).
What do you mean with reader? When the bus is stuck, the writer is the
slave and the reader should be the master that is trying to recovery the
bus, so technically it is not reading anything.
Are you thinking of a bus with multiple slaves? They shouldn't be
reading anything.
And what about STOP condition at the end of the 9 clock cycles? Is it
necessary? It should be (SCL is already high): set SDA low, pause, set
SDA high.
Do you use this sort of bus recovery?
Well, I plan to do so. But I do not like to use untested code,
and to preperly test it I would need special driver to inject
various upsets to I2C bus.
Yes, this should be ideal, but it's not simple to inject errors in the
I2C bus, so I asked for some ideas and suggestions.
[1]
https://www.analog.com/media/en/technical-documentation/application-notes/54305147357414AN686_0.pdf
[2]
https://elixir.bootlin.com/linux/v4.5/source/drivers/i2c/i2c-core.c#L604
On 11/9/22 2:32 AM, pozz wrote:
Il 08/11/2022 23:08, anti...@math.uni.wroc.pl ha scritto:
pozz <pozz...@gmail.com> wrote:
I wanted to implement an I2C bus recovery during initialization. The
reason is well known in literature[1].
I read the function i2c_generic_recovery[2] of Linux kernel, but I don't >>> understand one thing.
The bus recovery is necessary to bring a slave to the end of a byte
transmission that could be interrupted for some reason.
However the slave could be transmitting 0xFF, so why the above function >>> breaks the loop if SDA is detected high?
[Line 620] /* Break if SDA is high */
With normal devices start followed by stop should reset state of the bus. >> Howere, to send start we need SDA high. If this is bus with single
master SDA should be high at least at the end of byte (bus should
flat high as device waits for ACK).
Do you think that a slave transmitting 0xFF interrupts the transmissionIT is suppossed to if it meets the standard. ANY change of SDA when SCL
in the middle as soon as it detects a falling transition on SDA (STOP)?
is High resets the logic of every device on the bus in response to the
Start or Stop bit just sent.
Anyway, in this case the STOP transmission is necessary after readingYou don't need a STOP, you need either a start or stop. When you enable
SDA high. I couldn't find the STOP transmission in the Linux kernel
code, only a few clock cycles until SDA is detected high.
the I2C controller and start a transmission, it will begin with a start,
and that will provide the needed reset.
Maybe it's better to send 9 clock cycles whatever the level of SDA line. >>I am not sure if this helps: writer is supposed to stop seeing new
start, so it is not clear if extra clock give anything for writers.
Yes, if the slave transmitting something stops after seeing a STOP (SDA going low). I don't know it this is a well-known specification and if
all the I2C slaves implement this specification correctly.
It is a well known requirement of the I2C specification that any start
or stop bit needs to reset the logic of devices.
Not all devices support it though, but if you have one that doesn't and
you get stuck like this, your only answer is some other form of reset
(like a power cycle).
OTOH, if bus is clocked reader could get wrong data, so it seem
better to reset bus as soon as possible (that is first time when
SDA is high).
What do you mean with reader? When the bus is stuck, the writer is the slave and the reader should be the master that is trying to recovery the bus, so technically it is not reading anything.
Are you thinking of a bus with multiple slaves? They shouldn't be
reading anything.
And what about STOP condition at the end of the 9 clock cycles? Is it
necessary? It should be (SCL is already high): set SDA low, pause, set >>> SDA high.
Do you use this sort of bus recovery?
Well, I plan to do so. But I do not like to use untested code,
and to preperly test it I would need special driver to inject
various upsets to I2C bus.
Yes, this should be ideal, but it's not simple to inject errors in the
I2C bus, so I asked for some ideas and suggestions.
Il 08/11/2022 23:08, antispam@math.uni.wroc.pl ha scritto:
pozz <pozzugno@gmail.com> wrote:
I wanted to implement an I2C bus recovery during initialization. The
reason is well known in literature[1].
I read the function i2c_generic_recovery[2] of Linux kernel, but I don't >> understand one thing.
The bus recovery is necessary to bring a slave to the end of a byte
transmission that could be interrupted for some reason.
However the slave could be transmitting 0xFF, so why the above function
breaks the loop if SDA is detected high?
[Line 620] /* Break if SDA is high */
With normal devices start followed by stop should reset state of the bus. Howere, to send start we need SDA high. If this is bus with single
master SDA should be high at least at the end of byte (bus should
flat high as device waits for ACK).
Do you think that a slave transmitting 0xFF interrupts the transmission
in the middle as soon as it detects a falling transition on SDA (STOP)?
Anyway, in this case the STOP transmission is necessary after reading
SDA high. I couldn't find the STOP transmission in the Linux kernel
code, only a few clock cycles until SDA is detected high.
Maybe it's better to send 9 clock cycles whatever the level of SDA line.
I am not sure if this helps: writer is supposed to stop seeing new
start, so it is not clear if extra clock give anything for writers.
Yes, if the slave transmitting something stops after seeing a STOP (SDA
going low). I don't know it this is a well-known specification and if
all the I2C slaves implement this specification correctly.
OTOH, if bus is clocked reader could get wrong data, so it seem
better to reset bus as soon as possible (that is first time when
SDA is high).
What do you mean with reader? When the bus is stuck, the writer is the
slave and the reader should be the master that is trying to recovery the
bus, so technically it is not reading anything.
Are you thinking of a bus with multiple slaves? They shouldn't be
reading anything.
On 11/9/22 2:32 AM, pozz wrote:
Il 08/11/2022 23:08, antispam@math.uni.wroc.pl ha scritto:
pozz <pozzugno@gmail.com> wrote:
I wanted to implement an I2C bus recovery during initialization. The
reason is well known in literature[1].
I read the function i2c_generic_recovery[2] of Linux kernel, but I
don't
understand one thing.
The bus recovery is necessary to bring a slave to the end of a byte
transmission that could be interrupted for some reason.
However the slave could be transmitting 0xFF, so why the above function >>>> breaks the loop if SDA is detected high?
[Line 620] /* Break if SDA is high */
With normal devices start followed by stop should reset state of the
bus.
Howere, to send start we need SDA high. If this is bus with single
master SDA should be high at least at the end of byte (bus should
flat high as device waits for ACK).
Do you think that a slave transmitting 0xFF interrupts the
transmission in the middle as soon as it detects a falling transition
on SDA (STOP)?
IT is suppossed to if it meets the standard. ANY change of SDA when SCL
is High resets the logic of every device on the bus in response to the
Start or Stop bit just sent.
Anyway, in this case the STOP transmission is necessary after reading
SDA high. I couldn't find the STOP transmission in the Linux kernel
code, only a few clock cycles until SDA is detected high.
You don't need a STOP, you need either a start or stop. When you enable
the I2C controller and start a transmission, it will begin with a start,
and that will provide the needed reset.
Maybe it's better to send 9 clock cycles whatever the level of SDA
line.
I am not sure if this helps: writer is supposed to stop seeing new
start, so it is not clear if extra clock give anything for writers.
Yes, if the slave transmitting something stops after seeing a STOP
(SDA going low). I don't know it this is a well-known specification
and if all the I2C slaves implement this specification correctly.
It is a well known requirement of the I2C specification that any start
or stop bit needs to reset the logic of devices.
Not all devices support it though, but if you have one that doesn't and
you get stuck like this, your only answer is some other form of reset
(like a power cycle).
OTOH, if bus is clocked reader could get wrong data, so it seem
better to reset bus as soon as possible (that is first time when
SDA is high).
What do you mean with reader? When the bus is stuck, the writer is the
slave and the reader should be the master that is trying to recovery
the bus, so technically it is not reading anything.
Are you thinking of a bus with multiple slaves? They shouldn't be
reading anything.
And what about STOP condition at the end of the 9 clock cycles? Is it
necessary? It should be (SCL is already high): set SDA low, pause, set >>>> SDA high.
Do you use this sort of bus recovery?
Well, I plan to do so. But I do not like to use untested code,
and to preperly test it I would need special driver to inject
various upsets to I2C bus.
Yes, this should be ideal, but it's not simple to inject errors in the
I2C bus, so I asked for some ideas and suggestions.
[1]
https://www.analog.com/media/en/technical-documentation/application-notes/54305147357414AN686_0.pdf
[2]
https://elixir.bootlin.com/linux/v4.5/source/drivers/i2c/i2c-core.c#L604 >>>
Well, I plan to do so. But I do not like to use untested code,
and to preperly test it I would need special driver to inject
various upsets to I2C bus.
Yes, this should be ideal, but it's not simple to inject errors in the
I2C bus, so I asked for some ideas and suggestions.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 299 |
Nodes: | 16 (2 / 14) |
Uptime: | 75:00:39 |
Calls: | 6,695 |
Calls today: | 5 |
Files: | 12,228 |
Messages: | 5,347,075 |
Posted today: | 2 |