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]