How byte addressing is done in 24C04 eeprom.
24C04 has 4K of eeprom, so byte address range 0 to 4095 i.e 0 to 0x0FFFH. So byte address require two bytes.
But here in Maxim app note, it only sends one byte to address the byte (
https://www.maximintegrated.com/en/app-notes/index.mvp/id/4649 ).
Foe example, if I have to write at address location 0x00, I should send two 0's.
Similarly for 4095 adress, I should send 0xff & 0xff.
But here codes works by sending one bytes only.
1. I have tested the code by sending one byte adress, & it is workign on hardware. I haven't tested by sending two byte address.
2. This is below codes for writing multiple bytes & reading back. Any comments/suggestions on it.
Performance wise I dont require to be exact 50kbps. Since I have to read/write only once at startup.
/* AT89C55WD, 12Mhz crystal, 1us inst time */
sbit sda = P1^7;
sbit scl = P1^6;
#define i2c_speed_kbps 50
#define half_bit_delay_us 10 /* ( (1*1000000) / (i2c_speed_kbps*1000) )/ 2 */
#define delay_10us() _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
#define delay_5us() _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
#include "regx55.h"
#include "i2c.h"
static uint8_t eeprom_write_mutiple_bytes(uint8_t address , uint8_t byte[] , uint8_t no_bytes)
{
uint8_t cnt;
uint8_t cnt2;
uint8_t err = 0U;
cnt = 10U;
/* write to eeprom */
i2c_start();
while( (1U == i2c_write_byte(0xa0U)) && (--cnt) )
{
/* stop */
i2c_stop();
/* delay 100ms */
for(cnt2 = 0U ; cnt2 < 20U ; cnt2++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
i2c_start();
}
if(0U == cnt)
{
err = 1U;
}
/* if no error */
if(0U == err)
{
/* address */
i2c_write_byte(address);
for(cnt = 0U ; cnt < no_bytes ; cnt++)
{
(void)i2c_write_byte(byte[cnt]);
}
/* stop */
i2c_stop();
}
/* delay 100ms */
for(cnt = 0U ; cnt < 15U ; cnt++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
return err;
}
static uint8_t eeprom_read_mutiple_bytes(uint8_t address , uint8_t byte[] , uint8_t no_bytes)
{
uint8_t cnt;
uint8_t cnt2;
uint8_t err = 0U;
cnt = 10U;
/* write to eeprom */
i2c_start();
while( (1U == i2c_write_byte(0xa0U)) && (--cnt) )
{
/* stop */
i2c_stop();
/* delay 100ms */
for(cnt2 = 0U ; cnt2 < 20U ; cnt2++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
i2c_start();
}
if(0U == cnt)
{
err = 1U;
}
/* if no error */
if(0U == err)
{
/* address */
i2c_write_byte(address);
/* restart */
i2c_restart();
i2c_write_byte(0xa1U);
/* address */
byte[0] = i2c_read_byte();
for(cnt = 1U ; cnt < no_bytes ; cnt++)
{
i2c_send_ack();
byte[cnt] = i2c_read_byte();
}
/* nack */
i2c_send_nack();
/* stop */
i2c_stop();
}
/* delay 100ms */
for(cnt = 0U ; cnt < 15U ; cnt++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
return err;
}
static void i2c_start(void)
{
scl = 1U;
sda = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
sda = 0U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
static void i2c_restart(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
}
static void i2c_stop(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
}
static void i2c_send_ack(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
static void i2c_send_nack(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
static uint8_t i2c_write_byte(uint8_t byte)
{
uint8_t cnt;
for(cnt = 0U ; cnt < 8U ; cnt++)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
if( (byte << cnt) & 0x80U )
{
sda = 1U;
}
else
{
sda = 0U;
}
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
/* get ack from slave */
scl = 0U;
sda = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
return sda;
}
static uint8_t i2c_read_byte(void)
{
uint8_t cnt;
uint8_t rxdata = 0U;
uint8_t temp;
for(cnt = 0U ; cnt < 8U ; cnt++)
{
scl = 0U;
sda = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
scl = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
temp = sda;
rxdata = rxdata | (temp << (7U - cnt));
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
}
return rxdata;
}