I2C slave on an LPC2101

Started by rfkd07 July 31, 2008
Currently I am implementing an I2C slave interface on an LPC2101. The
controller is connected to the I2C bus with two temperature sensors
and an LPC2148 which is the I2C master.

The LPC2148 can read both temperature sensors without problems but I
cannot get the I2C slave on the LPC2101 to run properly though I based
the code on the LPC2000 I2C slave code example (TN06005) from NXP.
Here's what I have:

______________________________________________________________________
enum { AA=2, SI, STO, STA, I2EN };

void __attribute__ ((interrupt("IRQ"))) i2cIsr() {
unsigned char st = I2C0STAT;
led(on); // Indicate an IRQ
I2C0CONCLR = 1< switch (st) {
case 0x60:
case 0x68:
I2C0CONSET = 1< break;
case 0x80:
// Do nothing on data reception
break;
case 0x88:
case 0xA0:
case 0xC0:
case 0xC8:
I2C0CONSET = 1< break;
case 0xA8:
case 0xB8:
I2C0DAT = 0xAB; // Send constant 0xAB
break;
default:
break;
}
VICVECTADDR = 0;
}

void i2cInit() {
// Configure port
PINSEL0 &= ~(3<<4 | 3<<6);
PINSEL0 |= 1<<4 | 1<<6;

// Configure VIC
VICINTENCLEAR = 0xFFFFFFFF;
VICINTSELECT = 0;
VICVECTCNTL0 = 9 | 1<<5;
VICVECTADDR0 = (unsigned int)i2cIsr;
VICINTENABLE = 1<<9;

// Configure I2C
I2C0SCLH = 294; // 100 kHz (~60 MHz PCLK)
I2C0SCLL = 294;
I2C0ADR = 0x4C<<1; // No GC support
I2C0CONSET = 1< }
______________________________________________________________________

As soon as I put the address of the LPC2101 (0x4C) on the bus, SCLK
remains low (checked with an oszilloscope). An interrupt is not fired
from what I can see - well, at least the test LED (line 5) is not
lighting up. Interrupts in general should work, I successfully tested
TIMER1 interrupts before. Any ideas?

Thanks in advance.

An Engineer's Guide to the LPC2100 Series

>>> "I2C0ADR = 0x4C<<1;"
when you shift the address, it becomes "0x98",
isn't it? From the master, try to send 0x98 or 0x99
to see if the interrupt is generated or not.

Tom

--- In l..., "rfkd07" wrote:
>
> Currently I am implementing an I2C slave interface on an LPC2101. The
> controller is connected to the I2C bus with two temperature sensors
> and an LPC2148 which is the I2C master.
>
> The LPC2148 can read both temperature sensors without problems but I
> cannot get the I2C slave on the LPC2101 to run properly though I based
> the code on the LPC2000 I2C slave code example (TN06005) from NXP.
> Here's what I have:
>
> ______________________________________________________________________
> enum { AA=2, SI, STO, STA, I2EN };
>
> void __attribute__ ((interrupt("IRQ"))) i2cIsr() {
> unsigned char st = I2C0STAT;
> led(on); // Indicate an IRQ
> I2C0CONCLR = 1< > switch (st) {
> case 0x60:
> case 0x68:
> I2C0CONSET = 1< > break;
> case 0x80:
> // Do nothing on data reception
> break;
> case 0x88:
> case 0xA0:
> case 0xC0:
> case 0xC8:
> I2C0CONSET = 1< > break;
> case 0xA8:
> case 0xB8:
> I2C0DAT = 0xAB; // Send constant 0xAB
> break;
> default:
> break;
> }
> VICVECTADDR = 0;
> }
>
> void i2cInit() {
> // Configure port
> PINSEL0 &= ~(3<<4 | 3<<6);
> PINSEL0 |= 1<<4 | 1<<6;
>
> // Configure VIC
> VICINTENCLEAR = 0xFFFFFFFF;
> VICINTSELECT = 0;
> VICVECTCNTL0 = 9 | 1<<5;
> VICVECTADDR0 = (unsigned int)i2cIsr;
> VICINTENABLE = 1<<9;
>
> // Configure I2C
> I2C0SCLH = 294; // 100 kHz (~60 MHz PCLK)
> I2C0SCLL = 294;
> I2C0ADR = 0x4C<<1; // No GC support
> I2C0CONSET = 1< > }
> ______________________________________________________________________
>
> As soon as I put the address of the LPC2101 (0x4C) on the bus, SCLK
> remains low (checked with an oszilloscope). An interrupt is not fired
> from what I can see - well, at least the test LED (line 5) is not
> lighting up. Interrupts in general should work, I successfully tested
> TIMER1 interrupts before. Any ideas?
>
> Thanks in advance.
>

