Skip to content

Commit bda3491

Browse files
committed
cores/i2c: documentation
1 parent e9b2b05 commit bda3491

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

lambdalib/cores/i2c/proto.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,39 @@
1515
STATUS_ERR = 1
1616

1717
class I2CProto(Elaboratable):
18+
""" Protocol oriented wrapper around the bidirectional I2CStream.
19+
20+
The main use of this module is for creating a I2C bridge from software,
21+
typically over UART or USB.
22+
23+
Sink stream description:
24+
`data`: header
25+
header[0]: 1 == read
26+
0 == write
27+
`data`: length
28+
amount of data bytes to read or write
29+
30+
When writing:
31+
-> `sink.data`
32+
header
33+
-> `sink.data`
34+
length
35+
-> `sink.data` ... `sink.data`
36+
data write ... data write
37+
<- `source.data`
38+
status
39+
40+
When reading:
41+
-> `sink.data`
42+
header
43+
-> `sink.data`
44+
length
45+
<- `source.data`
46+
status
47+
<- `source.data` ... `source.data`
48+
data read ... data read
49+
50+
"""
1851
def __init__(self,
1952
sys_clk_freq,
2053
i2c_freq=400e3,

lambdalib/cores/i2c/stream.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,82 @@ class I2CStage:
2727

2828

2929
class I2CStream(Elaboratable):
30+
""" Bidirectional stream wrapper for I2C.
31+
32+
Sink stream description:
33+
`r_wn`: 1 == read 8 bits on SDA
34+
0 == write 8 bits on SDA
35+
`data`: for write: data to write on SDA
36+
for read: N/A
37+
`last`: 1 to indicate this is the last I2C transfer,
38+
I2C stop will be sent at the end of this transaction.
39+
40+
Source stream description:
41+
`data`: for read: 8 bits read from SDA
42+
for write: N/A
43+
`last`: for read: indicate this was the last data read
44+
before the end of the I2C transaction.
45+
46+
Example of use: I2C 8bit address register write
47+
===============================================
48+
49+
Step 1: Write I2C chip address
50+
r_wn == 0
51+
data == I2C chip address << 1
52+
last == 0
53+
54+
Step 2: Write register address
55+
r_wn == 0
56+
data == register address
57+
last == 0
58+
59+
Step 3: Write register values
60+
r_wn == 0
61+
data == 1st register value
62+
last == 0
63+
64+
[...]
65+
66+
r_wn == 0
67+
data == nth register value
68+
last == 1 <--- I2C STOP
69+
70+
Example of use: I2C 8bit address register read
71+
==============================================
72+
73+
Step 1: Write I2C chip address
74+
r_wn == 0
75+
data == I2C chip address << 1
76+
last == 0
77+
78+
Step 2: Write register address
79+
r_wn == 0
80+
data == register address
81+
last == 1 <--- I2C STOP
82+
83+
Step 3: Write I2C chip address
84+
r_wn == 0
85+
data == (I2C chip address << 1) | 1
86+
last == 0
87+
88+
Step 4: Read register values
89+
sink.r_wn == 1
90+
sink.data == N/A
91+
sink.last == 0
92+
93+
source.data == 1st register value
94+
source.last == 0
95+
96+
[...]
97+
98+
sink.r_wn == 1
99+
sink.data == N/A
100+
sink.last == 1 <--- I2C STOP
101+
102+
source.data == nth register value
103+
source.last == 1
104+
"""
105+
30106
def __init__(self, pins, period_cyc, **kwargs):
31107
self.pins = pins
32108
self.period_cyc = period_cyc
@@ -132,6 +208,20 @@ def elaborate(self, platform):
132208

133209

134210
class I2CWriterStream(Elaboratable):
211+
""" Write only stream wrapper around I2CInitiator.
212+
213+
Important note:
214+
This module is intented to be used only
215+
when I2C transactions always have the same 3 steps format:
216+
1. I2C chip address
217+
2. register address
218+
3. register value
219+
220+
The `sink.last` signal is not used and I2C transaction is
221+
always stopped on the 3rd step after writing one register value.
222+
223+
As such, this module cannot be used to write a burst of registers.
224+
"""
135225
def __init__(self, pins, period_cyc, **kwargs):
136226
self.pins = pins
137227
self.period_cyc = period_cyc

0 commit comments

Comments
 (0)