Go Down

Topic: EEPROM , I2C e ATTiny85 (Read 451 times) previous topic - next topic

flz47655

Ciao a tutti,

Volevo cancellare nel tempo più breve possibile una EEPROM 24LC256 (32KBytes), per la comunicazione i2c ho utilizzato la libreria TinyWireM http://playground.arduino.cc/Code/USIi2c a cui ho apportato alcune modifiche:

- Cancellato #define SYS_CLK nel file USI_TWI_Master.h che non viene utilizzato
- Cancellato #define F_CPU 1000000UL nel file USI_TWI_Master.cpp visto che ho la CPU ad 8MHz ed il define è aggiunto dall'IDE in automatico con la giusta frequenza
- Modificato #define USI_BUF_SIZE 16 nel file TinyWireM.h col valore 34 per avere un buffer in invio maggiore

La cancellazione avviene cancellando tutte le 512 pagine (di 64KBytes l'una) col seguente codice

Code: [Select]

void clearMemoryPage(unsigned int page)
{
 for(int i=0; i<2; i++)
 {
   unsigned int addr = (page * 64) + (32 * i);
   TinyWireM.beginTransmission(0x50);
   TinyWireM.send((int)(addr >> 8));   // MSB
   TinyWireM.send((int)(addr & 0xFF)); // LSB  
   for(int b=0; b<32; b++)
   {      
     TinyWireM.send((byte)0);
   }
   TinyWireM.endTransmission();
   delay(6);
 }
}


Il problema è che effettivamente non vengono inviati tutti i byte, ho controllato con l'oscilloscopio e viene inviato solamente il pacchetto relativo all'indirizzo (quindi col comando beginTransmission) e sembra un problema di buffer in quanto nella libreria la funzione send è così scritta:

Code: [Select]

void USI_TWI::send(uint8_t data){ // buffers up data to send
 if (USI_BufIdx >= USI_BUF_SIZE) return;         // dont blow out the buffer
 USI_BufIdx++;                                   // inc for next byte in buffer
 USI_Buf[USI_BufIdx] = data;
}


La cosa strana è che nonostante abbia lasciato 2 byte per l'indirizzo non è possibile inviare 32 byte col buffer di 64 byte.. qualcuno ha già incontrato questo problema? Inviando 16 byte per volta il problema non sussiste ma raddoppiano i tempi di cancellazione che richiedono in tutto sui 10 secondi, un pò troppo..

flz47655

#1
Mar 10, 2013, 08:17 pm Last Edit: Mar 10, 2013, 08:25 pm by flz47655 Reason: 1
Avevo mancato di un byte la dimensione del buffer  :smiley-roll-blue: anche se non ho capito perché ci vogliono 3 byte in più... diciamo che non ho investigato affondo per mancanza di tempo, se qualcuno ha la risposta la posti senza problemi  :D
Dovevo impostare 35 byte, ad ogni modo impostando USI_BUF_SIZE = 67 sono riuscito a scrivere in un colpo (64 byte) solo le pagine, ecco il codice finale:
Code: [Select]

void clearMemoryPage(unsigned int page)
{
 // 512 Pages of 64 bytes [0-63,64-127,etc..]
 // USI_BUF_SIZE = 67, max data size 64 byte
 unsigned int addr = page * 64;
 TinyWireM.beginTransmission(0x50);
 TinyWireM.send((int)(addr >> 8));   // MSB
 TinyWireM.send((int)(addr & 0xFF)); // LSB  
 for(int b=0; b<64; b++)
 {      
   TinyWireM.send(byte(0));
 }
 TinyWireM.endTransmission();
 delay(6);
}

Cancellando la memoria teoricamente in 6*512 = 3072ms circa 3 secondi  :D volendo essere meno cauti e settando un ritardo di 5ms tra una scrittura di pagina e l'altra si possono raggiungere 2 secondi e mezzo, secondo me non vale la pena rischiare.

Aggiungendo i tempi necessari per passare i dati tramite i2c (che viaggia a 100kHz) si ottiene un tempo un pochino maggiore, lato PC ho ottenuto una latenza avvertita dall'utente di circa 7 secondi in tutto considerando la trasmissione dei comandi su seriale (lenta 9600bps su bluetooth), comunque molto meglio dei risultati che avevo ottenuto inizialmente.

Ciao

leo72


Avevo mancato di un byte la dimensione del buffer  :smiley-roll-blue: anche se non ho capito perché ci vogliono 3 byte in più...


Perché quando comunichi con uno slave aprendo la trasmissione con TinyWireM.beginTransmission(indirizzo), tutto quello che viene "spedito" nei successivi send viene in realtà infilato nel buffer di trasmissione e spedito materialmente solo quando chiudi la comunicazione con endTransmission.

flz47655

Ok, fin qui ci ero arrivato, se devo spedire X byte il buffer deve essere almeno di una dimensione analoga, non capisco oltre ai miei dati e all'indirizzo di 2 byte però cosa viene spedito nel terzo byte.

leo72


Ok, fin qui ci ero arrivato, se devo spedire X byte il buffer deve essere almeno di una dimensione analoga, non capisco oltre ai miei dati e all'indirizzo di 2 byte però cosa viene spedito nel terzo byte.

Non so.
Andrebbe aperta la lib e guardato un po' il codice per capire.

Go Up