K20 i2c master bug?

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

K20 i2c master bug?

4,529 Views
bowerymarc
Contributor V

I'm debugging a K20F120 board and running into a problem where the 9th SCL is not issued, somewhere in the middle of transferring (block write) several tens of KB, usually after several hundred bytes.

I noticed the same bug mentioned here: i2c: Is This a Bug?

I'm attaching a logic analyzer capture, where I set the cursors at the ACK bit of the previous two bytes.  You can see the spike on SDA but it's within timing requirements, it's a valid ACK.  So then you can count the Kinetis is only issuing 8 bytes the last time (analyzer set to trigger on a both-low timeout), so the slave has no chance to ACK.

Slowing down the overal timing doesn't help.  Putting  big waits between bytes doesnt help.  Doing one byte at a time doesn't help.  Tried setting the glitch filter to 3, that didn't help.  Eventually this happens....

Bug?  Workaround? 

Thx

MarcIMG_2708.JPG.jpg

0 Kudos
20 Replies

2,055 Views
gibbon1
Contributor III

I'm unsure if this is your problem, but take at look at this link,

http://mcuoneclipse.com/2012/12/05/kl25z-and-i2c-missing-repeated-start-condition/

I found the same bug on a KL15 part.

0 Kudos

2,055 Views
bowerymarc
Contributor V

Thanks Matt for the link... I'd seen it before but forgot where it was.  The captures above were with the prescaler set to 0.  Actually for this issue that isn't the problem.  It occurs after writing several hundred bytes, and the logic capture above is from such a transfer... since it's a write there is no repeated start condition.

Of course, this may occur sometimes on reads, so either I'll test this later once I solve this issue, or just play it safe and set the prescaler to 0.  In any case, this is a different issue, where the K20 is not sending the 9th clock pulse so it's not getting an ACK from the slave.

0 Kudos

2,055 Views
martynhunt
NXP Employee
NXP Employee

Hi Marc,

What baud rate are you trying to achieve? Also, do you have open drain enabled in the PORTx_PCRn register for the pins you are using for I2C? For correct I2C operation on K Series devices PORTx_PCRn[ODE] needs to be set to 1.

Best regards,

Martyn

0 Kudos

2,055 Views
bowerymarc
Contributor V

Baud rate??

The above shots are with SCL at 93khz, but as I stated I tried at a couple slower rates with no effect.

I assume the I2C_LDD PE component sets the pins up correctly unless you know something I don't....

As I stated initially the bus is working for short transfers.

0 Kudos

2,050 Views
chris_brown
NXP Employee
NXP Employee

Marc,

I would check using the debugger to make sure that the pins are being setup as Martyn has described.  It may be a Processor Expert bug, or maybe some other function in your program has overwritten the MUX selection for whatever reason in your program.  ??  Either way, it's always best to check and something that should be ruled out as a possibility. 

Thanks,
Chris

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Marc,

We had done a similar test to transfer 0xFFFF numbers data without find that issue.

If it is possible, could you provide more test environment info? I2C related hardware circuit and I2C related software code?

Thank you for the attention.

Ma Hui

0 Kudos

2,055 Views
bowerymarc
Contributor V

Hi Hui Ma, can you tell me about your successful test?  What I2C peripheral did you write 65K times to, and were you using I2C_LDD or other driver code?

Oddly, this only seems to happen when communicating with the ADAU1445, I can access the ADAU1966 for minutes on end, looping, with no hangs. 

But... when I put some code in the IC2_LDD's ISR to disable the I2C peripheral on the error and step thru that, the K20 is holding SCL low, when I disable it SCL goes high.  So the ADAU1445 isn't holding it.

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Marc,

I checked with Kinetis I2C module test engineer, we do the I2C module test between two I2C modules, such as: I2C0 module as master and I2C1 module as slave. The I2C communication is inner Kinetis MCU.

We find that phenomena (after the ninth CLK cycle on SCL line, there without low to high to low toggle signal in SDA line) during our test.

Whatever I2C module test with interrupt mode or polling mode, when I2C0 as master, there with this phenomena; when I2C1 as master, there without this phenomena, the behavior is after the ninth CLK cycle on SCL line,there always with low to high to low toggle signal in SDA line ).

The I2C communication baud rate only affect the that toggle signal width, higher baud rate with wider toggle signal (only for I2C1 module as master).

While, we found that toggle signals is continuous appears or continuous disappear during I2C test.

Whatever, we could get I2C test pass (get correct data transmit) with this toggle signal or without this toggle signal.

