Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« on: January 30, 2012, 07:15:45 pm » |
I'm trying to erase an 24LC256, but it's taking a really long time... like more than 10 seconds per byte. Here's my (abbreviated) code, which is inside a loop: while(pointer < EXTERAL_E2_SIZE) { Wire.beginTransmission(ADDRESS); Wire.write(highByte(pointer)); Wire.write(lowByte(pointer)); Wire.write(0xFF); Wire.endTransmission(); pointer++; } Using some serial debugging, I figured out that the the long delay comes from endTransmission(). My code seems fine, and my connection's alright... Where could this delay be coming from? Thanks a lot! baum
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #1 on: February 01, 2012, 05:10:25 pm » |
Update: I have found that this code works in my main program, but when copied and pasted over here, I takes ~1 minute per loop (I put a serial.println() at the end of the loop). Why would copy&pasted code work as fast as it should in the main program, but not here?
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #2 on: February 01, 2012, 05:14:38 pm » |
Using some serial debugging, I figured out that the the long delay comes from endTransmission().
endTransmission is the only thing that does any transmitting. The other stuff just puts things into a buffer. So if there is a delay, that's where it would be. Perhaps paste more code? Like the whole thing.
|
|
|
|
|
Logged
|
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #3 on: February 01, 2012, 05:20:39 pm » |
Well, I just figured it out... I forgot wire.begin()...  So maybe wire should tell you when you don't begin it? It's erasing as I type! baum
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #4 on: February 01, 2012, 05:24:40 pm » |
Note from the datasheet: When doing a write of less than 64 bytes the data in the rest of the page is refreshed along with the data bytes being written. This will force the entire page to endure a write cycle, for this reason endurance is specified per page. You may want to redesign so that you erase 64 bytes at a time. You are effectively making the chip do 64 lots of writes when it need only do one. In other words, you are reducing the chip life by a factor of 64 unnecessarily.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #5 on: February 01, 2012, 05:25:58 pm » |
Well, I just figured it out... I forgot wire.begin()...  So maybe wire should tell you when you don't begin it? The Blue Screen of Death? Well maybe someone could make a BSOD shield. 
|
|
|
|
|
Logged
|
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #6 on: February 01, 2012, 05:26:31 pm » |
Yeah, I guess. I'll just have to put in some page-detect code... but too bad there isn't a chip erase function.
baum
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #7 on: February 01, 2012, 08:51:45 pm » |
Would this be good? I can only do half of a page b/c of Wire buffer size. /* Erases both the internal and * external 24LC256 EEPROMs. */
#include <Wire.h> #include <EEPROM.h>
#define EEPROM_ADDRESS 0x50 #define EXTERNAL_EEPROM_SIZE 32768 //size of 24LC
#define L_PIN 13
#define arrayLength(array) (sizeof(array)/sizeof(array[0]))
void setup() { unsigned int memPointer = 0; Serial.begin(19200); Wire.begin();
pinMode(L_PIN, OUTPUT);
/* First clear the internal. */ for (int i = 0; i <= E2END; i++) { EEPROM.write(i, 0); }
blink(L_PIN);
/* And now the external EEPROM. */ byte eraseArray[BUFFER_LENGTH]; //32 bytes for standard Wire library memset(eraseArray, byte(0xFF), sizeof(eraseArray)); //Now eraseArray[] is filled with 0xFF. while(memPointer < EXTERAL_EEPROM_SIZE) { writeArray(eraseErray[], memPointer); } blink(L_PIN);
} //end setup
void loop() { }
void blink(byte pin) { digitalWrite(pin, HIGH); delay(200); digitalWrite(pin, LOW); return; }
/* writes and Array to the 24LC56.*/ void writeArray(byte data[], unsigned int& address) {
if(arrayLength(data) > BUFFER_LENGTH) { //too big for Wire buffer! return; }
unsigned int i;
Wire.beginTransmission(EEPROM_ADDRESS); Wire.write(highByte(address)); Wire.write(lowByte(address));
/* Now do a page write */
for(i = 0; i < arrayLength(data); i++) { Wire.write(data[i]); }
address += arrayLength(data); //increase the address.
Wire.endTransmission(); //send the data.
return; }
Thanks, baum
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #8 on: February 01, 2012, 09:03:16 pm » |
Well, no, because you are sending 34 bytes, and the buffer size is 32 (you have to count the address).
|
|
|
|
|
Logged
|
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #9 on: February 01, 2012, 09:45:03 pm » |
Thanks... so is there anyway of sending a full 64 byte page? And why does Wire only send the data @ endTransmission?
baum
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #10 on: February 01, 2012, 10:01:46 pm » |
You could increase the buffer size, bearing in mind there are 5 of them. So already you are using 5 x 32 bytes.
Why? Well sending is fairly time-critical, so I think they designed it so you can do calculations and stuff, and that just gets buffered.
|
|
|
|
|
Logged
|
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #11 on: February 01, 2012, 10:19:30 pm » |
You could increase the buffer size, bearing in mind there are 5 of them. So already you are using 5 x 32 bytes. So there are 5 buffers, each 32 bytes. I am using all 5 of them (160 bytes) yet only have a 32 byte buffer...? Which one's which? Thanks for clarifying about endTransmission(). baum
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #12 on: February 01, 2012, 10:36:13 pm » |
Inside Wire.h: ... #define BUFFER_LENGTH 32 ...
Inside Wire.cpp: ... uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; ... uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; ... Inside twi.h: ... #define TWI_BUFFER_LENGTH 32 ...
Inside twi.c: ... static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; ... static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; ... static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; ...
So you don't have one buffer of 160 bytes, you have 5 x 32 byte buffers, used for different things.
|
|
|
|
|
Logged
|
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #13 on: February 02, 2012, 06:33:50 pm » |
But I could change that 32 to something else, and get a larger buffer? Or is this hardcoded?
baum
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
Connecticut
Offline
Edison Member
Karma: 16
Posts: 1214
RTFD (Datasheet in our case)
|
 |
« Reply #14 on: February 02, 2012, 07:22:43 pm » |
So I (tried) to incorporate in a page write, and now it won't erase. Odd thing is that the writeArray function is copied from another program, where it works. /* Science Research Timer Erase * Erases both the internal and * external 24LC256 EEPROMs. */
#include <Wire.h> #include <EEPROM.h>
#define EEPROM_ADDRESS 0x50 #define EXTERNAL_EEPROM_SIZE 32768L //size of 24LC
#define L_PIN 3
void setup() { unsigned long memPointer = 0; Serial.begin(19200); Wire.begin();
pinMode(L_PIN, OUTPUT);
/* First clear the internal. */ for (int i = 0; i <= E2END; i++) { EEPROM.write(i, 0); }
blink(L_PIN);
/* And now the external EEPROM. */ char eraseArray[BUFFER_LENGTH]; //32 bytes for standard Wire library for(int i = 0; i < BUFFER_LENGTH; i++) { eraseArray[i] = 0xFF; } //Now eraseArray[] is filled with 0xFF. while(memPointer < EXTERNAL_EEPROM_SIZE) { writeArray(eraseArray, BUFFER_LENGTH, memPointer); memPointer += BUFFER_LENGTH; //increase the address. Serial.println(memPointer); } digitalWrite(L_PIN, HIGH); } //end setup
void loop() { }
void blink(byte pin) { digitalWrite(pin, HIGH); delay(200); digitalWrite(pin, LOW); return; }
/* writes an Array to the 24LC56.*/ void writeArray(char data[], int length, unsigned int address) {
if((length + 2) > BUFFER_LENGTH) { //too big for Wire buffer! return; }
unsigned int i;
Wire.beginTransmission(EEPROM_ADDRESS); Wire.write(highByte(address)); Wire.write(lowByte(address));
/* Now do a page write */
for(i = 0; i < length; i++) { Wire.write(data[i]); }
Wire.endTransmission(); //send the data.
return; }
|
|
|
|
|
Logged
|
I'm not kidding. If I am asking a question whose answer is found within the concerned product's datasheet, shame on me. If I am answering a similar question, shame on you!
|
|
|
|
|