Hallo,
ich programmiere einen ATmega als I2C slave, den man mit wie üblich
ansteuern kann: Registernummer senden, dann Register lesen/schreiben.
Das funktioniert problemlos, wenn der Master ein anderer ATmega ist,
führt aber zu Problemen, wenn man es mit einem Raspberry Pi (aktuell
3b+) mit >200kHz versucht.
Die Ursache des Problems ist, dass der ATmega dann anfängt den clock zu
stretchen (auch wenn die Interrupt Routine nur das Interrupt Flag
zurücksetzt, also extrem kurz ist.). Der RasPi kommt mit dem stretchen
normalerweise zurecht - nur nicht beim repeated start. Den repeated
start vollführt er nämlich, während der ATmega den clock stretcht. Der
ATmega bemerkt den repeated start also nicht.
Das Problem liegt also eindeutig beim RasPi. Dennoch möchte ich, dass
mein ATmega auch von einem RasPi angesprochen werden kann.
TL;DR: Ich suche einen IC, der mit 400kHz oder mehr I2C sprechen kann
ohne clock streching machen zu müssen. Dieser IC soll als
Zwischenspeicher fungieren: ich schreibe da regelmäßig meine
Registerwerte rein (ob mit I2C oder mit SPI oder was anderem ist erstmal
egal) und der RasPi kann den dann auslesen wann er Lust dazu hat.
Gibt es sowas?
Gibt es vielleicht eine bessere Lösung für mein Problem?
p.s. ich entschuldige mich für das Denglisch!
Einfacher: kein repeated start benutzen.
Beim Lesen einfach als Ziel/Startadresse die letzte geschriebene Adresse
benutzen. Das macht der repeated start ja effektiv auch und spart
lediglich einmal die Slaveaddresse zu schicken.
Ansonsten kann das prinzipiell jeder oder auch kein Controller, das ist
eine reine Performance- und Prioritätsfrage. Im Zweifelsfall könnte
sogar bitbangen helfen.
Prinzipiell gebe ich dir ja Recht, aber ich möchte, dass mein Gerät von
anderen Leuten benutzt wird und möchte deswegen so wenig Auflagen wie
möglich haben.
Somit suche ich eine Lösung, die mit dem standard RasPi funktioniert,
ohne dass ich am diesem etwas ändern muss.
Aus den Erfahrungen des letzten Jahres:
Der Raspi kann keinen Clock stretchen. Das kann die Hardware nicht.
Punkt.
Wenn man über I2C eine Chip mit Clock Stretching anschliesst, dann gibt
es Probleme.
Lösungen:
SPI statt I2C.
I2C Chip ohne Clockstretching.
Zwischenspeicherung auf einem USB-Stick.
Warum muss es ein alter ATMega sein. Da gibt es doch auch fixere Slaves,
die das in Echtzeit ohne Clockstretching schaffen.
stretcher schrieb:> TL;DR: Ich suche einen IC, der mit 400kHz oder mehr I2C sprechen kann> ohne clock streching machen zu müssen. Dieser IC soll als> Zwischenspeicher fungieren: ich schreibe da regelmäßig meine> Registerwerte rein (ob mit I2C oder mit SPI oder was anderem ist erstmal> egal) und der RasPi kann den dann auslesen wann er Lust dazu hat.> Gibt es sowas?
nein. Du könntest so etwas in einem FPGA implementieren, aber das wäre
Aufwand.
fchk
Vielen Dank für die Tipps! Werde wohl auf einen schnelleren Controller
umsteigen, da ich den RasPi nicht in der Hand habe und es wohl keinen
passenden Adapter auf der ATmega Seite gibt.
Eventuell kannst du das auf dem Atmega ohne ISR (also mit Warteschleife)
implementieren, dann antwortet er schneller - vorgesetzt da ist keine
anderer Interrupt der dazwischen grätscht.
Hallo,
von NXP gibt es ein SPI to I2C Interface, den SC181S600
(https://www.nxp.com/docs/en/data-sheet/SC18IS600.pdf).
Viellecht bietet dieser Chip einen Lösungsansatz. Er wird zwischen den
RasPi und ATMega geschaltet. Seitens RasPi wird er über SPI
angesprochen. Der SC181S600 macht dann die Protokollumsetzung von der
SPI Seite auf I2C in Richtung ATMega (und zurück). Die I2C Seite scheint
die wesentlichen I2C-Eigenschaften und Funktionen zu unterstützen und
ist bis 400 kHz Datentransferrate spezifiziert.
Viele Grüße,
Anton
Der Raspi hat eine unvollständige I2C-Unterstützung,
(kein Clock-streching, kein repeated start),
die in den meißten Biliotheken noch weiter kastriert wird.
(Registerzugriff nur 8 bit , bei einigen auch mal 16 bit).
Damit kann man zwar einen PCF 8574 (und auch einige weitere simple
Modelle) ansprechen, aber bei komplexen Sachen bist du mit dem Raspi
aussen vor.
Abhilfe:
1. bessere I2C-Bibliothek verwenden
2. I2C per Bitbanging am Raspi
3. I2C-Takt des Raspi drosseln
4. im Atmega eine simplere Registeraddessierung einbauen.
Wie hat Broadcom eigentlich das i2c-logo nutzen dürfen, bei so einer
mangelhaften I2C-Umsetzung? imho ist der raspi vor dem Ablaufen der
Rechte an i2c entstanden?
Bernie schrieb:> I2C-Takt des Raspi drosseln
Abgesehen von der Sinnhaftigkeit des Vorhabens ist natürlich das das
Mittel der Wahl! Zumal wenn es problemlos bei Dritten laufen muß.
Gruß Rainer
stretcher schrieb:> Die Ursache des Problems ist, dass der ATmega dann anfängt den clock zu> stretchen (auch wenn die Interrupt Routine nur das Interrupt Flag> zurücksetzt, also extrem kurz ist.).
Tatsächlich?!
400kHz I2C-Clock bedeutet, dass der ATmega in weniger als 1,25µs
reagieren muss, um Clock-Stretching zu verhindern. Bei 16MHz Systemtakt
hat er also 20 Takte Zeit dafür. Geht das? Natürlich. Mit einer
entsprechend optimierten ISR kann er innerhalb von 7 Takten was tun
(eigentlich hat er es dann sogar schon getan, aber der Master sieht's
erst nach 7 Takten). Mit einer "in-place"-ISR kann man das sogar noch
auf 5 Takte reduzieren.
Es ist also möglich und zwar mit ziemlich komfortablem
Sicherheitsabstand.
Allerdings: um zusätzlich konkurrierende Interrupts nutzen zu können,
sind fortgeschrittene Programmiertechniken auch für deren ISRs nötig.
Dann wird's richtig eng und die Sache beginnt Spaß zu machen.
Einfacher wird's mit dem erweiterterten Interuptsystem, was die neueren
Tinys und Megas von den XMega geerbt haben. Da kann man die I2C-ISR mit
einer echten höheren Hardware-Priorität als die Konkurrenz laufen
lassen, braucht sich also um deren Aktivitäten nur in sehr viel
geringerem Umfang kümmern.
Allerdings ist das hier eigentlich wieder garnicht mehr nötig, weil die
auch eine verbesserte I2C-Hardware haben, die Spielchen wie Auto-Ack von
Hause aus beherrscht, man muss ihr aber natürlich sagen, dass sie es tun
soll.
Zusammenfassend: Entweder, du lernst, in einer dem Problem angemessenen
Sprache zu programmieren oder du nimmst Hardware, mit der es möglich
ist, die Schwächen deiner Sprache zu umschiffen.