I also check the I2C specification, there with no requirement about this toggle signal during I2C communication.

Please check below picture:

About I2C communication problem with ADAU1445 chip, if there with EMI noise on SCL link, which cause the I2C communication fail?

Thank you for the attention.

I2C.jpg

0 Kudos

2,055 Views
bowerymarc
Contributor V

Hi Hui Ma,

Aha, so your test is missing having some external i2c wiring. 

In any case the blip you see is normal I believe.  After the ACK, when the clock goes low again the slave should release SDA, and the master(s) need to wait for this to go high to start another cycle (arbitration).

I wonder how long you ran the test.  You should be able to run it for 15 minutes or so with constant transfers.  Should be way more than 65KB transferred (more like 4.5MB),  as sometimes I could go for minutes before getting the syndrome described.

You can get an idea from my scope shot above what the noise is like on the line.  There's about 3 inches of trace on the board, and  2.0KΩ pullups. But unless the noise is causing the K20 to latch up or something, I don't see how it's causing my issue.  It's a possibility - is the K20 sensitive to undershoot/overshoot?  Could that cause something to happen internally?  What is clearly happening is the K20 I2C peripheral is failing to emit the 9th clock pulse, but it's state machine thinks it did and misinterprets a high SDA as a NACK.  I set a breakpoint in IC2_LDD's NACK event and trigger the logic analyzer on a low-SCL timeout, and they trigger consistently on the same event.

Also, in I2C_LDD's ISR, in the branch that first catches the NACK, I put some code in there to disable the I2C peripheral (      I2C_PDD_EnableDevice(I2C0_BASE_PTR, PDD_DISABLE); ) and re-enable.  Set a breakpoint there and stepped thru it, and when I disable the I2C peripheral, SCL goes high, indicating that the K20 is holding it low.

I also tried messing with some of the PORT controls:  passive filter, digital filter, slew rate, drive strength.  None seem to make a huge difference.

Currently I'm working on a bit-banged I2C master implementation (using Erich Steygers's code with some mods) as a basis of comparison, I'll let you know how that goes.

Thanks for keeping on this.

Best,

Marc

0 Kudos

2,055 Views
bowerymarc
Contributor V

finished testing with bit-banging driver, and i'm able to do >4.5M transfers without any hanging.  The code does detect various things like the slave NACKing 1st or 2nd byte of a written register address (as part of a register read), and code to do a 'walking SCL's followed by STOP' bus recovery (can't really call it a reset).  But all things that should be possible with the I2C peripheral in the chip.  More evidence that the onboard peripheral thinks it's sending 9 clocks when externally only 8 are issued.

Hui Ma, did you extend your test from 65K transfers up past 1M?

thanks again,
Marc

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Marc,

We find some updated info about this issue. When the I2C module 0 with slow baud rate (20Kbps), the SDA arbitration signal appears. So far, we are checking with this issue. When there with any updated info, we will let you know. Thank you for the patience.

B.R.

Ma Hui

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Marc,

So far, we find the root cause I2C module 0 without that SDA arbitration signal. For we enable the both I2C module 0 & 1 with same interrupt priority and I2C0 as master and I2C1 as slave.

When interrupt happens, the I2C module 0 interrupt service routine will execute firstly, then following with I2C module 1 interrupt service routine. During the I2C1 interrupt service routine execute, I2C module 0 as master will start to send next data, at this point the I2C1 as slave doesn't release I2C bus, I2C0 as master could not get the bus control right to pull up SDA line. That's why we could not see that arbitration signal during I2C0 as master.

After that, we use two board and one as master and another one as slave. Whatever I2C0 and I2C1 as master, we could see that arbitration signal.

Accordingly, we think the external I2C slave device hold the SDA line without release in time, that cause the arbitration signal disappear.

We also think the I2C master side software doesn't affect this behavior.

For you have tried two I2C devices, one works, the other not. Could you check ADAU1445 specification, if it with same I2C timing characters with ADAU1966.

And you could add delay during I2C master each byte transfer.

Wish it helps.

B.R.

Ma Hui

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Marc,

We do a 4MB I2C communication test today, and the result is also passed.

The test is based on one Kinetis chip with two I2C modules, the external I2C pins are connected, not inner chip.

We test interrupt mode and polling mode,both are working normally.

We are consider if the software code cause that issue.

If you could try with attached I2C module example code and do related test again.

Wish it helps.

BTW: The I2C code is abstracted from Kinetis 120MHz product example code below:

KINETIS_120MHZ_SC  : Kinetis 120MHz bare metal sample code.

K70_120: Kinetis K70 Graphic LCD 120/150 MHz MCUs

B.R.

Ma Hui

0 Kudos

2,055 Views
bowerymarc
Contributor V

Hi Hui Ma,

Still trying to compile... I downloaded the KINETIS_120MHZ_SC package and unzipped it into my workspace per instructions, but got a linker error.... before modifying any code I tried compiling k60-hello-world and the files all compile but then:

mingw32-make: *** [k60-hello-world.afx] Error -1073741811

and I get a microsoft 'MW ARM Linker has encountered a problem and needs to close.  We are sorry for the inconvenience.' box...

so I haven't gotten to actually running your code today :smileysad: 

0 Kudos

2,055 Views
bowerymarc
Contributor V

Hi Hui Ma,

Thanks I will try this code out today!

Best,

Marc

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Marc,

Thank you for the info.

I am checking with I2C module test engineer.

I will let you know when there with any updated info.

Thank you for the patience.

B.R.

Ma Hui

0 Kudos

2,055 Views
bowerymarc
Contributor V

The i2c bus is physically probably 4" with 2kΩ pullups to +3.3V.  Two devices on the bus, an ADAU1966 and ADAU1445.  I'm writing to the ADAU1445.  It's about 13KB of data in an array.  The part supports burst mode, where you write the 'register address' (looks like first 2 data words to i2c) then as many bytes as you want.  Here's the code for writing a block (note, it depends on Erich Styger's 'generic I2C' Processor Expert module):

void SIGMA_WRITE_REGISTER_BLOCK( byte devAddress, int address, int length, ADI_REG_TYPE* pData )

{

  word addrBuf = address;

  byte ret = ERR_OK;

/*

  while( length > WRITE_SIZE )

  {

  ret = I2Cbus_WriteAddress(ADAU1445_BASE_ADDR + devAddress, &addrBuf, sizeof(addrBuf), pData, WRITE_SIZE);

  Sigma_ErrCheck( ret, "SIGMA_WRITE_REGISTER_BLOCK (big)");

  addrBuf += WRITE_SIZE;

  pData += WRITE_SIZE;

  length -= WRITE_SIZE;

  FRTOS1_vTaskDelay(1/portTICK_RATE_MS);

  }

  if( length > 0)

  {

  ret = I2Cbus_WriteAddress(ADAU1445_BASE_ADDR + devAddress, &addrBuf, sizeof(addrBuf), pData, length);

  Sigma_ErrCheck( ret, "SIGMA_WRITE_REGISTER_BLOCK");

  }

*/

  if (I2Cbus_SelectSlave(ADAU1445_BASE_ADDR + devAddress) != ERR_OK)

  {

  ret = ERR_FAILED;

  }

else

  {

  ret = I2Cbus_WriteBlock(&addrBuf, sizeof(addrBuf), I2Cbus_DO_NOT_SEND_STOP);

  if( ret == ERR_OK)

  ret = I2Cbus_WriteBlock(pData, length, I2Cbus_SEND_STOP);

  }

  if (I2Cbus_UnselectSlave() != ERR_OK)

  {

  ret = ERR_FAILED;

  }

  Sigma_ErrCheck( ret, "SIGMA_WRITE_REGISTER_BLOCK");

}

(notes: Sigma_ErrCheck() simply prints out an error message if ret != ERR_OK.  You can see a previous version of the function commented out above the current version)

And here's a scope capture of a typical transaction (same part - note, this is not the same transaction as captured by the logic analyzer above, actually it's the beginning of that transaction)

IMG_2706.JPG.jpg

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Thank you, Harper.

Please check Harper provides link and if set I2C_LDD Presc.Value to 1 could fix this problem or not? For KL25 is using the same I2C module with K20.

Wish it helps.

0 Kudos

2,055 Views
bowerymarc
Contributor V

Another thought about the clock divider... it could either be an issue with the divider chain itself, or a minimum frequency the i2c module needs to operate.  Since I'm running the K20F120 at 120MHz, my clock options are 60, 30, 15MHz for the i2c module.... perhaps any of those is above the minimum frequency.

Another question for you Hui_Ma: do the GPIO settings on the pin have any effect when you're using i2c?  For instance, the analog glitch filter, digital glitch filter, slew rate, drive controls, etc.??

Thanks,

M

0 Kudos

2,055 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Marc,

I am checking this issue. Please be patience when I could get some updated info.

B.R.

Ma Hui

0 Kudos