AVR, EEProm, I2C, Fehler in twitest?

OP #1808808
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
#1811093
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren