Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
02/23/09 07:42
Read: times


 
#162682 - AT24C512 Sequential Read failed!!
Hi all,

I am working with AT24C512 I2C EEPROM interfaced to P89C664HBA controller on SDCC. The following is a program written by me to write and read to/from the EEPROM - byte-wise and page-wise. Well all seems to be working fine except the sequential read operation. Can anyone tell me how can I sort this out?

Regards,
Sarma
#define SCL P1_6
#define SDA P1_7
#define EEPROM_READ_ADDR  0XA1
#define EEPROM_WRITE_ADDR 0XA0
#define HIGH  1
#define LOW   0
#define ACK   LOW
#define NACK  HIGH
#define SUCCESS HIGH
#define ERROR LOW

#define TEST_NUM 0x81

__sbit __at (0x96) P1_6 ;
__sbit __at (0x97) P1_7 ;


/* I2C functions */
void start()
{
	/* I2C START condition */
	SCL = SDA = HIGH;
	NOP;
	SDA = LOW;
	NOP;
	SCL = LOW;
}

void stop()
{
	/* I2C STOP condition */
	SDA = LOW;
	SCL = HIGH;
	NOP;
	SDA = HIGH;
	NOP;
	SCL = LOW;
}

unsigned char clock()
{
	/* A subroutine to generate a clock pulse and return the
	 * status of the data bus during the clock period */
	unsigned char status = 0;
	SCL = HIGH;
	NOP;
	while(!SCL);		/* eliminate ripples */
	status = SDA;
	SCL = LOW;
	return (status);
}

unsigned char write(unsigned char byte)
{
	/* I2C WRITE operation, Write a byte on SDA and return the
	 * acknowledgement */
	unsigned char mask = 0x80;
	unsigned char status= ACK;
	
	for ( ; mask > 0 ;  ) {
		SDA = (byte & mask) ? ( SET ):( CLEAR ) ;
		mask >>= 1;
		clock();
	}
 	return (clock());	/* return the status of SDA line on
				 * the 9th pulse */
}

unsigned char read(unsigned char status)
{
	/* I2C READ operation, read one byte from the transmitter and
	 * give ack/nack to it */
	unsigned char byte = 0;
	unsigned char count, level = 0;
/* 	if (status == NACK) */
/* 		print_on_lcd("NACK!!"); */
	for ( count = 0; count < 8; count++ ) {
		byte <<= 1;
		level = clock();
		byte |= level;		
	}
	SDA = status;		/* status = 1 :- NACK
				 * status = 0 :- ACK */
	clock();
	return byte;
}

/* EEPROM functions */
unsigned char byte_write( unsigned int addr, unsigned char val )
{
	/*  A write operation requires two 8-bit data word addresses
	 *  following the device address word and acknowledgment. Upon
	 *  receipt of this address, the EEPROM will again respond
	 *  with and then clock in the first 8-bit data
	 *  word. Following receipt of the 8-bit data word, the EEPROM
	 *  will output . The addressing device, such as a
	 *  microcontroller, then must terminate the write sequence
	 *  with a stop condition. At this time the EEPROM enters an
	 *  internally-timed write cycle, tWR, to the nonvolatile
	 *  memory.  All inputs are disabled during this write cycle
	 *  and the EEPROM will not respond until the write is
	 *  complete */

	unsigned char status = ERROR;
	
	start();
	
	if ( write(EEPROM_WRITE_ADDR) == ACK ) {
		if ( write( (addr & 0xFF00) >> 8 ) == ACK ) {
			if ( write( (addr & 0x00FF) ) == ACK ) {
				if ( write(val) == ACK ) {
					status = SUCCESS;
				}
				else
					print_on_lcd("write val failed!!");
			}
			else
				print_on_lcd("write low byte failed!!");	
		}
		else
			print_on_lcd("write high byte failed!!");		
	}
	else
		print_on_lcd("write device id failed!!");
	

	stop();
	
	delay_millisec(10); 		/* Twr = 10ms max */

	return status;
}


unsigned char byte_read( unsigned int addr )
{
	/* A random read requires byte write sequence to load in the
	 * data word address. Once the device address word and data
	 * word address are clocked in and acknowledged by the EEPROM,
	 * the microcontroller must generate another start
	 * condition. The microcontroller now initiates a current
	 * address read by sending a device address with the
	 * Read/Write select bit high. The EEPROM acknowledges the
	 * device address and serially clocks out the data word. The
	 * microcontroller does not respond with but does generate a
	 * following stop condition */
	
	unsigned char val = ERROR;

	start();
	if ( write(EEPROM_WRITE_ADDR) == ACK ) {
		if ( write( (addr & 0xFF00) >> 8 ) == ACK ) {
			if ( write( (addr & 0x00FF) ) == ACK ) {
				/* Dummy write successful */
				start();

				if ( write(EEPROM_READ_ADDR) == ACK) {
					val = read(NACK);
				}
				else
					print_on_lcd("write device Read id failed!!!");
			}
			else
				print_on_lcd("write addr low byte failed!!!");

		}
		else
			print_on_lcd("write addr high byte failed!!!");
	}
	else
		print_on_lcd("write device_write id failed!!!");

	stop();

	return val;
}

/* Current address Read */

unsigned char current_read()
{
	/* read a byte from the last address read/written + 1 */

	unsigned char byte = ERROR;
	
	start();

	if ( write(EEPROM_READ_ADDR) == ACK ) 
		byte = read(NACK);
	
	else
		print_on_lcd("write(read id) failed!! ");

	stop();

	return byte;
}

/* Sequential read */
unsigned int seq_read( unsigned int size, __idata unsigned char *buf, unsigned char addr)
{
	/* read sequentially 'size' bytes to buffer 'buf' starting
	 * from address 'addr' */
	unsigned int num = 1;	/* count the number of bytes read */
	unsigned char byte = 0;
	
	*buf++ = byte_read(addr);

	start();
	
	if ( write(EEPROM_READ_ADDR) == ACK ) {
		for (  ; size -1 ; size-- ) {
			buf[num] = read(ACK);
			num++;
		}
		buf[num] = read(NACK); /* transmit NACK with last byte
					* followed by a STOP */
                num++;
	}
	else
		print_on_lcd("Device not selected!");

	stop();
	return (num);
}

/* main program */

main()
{
	unsigned char addr = 0;
	unsigned char *ptr =  "testing page read operation";
	unsigned int i = 0;
	__idata unsigned char buf[128] = ""; /* A null string */
	
	init_lcd();

	print_on_lcd("EEPROM test");
	for ( i = 0; ptr[i]; i++ ) {
		if ( byte_write( i, ptr[i] ) != SUCCESS ) 
			print_on_lcd("byte_write() failed!!!");
	}
	byte_write( i, ptr[i] ); /* for last cahracter */

	print_on_lcd("seq_read()!!");
	seq_read( 20, buf, 0x00 );
	print_on_lcd(buf);
	
	for ( i = 0; i < 20; i++ ) {
		buf[i] = byte_read(i);
	}
	print_on_lcd("otherwise!!");
	print_on_lcd(buf);
	while (1);
	
}

 



List of 19 messages in thread
TopicAuthorDate
AT24C512 Sequential Read failed!!            01/01/70 00:00      
   the IIC engine is identical ...            01/01/70 00:00      
      Sample code            01/01/70 00:00      
   what are the symptoms?            01/01/70 00:00      
      symptoms            01/01/70 00:00      
   A common mistake...            01/01/70 00:00      
   Your code looks fine            01/01/70 00:00      
      It took me ages !            01/01/70 00:00      
         uint8_t range            01/01/70 00:00      
         confusion            01/01/70 00:00      
            you use uint8_t in your read_seq ()            01/01/70 00:00      
            Do you want the full corrected source code ?            01/01/70 00:00      
               my own code            01/01/70 00:00      
                  An explanation            01/01/70 00:00      
                     code update            01/01/70 00:00      
                        diff is your friend            01/01/70 00:00      
                           size -1            01/01/70 00:00      
                        write program, rather than code...            01/01/70 00:00      
                           It's Working            01/01/70 00:00      

Back to Subject List