So setzen Sie NACK direkt nach dem aktuellen Byte in TWI (ATMega8)

Ich habe einige Erfahrung mit I²C (TWI), da ich es zuvor verwendet habe, aber es scheint, dass ich dieses spezielle Problem nicht lösen kann. Ich beabsichtige, zwei CPUs über I²C zu kommunizieren. Einer ist immer der Herr und der andere der Sklave. Ich definiere das Kommunikationsprotokoll selbst, daher ist es etwas flexibel, aber ich möchte, dass es so effizient wie möglich ist (dh je weniger Bytes, desto besser).

Ich möchte, dass der Slave NACK für bestimmte Werte setzt; zum Beispiel:

MASTER = START + sends SLAVE ADDRESS
SLAVE = sets ACK
MASTER = sends any one "byte" command
SLAVE = sets ACK or NACK depending if "byte" was a valid command or not.

Die letzte Aussage ist das Problem, denn anscheinend muss ich mich als Slave für ACK oder NACK entscheiden, bevor ich den einen "Byte" -Befehl erhalte; dh als Antwort auf TWSR = 0x60 (SLA+W empfangen). Das Problem ist, dass ich im Voraus nicht weiß, ob der Befehl gültig ist oder nicht! Anscheinend ist das Setzen oder Löschen des TWEA-Bits nur für das nächste zu empfangende Byte wirksam.

So sehr ich auch in die Dokumentation gegraben habe, ich kann keine Möglichkeit finden, mit NACK "on the fly" zu antworten, da der ATMega den Interrupt NACH dem Senden des ACK (oder NACK) setzt. TWSR ist entweder 0x80 oder 0x88, was „Byte empfangen, ACK gesendet“ bzw. „Byte empfangen, NACK gesendet“ bedeutet.

Gibt es neben dem Hinzufügen von Füllbytes oder der Implementierung einer Bit-Banging-I²C-Bibliothek eine Möglichkeit, dies zu lösen?

Der Master-Controller ist ein NXP LPC2148, während der Slave-Controller ein ATMega1284P ist.

Danke schön.

Antworten (1)

Bitte tun Sie das nicht! Dafür sind I²C ACK/NACK nicht gedacht. Sie sind als Protokollelemente gedacht, nicht als Teil der Daten.

Zum Beispiel wird ein beim Senden der Geräteadresse empfangenes NACK den Host-Controller veranlassen, einen "Adressierungsfehler" zu signalisieren, und ein während einer Übertragung von N Bytes empfangenes NACK veranlasst den Host-Controller, dem aufrufenden Treiber einen "Datenübertragungsfehler" zu signalisieren. Das heißt, die Anzahl der gesendeten Bytes war falsch oder die SMBUS-Prüfsumme ist fehlgeschlagen.

Während Leseübertragungen bezeichnet NACK normalerweise das Ende der zu empfangenden Daten.

Ist es das, was Sie signalisieren wollen? Ich wette nicht!

EDIT: Ich gebe Ihnen ein Beispiel. Bitte werfen Sie einen Blick auf die DS28E17 Onewire to I²C Master Bridge. Es ist ein I²C-Hostcontroller, der sich auf einem Eindrahtbus befindet. Es führt die gesamte I²C-Kommunikation autonom durch und Sie können ( Sie können nicht ) einzelne ACK/NACKs empfangen. Sie raten diesem Chip, eine Anzahl von Bytes zu schreiben, und er wird dies gerne tun. Aber es wird Ihnen nicht sagen, ob das letzte Bit ACK oder NACK war. Es kann Ihnen nur sagen, ob ein unerwartetes NACK aufgetreten ist. Ihr Slave bricht also das Protokoll und kann nicht hinter einem DS28E17 verwendet werden.

Es scheint jedoch nicht der Fall zu sein. Ich habe in der (*UM10204 I2C-Bus-Spezifikation und Bedienungsanleitung) folgendes gelesen: "Es gibt fünf Bedingungen, die zur Generierung eines NACK führen: [...] 3. Während der Übertragung erhält der Empfänger Daten oder Befehle, die 4. Während der Übertragung kann der Empfänger keine Datenbytes mehr empfangen. [...]". Ich beabsichtige, es sowohl für [3] als auch für [4] zu verwenden.
Die Tatsache, dass es Geräte gibt, die dies nicht tun (vielleicht der AVR eingeschlossen), bedeutet nicht, dass dies nicht möglich oder nicht möglich ist!
Was zählt, ist der praktische Nutzen. Bitte werfen Sie einen Blick auf die verschiedenen Macken, die der Linux-Kernel implementieren muss, um die reichliche Anzahl von kaputten Host-Adaptern und kaputten Geräten zu unterstützen. Sie sind alle kaputt, weil ihre Designer sagten "die Spezifikation erlaubt es" und dann nutzen sie alles, was die Spezifikation zulässt, in vollen Zügen. So schicken Sie Ihre Benutzer direkt ins Verderben. Bitte, tun Sie das nicht! Bitte entwerfen Sie ein Gerät, das am besten mit dem Pandämonium kompatibel ist, das bereits in freier Wildbahn ist.
Dies ist kein Fall von "Die Spezifikationen leugnen es nicht, also ist es erlaubt". Dies ist in der Spezifikation ausdrücklich als beabsichtigte Verwendung des NACK-Signals angegeben. Ihre Antwort "Dafür sind I²C ACK/NACK nicht gedacht" ist entweder Ihre persönliche Meinung (die für meine Frage irrelevant ist) oder schlichtweg falsch.
@Guillermo Prandi: Bitte setzen Sie Ihre Entwicklungsarbeit in Ruhe fort und lassen Sie mich bitte keine weiteren Blicke darauf werfen. Danke schön.
Nur zum Kichern, der SC16IS741A (I²C-zu-UART-Schnittstelle) von NXP macht genau das, was ich tun möchte: Er setzt NACK, wenn sein Puffer voll ist. Ich möchte dieses Verhalten nur von meinem ATmega emulieren.