I'm new to LPC and need help with I2C

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I'm new to LPC and need help with I2C

3,341 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jherrera8 on Fri Oct 07 11:20:12 MST 2011
Hello,

I am working on a school project and I need some help understanding the code for I2C. I have a 1769 and I am trying to use an IMU (accel and gyro) with my LPC. I cannot figure out how to set the IMU up. I I don't think I need to write to it, I just need to read the data from the IMU. I have looked at the example code and really don't understand whats going on. Any help would be greatly appreciated,

Thanks,
J
0 Kudos
13 Replies

2,286 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jherrera8 on Wed Oct 12 13:14:44 MST 2011
I figured it out, turns out the registers were never changing because there was an issue with the resistors. The lines were pulled low, and I rechecked the ground lines. Sure enough, there was the problem. Thanks for all the help. At least I understand everything better:)

J
0 Kudos

2,287 Views
aresmarser
Contributor III

Hi LPC WARE,

I also met some I2C issue which may be similar with yours.

Is it possible to share how you found and resolved the problem?

It would be great if you can help anything.

Many thanks,

Arna

0 Kudos

2,286 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Tue Oct 11 19:57:58 MST 2011
What line does the code hang up at? If the SCL line is low when the start bit is set the LPC will just wait there until the SCL line goes high. When the SCL line is low the LPC assumes the bus is busy. Do the pins get pulled up all the way? Do you have continuity between the LPC and sensor?
You should use the debugger to watch the I2C registers and see if the correct bits are being set.
http://http://knowledgebase.nxp.com/member.php?u=4967
0 Kudos

2,287 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jherrera8 on Tue Oct 11 19:18:11 MST 2011
I believe so, I bought this IMU from SparkFun, and I believe the board has 4.7k resistors.
0 Kudos

2,287 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Tue Oct 11 18:51:39 MST 2011
Do you have the required pullup resisters on SDA/SCL?
0 Kudos

2,289 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by NXP_Europe on Tue Oct 11 15:41:02 MST 2011
Hello jherrera8,

When playing with the IIC-signals it is recommended to use an IIC-logger. One can see the 'start', 'ack', 'stop' and the data-transfer.

There are USB-versions which are cheap or maybe you can borrow one.

The sequencer routine of IIC can be difficult to understand for the first time.
0 Kudos

2,290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jherrera8 on Tue Oct 11 15:35:18 MST 2011

Quote: fjrg76
Hi

Have you check (e.g. with an oscilloscope) that signals from I2C pines come-in and come-out from/to LPC/your sensor? The I2C ISR has been enabled? When the master sends the first byte it expects that the slave answers (within the ACK bit). In both cases (ACK or NAK from slave) the isr should fire. If don't then you must check the two points I mentioned earlier.

Greetings



I don't understand what you are trying to say. When I use my logic analyzer , it shows the data and clock lines go high at the same time. The signals are very small and happen far apart from each other(few secs). Can you elaborate on your statement please,

Thanks, J
0 Kudos

2,290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fjrg76 on Tue Oct 11 15:13:37 MST 2011
Hi

Have you check (e.g. with an oscilloscope) that signals from I2C pines come-in and come-out from/to LPC/your sensor? The I2C ISR has been enabled? When the master sends the first byte it expects that the slave answers (within the ACK bit). In both cases (ACK or NAK from slave) the isr should fire. If don't then you must check the two points I mentioned earlier.

Greetings
0 Kudos

2,290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jherrera8 on Tue Oct 11 11:15:34 MST 2011
After much reading, I now understand what is supposed to be going on. I have tried using the code and it seems like the interrupt never gets called. The code just sits, and I think that it is waiting for the interrupt to be called. What is supposed to call the interrupt?

Thanks for all the help,
J


Edit: So what I see, it that the code initializes the pins, then calls the I2C Engine function. After it calls that function, the code does nothing, and the interrupt function never gets called.
0 Kudos

2,289 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fjrg76 on Sat Oct 08 19:05:05 MST 2011
I2C can be handled either by polling or interrupts. In the example you gave, whenever there is a changed in the machine-state, an interrupt is fired. You should start I2C by polling. Google this User Manual:

UM10114

Fig 42, page 188, there you will find a great explanation about the I2C protocol.
0 Kudos

2,290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by vasanth on Sat Oct 08 03:11:09 MST 2011
[COLOR=red][COLOR=Black][COLOR=blue]Read section 19.9 (I2C Operating Modes) of the LPC17xx user manual.[/COLOR][/COLOR][/COLOR]

The code is a simple state machine but happens inside a Interrupt Handler.
Once the main code sets up the I2C hardware (pins, clocks, interrupts etc...), starting an I2C frame fires I2C interrupt.

An interrupt will be fired every time the I2C hardware completes its present state.
Inside the ISR, the state machine routine checks the present I2C hardware state (which is a numerical value) and takes actions (clears the interrupt flag, read/write the data registers and configure the control register for the next desired I2C state...) appropriately until the whole I2C frame is completed.

But my humble suggestion is to
[COLOR=red][COLOR=Black][COLOR=blue]Read section 19.9 (I2C Operating Modes) of the LPC17xx user manual.[/COLOR][/COLOR][/COLOR]
again and again until you understand...;)
0 Kudos

2,290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jherrera8 on Fri Oct 07 18:31:10 MST 2011
Thanks for the reply, I will definitely look at that. Also, I have an idea how it works, I'm just a bit uneasy about the code. Could somebody explain a bit more about what is going on in this example code. Thanks guys,

void I2C0_IRQHandler(void)
{
  uint8_t StatValue;

  timeout[0] = 0;
  /* this handler deals with master read and master write only */
  StatValue = LPC_I2C0->STAT;
  switch ( StatValue )
  {
case 0x08:/* A Start condition is issued. */
WrIndex0 = 0;
LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++];
LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
break;

case 0x10:/* A repeated started is issued */
RdIndex0 = 0;
/* Send SLA with R bit set, */
LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++];
LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
break;

case 0x18:/* Regardless, it's a ACK */
if ( I2CWriteLength[0] == 1 )
{
  LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
  I2CMasterState[0] = I2C_NO_DATA;
}
else
{
  LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++];
}
LPC_I2C0->CONCLR = I2CONCLR_SIC;
break;

case 0x28:/* Data byte has been transmitted, regardless ACK or NACK */
if ( WrIndex0 < I2CWriteLength[0] )
{  
  LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++]; /* this should be the last one */
}
else
{
  if ( I2CReadLength[0] != 0 )
  {
LPC_I2C0->CONSET = I2CONSET_STA;/* Set Repeated-start flag */
  }
  else
  {
LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
I2CMasterState[0] = I2C_OK;
  }
}
LPC_I2C0->CONCLR = I2CONCLR_SIC;
break;

case 0x30:
LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
I2CMasterState[0] = I2C_NACK_ON_DATA;
LPC_I2C0->CONCLR = I2CONCLR_SIC;
break;

case 0x40:/* Master Receive, SLA_R has been sent */
if ( (RdIndex0 + 1) < I2CReadLength[0] )
{
  /* Will go to State 0x50 */
  LPC_I2C0->CONSET = I2CONSET_AA;/* assert ACK after data is received */
}
else
{
  /* Will go to State 0x58 */
  LPC_I2C0->CONCLR = I2CONCLR_AAC;/* assert NACK after data is received */
}
LPC_I2C0->CONCLR = I2CONCLR_SIC;
break;

case 0x50:/* Data byte has been received, regardless following ACK or NACK */
I2CSlaveBuffer[0][RdIndex0++] = LPC_I2C0->DAT;
if ( (RdIndex0 + 1) < I2CReadLength[0] )
{  
  LPC_I2C0->CONSET = I2CONSET_AA;/* assert ACK after data is received */
}
else
{
  LPC_I2C0->CONCLR = I2CONCLR_AAC;/* assert NACK on last byte */
}
LPC_I2C0->CONCLR = I2CONCLR_SIC;
break;

case 0x58:
I2CSlaveBuffer[0][RdIndex0++] = LPC_I2C0->DAT;
I2CMasterState[0] = I2C_OK;
LPC_I2C0->CONSET = I2CONSET_STO;/* Set Stop flag */
LPC_I2C0->CONCLR = I2CONCLR_SIC;/* Clear SI flag */
break;

case 0x20:/* regardless, it's a NACK */
case 0x48:
LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
I2CMasterState[0] = I2C_NACK_ON_ADDRESS;
LPC_I2C0->CONCLR = I2CONCLR_SIC;
break;

case 0x38:/* Arbitration lost, in this example, we don't
deal with multiple master situation */
default:
I2CMasterState[0] = I2C_ARBITRATION_LOST;
LPC_I2C0->CONCLR = I2CONCLR_SIC;
break;
  }
  return;
}
0 Kudos

2,290 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fjrg76 on Fri Oct 07 16:51:57 MST 2011
Hi

I assume you have no experience with such a bus. IIC isn't difficult as it seems at first glance, but before you start your project, you should have some knowledge about the bus. You may try this approach:

------------------
Layer 1. Your app
------------------
Layer 2. Your IMU driver
------------------
Layer 3. The LPC IIC driver
------------------
Layer 4. Hardware
------------------

This is known as "Layer approach design", and it's very helpful and powerful. Start reading about IIC bus. Then move forward to understand how the IMU chip works and uses IIC. No coding yet until you are confident with both.

Once that have been understood, try to write some basic and generic IIC functions like: iic_init(), iic_send_start(), iic_read_byte(), and so on. Next step is to make your IMU chip to give some alive signals. Perhaps would be easier to test those function with somewaht mor familiar, like an eeprom.

Hope you've got the idea. If not, please let me know it and I'll try to help you a little bit more. I'm starting with NXP Cortex MCUs also, but I wrote an IIC driver for the LPC212x, and LPC210x ARM7-TDMI NXP chips, and maybe looking at it gives you a better idea (I need to check how similar is the IIC peripheral in both architectures).

Good luck :) !!
0 Kudos