Double Buffered I2C Difficulties (eg. KL27)

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

Double Buffered I2C Difficulties (eg. KL27)

5,557 Views
mjbcswitzerland
Specialist V

Hi All

Although the migration guide for moving from the KL25 to the KL27 [http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4997.pdf ] states that the fact that the KL27 has double-buffered I2C has no impact on the software it has been known for some time that KL25 (or other KL or K parts) I2C code will not run correctly on a KL27.

Furthermore, the recommended software flow diagram for the KL27 in its user's manual is rather different from that in the KL25 user's manual.

So finally this source or difficulties was analysed in some detail by testing an I2C master/slave configuration involving a KL25 (standard single-buffered I2C which causes no troubles) and a KL27 (with the new double-buffered design).

Tests were alternated between the KL25 being master to the KL27 slave and the KL27 being master to the KL27. The behavour (interrupt and status register reactions) were compared and workarounds made in the KL27 software until operation was correct for all tests in both configurations.

The attached drawings show the results, indicating the differences (some minor and having no software impact) and others requiring extra interrupt handling to avoid the original driver either hanging in interrupt loops (on KL27) or the (KL27) I2C master sending rubbish when it should send the slave address.

For simplicity, the double-buffered capabilities (queuing two bytes) is not utilised so that the reasons for incompatibility with standard KL I2C drivers is obvious.

Note the worst behaviour found (detailed also in the drawings) was that it is not possible to send a "repeated start condition" by writing the repeated start control and sending the slave address (as the KL25 does) because the KL27 will then send the repeated start but with a slave address equal to the last data byte that it had sent. The only way to do this that could be identified was to command the repeated start, wait for it to actually have completed on the bus (using the KL27's new start condition interrupt) and then sending the required address.

If any one has comments (or personal experience) I would be interested in hearing them.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html

KL25: http://www.utasker.com/kinetis/FRDM-KL25Z.html / http://www.utasker.com/kinetis/TWR-KL25Z48M.html

KL27: http://www.utasker.com/kinetis/FRDM-KL27Z.html / http://www.utasker.com/kinetis/Capuccino-KL27/Capuccino-KL27.html

For the complete "out-of-the-box" Kinetis experience and faster time to market

:smileyinfo: Out-of-the-box support for 46 Kinetis boards and 10 IDEs (460 combinations from a single code source with no porting required)

Labels (1)
26 Replies

2,684 Views
Xlerb
Contributor II

Hi Mark,

Digital scope used for measurements and no clock stretching.

I've tried several settings and the KL17 IIC bit rate is always slower than it should be.

By comparison the K10 IIC rate comes out exactly as it should.

Can anyone else verify this?

I also note that the KL ref manual says that the "SCL divider value may

vary by ±2 or ±4" for the lowest 16 ICR settings and refers one to the chip specific data.

Alas it doesn't seem to be mentioned in the data sheet.

Anyone from NXP listening?

Regards,

Martin.

0 Kudos

2,684 Views
bobpaddock
Senior Contributor III

>I've tried several settings and the KL17 IIC bit rate is always slower than it should be.

I noticed it was different than I expected, did not record by how much.

> Anyone from NXP listening?

No.  Mark and I started this discussion last fall.
Thought the official channels of Distribute to Factor and back etc.The response was "The code generated by KSDK works."

The reason that code works is because it inserts a software busy loop after the Repeated Start bug to wait for the hardware race condition(s) to be over.  It also inserts busy loops that completely negates any value in double buffering.

These double buffered parts are seriously broken and Freescale/NXP refuses to acknowledge it with an Errata or data sheet update, to leave person after person to stumble in to the problem as these threads show.

I'm not really inclined to design in any Kinetis parts in the future after this experience.

0 Kudos

2,684 Views
mjbcswitzerland
Specialist V

Bob

The migration guide (AN4997) has indeed been updated to include double-buffered I2C requirements - Rev. 1 from 4/2016.

The change is:

First Revision:

5.9.1 Software impact

There is no software impact when using the updated I2C module.

Rev. 1:

5.9.1 Software impact

There is a significant software impact due to the double-buffering feature. Look at the double-buffering

mode section and the flowchart related to the I2C interrupt routine at the end of the I2C module section in

the corresponding MCU reference manual.

Consider these notes:

• Check the EMPTY status flag before writing to the I2C_D register and wait for the EMPTY flag

to write the second value to the I2C_D immediately after the first write (to apply the

double-buffering feature).

• The master must send the NACK before the repeat start in the buffering mode.

• The I2C module on the KLx6/KL34 MCUs must wait for the I2C_D register to be read to start the

next transaction. With the KL43/KL33/KL27/KL17 I2C module in the buffer mode, the TCF is

cleared automatically by the internal reading or writing into the I2C_D data register. You don’t

have to wait to read from/write to the I2C data register manually in the Rx/Tx mode.

• A delay is required during the repeated start sequence due to the EMPTY flag. Send the repeat start,

apply a small delay (depends on the I2C clock selection) before waiting for the EMPTY flag, and

then write to the I2C_D register.

Although I am not sure about the workaround - the proven uTasker implementation solves it without adding any delays and also manages to send the NACK after the repeated start has been sent - it is clear that it has become known that it is not compatible as was initially believed/assumed.

The KL17 and KL27 erratas haven't been updated since April. 2015 but I have received some information about new I2C related erratas that may be included in subsequent versions, even if they don't directly relate to the actual topic in hand. I don't know whether the descriptions and workarounds will remain like this in the official version but the following may be of interest to users where the mentioned features could be of importance. Since these are presently unofficial I don't accept any responsibility for accuracy but recommend any affected users directly contact the manufacturer for latest information when starting their project.

"

Title:

I2C: Slave does not hold bus between byte transfers and may result in lost data

Errata Description:

When the I2C module is used as a slave device, the bus is not held by the slave between byte transfers. If the I2C slave I2C_D register and the data buffer are full, incoming data from an I2C master will overwrite data in the data buffer.

Errata Workaround:

When configured as a slave, the delay in processing incoming bytes should be minimized. Delay can be minimized by the use of DMA or increased interrupt priority.

Title:

I2C: Address match wake-up from low-power mode cannot receive data

Errata Description:

When the device is in a low-power mode that supports address match wake-up, receiving a matching address will wake up the MCU, however, the I2C will not respond correctly. I2C traffic after the wake-up address will not generate TCF interrupt events.

Errata Workaround:

Either one of the following sequences will enable the address match wake-up to operate correctly:

1) Send only the matching slave address followed by a repeated start and then resend the matching slave address including any subsequent data.