Thanks for your reply. But the documentation says:

I2C0ADR
0 GC General Call enable bit.
7:1 Address The I2C device address for slave mode.

So the shift should be correct. In case I don't shift the address the
controller doesn't react at all (SCLK raises back to high after
addressing, no ACK/NAK from the slave). When shifted, SCLK remains
low. Any other ideas?

--- In l..., "Dezheng Tang" wrote:
>
> >>> "I2C0ADR = 0x4C<<1;"
> when you shift the address, it becomes "0x98",
> isn't it? From the master, try to send 0x98 or 0x99
> to see if the interrupt is generated or not.
>
> Tom
Doh, I was using an old CRT. It works now.

--- In l..., "rfkd07" wrote:
>
> Currently I am implementing an I2C slave interface on an LPC2101. The
> controller is connected to the I2C bus with two temperature sensors
> and an LPC2148 which is the I2C master.
>
> The LPC2148 can read both temperature sensors without problems but I
> cannot get the I2C slave on the LPC2101 to run properly though I based
> the code on the LPC2000 I2C slave code example (TN06005) from NXP.
> Here's what I have:
>
> ______________________________________________________________________
> enum { AA=2, SI, STO, STA, I2EN };
>
> void __attribute__ ((interrupt("IRQ"))) i2cIsr() {
> unsigned char st = I2C0STAT;
> led(on); // Indicate an IRQ
> I2C0CONCLR = 1< > switch (st) {
> case 0x60:
> case 0x68:
> I2C0CONSET = 1< > break;
> case 0x80:
> // Do nothing on data reception
> break;
> case 0x88:
> case 0xA0:
> case 0xC0:
> case 0xC8:
> I2C0CONSET = 1< > break;
> case 0xA8:
> case 0xB8:
> I2C0DAT = 0xAB; // Send constant 0xAB
> break;
> default:
> break;
> }
> VICVECTADDR = 0;
> }
>
> void i2cInit() {
> // Configure port
> PINSEL0 &= ~(3<<4 | 3<<6);
> PINSEL0 |= 1<<4 | 1<<6;
>
> // Configure VIC
> VICINTENCLEAR = 0xFFFFFFFF;
> VICINTSELECT = 0;
> VICVECTCNTL0 = 9 | 1<<5;
> VICVECTADDR0 = (unsigned int)i2cIsr;
> VICINTENABLE = 1<<9;
>
> // Configure I2C
> I2C0SCLH = 294; // 100 kHz (~60 MHz PCLK)
> I2C0SCLL = 294;
> I2C0ADR = 0x4C<<1; // No GC support
> I2C0CONSET = 1< > }
> ______________________________________________________________________
>
> As soon as I put the address of the LPC2101 (0x4C) on the bus, SCLK
> remains low (checked with an oszilloscope). An interrupt is not fired
> from what I can see - well, at least the test LED (line 5) is not
> lighting up. Interrupts in general should work, I successfully tested
> TIMER1 interrupts before. Any ideas?
>
> Thanks in advance.
>