Page MenuHomeFreeBSD

iicbb: rebuild the bit-banging algorithms using different primitives
ClosedPublic

Authored by avg on Oct 31 2019, 4:08 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Nov 19, 1:22 PM
Unknown Object (File)
Sun, Nov 10, 1:58 PM
Unknown Object (File)
Sun, Nov 10, 9:47 AM
Unknown Object (File)
Sat, Nov 9, 5:56 AM
Unknown Object (File)
Sat, Nov 9, 5:50 AM
Unknown Object (File)
Oct 3 2024, 10:08 PM
Unknown Object (File)
Oct 1 2024, 1:42 PM
Unknown Object (File)
Sep 26 2024, 3:28 AM
Subscribers
None

Details

Summary

I2C_SET was quite inflexible, it used too long delays as well as some
unnecessary delays. The new building blocks are iicbb_clockin and
iicbb_clockout. The former sets SDA and starts the high period of SCL, the
latter executes the low period of SCL. What happens during the high phase
depends on the operation. For writes we just hold both lines, for reads we
poll SDA. S, Sr and P change SDA in the middle of the high period.

Also, the calculation of udelay has been updated, so that the resulting
period more closely corresponds the requested bus frequency.
There is a new knob, io_delay, that allows to further adjust udelay based on
the estimated latency of pin toggling operations.

Finally, I slightly changed debug tracing and added error indicators to it.
The debug prints are compiled in but disabled by default.
This can be of use if there is any fallout from this change.

Some ideas for further improvements:

  • add a function for sub-microsecond delays (e.g., in units of 1/10th of a microsecond) and use it for more precise timing of short delays;
  • account for the actual time spent in the pin I/O.
Test Plan

Reading temperature and humidity from HTU21 in the bus hold mode:

<<w80+ we3+ <w81+ .....r6d+ rac+ r94- >>
<<w80+ we5+ <w81+ .............r47+ re2+ r84- >>

where '<<' is S, '<' is Sr, '>>' is P, '.' is one millisecond of clock
stretching by the slave.

Reading temperature and humidity in the no-hold mode:

<<w80+ wf3+ >>
<<w81- >>
<<w81+ r6d+ r54+ raf- >>
<<w80+ wf5+ >>
<<w81- >>
<<w81+ r48+ r4e+ r9c- >>

where '+' is Ack and '-' is NoAck.
We see that first read attempts are not acknowledged.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

I think think this is fine, assuming that 'now' is updated often enough to be meaningful for fast bus speeds. Though the old code has issues > 500KHz too...
I think this is a better method in general. Some devices don't like to be polled that fast, but they are rather the exception than the rule (and I'm not aware of any GPIOish device that can't cope). Polling faster should give a better response time than the fixed delays.

So this is a messy area, and despite some vague quibbles, I think this is a much less messy way to go.

This revision was not accepted when it landed; it landed in state Needs Review.Jun 11 2020, 5:34 AM
This revision was automatically updated to reflect the committed changes.