EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

I2C with Rabbit RCM2000

Started by Geri April 18, 2005

Hi

I am using a Rabbit 2000 with an ATMEL I2C-EEPROM called AT24C256
(256KB-Size). After wireing the hardware I tried to connect to the I2C-
EEPROM with the simple Example I2C_24LC16.C, delivered with Dynamic C.
Unfortunately the procedure does not work. I already had some
approaches but I did not succeed.
Maybe someone of you had already the same problem an give me a hint
what I can do. Can it be that the procedures does not work with this
big EEPROM? Pleas, does anyone have a piece of source that show me how
to managed this problem?

Many thanks for your help in advance

Gerhard



The sample program is for a much smaller device, it
will not work for the 24C256. I use a 256 device
myself, and what I did was to take the DC built-in
read and write procedures and modify them for the
larger eeprom.

Steve
==============================================

typedef USL unsigned long;
typedef UCH unsigned char;

/* START FUNCTION DESCRIPTION
********************************************
ReadMem <I2CMEM.LIB>

SYNTAX: int ReadMem(unsigned long adr,
unsigned char *p,
unsigned char len);

DESCRIPTION: Reads data from slave EEPROM device.
Sends: START, control byte, High byte of
address, and low
byte of address, read START, control byte
+1.
reads: data (sending ACKs and NAK on last
data) STOP.
Waits for slave to respond. EEPROM does
not respond while
internal write takes place.

PARAMETER1: unsigned long adr - address in EEPROM
PARAMETER2: unsigned char *p - pointer to buffer for
data
PARAMETER3: unsigned char len - number of bytes to
read (PAGESIZE max)

RETURN VALUE: 0 or error code (see code)

END DESCRIPTION
**********************************************************/

int ReadMem( USL adr, UCH *p, UCH len )
{
auto unsigned char cnt, cntl, hb, lb;
auto short int err;

#ifdef _24LC512_
cntl = (((UCH)(adr >> 15)) & 0x0E) | 0xA0;
hb = (UCH)(adr >> 8);
#else
#ifdef _24LC256_
cntl = (((UCH)(adr >> 14)) & 0x0E) | 0xA0;
hb = ((UCH)(adr >> 8)) & 0x7F;
#else // assume 24LC128 device
cntl = (((UCH)(adr >> 13)) & 0x0E) | 0xA0;
hb = ((UCH)(adr >> 8)) & 0x3F;
#endif
#endif
lb = (UCH)adr;

if ( err = i2c_startw_tx() ) {
i2c_stop_tx();
return -10+err; // Return too long stretching
}
if ( err = i2c_wr_wait(cntl) ) {
i2c_stop_tx();
return -20+err; // Return no ack on control byte
}
if ( err = i2c_write_char(hb) ) {
i2c_stop_tx();
return -30+err; // Return no ack on high byte of
address
}
if ( err = i2c_write_char(lb) ) {
i2c_stop_tx();
return -40+err; // Return no ack on low byte of
address
}
//i2c_Delay(10);
if (err=i2c_startw_tx()) {
i2c_stop_tx();
return -50+err; // Return too long stretch on read
}
if ( err = i2c_wr_wait(cntl+1) ) {
i2c_stop_tx();
return -60+err; // Send read to slave - no ack
(retried) return -5
}
for ( cnt = 0; cnt < len; cnt++ ) {
err = i2c_read_char( &(p[cnt]) );
if ( err ) {
i2c_stop_tx();
return -60+err;
}
if (cnt==(len-1)) {
i2c_send_nak();
}
else {
i2c_send_ack();
}
}
i2c_stop_tx();
return 0;
}

/* START FUNCTION DESCRIPTION
********************************************
WriteMem <I2CMEM.LIB>

SYNTAX: int WriteMem(unsigned long adr,
unsigned char *p,
unsigned char len);

DESCRIPTION: Writess data to slave EEPROM device.
Sends: START, control byte, High byte of
address, and low
byte of address, then data, STOP.
Waits for slave to respond. EEPROM does
not respond while
internal write takes place.

PARAMETER1: unsigned long adr - address in EEPROM
PARAMETER2: unsigned char *p - pointer to data
PARAMETER3: unsigned char len - number of bytes to
write (PAGESIZE max)

RETURN VALUE: 0 or error code (see code)

END DESCRIPTION
**********************************************************/

int WriteMem( USL adr, UCH *p, UCH len )
{
auto unsigned char cnt, cntl, hb, lb;
auto short int err;

#ifdef _UNIVERSAL_HPA_
if ( !IsPwrOk() )
return(-1);
#endif

#ifdef _24LC512_
cntl = (((UCH)(adr >> 15)) & 0x0E) | 0xA0;
hb = (UCH)(adr >> 8);
#else
#ifdef _24LC256_
cntl = (((UCH)(adr >> 14)) & 0x0E) | 0xA0;
hb = ((UCH)(adr >> 8)) & 0x7F;
#else // assume 24LC128 device
cntl = (((UCH)(adr >> 13)) & 0x0E) | 0xA0;
hb = ((UCH)(adr >> 8)) & 0x3F;
#endif
#endif
lb = (UCH)adr;

if ( err = i2c_startw_tx() ) {
i2c_stop_tx();
return -10+err; // Return too long stretching
}
if ( err = i2c_wr_wait(cntl) ) {
i2c_stop_tx();
return -20+err; // Return no ack on control byte
(retried)
}
if ( err = i2c_write_char(hb) ) {
i2c_stop_tx();
return -30+err; // Return no ack on high address
byte
}
if (err = i2c_write_char(lb) ) {
i2c_stop_tx();
return -40+err; // Return no ack on low address byte
}
for ( cnt = 0; cnt < len; cnt++ ) {
i2c_write_char( p[cnt] );
}
i2c_stop_tx();
return 0;
} --- Geri <gcoolfire@gcoo...> wrote:
>
> Hi
>
> I am using a Rabbit 2000 with an ATMEL I2C-EEPROM
> called AT24C256
> (256KB-Size). After wireing the hardware I tried to
> connect to the I2C-
> EEPROM with the simple Example I2C_24LC16.C,
> delivered with Dynamic C.
> Unfortunately the procedure does not work. I already
> had some
> approaches but I did not succeed.
> Maybe someone of you had already the same problem an
> give me a hint
> what I can do. Can it be that the procedures does
> not work with this
> big EEPROM? Pleas, does anyone have a piece of
> source that show me how
> to managed this problem?
>
> Many thanks for your help in advance
>
> Gerhard >
>




Hello Steve

Many thanks for your fast response, your helpful hints and the source
code!!!
Now, for me some things are getting clearer because one problem I
deteced with the sample program was, that the address, written has
only a length of 8 bits.

Many thanks from Austria

Gerhard




The 2024 Embedded Online Conference