I2C works in Debug with Multilink universal, not in standalone

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

I2C works in Debug with Multilink universal, not in standalone

Jump to solution
5,146 Views
samc
Contributor III

Hello,

I use the I2C bus of the MKL17Z256VFT4 at 400KHz. When I have the PE Multilink universal connected to the board it works perfectly, when I unplug the Mulitlink it always works but when I restart my board the I2C bus doesn't work. I know my program is running because I do a blink of a LED thanks to a PIT_Interrupt. I have 2 I2C slaves on the bus and no response of the both so I think it's from the MCU.

On BK000001.BMP it's I2C frame when it works and on BL00002.BMP when it doesn't work. This last appears just one time at the start-up of the MCU, after this the bus remains in Vcc State. I think the MCU try a first communication then abandons.

It seems the clock doesn't want to works, SDA fall to "0" but not the SCL.

Sam,

0 Kudos
Reply
1 Solution
4,368 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

    Thank for your good question, and sorry for the inconvenience we bring you!

    After debugging with JLINK tool, we have found the factor which have caused the LPUART can't receive the data, because the code enter FlexIO interrupt handler.

    So, now please disable the flexIO interrupt in your main code:

    NVIC_DisableIRQ(30);

  Please do it like this:

68.jpg

After the modification, then download the code to your KL17 chip, and try it again, you will receive the data with LPUART.

Any question you meet, please let me know!


Have a great day,
Jingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
Reply
33 Replies
3,161 Views
scottm
Senior Contributor II

I just ran into something not entirely unlike this when adding a bootloader - my project was proven code migrated from CW6 to CW10 with Processor Expert so everything got shuffled around.

What I discovered is that the linker file specified one entry point and the reset vector pointed to another.  Some of the startup code was being bypassed because the debugger apparently starts execution at the entry point as defined in the linker and not at the reset vector.  This had me cursing at the system for a good 20 minutes, trying to figure out why my UART was running at entirely the wrong speed.

Scott

0 Kudos
Reply
3,162 Views
samc
Contributor III

I think to find the problem. I did a test without bootloader at start and it seems to work...

EDIT :  I confirm the problem is when the MCU starts from bootloader!

With this it's OK :

/* Flash Configuration */

    .section .FlashConfig, "a"

    .long 0xFFFFFFFF

    .long 0xFFFFFFFF

    .long 0xFFFFFFFF

    .long 0xFFFF3FFE

With this it's KO :

/* Flash Configuration */

    .section .FlashConfig, "a"

    .long 0xFFFFFFFF

    .long 0xFFFFFFFF

    .long 0xFFFFFFFF

    .long 0xFFFFFFFE

Have I forget everything in the code to avoid this problem ?

So I absolutely need of the bootloader at start.

0 Kudos
Reply
3,162 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

OK, thank you for your more information.

The main difference is the boot source selection in the FOPT area, 0x40d is the FOPT register data, if you configure it as 0XF3, it means, boot from flash. if you configure FOPT to 11, it means boot from ROOM.

  So, you can modify your application code, and let it run from the flash.


Have a great day,
Jingjign

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
3,162 Views
samc
Contributor III

Hi,

Yes I know I did the test with boot from flash and boot from ROM. The problems on the I2C disappears when I boot from flash but it's not possible for me, I need to boot from ROM to enter Bootloader at startup.

0 Kudos
Reply
3,162 Views
kerryzhou
NXP TechSupport
NXP TechSupport

What the I2C pin you are using?

The same pin withROM bootloader I2C?


Have a great day,
Jingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
3,162 Views
samc
Contributor III

It's not the same pin as the ROM Bootloader :

- ROM BOOTLOADER  :

     - I2C0_SDA : Pin 28 (PTB1)

     - I2C0_SCL : Pin 27 (PTB0)

- My board :

     - I2C0_SDA : Pin 5 (PTE18)

     - I2C0_SCL : Pin 6 (PTE19)

I just succed to work the I2C bus with the bootloader, when I deactivate the I2C in the BCA it works well.

I'm surprised to observed this behaviour, the bootloader have to free the I2C bus after bootloading ? no ?

