Page 1 of 1

L432KC i2cMasterTransmit freezes

Posted: Thu Jun 14, 2018 11:21 pm
by Raul
I'm having some hard time trying to run I2C transactions with a STM32L432KC, from the first call I do to i2cMasterTransmit the application seems to freeze, nothing seems to run at the thread level and there aren't any assertions have debug checks enabled.
Before I proceed I'd like to point out that I've been through the recommended troubleshooting guide and that I can run the same code with exactly the same I2C slave using a STM32L476RG instead with no issues at all.

Under Chibios 18.2.0, using I2C1, with no other peripherals enabled, these are the pertinent settings I have:

Code: Select all

/*
 * I2C driver system settings.
 */
#define STM32_I2C_USE_I2C1                  TRUE
#define STM32_I2C_USE_I2C3                  FALSE
#define STM32_I2C_BUSY_TIMEOUT              50
#define STM32_I2C_I2C1_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 7)
#define STM32_I2C_I2C1_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 6)
#define STM32_I2C_I2C3_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 3)
#define STM32_I2C_I2C3_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C1_IRQ_PRIORITY         5
#define STM32_I2C_I2C3_IRQ_PRIORITY         5
#define STM32_I2C_I2C1_DMA_PRIORITY         3
#define STM32_I2C_I2C3_DMA_PRIORITY         3
#define STM32_I2C_DMA_ERROR_HOOK(i2cp)      osalSysHalt("DMA failure")


I managed to take a capture with a logic analyzer, this is produced by calling i2cMasterTransmit with 1 byte tx buffer and 3 bytes for the rx.
The write and cmd byte make it through, with the expected SCL clock, but when it is time to perform the start condition belonging to the 3 byte read, SCL remains permanently low until an application reset.

i2c_capture.png
i2c_capture.png (6.48 KiB) Viewed 4910 times


Has anybody managed to run I2C transactions with a STM32L432KC?, I noticed there's support for a nucleo board based on that MCU.

Any suggestions regarding what I could do to debug this issue further will be appreciated.
I looked into i2c_lld_master_transmit_timeout and managed to trace the call down to I2Cv2/hal_i2c_lld.c:1139

Code: Select all

 
 /* Waits for the operation completion or a timeout.*/
  msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);


What I seem to gather there is because the timeout is INFINITE, this is deliberate, and the transaction never concludes threads don't run.

Thanks in advance,

Raul

Re: L432KC i2cMasterTransmit freezes

Posted: Fri Jun 15, 2018 7:43 am
by Giovanni
Hi,

Hard to tell, if the thread stays in that function means that I2C ISR is not invoked.

You should verify GPIO pins setup.

Giovanni

Re: L432KC i2cMasterTransmit freezes

Posted: Fri Jun 15, 2018 8:35 am
by alex31
Has anybody managed to run I2C transactions with a STM32L432KC?, I noticed there's support for a nucleo board based on that MCU.


Yes, i use stm32nucleol432 to drive i2c IMU (invensense 9250) without problem.

Do you use external pullup for scl/sda or do you rely on internal ones ?

are you sure of your timingr value ? (can be different on the two boards if the clock tree has not same configuration), cubemx helps to calculate timingr value.

Alexandre

Re: L432KC i2cMasterTransmit freezes

Posted: Fri Jun 15, 2018 2:55 pm
by Raul
Hi Giovanny, Alex,

Thanks for your observations.

Hard to tell, if the thread stays in that function means that I2C ISR is not invoked.


That's a interesting point, I guess it makes sense that the Start and read operations wouldn't occur if that was the case? How can I double check that the interrupts are enabled?
I believe the GPIO configuration is correct, alternate enabled, etc. I've compared the *conf.h with the ones for the nucleo L432 demo and the settings are pretty much identical (Use same clock arrangement).

Do you use external pullup for scl/sda or do you rely on internal ones ?


I've tried with both (no external when using the internal) and have the same results.

are you sure of your timingr value ? (can be different on the two boards if the clock tree has not same configuration), cubemx helps to calculate timingr value.


Yep, good point. I checked that originally with Cubemx tool (timing = 0x10909CEC assuming 0 for falling and raising times, added 1000 rasiing and 40 falling in case of internal resistors) I'd assume that the register is correct during initialization as I get the 100 KHz ok.

I have just ordered a stm32nucleol432, it is worth to test it against that as the results would be very conclusive. I'll update.

Raul

Re: L432KC i2cMasterTransmit freezes

Posted: Fri Jun 15, 2018 3:27 pm
by Polux
Hi,

I also used the Nucleo432, connected to 4 MCP23017 (I/O ports). I used external 2k2 resistors and connection was fairly easy.
But as I also used CAN, the STM32 is not running at full speed, due to timings problems when used with internal RC.

I will post the code when I go home.

Angelo

Re: L432KC i2cMasterTransmit freezes

Posted: Fri Jun 15, 2018 7:16 pm
by Raul
Hi Angelo,

But as I also used CAN, the STM32 is not running at full speed, due to timings problems when used with internal RC.


Could you elaborate on that? With not running at full speed do you mean the I2C (at 400 KHz)? I'm also intending to use CAN, disable at this stage, what are the incompatibilities between I2C and CAN?

