Externes Eeprom am Raspberry mit I2C

Für Fragen von Einsteigern und Programmieranfängern...
Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Externes Eeprom am Raspberry mit I2C

Beitrag von Marc »

Hallo Zusammen

Ich versuche ein serielles Eeprom (I2C) am Raspberry zum laufen zu bringen.
Natürlich klappt das nicht so einfach.
Wenn ich i2c.setdevice verwende dann funktioniert das. Das ist dann auch das erste byte das übertragen wird.
Problem ist bit 8 da muss ich festlegen ob ich vom Rom lesen oder schreiben will.
Gibts da einen Trick?
Dateianhänge
I2C_Eeprom.tar.gz
(275.05 KiB) 68-mal heruntergeladen
Good code comes from experience, experience comes from bad code.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Mathias »

Für dieses Problem hatte ich mal ein Klasse geschrieben, ich kann sie dir morgen posten, wen es dich interessiert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Marc »

Weiss gerade nicht was genau eine Klasse ist, aber es tönt Heldenmässig.
Hatte man bei 'setdevice' übersehen das nur 7bit für die Adresse sind?
Good code comes from experience, experience comes from bad code.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Mathias »

Weiss gerade nicht was genau eine Klasse ist,

Dies zB.:

Code: Alles auswählen

type
  TForm1 = class(TForm)
  private
    { private declarations }
  public
    { public declarations }
  end;

Ich habe vorhin deine Source angeguckt, so wie es scheint verwendest du schon die I²C-KIasse welche ich mal geschrieben habe. :wink:

Im Anhang ein Code, welcher ein EEPROM über den i²C-Bus beschreibt und liest.
Es hat noch Code dabei, welcher ein zweizeiliges LCD-Display anspricht.

Was noch interessant wäre, was für EEPROMs willst du beschreiben ?
Dateianhänge
I2C_LCD.tar.gz
(129.83 KiB) 85-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Marc »

Danke für die Hilfe und den Code.
Probiere das morgen gleich mal aus.
Mas sehen wie Du das machst.

Da EEprom ist ein 24LC256.
https://www.reichelt.de/EEPROM-seriell- ... CH=24lc256
Good code comes from experience, experience comes from bad code.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Mathias »

Da EEprom ist ein 24LC256.

Diese habe ich auch verwendet.
Und auch den 24LC64, ich denke da wird die ganze Familie unterstützt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

[gelöst] Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Marc »

Hallo Mathias

Vielen Dank für die Hilfe.
Dein Code funktioniert.
Ich seh noch nicht ganz durch aber es tut was es soll.
Mal sehen wie und wie schnell das läuft.
Good code comes from experience, experience comes from bad code.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Mathias »

Ich seh noch nicht ganz durch aber es tut was es soll.

Mit buf0+1 sagst wo im EEPROm geschrieben wird, und buf3 ist das zu schreibende Zeichen.

Code: Alles auswählen

procedure TI2CEEPROM.WriteChar(ch: char);
var
  buf: packed array of byte;
begin
  SetLength(buf, 3);
 
  buf[0] := FPosition shr 8;
  buf[1] := FPosition and $FF;
  buf[2] := byte(ch);
 
  I2C_Class.SetDevice(Device_Addr);
  I2C_Class.writeBuf(buf);
  Sleep(10);
 
  Inc(FPosition);
end;   
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Marc »

Das hab ich soweit. Danke.
Der Fragen sind im Moment 2.

1. Frage Wozu ist das sleep(10) ? Hattest Du Timingprobleme?
Ich hab das mal weggemacht da ich den ganzen Speicher füllen muss (32768 Byte).
Da brauche ich jetzt ca 6 Sek. Muss aber noch schneller werden.
Habe ca 0.5 Sek Zeit das Eeprom zu füllen.
Ist aber auch noch im Byte Mode.
Gibt ja noch den Page Mode der wird einiges schneller sein.
Den versuche ich jetzt mal.

2. Frage. FPosition hast Du als int16 deklariert.
Da fliegt mir das Programm um die Ohren wenn ich die letzte Zelle beschreibe (32767)
weil ja unten noch ein inc(FPosition) kommt. Vieleicht wäre Word besser? Braucht ja auch nur 2 Byte.
Oder wird int16 ev. schneller bearbeitet?

Hab jetzt einfach mal eine WriteByte Prozedur (ohne increment) draus gemacht. So läufts gerade bestens im Bytemode. :D
Good code comes from experience, experience comes from bad code.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Timm Thaler »

Marc hat geschrieben:1. Frage Wozu ist das sleep(10) ? Hattest Du Timingprobleme?
...
Gibt ja noch den Page Mode der wird einiges schneller sein.


Nanana, da lesen wir aber ganz schnell mal das Datenblatt.

Nach einem Bytewrite musst Du dem EEprom Zeit geben den Wert zu speichern. Ein Write dauert 5msec. 32kByte einzeln geschrieben dauern damit 160sec! Wenn Du das in 6sec schaffst kannst Du davon ausgehen, dass Daten nicht richtig geschrieben werden. Vielleicht nicht gleich, aber irgendwann gehts schief.

Ein Pagewrite dauert ebenfalls 5msec. Eine Page kann maximal 64 Byte sein. Für 32kByte musst Du 512 Pages schreiben. Dauert 2.5sec. Deine 0.5sec sind nicht zu schaffen.

Du kannst nach dem Bytewrite oder Pagewrite erneut Transmissionen starten und das Ackn prüfen (Datenblatt Seite 10). Der Eeprom wird erst ein Ackn schicken, wenn das Write erfolgt ist. Damit kommst Du vielleicht auf 2-3msec pro Page runter. Aufpassen dass Du ein Timeout einbaust, falls der Eeprom gar nicht reagiert.

