Forum: Compiler & IDEs AVR, EEProm, I2C, Fehler in twitest?


von Harald P. (haraldp)


Lesenswert?

Ich vermute, daß es etliche AVR-Anwender gibt, die ihren Microcontroller 
durch ein I2C-EEProm ergänzen.
Nun liegt dankenswerterweise jeder WinAVR-Version ein Beispiel für die 
Ansteuerung eines EEProms mittels I2C (twi) bei (z.B. 
...\WinAVR-20100110\doc\avr-libc\examples\twitest). Obwohl ich diese 
c-Implementierung (modifiziert) seit längerem benutze, ist mir erst 
jetzt ein Fehler aufgefallen.
Werden mehr als ein Byte drei Byte vor einer Page-Grenze geschrieben, so 
wird ein Byte zuviel ins EEProm geschrieben.
Der Fehler liegt m.E. in einer falschen Vergleichsabfrage in der 
Funktion int ee24xx_write_page(uint16_t eeaddr, int len, uint8_t *buf).
Falsch:
...
  if (eeaddr + len < (eeaddr | (PAGE_SIZE - 1)))
    endaddr = eeaddr + len;
...
Richtig:
...
  if (eeaddr + len <= (eeaddr | (PAGE_SIZE - 1)))
                   ===
    endaddr = eeaddr + len;
...

Kann jemand aus dem Forum meine Feststellung verifizieren? Das 
twitest-Beispiel wird schon seit vielen Jahren so publiziert. Vielleicht 
ist schon anderen dieses Verhalten aufgefallen - oder habe ich mich 
einfach geirrt?

Harald Peters

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Schon möglich, dass da ein Bug drin ist.  Sollte sich das nicht
einfach mit paar experimentellen Daten verifizieren lassen?  Ich
habe nur gerade keinen I²C-EEPROM zu Hause "betriebsbereit".

Wenn's ein Bug ist, dann schreib' bitte einen Bugreport bei
savannah.nongnu.org.

von Harald P. (haraldp)


Lesenswert?

An Jörg:
ich bin mir sicher, daß es ein Bug ist. Allerdings ist mir unklar, wo 
ich diese Info bei savannah.nongnu.org loswerden kann.
Harald

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?


von Peter D. (peda)


Lesenswert?

Der Code ist ja ziemlich unübersichtlich.
Ich würde modular programmieren:
1
static void si2c_start( void );
2
static void si2c_stop( void );
3
static uint8_t si2c_r( uint8_t nack );
4
static uint8_t si2c_w( uint8_t val );

Und dann die Schreibfunktion für nen 24C512:
1
uint8_t eeprom_wr( uint16_t eeaddr, uint8_t *sram, uint16_t len )
2
{
3
  do{
4
    if( !set_addr( eeaddr ))
5
      return 0;                                         // 0 = failed
6
    do
7
      si2c_w( *sram++ );
8
    while( --len && (++eeaddr & (PAGE_SIZE-1)));        // end or next page
9
    si2c_stop();
10
  }while( len );                                        // end
11
  return 1;                                             // 1 = success
12
}

Dann ist es auch wurscht, ob man das I2C in HW oder SW macht.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Der Code ist ja ziemlich unübersichtlich.
> Ich würde modular programmieren:

Patches welcome. ;-)

Ich wollte damals in erster Linie überhaupt die TWI-Handhabung des
AVR lernen.  Das Teil hat mittlerweile fast 8 Jahre auf dem Buckel.

von Harald P. (haraldp)


Lesenswert?

Ich bin wie Peter der Meinung, daß man dieses Teil tatsächlich noch 
einmal sauber programmieren sollte. Mit den vielen GoTos ist das 
Programm doch recht unübersichtlich. Aber wie dem auch sei, es sollte 
wenigstens korrekt sein.
Harald

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Harald P. schrieb:
> Ich bin wie Peter der Meinung, daß man dieses Teil tatsächlich noch
> einmal sauber programmieren sollte.

Bitte, gern, tu's. ;-)  Von "man sollte" entsteht kein Code.  Der
Patchtracker steht auf savannah gleich neben dem Bugtracker...

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.