0 Kudos
Reply
3,162 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

  Actually it is the same I2C module.

    Even you want to use the ROM bootloader, you still can configure the FOPT select the code run from Flash.

    When you want to run the ROM bootloader, you just need to assert NMI/BOOTCFG0 pin, from the reference manual:

The following conditions will force the hardware to start the Kinetis Bootloader:

• BOOTSRC_SEL field of FOPT register is set to either 0b11 or 0b10. This forces the

ROM to run out of reset.

The BOOTCFG0 pin is asserted. The pin must be configured as BOOTCFG0 by

setting the BOOTPIN_OPT bit of FOPT to 0.

• A user applications running on flash or RAM calls into the Kinetis Bootloader entry

point address in ROM, to start Kinetis Bootloader execution.

  So you can choose the NMI pin as the ROM bootloader enter pin, then you still can run the code from flash.

  You can try it on your side.


Have a great day,
Jingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
3,162 Views
samc
Contributor III

Hello,

I know these informations, so for the moment I just boot from ROM Bootloader and I observe when the I2C peripheral is activated in the Bootloader it doesn't work correctly when switching to user application, I don't know why. This seems not be normal for me.

0 Kudos
Reply
3,162 Views
kerryzhou
NXP TechSupport
NXP TechSupport

I will check it on my side with ROM bootloader.

Now confirm the question again, just the I2C0 in the app can't work after the ROM bootloader downloading the application code?

Other function in the app code still works ok?

Best Regards,

Jingjing

0 Kudos
Reply
3,162 Views
samc
Contributor III

No problem with other peripheral. For exmaple, I leave the LPUART0 and SPI activated in the ROM bootloader and the two works correctly in my application (I only use LPUART0 to use the bootloader). The SPI works correctly with a flash, no problem with ADC, clockmanager OK, PIT Timer OK

0 Kudos
Reply
3,162 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

I have test it on our FRDM-KL27 board, the chip is MKL27Z64VLH4, this chip has no PTE18,PTE19, so I use PTB0,PTB1 as the I2C0 pin.

My test code is the KSDK2.0_FRDM-KL27, after I use the UART ROM bootloader, my I2C0 still works ok on my side.

I don't know how did you initialize your I2C0 in your application code.

Please disable the I2C0 module at first, then enable it again, this is the I2C initialization code for your reference:

void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)

{

    assert(masterConfig && srcClock_Hz);

    /* Temporary register for filter read. */

    uint8_t fltReg;

#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION

    uint8_t c2Reg;

#endif

    /* Enable I2C clock. */

    CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);

    /* Disable I2C prior to configuring it. */

    base->C1 &= ~(I2C_C1_IICEN_MASK);

    /* Clear all flags. */

    I2C_MasterClearStatusFlags(base, kClearFlags);

    /* Configure baud rate. */

    I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz);

#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION

    /* Configure high drive feature. */

    c2Reg = base->C2;

    c2Reg &= ~(I2C_C2_HDRS_MASK);

    c2Reg |= I2C_C2_HDRS(masterConfig->enableHighDrive);

    base->C2 = c2Reg;

#endif

    /* Read out the FLT register. */

    fltReg = base->FLT;

#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF

    /* Configure the stop / hold enable. */

    fltReg &= ~(I2C_FLT_SHEN_MASK);

    fltReg |= I2C_FLT_SHEN(masterConfig->enableStopHold);

#endif

    /* Configure the glitch filter value. */

    fltReg &= ~(I2C_FLT_FLT_MASK);

    fltReg |= I2C_FLT_FLT(masterConfig->glitchFilterWidth);

    /* Write the register value back to the filter register. */

    base->FLT = fltReg;

    /* Enable the I2C peripheral based on the configuration. */

    base->C1 = I2C_C1_IICEN(masterConfig->enableMaster);

}

Please disable I2C prior to configure it, and try again on you side.

If you still have question, please let me know!


Have a great day,
Jingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
3,162 Views
samc
Contributor III

Hello,

The I2C is initialized automatically becaus eI use Processor Expert, so  the function i2c_status_t I2C_DRV_MasterInit(uint32_t instance, i2c_master_state_t * master) is called automatically in CPU.c.

However PE doesn't generate the same code as you, in the func tion I Have:

i2c_status_t I2C_DRV_MasterInit(uint32_t instance, i2c_master_state_t * master)

{

    assert(master);

    assert(instance < I2C_INSTANCE_COUNT);

    I2C_Type * base = g_i2cBase[instance];

    /* Exit if current instance is already initialized */

    if (g_i2cStatePtr[instance])

    {

        return kStatus_I2C_Initialized;

    }

    /* Initialize driver instance struct */

    memset(master, 0, sizeof(i2c_master_state_t));

    /* Create sync object for transfer. */

    OSA_SemaCreate(&master->irqSync, 0);

    /* Enable clock for I2C.*/

    CLOCK_SYS_EnableI2cClock(instance);

    /* Initialize peripheral to known state.*/

    I2C_HAL_Init(base);

    /* Save runtime structure pointer */

    g_i2cStatePtr[instance] = master;

    /* Enable I2C interrupt in NVIC level.*/

    INT_SYS_EnableIRQ(g_i2cIrqId[instance]);

    /* Indicate I2C bus is idle. */

    master->i2cIdle = true;

    /* Enable module.*/

    I2C_HAL_Enable(base);

    return kStatus_I2C_Success;

}

But I have a news, today I develop the use of the LPUART in my application and I have the same problem! LPUART is the way I use to flash through bootloader then I can't deactivate it in BCA. The analysis is the same, in debug mode LPUART works correctly but in standalone nothing...it becomes urgent, the first version of my application I make today need the LPUART to work.

I just try to Deinit and Reinit the LPUART at startup of the application and the problem is the same.

0 Kudos
Reply
3,160 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

    When you run you code after the ROM bootloader, you need to wait about 5 seconds, then the application code can be run, did you wait over 5 seconds each time when you test it?

  Both  I2C0 and LPUART module I have test it on my side, it works ok, but when you configure run from the ROM, you need to wait 5 seconds, then the the application code can run, in the first 5 seconds, the mcu is waiting for the ROM bootloader commander, so please test it agian, wait over 5 seconds after power on or reset, and check you code function again.

Best Regards,

Jingjing

0 Kudos
Reply
3,161 Views
samc
Contributor III

Hi,

I tested in adding a while loop at first in the main function of my program, just before the PE function : PE_low_level_init();

It waits for 6-7 approximatively. It has no effect. I tested in configuring 6s in the BCA area for peripherel detection timeout. No effect.

But I don't understand this manipulation. Why wait for 5 s at the beginning of the application ? Normally at startup the MCU points to the ROM bootloader so the main function is executed only when boot from ROM is terminated, in other words bootloader and user app cannot run at the same time, so normaly no conflict and no need to wait for 5 s at user app startup ?

I did some other test with LPUART. When the MCU sends a periodic frame there is no problem but when I send a frame to the MCU, at this time it buggs, so apprently the problem is on MCU receiving. In more the MCU seems tu bug completely because I use a LED blinking thank to a PIT Timer and after I sended a frame, no more blinking stops. It's very strange it's only when the peripheral is activated in the BCA.... I join my memory area in the linker file and the BCA config, if you see an error here...

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00;

STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;

/* Specify the memory areas */