Thanks,

Raul

Re: L432KC i2cMasterTransmit freezes

Posted: Wed Jul 04, 2018 9:28 pm
by Raul
Quick update, run it on the stm32nucleol432 I ordered and no problems at all with I2C.

Raul

Re: L432KC i2cMasterTransmit freezes

Posted: Thu Jul 05, 2018 7:36 am
by Polux
Hi Raul,

I had the same problem on both the nucleo446 and NucleoL432. CAN needs stable and precise clock, and internal RC set to run at full speed is not good enough to ensure these timings.
On STM32F446, using RC, I had to slow down to about 80MHz core frequency to have CAN correctly working. But as I didn't analyzed the low level communication, it is possible I still have transmission errors.
On STM32L432, I run it at about 48MHz to have CAN working.

To use core full speed and have CAN working, these boards should be fitted with an oscillator or a quartz,

Angelo

Re: L432KC i2cMasterTransmit freezes

Posted: Fri Jul 06, 2018 3:08 pm
by Raul
Hi Angelo,

Quick couple of questions, in your specific setup with your STM32L432 when you had to drop the system frequency sourced by the RC oscillator (MSI), did you also have the LSE enabled too? What frequency is your CAN bus running at?

I found the following from the documentation:

Code: Select all

 Multispeed internal RC oscillator (MSI), trimmable by software, able to generate 12 frequencies from 100 kHz to 48 MHz. When a 32.768 kHz clock source is available in the system (LSE), the MSI frequency can be automatically trimmed by hardware to reach better than ±0.25% accuracy. In this mode the MSI can feed the USB device, saving the need of an external high-speed crystal (HSE). The MSI can supply a PLL
 


I'd have thought that should be sufficient for CAN.

Raul

Re: L432KC i2cMasterTransmit freezes

Posted: Tue Sep 18, 2018 9:52 am
by BreederBai
Raul wrote:I'm having some hard time trying to run I2C transactions with a STM32L432KC, from the first call I do to i2cMasterTransmit the application seems to freeze, nothing seems to run at the thread level and there aren't any assertions have debug checks enabled.
Before I proceed I'd like to point out that I've been through the recommended troubleshooting guide and that I can run the same code with exactly the same I2C slave using a STM32L476RG instead with no issues at all.

Under Chibios 18.2.0, using I2C1, with no other peripherals enabled, these are the pertinent settings I have:

Code: Select all

/*
 * I2C driver system settings.
 */
#define STM32_I2C_USE_I2C1                  TRUE
#define STM32_I2C_USE_I2C3                  FALSE
#define STM32_I2C_BUSY_TIMEOUT              50
#define STM32_I2C_I2C1_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 7)
#define STM32_I2C_I2C1_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 6)
#define STM32_I2C_I2C3_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 3)
#define STM32_I2C_I2C3_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C1_IRQ_PRIORITY         5
#define STM32_I2C_I2C3_IRQ_PRIORITY         5
#define STM32_I2C_I2C1_DMA_PRIORITY         3
#define STM32_I2C_I2C3_DMA_PRIORITY         3
#define STM32_I2C_DMA_ERROR_HOOK(i2cp)      osalSysHalt("DMA failure")


I managed to take a capture with a logic analyzer, this is produced by calling i2cMasterTransmit with 1 byte tx buffer and 3 bytes for the rx.
The write and cmd byte make it through, with the expected SCL clock, but when it is time to perform the start condition belonging to the 3 byte read, SCL remains permanently low until an application reset.

i2c_capture.png

Has anybody managed to run I2C transactions with a STM32L432KC?, I noticed there's support for a nucleo board based on that MCU.

Any suggestions regarding what I could do to debug this issue further will be appreciated.
I looked into i2c_lld_master_transmit_timeout and managed to trace the call down to I2Cv2/hal_i2c_lld.c:1139

Code: Select all

 
 /* Waits for the operation completion or a timeout.*/
  msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);


What I seem to gather there is because the timeout is INFINITE, this is deliberate, and the transaction never concludes threads don't run.

Thanks in advance,

Raul


I have the same problem as you, I am using STM32F105. Call i2cStart(&I2C,&I2CCfg) before calling i2cMasterTransmitTimeout to solve this problem, you can try it.

Code: Select all

template <unsigned RxSize>
std::array<uint8_t, RxSize> read(const std::uint8_t first_reg)
{
    i2cStart(&I2C,&I2CCfg);
    static std::array<uint8_t, 1> tx_buf;
    static std::array<uint8_t, RxSize> rx_buf;
    std::fill(tx_buf.begin(), tx_buf.end(), 0);
    std::fill(rx_buf.begin(), rx_buf.end(), 0);
    tx_buf[0] = first_reg;
 
    i2cAcquireBus(&I2C);

    i2cMasterTransmitTimeout(&I2C,
                               HAL_COMPASS_IST8310_I2C_ADDR,
                               tx_buf.data(),
                               tx_buf.size(),
                               rx_buf.data(),
                               rx_buf.size(),
                               TIME_INFINITE);

    i2cReleaseBus(&I2C);

    return rx_buf;
}

This is the link I posted the question.viewtopic.php?f=25&t=4813&p=33798#p33798