In diesem Thread soll es um die Realisierung eines I²C-Busses durch das USI, welches es in einigen ATtinies (und wohl auch wenigen ATmegas) gibt, gehen.
Vorweg erstmal nötige Fakten über I²C selbst. (Wobei ich nur an der Oberfläche bleiben werde - für den tieferen Einstieg wird eine Suche im Internet sicher Resultate erbringen. Hervorheben möchte ich zumindest die I²C-Spezifikation von NXP).
Grundsätzlich ist nach einer (Repeated-) Start-Condition der Master Transmitter. Das erste übertragene Byte besteht aus der Receiver-Adresse (7bit, auf 10bit-Adressierung gehe ich hier nicht ein), das LSB bestimmt die Datenrichtung für den Rest des Telegrammes (also bis zum nächsten Stop oder Start). Low=Master bleibt Transmitter, High=Slave wird Transmitter.
(*) Wann kann der Master überhaupt ein Repeated Start oder ein Stop generieren? Theoretisch immer dann, wenn der Slave SDA vor der steigenden SCL-Flanke nicht Low hält.
Insbesondere also als Transmitter (ausserhalb des ACK/NACK-Slots).
Als Receiver, wenn der Slave 'n High vorbereitet hat, oder innerhalb seines ACK/NACK-Slots.
Aber wann darf er ein Repeated Start/Stop generieren?
Ok, soweit erstmal der Überblick über den eigentlichen I²C-Bus.
Im nächsten Beitrag würde ich dann erstmal nur auf die USI-Hardware eingehen wollen.
Also bitte hier vorerst keine Kommentare anhängen - etwaige Hinweise und Korrekturen etc... bitte als persönliche Nachricht
Vorweg erstmal nötige Fakten über I²C selbst. (Wobei ich nur an der Oberfläche bleiben werde - für den tieferen Einstieg wird eine Suche im Internet sicher Resultate erbringen. Hervorheben möchte ich zumindest die I²C-Spezifikation von NXP).
- zwei Signale (Leitungen) - SCL=Serial Clock, SDA=Serial Data
- beide Signale sind dominant-rezessiv (im freigegebenen (idle) Zustand ziehen externe Pull-Widerstände die Signale auf high (rezessiv)
- jeder Teilnehmer kann(!) sie auf Gnd legen (dominant)
- den freien Bus darf(!) ein Teilnehmer belegen, indem er eine Startcondition generiert. Dadurch wird er zum Master (bis er selbst den Bus durch eine Stop Condition wieder freigibt, oder die Arbitrierung an einen anderen Master verliert).
- Nur der (ein) Master darf die SCL low ziehen - jeder Teilnehmer darf SCL dann weiter low halten (Clock-Stretching).
Code:
_ _
SDA \ /
¯¯¯¯¯¯'''¯¯¯¯¯¯
_____ _____
SCL \ /
¯¯'''¯¯
^ ^ ^ ^
| | | |
(1) (2) (3) (4)
- (1) Teilnehmer zieht SDA low, während SCL (und SDA) high sind, belegt dadurch den Bus, wird zum Master (->Start Condition)
- (2) Master zieht SCL low.
- (3) Master gibt SCL frei (geht über Pullup high).
- (4) Master gibt SDA frei, während SCL high ist (-> Stop Condition)
- Ein leeres Telegramm (nur Start und Stop) ist nicht erlaubt.
- Nach einer (Repeated) Start Condition ist immer der Master Transmitter, alle anderen Teilnehmer Receiver.
- Der Master generiert neun Taktimpulse auf SCL, während der ersten acht wird ein Byte (beginnend mit dem MSB) vom Transmitter an den Receiver übertragen. (D.h. der Transmitter legt vor der steigenden SCL-Flanke (bzw direkt nach der vorherigen fallenden Flanke) den entsprechenden "Pegel" auf SDA, nach der steigenden SCL-Flanke liest der Receiver das Bit ein.
Beim neunten Takt überträgt der Receiver ein ACK(=low) / NACK(=high) zum Transmitter. (D.h. nach der fallenden SCL-Flanke des achten Bits gibt der Transmitter SDA frei, und der Receiver legt den entsprechenden Pegel auf SDA.) Nach der fallenden Flanke des neunten Bits gibt der Receiver SDA dann wieder frei. - Ggf. werden weitere Bytes (genauso) übertragen.
- Der Master beendet das Telegramm mit einer Stop Condition
Code:
_ _____ _____ _____ _____ _____ _____ _____ _____ _____ _
SDA \ / MSB X 7 X 6 X 5 X 4 X 3 X 2 X LSB X ACK \ /
¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯
____ __ __ __ __ __ __ __ __ __ ____
SCL \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
¯¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯¯
(Start)^ ^ ^ ^ ^ ^ ^ (Stop)
| | | | | | |
(1)(2) . . . (3)(4)(5)(6)(7)
- (1) Fallende SCL-Flanke -> Transmitter (derzeit der Master) legt sein MSB auf SDA.
- (2) Steigende SCL-Flanke -> alle Receiver lesen SDA ein.
- (3) Fallende SCL-Flanke -> Transmitter legt sein LSB auf SDA.
- (4) Steigende SCL-Flanke -> Receiver lesen SDA ein.
- (5) Fallende SCL-Flanke -> Transmitter gibt SDA frei, (adressierter) Receiver legt ACK/NACK auf SDA.
- (6) Steigende SCL-Flanke -> Transmitter liest SDA (ACK/NACK) ein.
- (7) Fallende SCL-Flanke -> Receiver gibt SDA frei.
Grundsätzlich ist nach einer (Repeated-) Start-Condition der Master Transmitter. Das erste übertragene Byte besteht aus der Receiver-Adresse (7bit, auf 10bit-Adressierung gehe ich hier nicht ein), das LSB bestimmt die Datenrichtung für den Rest des Telegrammes (also bis zum nächsten Stop oder Start). Low=Master bleibt Transmitter, High=Slave wird Transmitter.
Code:
_ _____ _____ _____ _____ _____ _____ _____ _____ _
SDA \ /ADDR7XADDR6XADDR5XADDR4XADDR3XADDR2XADDR1\ R/W / ACK \ /
¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
____ __ __ __ __ __ __ __ __ __ ____
SCL \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
¯¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯ ¯¯¯
(*) Wann kann der Master überhaupt ein Repeated Start oder ein Stop generieren? Theoretisch immer dann, wenn der Slave SDA vor der steigenden SCL-Flanke nicht Low hält.
Insbesondere also als Transmitter (ausserhalb des ACK/NACK-Slots).
Als Receiver, wenn der Slave 'n High vorbereitet hat, oder innerhalb seines ACK/NACK-Slots.
Aber wann darf er ein Repeated Start/Stop generieren?
Ok, soweit erstmal der Überblick über den eigentlichen I²C-Bus.
Im nächsten Beitrag würde ich dann erstmal nur auf die USI-Hardware eingehen wollen.
Also bitte hier vorerst keine Kommentare anhängen - etwaige Hinweise und Korrekturen etc... bitte als persönliche Nachricht
Zuletzt bearbeitet: