Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Problem using I2C for reading EEPROM 24LC515

Problem using I2C for reading EEPROM 24LC515

2005-11-16 by Marcio Zaquela

Hi guys,

I´m having some problems reading EEPROM 24LC515 using I2C interface.

I can read addresses 0x0000 to 0x7FFF (BLOCK=0) but I can´t read addresses 0x8000 to 0xFFFF (BLOCK=1) of this memory.

The CONTROL BYTE for accessing BLOCK 0 is 0xA0 and for accessing BLOCK 1 is 0xA8. 

When I send 0xA8 I don´t receive any acknowledge bit from the memory (I receive the ACK when I send 0xA0).

Does anyone had any similar problem and can help me ?

Thanks,
Marcio


[Non-text portions of this message have been removed]

Re: [lpc2000] Problem using I2C for reading EEPROM 24LC515

2005-11-16 by Ake Hedman, eurosource

No I don't have that problem (see attached code) but have a problem with 
the timing on write (currently solved with a nasty hack....).

/Ake

Marcio Zaquela wrote:

> Hi guys,
>
> I´m having some problems reading EEPROM 24LC515 using I2C interface.
>
> I can read addresses 0x0000 to 0x7FFF (BLOCK=0) but I can´t read 
> addresses 0x8000 to 0xFFFF (BLOCK=1) of this memory.
>
> The CONTROL BYTE for accessing BLOCK 0 is 0xA0 and for accessing BLOCK 
> 1 is 0xA8.
>
> When I send 0xA8 I don´t receive any acknowledge bit from the memory 
> (I receive the ACK when I send 0xA0).
>
> Does anyone had any similar problem and can help me ?
>
> Thanks,
> Marcio
>
>
> [Non-text portions of this message have been removed]
>
>
> ------------------------------------------------------------------------
> YAHOO! GROUPS LINKS
>
>     *  Visit your group "lpc2000
>       <http://groups.yahoo.com/group/lpc2000>" on the web.
>        
>     *  To unsubscribe from this group, send an email to:
>        lpc2000-unsubscribe@yahoogroups.com
>       <mailto:lpc2000-unsubscribe@yahoogroups.com?subject=Unsubscribe>
>        
>     *  Your use of Yahoo! Groups is subject to the Yahoo! Terms of
>       Service <http://docs.yahoo.com/info/terms/>.
>
>
> ------------------------------------------------------------------------
>


-- 
 ---
Ake Hedman (YAP - Yet Another Programmer)
eurosource, Brattbergavägen 17, 820 50 LOS, Sweden
Phone: (46) 657 413430 Cellular: (46) 73 84 84 102
Company home: http://www.eurosource.se      
Kryddor/Te/Kaffe: http://www.brattberg.com
Personal homepage: http://www.eurosource.se/akhe
Automated home: http://www.vscp.org


  ----------

///////////////////////////////////////////////////////////////////////////////
// File: eeprom.h
//
// I2C EEPROM handler
// Copyright (C) 2005 Ake Hedman, akhe@...
// http://www.vscp.org
//
// $RCSfile: eeprom.h,v $
// $Revision: 1.3 $
//

union {

	unsigned short int Val;
    struct {
		unsigned char LSB;
        unsigned char MSB;
    } bytes;
	
} memAddress;
  
// Read address for eeprom  
#define EEPROM_ADDR		0xA8 
 
extern volatile boolean bI2c_lock;

// Initialize I2C
void i2cInit( void );

// I2C interrupt routine
void I2CISR( void );	
																			
// Background call to start master send and receive byte transfers
boolean I2CTransferByte( unsigned char I2CAddr,
							unsigned short MemAddr,
							unsigned char count,
							unsigned char *pData );

// Write eeprom
boolean writeEEPROM( uint16_t addr, uint8_t data );

// Read eeprom
int16_t readEEPROM( uint16_t addr );

  ----------

///////////////////////////////////////////////////////////////////////////////
//
// File: eeprom.c
//
// I2C EEPROM handler
// Copyright (C) 2005 Ake Hedman, akhe@eurosource.se
// http://www.vscp.org
//
// $RCSfile: eeprom.c,v $
// $Revision: 1.4 $
//

#include "types.h"
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lpc213x.h"
#include "config.h"
#include "armVIC.h"
#include "eeprom.h"
#include "sysTime.h"

#define MAX_I2C_DATA	8

unsigned char	I2CData[ MAX_I2C_DATA ];
unsigned char	*pI2CData;
uint8_t	I2Counter;
uint8_t	I2CAddress;
volatile boolean bI2c_lock;

///////////////////////////////////////////////////////////////////////////////
// i2c1Init
//

void i2cInit( void )
{
	bI2c_lock = FALSE;						// Initilise the lock flag

	//PINSEL0  |= 0x30c00000; 				// Activate I2C 1
	PINSEL0 |= 0x50; 						// Activate I2C 0
	
	// initialize the interrupt vector
	VICIntSelect &= ~VIC_BIT (VIC_I2C0 );	// I2C selected as IRQ
	VICVectCntl2 = VIC_ENABLE | VIC_I2C0;
	VICVectAddr2 = (uint32_t)I2CISR;    	// address of the ISR
	VICIntEnable = VIC_BIT( VIC_I2C0 );    	// I2C interrupt enabled
	
	I20SCLH = 75;	// Set bit rate 60.0000hz / (SCLH + SCLL ) = 60.0000/(75+75) = 400.0Khz
	I20SCLL = 75;
}

///////////////////////////////////////////////////////////////////////////////
// writeEEPROM
//
// return: True on success.

