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
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.
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
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.