Beim Pagewrite beachten: Pages sind immer 64 Byte groß. Wenn man kleinere Pages schreibt, müssen die in die 64 Byte passen. Also 16-16-16-16... Bytes gehen, 20-20-20-20... Bytes gehen nicht.

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Marc »

Danke für deinen Post.
Bin noch Anfänger. Eigentlich hätte ich auch lieber ein serielles S-RAM. Aber auf die schnelle nichts gefunden.
Es ist das erste mal das ich so einen EEprom Chip verwende und mich überhaupt im Detail um das I2C Protokoll kümmere.
Also alles Neuland. :-)

Bei mir steht das es maximal 5mS dauert -> '• Page Write Time 5 ms Max.'
Es kann ja auch nicht meine Aufgabe sein zu raten wann das ROM denn fertig ist mit speichern?
Wenn das Ack kommt ist es fertig? Oder nicht?
Was ich gesehen habe (Stichproben) war alles richtig gespeichert.
Das mit den Pages ist gerade schwieriger als gedacht. Aber ich bin Optimist und ich bin dran. :-)

Das das Eeprom gar nicht reagiert ist eigentlich keine Option.
Wenn das rumzickt mach ich eine Elektronenröhrenschaltung mit Relais und Lochstreifen, das geht immer.
Good code comes from experience, experience comes from bad code.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Timm Thaler »

Marc hat geschrieben:Bin noch Anfänger. Eigentlich hätte ich auch lieber ein serielles S-RAM. Aber auf die schnelle nichts gefunden.
Es ist das erste mal das ich so einen EEprom Chip verwende und mich überhaupt im Detail um das I2C Protokoll kümmere.


Du bist Dir aber im klaren, dass so ein Eeprom eine begrenzte Anzahl Schreibzyklen hat? Lesen kannst Du dagegen so oft Du willst.

Die liegt zwar bei 1Mio für diesen Typ, aber wenn Du alle 5msec in immer dieselbe Zelle schreiben würdest, wäre diese in 1h 23min erledigt (real halten die Zellen mehr als 1Mio Zyklen, aber das ist dann halt nicht mehr spezifiziert).

Selbst bei einem Pagewrite alle 5msec mit 512 Pages bekommst Du das Eeprom in 30 Tagen tot.

Und sag nicht, das macht ja keiner, es gab mal eine Telefonserie, die nach einigen Monaten keine Telefonnummern mehr halten konnte: Ein Programmierer war so klever den Eeprom fürs Telefonbuch regelmäßig neu zu schreiben. Dummheit - oder geplante Obsoleszenz?

Ich hab zwar solche Eeproms auch schon als Messwertspeicher missbraucht, aber das waren dann nur ein paar Werte alle paar Minuten und ein kompletter Durchlauf dauerte mehrere Wochen. Ansonsten sind das halt Speicher um Daten abzulegen, die sich selten oder nie ändern.

Was hast Du denn für Daten und wie oft schreibst Du die?

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Marc »

Danke für den Hinweis.
Das ist mir klar. Und nach meinen Berechnungen ist es nach einem Monat auch hinüber.
Wie geschrieben ich hab noch nichts besseres gefunden, und für einen Prototypen wirds reichen.
Die S-Ram die ich bis jetzt gesehen habe waren meist parallel anzusprechen.
Ausser dieses hier . http://www.cypress.com/file/139691/download aber scheint recht exotisch.

Zumindest lern ich gerade was über Eeprom und es schaut am Ende ein nettes Demo heraus wie man den Chip anspricht.
Das Eeprom (oder S-Ram) ist als Brücke gedacht zwischen dem Raspberry und dem AVR (644 oä.) Der Raspberry hat dann Zeit das Eeprom zu füllen wenn es ihm passt, und der AVR kann sie 'real time' weiterverarbeiten.
Die i2c leitungen würde ich dann hin und her schalten, das der Raspi und der AVR Zugang zum Rom haben (nacheinander).
Good code comes from experience, experience comes from bad code.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von af0815 »

Marc hat geschrieben:Die i2c leitungen würde ich dann hin und her schalten, das der Raspi und der AVR Zugang zum Rom haben (nacheinander).

https://electronics.stackexchange.com/questions/4904/sram-which-two-chips-can-read-write

Hardware: Dual Ported I2C EEPROM
http://www.onsemi.com/pub/Collateral/CAT24C208-D.PDF

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Externes Eeprom am Raspberry mit I2C

Beitrag von Timm Thaler »

Größere SRAMs gibt es für I2C nicht, weil der I2C verhältnismäßig langsam ist und man mit RAM schnell arbeiten möchte. Kleine SRAMs gibt es meist als Zugabe zu RTCs, aber das sind dann nur wenige Byte.

Größere SRAMs mit seriellen Bus macht man deswegen mit SPI. Microchip hat so viele davon, dass sie die sogar verkaufen: http://www.microchip.com/wwwproducts/en/23K256

Nachteil, die arbeiten bestenfalls mit 3.3V, manche auch nur mit 2.2V. Also unbedingt auf die Spannungsangaben achten!

Die Idee den I2C hin- und herzuschalten halte ich für ungünstig, der I2C ist für sowas nicht gedacht.

Wenn die Daten nur in eine Richtung zwischengespeichert werden sollen, ist ein Fifo genau das was Du suchst. Allerdings kenne ich kein 32kByte Fifo, wahrscheinlich weil man das eher nicht braucht.

Was hat den der Atmega so Wichtiges zu tun, dass er nicht immer mal per Interrupt die Daten vom I2C abholen und zwischenspeichern kann? Dafür bietet sich der Hardware-I2C geradezu an.

Antworten