2) Send only the matching slave address followed by a stop condition and then resend the matching slave address including any subsequent data.

"

Regards

Mark

0 Kudos

2,684 Views
bobpaddock
Senior Contributor III

Good that they are making an attempt.

Problem with putting it in the migration guide is if it is a new design it is not likely to be looked at, as there is nothing being migrated.

"The master must send the NACK before the repeat start in the buffering mode."

Seems like a violation of the NXP I2C specifications?:
http://www.nxp.com/documents/user_manual/UM10204.pdf

Sections 3.1.3 -> 3.1.6

Now when get we get parts that actually work?

Not really expecting to see them before I retire in a decade or three.


The KL28 has quad buffering and a completely different system.

Can't help wonder if is broken more, or broken less than this family.

0 Kudos

2,684 Views
mjbcswitzerland
Specialist V

2,687 Views
Xlerb
Contributor II

Hi Mark,

Many thanks!

I've just spent a day trying to figure why our K10 I2C code doesn't work on KL17. It's the repeated start issue.

BTW - I'm finding that the I2C bit rates don't agree with the calculated. Has anyone else noticed this?

eg I2C->F = 0x1b with 16MHz clock gives me 117.65kbps. Ref manual (rev 5, Jan 2016) says /128 so should be 125kbps.

Regards,

Martin.

0 Kudos

2,684 Views
mjbcswitzerland
Specialist V

Martin

Your vaues look quite close so it may depend on how you are measuring - eg. there may be some clock-stretching going on in the slave's ack.

Regards

Mark

0 Kudos

2,690 Views
saul_2510
Contributor I

Hi Mark!

I'm having the same problem with the KL03Z if you have a solution please let me know! I have wasted so much time with this!

0 Kudos

2,690 Views
mjbcswitzerland
Specialist V

Hi

I have attached the uTasker I2C driver as reference (supports master or slave, and single or doubled buffered devices).

It has been used successfully in industrial and consumer products based on KL parts with double-buffering and intensive use of repeated starts etc. (eg. communication with I2C based processor, touch screen controller polling and various monitoring devices at the same time) so solves all known issues with the newer I2C controller.

This is available integrated into the uTasker project and simulated in its KL simulator so generally allows any project to be developed faster and more reliably than traditional download/debug cycling (as well as giving an immediate solution to the I2C issues).

Regards

Mark

http://www.utasker.com/kinetis/FRDM-KL03Z.html

0 Kudos

2,690 Views
bobpaddock
Senior Contributor III

You are a good Mind Reader.  :-)

I just got back to beating on this problem last week.

However the link you posted does not seem to be the correct one.

Nor did I see any mention of I2C issues at:
µTasker FRDM-KL43Z support

0 Kudos

2,690 Views
mjbcswitzerland
Specialist V

Hi

I linked to the KL03 board, which the last question was about. Go one level up to find all supported boards.

There is no mention of I2C problems at the KL43 link since there are none known (same fix for all double-buffered parts).

Regards

Mark

0 Kudos

2,690 Views
bobpaddock
Senior Contributor III

Form software as not showing any attachment until I expanded the thread completely.

I really hate this form software. :-(

0 Kudos

2,690 Views
bobpaddock
Senior Contributor III

Mark Butcher wrote:

Note the worst behaviour found (detailed also in the drawings) was that it is not possible to send a "repeated start condition" by writing the repeated start control and sending the slave address (as the KL25 does) because the KL27 will then send the repeated start but with a slave address equal to the last data byte that it had sent. The only way to do this that could be identified was to command the repeated start, wait for it to actually have completed on the bus (using the KL27's new start condition interrupt) and then sending the required address.

Sadly I had to waste far to much time discovering that for my self a few weeks ago.  Makes me lose faith that Freescale actually tests parts before inflicting them on us.

It is not that Repeated Start is an uncommon thing to do on I2C.  Their own Accelerometers actually require Repeated Start and they don't like having stuttering bytes on the bus. :-(

Do hope Freescale issues a proper errata to save future people from such a waste of time.

Thank You for the detailed report.

0 Kudos

2,690 Views
mjbcswitzerland
Specialist V

Hi Bob

Thank you for the feedback - if I understand correctly you confirm the repeated start behavior - did you solve it the same way as I or did you find another solution?

As reference, there is another report of difficulties that I made (at the time I decided to avoid I2C in the new devices so it is only now that I finally had no choice but to get to the bottom of it). KL43 I2C problem Here there is a confirmation of a difficulty when debugging where the master will send infinite clocks - for the attached investigation I didn't use the debugger but instead a logic analyser with the driver setting codes on some ports to see register vaues and interrupt timings.

I have received information of a new errata being prepared for the KL17/KL27 but there is no reference to these items as far as I can see:

"I2C: Slave does not hold bus between byte transfers and may result in lost data"

"I2C: Address match wake-up from low-power mode cannot receive data"

The first one points out that some of the slave's bus holding characteristics are not operational and so software should be as fast as possible to avoid underruns (I could imagine some relation to the infinite clocks at the master) or use DMA (although DMA at a slave is often not possible because many slave devices need to process each byte received in order to decide what to do next).

But it also concerns me that "practically" it hasn't been possible to use the master mode with repeated starts without workarounds since its behavior is otherwise incorrect, but there is no confirmation of such difficulties from the manufacturer. It surpises me that the migration guide states that there is no software impact although "practically" drivers working normally on other parts fail (even catastrophically). That is also why I prefer to make reports so that information is available and can be compared with other users' experiences - either to identify what "we" are doing wrong in the process and correct it the right way or to identify perhaps why the issues are not identified by the manuafacturer's own testing.

Regards

Mark

0 Kudos

2,690 Views
bobpaddock
Senior Contributor III

Attached is code that implements  AN4342 and "Typical I2C Interrupt Routine" in KL27 Reference Manual,

for the Master only. Has the various bug fixes to work around the broken hardware.

It is so full of busy loops that one might as well just do a bit banger in software.
Yes, a RTOS or State Machine would help, it would also most likely slow things down from the context switching.


/** @(#)ai2c.c             <07-Jul-2016 14:14:15 Bob Paddock>

*

*  \file ai2c.c

*  \brief  i2c for MKL27, intended for use with Freescale/NXP Accelerometer.

*

*      Purpose:        General I2C handler, created using the flowchart example

*                      included in the I2C chapter of the User Manual.

*                      Only Master is implemented as we are never a slave.

*  See AN4342 and "Typical I2C Interrupt Routine" in KL27 Reference Manual.

*

* Use at own risk the underlying hardware of the KL43/KL27 I2C Double

* Buffered hardware is broken.

*/

0 Kudos

2,690 Views
bobpaddock
Senior Contributor III

Mark Butcher wrote:

Hi Bob

Thank you for the feedback - if I understand correctly you confirm the repeated start behavior - did you solve it the same way as I or did you find another solution?

As reference, there is another report of difficulties that I made (at the time I decided to avoid I2C in the new devices so it is only now that I finally had no choice but to get to the bottom of it). KL43 I2C problem Here there is a confirmation of a difficulty when debugging where the master will send infinite clocks - for the attached investigation I didn't use the debugger but instead a logic analyser with the driver setting codes on some ports to see register vaues and interrupt timings.

I have received information of a new errata being prepared for the KL17/KL27 but there is no reference to these items as far as I can see:

"I2C: Slave does not hold bus between byte transfers and may result in lost data"

"I2C: Address match wake-up from low-power mode cannot receive data"

The first one points out that some of the slave's bus holding characteristics are not operational and so software should be as fast as possible to avoid underruns (I could imagine some relation to the infinite clocks at the master) or use DMA (although DMA at a slave is often not possible because many slave devices need to process each byte received in order to decide what to do next).

But it also concerns me that "practically" it hasn't been possible to use the master mode with repeated starts without workarounds since its behavior is otherwise incorrect, but there is no confirmation of such difficulties from the manufacturer. It surpises me that the migration guide states that there is no software impact although "practically" drivers working normally on other parts fail (even catastrophically). That is also why I prefer to make reports so that information is available and can be compared with other users' experiences - either to identify what "we" are doing wrong in the process and correct it the right way or to identify perhaps why the issues are not identified by the manuafacturer's own testing.

Regards

Mark

Thank you for the feedback - if I understand correctly you confirm the repeated start behavior - did you solve it the same way as I or did you find another solution?

As reference, there is another report of difficulties that I made (at the time I decided to avoid I2C in the new devices so it is only now that I finally had no choice but to get to the bottom of it). KL43 I2C problem

Mark

After seeing what the I2C was doing on my bus analyzer I went looking to see if anyone else was having issues.  When I saw your KL43 report, the parent of the KL27, I gave up on the hardware and did a I2C Bit-Banger.  Not happy about the wasted time in the required busy loops now nor of the wasted time in the shipping schedule.

I believe I've run into two other issues with the KL27.  I just posted one about CLKOUT[Bus] not appearing to work correctly.  I'd appreciate your input in looking at my code to see if I'm missing something.

The other issue has to do with the KL27 bootloader when having NMI programmed to be the BOOT# pin.  I need to look at this closer before making a report.  What I'm seeing is that if I assert BOOT# and use blhost to flash the part all works as expected.  Now I raise BOOT# and assert the RESET# pin I expect my code to start running right away, it doesn't.  It still appears to enter the bootloader as tho a bit in the part got latched keeping it thinking BOOT# is still asserted.  Only way to get my code to run immediately is to cycle power, which clears the effect of having had BOOT# asserted, which will be unacceptable in my final product.  Have you run into anything like this?

0 Kudos

2,690 Views
mjbcswitzerland
Specialist V

Hello Bob

Strangely I only just noticed this response/question.

I have however already commented on the CLKOUT (as you know).

I have avoided the new internal loaders (disabling it so that it can't impact). Unless one is using the smallest chip where there wouldn't be enough space to keep a boot loader I don't consider the internal ones as beneficial:

- a bed of nails in production to the SWD and a good programming software is more practical

- in the field USB-MSD is 'by-far' the best updating method (rather than the USB-HID that the internal loader uses)

Regards

Mark

0 Kudos

2,690 Views
bobpaddock
Senior Contributor III

I have avoided the new internal loaders (disabling it so that it can't impact). Unless one is using the smallest chip where there wouldn't be enough space to keep a boot loader I don't consider the internal ones as beneficial:

- a bed of nails in production to the SWD and a good programming software is more practical

- in the field USB-MSD is 'by-far' the best updating method (rather than the USB-HID that the internal loader uses)

We differ there.  Been using the bed of nails or getting the chips programmed by distributor in other products

May be a difference in quantity?

In some product lines we are doing 80,000 units per year.
Any built in bootloader is a benefit to us even if it is to just load our own bootloader.

Do you know of any KL43/KL27 Bare Metal USB-MSD bootloaders?

As to my original question:

In "6.3.3 Boot sequence" of the KL27RM it says that if BOOTPIN_OPT=0 then boot from ROM is forced.
To me that says that if BOOTCFG0 (NMI)# is not asserted then my code in flash will run. 

Sadly that is not always the case.

With FOPT set thus:

[I'll also be really ticked if the forum software once again hoses my code. :-(]

    /*

     * FOPT:

     *    7:BOOTSRC_SEL1                           0x80U

     *    6:BOOTSRC_SEL0                           0x40U

     *    00 = Flash, 01 = Reserved, 10/11 = ROM

     *

     *    5:NV_FOPT_FAST_INIT_MASK                 0x20U

     *    1 = Fast

     *

     *    4:NV_FOPT_LPBOOT1_MASK                   0x10U

     *      See bit zero

     *

     *    3:NV_FOPT_RESET_PIN_CFG_MASK             0x08U

     *    0 = Disabled Reset.

     *

     *    2:V_FOPT_NMI_DIS_MASK                    0x04U

     *    0 = Disable NMI

     *

     *    1:BOOTPIN_OPT                            0x02U

     *    0 = Force boot from ROM if BOOTCFG0 asserted.

     *

     *    0:NV_FOPT_LPBOOT0_MASK                   0x01u

     *    00 /8 VLPR on exit reset

     *    01 /4 VLPR on exit reset

     *    10 /2 RUN on exit

     *    11 /1 RUN on exit

     *

     */

    0x38U,      /**< Non-volatile Flash Option Register, offset: 0xD NV_FOPT Disable NMI pin.  Boot from Flash not ROM */

At each reset the part still goes into the ROM bootloader after bootloading and after BOOTCFG0# has been set high before reseting.

I expect the part to just jump to my code when BOOTCFG0# is high at *ANY* reset.

What have I missed?

I added this to my vectors.c to get it to work after the initial reset after boot.

Still have to endure the five second wait after the software update. :-(

  /*

   * Indicates the boot source, the boot source remains set until the

   * next System Reset or software can write logic one to clear the

   * corresponding mode bit.  While either bit is set, the NMI input

   * is disabled and the vector table is relocated to the ROM base

   * address at 0x1C00_0000. These bits should be cleared by writing

   * logic one before executing any code from either Flash or SRAM.

   */

  if( 0U != (RCM_MR & RCM_FM_FORCEROM_MASK) )

    {

      RCM_FM = 0U;

      RCM_MR = RCM_MR_BOOTROM_MASK;

    }

To me it really seems like the chip did not read the documentation...

0 Kudos

2,690 Views
mjbcswitzerland
Specialist V

Hi Bob

I would also accept using the internal loader to load a more suitable loader for field usage when it proved a suitable/practical method, whereby it is also possible to then disable the loader in case it causes any probems (such as start-up delays).

Note that Freescale has some errate for the ROM loaders so, since the loader code is just a loader software burned ito ROM, I expect that it will develop with time (as comparison, NXP's internal serial loaders in their LPC2xxx family originally had quite nasty bugs but fortunately they had a method which allowed updating them in the field too). If you think that the loader has a bug it is best to enter a service request (this can be done from your account at freescale.com).

USB-MSD Loaders:

I am always confused when the term Bare-Metal is used to specify a SW's requirement but if it means that interrupts and DMA are still allowed to be used and modular code written then I have such for KL27 and KL43 at the links here (Windows 8.1 and MAC OS X conform):

KL27: http://www.utasker.com/kinetis/FRDM-KL27Z.html / http://www.utasker.com/kinetis/Capuccino-KL27/Capuccino-KL27.html

KL43: http://www.utasker.com/kinetis/FRDM-KL43Z.html / http://www.utasker.com/kinetis/TWR-KL43Z48M.html

They build with KDS, CW, IAR, Keil, Crossworks, Greenhill, Atollic, CooCox, VisualStudio or a GCC make file.

Regards

Mark

P.S. Unfortunately the forums handling of posted code is not at all good - it works only when there are no comments in the code (because it confuses the white space between code and comments as table entries).
I have resorted to posting code as html by placing it in a <pre></pre> area. The problem with this is that it will all be on a single line so then add <br> to each line ending too. As long as the code is not too long it is worth the effort to avoid it looking like garbled junk when trying to show someone snippets and such, without having to resort to attaching it (which no one will probably ever look at).

0 Kudos

2,690 Views
bobpaddock
Senior Contributor III

...

Note that Freescale has some errate for the ROM loaders...

USB-MSD Loaders:

I am always confused when the term Bare-Metal is used to specify a SW's requirement...

... attaching it (which no one will probably ever look at).

I'll track down the erratas.

'Bare-Metal' to me is no CW/KDS/Funny magical black boxes/no vendor supplied stacks (usually do to much, frequently buggy and in Freescale case have code for processors long forgotten hanging around with to many #IF making it hard to do code inspections).

All of those things are great if you are in a hurry and care nothing about code quality (think DO-178C).

My stuff needs to be MISRA compliant and not cause Lint to freak out.  Rare to find that.

Exactly how do you attach something?

Using Chrome I'm not seeing a way to do it.

0 Kudos