boolean writeEEPROM( uint16_t addr, uint8_t data )
{
	boolean rv;
	
	rv = I2CTransferByte( EEPROM_ADDR, addr, 1, (unsigned char *)&data );
	pause( TEN_MS );	// HACK!!! TODO Remove
	
	return rv;
}

///////////////////////////////////////////////////////////////////////////////
// readEEPROM
//
// Return: -1 on failure, data on success.

int16_t readEEPROM( uint16_t addr )
{
	uint32_t start;
	
	// Write address
	if ( !I2CTransferByte( EEPROM_ADDR, addr, 0, NULL ) ) {
		return -1;	
	}
	
	//  Read content of address
	if ( !I2CTransferByte( EEPROM_ADDR + 1, addr, 1, NULL ) ) {	
		return -1;
	}
	
	// Wait until data is available
	start = getSysTICs();
	while ( bI2c_lock ) {			// Wait for interrupt to signal end of I2C activity
		if ( getElapsedSysTICs( start ) > HUNDRED_MS ) return -1;
		WDOG();
	}
	
	return I2CData[ 0 ];
}

///////////////////////////////////////////////////////////////////////////////
// I2CTransferByte
//

boolean I2CTransferByte( unsigned char I2CAddr,
							unsigned short memAddr,
							unsigned char count,
							unsigned char *pData )
{
	unsigned char i;
	uint32_t start;

	// CAN only hadle MAX_I2C_DATA + sizeof( addr )
	if ( I2CAddr & 1 ) {
		if ( count > MAX_I2C_DATA ) return FALSE;
	}
	else {
		if ( count > ( MAX_I2C_DATA - 2 ) ) return FALSE;
	}
	
	// Wait until last I2C operation has finished.
	start = getSysTICs();
	while ( bI2c_lock ) {			// Wait for interrupt to signal end of I2C activity
		if ( getElapsedSysTICs( start ) > HUNDRED_MS ) return FALSE;
		WDOG();
	}
	
	bI2c_lock = TRUE;                  	// Set I2C bus as active
	I2CAddress = I2CAddr;				// Sava I2C address

	// If write operation the address should also be sent
	if ( I2CAddr & 1 ) {
	
		// Read
		I2Counter = count;
		pI2CData = pData;		// Point at user buffer
		
	}
	else {
	
		// Write
		I2Counter = count + 2;				// Add address length to count
		I2CData[ 0 ] = ( memAddr >> 8 );	// MSB of memeory address
		I2CData[ 1 ] = memAddr & 0xff;		// LSB of address
		
		for ( i=0; i<count; i++ ) {
			I2CData[ i + 2 ] = pData[ i ];
		}
		
		pI2CData = I2CData;		// Point at internal buffer

	}
	
	I20CONCLR 	= 0x000000FF;	// Clear all I2C settings
	I20CONSET 	= 0x00000040; 	// Enable the I2C interface
	I20CONSET 	= 0x00000020; 	// Start condition
		
	return TRUE;
}





///////////////////////////////////////////////////////////////////////////////
// I2CISR
//

void I2CISR( void )					// I2C interrupt routine
{
	// perform proper ISR entry so thumb-interwork works properly
	ISR_ENTRY();
	
	switch ( I20STAT ) {				// Read result code and switch to next action
	
		// Start and Send byte conditions
		case 0x00:						// Bus errror
			I20CONSET = 0x10;			// STOP 
			bI2c_lock = FALSE;
			break;
		
		case 0x08:						// Start bit sent
			I20DAT = I2CAddress; 		// Send address and write bit
			I20CONCLR = 0x20;			// Clear start flag
			I20CONSET = 0x04;			// Set ACK bit
			break;

		case 0x10:
			I20DAT = I2CAddress; 		// Send address and write bit
			I20CONSET = 0x04;			// Set ACK bit
			break;

		case 0x18:						// Start Data
			I20DAT = *pI2CData++;		// Write data to tx register
			break;
			
		case 0x20:						// Slave address+W, Not ACK
			I20CONSET = 0x14;			// Set STOP and ACK bits
			bI2c_lock = FALSE;
			break;
		
		case 0x28:						// Data sent, ACK
			I2Counter--;
			if ( 0 == I2Counter ) {	
				I20CONSET = 0x14;		// Set STOP
				bI2c_lock = FALSE;
			}
			else {
				I20DAT = *pI2CData++;	// Write data to tx register
				I20CONSET = 0x04;		// Set AA bit
			}
			break;

		case 0x30:						// Data sent, NOT Ack
			I20CONSET = 0x14;			// Set STOP and ACK bits
			bI2c_lock = FALSE;
			break;

		case 0x38:						// Arbitration lost
			I20CONSET = 0x24;			// Set STAT and ACK bits
			break;
			
		// * * * Receive byte conditions
		case 0x40:						// Slave Address + R, ACK
			I20CONSET = 0x04;			// Enable ACK for data byte
			break;

		case 0x48:						// Slave Address +R, Not Ack
			I20CONSET = 0x10;			// Set STOP and ACK bits
			bI2c_lock = FALSE;
			break;

		case 0x50:						// Data Received, ACK 
			I2CData[ 0 ] = I20DAT;
			I20CONSET = 0x10;			// Set STOP bit
			bI2c_lock = FALSE;
			break;

		case 0x58:						// Data Received, Not Ack
			I2CData[ 0 ] = I20DAT;
			I20CONSET = 0x10;			// Set STOP bit
			bI2c_lock = FALSE;
			break;

		default:
			break;

	}

	I20CONCLR = 0x08;					// Clear I2C interrupt flag
	VICVectAddr = 0x00000000;			// Clear interrupt in 

	ISR_EXIT();                         // recover registers and return
}


[Non-text portions of this message have been removed]

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.