MEMORY {

  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000200

  m_flash_config        (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000010

  m_interrupts_ram      (RW)  : ORIGIN = 0x1FFFE000, LENGTH = 0x00000200

  m_text                (RX)  : ORIGIN = 0x00000410, LENGTH = 0x0003FBF0

  m_data                (RW)  : ORIGIN = 0x1FFFE200, LENGTH = 0x00007E00

  m_bca                 (RX)  : ORIGIN = 0x000003C0, LENGTH = 0x00000040

}

/* BCA Area */

    .section .bca, "a"

    .ascii "kcfg"         // [00:03] tag

    .long 0xFFFFFFFF     // [07:04] crcStartAddress

    .long 0xFFFFFFFF     // [0B:08] crcByteCount

    .long 0xFFFFFFFF     // [0F:0C] crcExpectedValue

    .byte 0x01             // [10] enabledPeripherals

    .byte 0xFF             // [11] i2cSlaveAddress

    .short 5000         // [13:12] peripheralDetectionTimeout (milliseconds)

    .short 0xFFFF         // [15:14] usbVid

    .short 0xFFFF         // [17:16] usbPid

    .long 0xFFFFFFFF    // [1B:18] usbStringsPointer

    .byte 0xFF             // [1C] clockFlags

    .byte 0xFF             // [1D] clockDivider

    .byte 0xFF             // [1E] bootFlags

    .byte 0xFF             // [1F] reserved*/

0 Kudos
Reply
3,161 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

   If run from the ROM, not the flash, from the  reference manual Figure 13-2.Kinetis Bootloader Start-up Flowchart, you may know the code will wait the timeout and jump to user application.  

    Now, Maybe you really need to give me your test project, then I can test it on my side, or you can configure PTA1, PTA2 as your uart test port, then give me you bin file, I can test it on my platform:FRDM-KL27.

    I use LPUART as the UART interface, and test it on my FRDM-KL27 board, use KSDK2.0-FRDM-KL27 helloworld as the application code(it use PTA1, PTA2 as the uart tranmit and receive pin), use KBOOT2.0 kinetisFlash Tool as the BCA configuration tool and the code downloading tool. I configure the BCA to enable all the peripheral, then modify the application bin file to enable it, and download it to the KL27, after download, the chip will be reset automatically, the LPUART will send the data: hello world, then if the mcu receive the char, it will send back with LPUART, the UART can receive data, the attachment is my test picture:

  " helloword" is printf after the app has been downloaded, "abcd" is the mcu received and send back to the PC.

   So, maybe you also can try the KDSK2.0 sample code on your side, otherwise, please send me your whole test project, you can zip it with password, then send me your password with the message.

Have a great day,
Jjingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
3,161 Views
samc
Contributor III

Hi,

I joined a project in a last reply above (30 june) you can check it.

I tested your I2C init but I have a lot of error at compilation....

I tried the KSDK 2.0.0 and it doesn't work with processor expert....I don't know what to do anymore...

EDIT: As the Tx works for the LPUART I compare the LPUART register value in debug mode and in standalone (I send BaudRate/Status/Control/Data and match Adress every second) and there is no difference. I retry, when I send a byte on the Rx, the MCU dosn't works.

I can't skip the I2C in bootloader but I really need the LPUART in my app to send data to my board.

I will try with I2C on my FRDM-KL43Z to see.

0 Kudos
Reply
3,161 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

    I have created a PE KDS project on my side, I reproduce your problem now.

   Please don't worry, I will go on to check the root problem, after I get the result, I will let your know.

  Now please wait patiently.

Jingjing

0 Kudos
Reply
3,161 Views
samc
Contributor III

Hi,

You said you have reproduced the problem on your side ?

In my side I tested with FRDM-KL43Z and it seems to work correctly....

0 Kudos
Reply
3,161 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Samuel,

    Yes, I also test it on the FRDM-KL43 board, and create a PE KDS KL17Z256VLH4 project, I have reproduced your LPUART receive problem after enable BCA LPUART .

    LPUART used pin is PTA1 and PTA2.

    Did your customer board KL17 also use PTA1 and PTA2?

    Now, I am checking it, whether it is just the PE project problem, and need to communicate with other colleagues about this question. If I have any progress, I will let you know as soon as possible.

   Please wait patiently.

   Thanks  a lot for your understanding.

Best Regards.

Jingjing

0 Kudos
Reply
3,161 Views
samc
Contributor III

Hi,

It's a great news you have reproduced the problem! At  moment I believed to become crazy...so now as you have the problem in your hands, you will can find a solution!

To reply to your question, yes my board uses PTA1 and PTA2.

For information I have 2 cases created with the support about bootloader:

- One for the subject of this topic, as you have reproduced the problem it can close I think.

- Another one with the call of ROM bootloader in my application with his AN  Call ROM Bootloader from customer application with FRDM-KL43Z board

In this one I explain that I'm able to call the ROM bootloader in my application and reprogram it with the Kinetis Upater, but just one time. After the first reprogramming, the program restarts correctly but when I call the Bootloader one more time, the Kinetis Updater is unable to reconnect to the bootloader.

I know each thing at each time, but I prefer to expose it as it's concern the bootloader, maybe there's a link with the problem you treat actually.

Thank you for your help!

0 Kudos
Reply