Pages: [1]   Go Down
Author Topic: Wire and 24LC256 Issue  (Read 1767 times)
0 Members and 1 Guest are viewing this topic.
Connecticut
Offline Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
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

Connecticut
Offline Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, I just figured it out... I forgot wire.begin()...   smiley-sad-blue So maybe wire should tell you when you don't begin it?

It's erasing as I type!

baum
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Note from the datasheet:

Quote
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
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, I just figured it out... I forgot wire.begin()...   smiley-sad-blue 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. smiley-wink
Logged

Connecticut
Offline Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Connecticut
Offline Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Would this be good? I can only do half of a page b/c of Wire buffer size.


Code:
/* 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

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, no, because you are sending 34 bytes, and the buffer size is 32 (you have to count the address).
Logged

Connecticut
Offline Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks... so is there anyway of sending a full 64 byte page? And why does Wire only send the data @ endTransmission?

baum
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Inside Wire.h:

Code:
...
#define BUFFER_LENGTH 32
...

Inside Wire.cpp:

Code:
...
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
...
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
...

Inside twi.h:

Code:
...
  #define TWI_BUFFER_LENGTH 32
...

Inside twi.c:

Code:
...
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 Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

But I could change that 32 to something else, and get a larger buffer? Or is this hardcoded?

baum
Logged

Connecticut
Offline Offline
Edison Member
*
Karma: 17
Posts: 1216
RTFD (Datasheet in our case)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
/* 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

Pages: [1]   Go Up
Jump to: