Forum: Mikrocontroller und Digitale Elektronik I2C Zwischenspeicher für RasPi - ATmega 400kHz


von stretcher (Gast)


Lesenswert?

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!

von i2c (Gast)


Lesenswert?

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.

von stretcher (Gast)


Lesenswert?

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.

von PittyJ (Gast)


Lesenswert?

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.

von Frank K. (fchk)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

stretcher schrieb:
> Gibt es vielleicht eine bessere Lösung für mein Problem?

USB-I²C Stick benutzen

von stretcher (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Anton Hermann S. (antonhermann)


Lesenswert?

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

von Bernie (Gast)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

stretcher schrieb:
> Dieser IC soll als
> Zwischenspeicher fungieren

Warum nimmst Du dann nicht einfach einen echten Speicher (EEPROM, SRAM, 
FRAM), sondern willst unbedingt einen MC vergewaltigen?

Z.B. 47L64 mit I2C bis 1MHz:
http://ww1.microchip.com/downloads/en/DeviceDoc/47L64-Data-Sheet-DS20006168B.pdf

23LC512 mit SPI bis 20MHz:
https://www.microchip.com/en-us/product/23LC512

von Rainer V. (a_zip)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

Du kannst auch so einen SRAM nehmen und abwechselnd von beiden CPUs 
drauf zugreifen.

von c-hater (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.