im trying to write driver for EEPROM (24LC64):

  • page size: 32 byte
  • capacity: 8KB (64Kbit)

definition code:

#define E24LC64_WRITE_PAGE_SIZE 32
#define E24LC64_TOTAL_SIZE 8000
#define E24LC64_WRITE_DELAY_MS 5

class public function:

uint32_t E24LC64::eeprom_write(uint16_t address, const uint8_t* buff,int32_t length){
                        //          19      this is test. trimmed?          22
uint8_t page_head_addr ;
int32_t sent_length;
uint32_t err_val = TWI_SUCCESS;
//do we need to write next page:
while ( (length>0) && (TWI_SUCCESS == err_val) ){
    err_val = _PageWrite(address, buff, length);
    page_head_addr = (address % E24LC64_WRITE_PAGE_SIZE);
    sent_length = E24LC64_WRITE_PAGE_SIZE - page_head_addr;
    length  -=  sent_length;
    address +=  sent_length;
    buff += sent_length;
return err_val;


class private function to write pages

    this function write pages
    it trims the right bytes if they exceed the page boundary.
    max length = EEPROM page size.
uint32_t E24LC64::_PageWrite(uint16_t ROMADDR, const uint8_t *buff, uint8_t length){
    uint8_t send_length;

    uint8_t page_head_addr = (ROMADDR % E24LC64_WRITE_PAGE_SIZE);

    if ( (page_head_addr + length)>E24LC64_WRITE_PAGE_SIZE){
        send_length = E24LC64_WRITE_PAGE_SIZE - page_head_addr; //trim the extra
        send_length = length;

    twi_packet_t packet;
    packet.buffer = (void*) buff;
    packet.length = send_length;
    packet.chip = _I2Caddr;
    packet.addr[0] = uint8_t(ROMADDR & 0xff00);
    packet.addr[1] = uint8_t((ROMADDR >> 8) & 0x00ff);
    packet.addr_length = 2;
    uint32_t err_val = twi_master_write(_pTWI, &packet);

    if (err_val == TWI_SUCCESS)
    return err_val;


user call:

E24LC64 ext_eeprom(TWI0, 0x50);
char mystr[] = "this is test. trimmed?";

the error: the function eeprom seems to write back to address 19! enter image description here

so it looks like this code didnt execute?!

address +=  sent_length;

can you spot the logical error that makes the page write overlapping?

  • \$\begingroup\$ Brief glance at the data sheet, it seems to allow 4 bytes at a time? But your code doesn't handle this, or does it? You stuff in 19 to the _PageWrite function. \$\endgroup\$ – Lundin Feb 4 at 15:29
  • \$\begingroup\$ @Lundin where are you refering to in the datasheet? \$\endgroup\$ – Hasan alattar Feb 4 at 15:43
packet.addr[0] = uint8_t(ROMADDR & 0xff00);
packet.addr[1] = uint8_t((ROMADDR >> 8) & 0x00ff);

This is probably not what you want. Notice that you are masking the low byte of ROMADDR in both lines which results in addr[0] being 0x00 every time.


packet.addr[0] = (uint8_t)(ROMADDR >> 8);  // High byte of ROMADDR
packet.addr[1] = (uint8_t)(ROMADDR); // Low byte of ROMADDR
  • \$\begingroup\$ oh, thanks, you are right, although there is still weird problem i need to find and update the code and results in the question \$\endgroup\$ – Hasan alattar Feb 4 at 15:18
  • \$\begingroup\$ hello, @JimmyB, could you update the answer to make addr[0] as high byte and addr[1] as low byte as its what should be sent in sequence in the datasheet of the chip \$\endgroup\$ – Hasan alattar Feb 5 at 7:11
  • \$\begingroup\$ @Hasanalattar Thanks for pointing that out. Updated the answer :) \$\endgroup\$ – JimmyB Feb 5 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.