I2C never sends a bit

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
AnSc
Posts: 17
Joined: Tue Mar 29, 2022 4:16 pm
Has thanked: 1 time
Been thanked: 2 times

I2C never sends a bit

Postby AnSc » Sun May 29, 2022 10:52 am

Hi,

I'm trying to get I2C to run but after a few days of searching and stripping down my project to the bare minimum for I2C I never see a single bit sent on I2C outputs (no signal change on oscilloscope), no clock.

I made sure that the outputs actually work by toggling the output and seeing the level change on my oscilloscope.

There must be something I'm missing but I cannot figure out what…
Any help would be much appreciated.

The first I2C transmit runs through but the second one halts the system with reason "i2cMasterTransmitTimeout". Increasing the timeout did yield no success.

MCU is a STM32F103.

Code from main.c:

Code: Select all

#include "ch.h"
#include "hal.h"
#include "board.h"

#define NV_DEVADDR      0b1010110   // E1, E2 are pulled HIGH in hardware, only 7 bits for address, R/W bit is added by driver
#define NV_MEMSIZE      512         // 4 Kibit / 512 Byte
#define NV_PAGESIZE     16          // Bytes
#define NV_PAGES        32
#define NV_WRITETIME_MS 5           // guaranteed maximum in datasheet
#define NV_TIMEOUT_MS   5

static const I2CConfig i2ccfg = {
  OPMODE_I2C,
  400000,
  FAST_DUTY_CYCLE_2
};

static const I2CConfig i2ccfg_ls = {
  OPMODE_I2C,
  100000,
  STD_DUTY_CYCLE
};

/** Application entry point. */

int main(void) {
  uint8_t mem_address[1] = {0x00};
  uint8_t nvsettings[4]  = {0}; // holds the temporay read values

  halInit();    // calls boardInit() at last
  chSysInit();

  // start I2C
  i2cStart(&I2CD1, &i2ccfg_ls);

  /*
   * Normal main() thread activity, in this demo it does nothing.
   */
  while (true) {
    i2cAcquireBus(&I2CD1);
    i2cMasterTransmitTimeout(&I2CD1,
                             NV_DEVADDR,
                             mem_address, sizeof(mem_address),
                             nvsettings, sizeof(nvsettings),
                             TIME_MS2I(NV_TIMEOUT_MS)
                            );
    i2cReleaseBus(&I2CD1);

    chThdSleepMilliseconds(500);
  }
  return 0;
}


board.h:

Code: Select all

/*
 * Port B setup.
 * Everything input with pull-up except:
 * PB0,1    - Push Pull output  (LED).
 * PB6,7    - open drain "I2C"
 * PB8,9    - "debug" outputs
 * PB11..15 - normal input, pull-down externally provided
 */
#define VAL_GPIOBCRL            0x55888833      /*  PB7...PB0 */
#define VAL_GPIOBCRH            0x44444338      /* PB15...PB8 */
#define VAL_GPIOBODR            0xFFFFFFFF


mcuconf.h:

Code: Select all

/*
 * I2C driver system settings.
 */
#define STM32_I2C_USE_I2C1                  TRUE


halconf.h:

Code: Select all

#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C                         TRUE
#endif

#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION            TRUE
#endif

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: I2C never sends a bit

Postby Giovanni » Sun May 29, 2022 11:52 am

Hi,

Enable assertions and state checker in chconf.h and see if something is caught (see debug section in the file).

Giovanni

AnSc
Posts: 17
Joined: Tue Mar 29, 2022 4:16 pm
Has thanked: 1 time
Been thanked: 2 times

Re: I2C never sends a bit

Postby AnSc » Sun May 29, 2022 12:35 pm

Thanks for the fast reply. :)

state checks and assert where already enabled.
enabled statistics too.
However I'm not sure how to read this.

What I found is, that at entering i2cMasterTransmitTimeout the second time i2cp state is already at I2C_LOCKED.

osalDbgAssert then enters chSysHalt

Attached are the statistics from start till entering halt.
Attachments
trace_threads_i2c_2022-05-29.png
trace_threads_i2c_2022-05-29.png (7.94 KiB) Viewed 2321 times
trace_i2c_2022-05-29.png
trace_global_i2c_2022-05-29.png
trace_global_i2c_2022-05-29.png (4.11 KiB) Viewed 2321 times

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: I2C never sends a bit

Postby Giovanni » Sun May 29, 2022 1:08 pm

That is an assertion in the i2cMasterTransmitTimeout(), probably the driver is in an invalid state when you call the function, inspect the assertion condition in there.

Giovanni

AnSc
Posts: 17
Joined: Tue Mar 29, 2022 4:16 pm
Has thanked: 1 time
Been thanked: 2 times

Re: I2C never sends a bit

Postby AnSc » Sun May 29, 2022 4:47 pm

I stepped through the code.
At i2cStart the status changes from 1 "I2C_STOP" to 2 "I2C_READY".

In i2cMasterTransmitTimeout it then changes to 3 "I2C_ACTIVE_TX".
in i2c_lld_master_transmit_timeout

Code: Select all

if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))


directly break; in the first iteration.

dp->CR2 changes to 0xb24
dp->CR1 changes to 0x101

Code: Select all

  rdymsg = i2c_lld_master_transmit_timeout(i2cp, addr, txbuf, txbytes,
                                           rxbuf, rxbytes, timeout);


returns with -1 which seems to be equal to MSG_TIMEOUT which then sets

Code: Select all

 i2cp->state = I2C_LOCKED;


rdymsg is derived from msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout); in i2c_lld_master_transmit_timeout.

Why does this function return -1?

the timeout transmitted to this function is 50. Does this sound like a reasonable number in this context?
My guess is this could be the number from mcuconf.h:

Code: Select all

#define STM32_I2C_BUSY_TIMEOUT              50

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: I2C never sends a bit

Postby Giovanni » Sun May 29, 2022 5:22 pm

Hi,

It is a timeout, it can be caused by I2C not receiving an ACK in time, this could be caused by a problem with GPIO setup or external wiring.

If you don't see any signal on I2C pins then you should double check those GPIO settings.

Giovanni

AnSc
Posts: 17
Joined: Tue Mar 29, 2022 4:16 pm
Has thanked: 1 time
Been thanked: 2 times

Re: I2C never sends a bit

Postby AnSc » Mon May 30, 2022 2:44 pm

Today I took again a look on the demo STM32F1xx-I2C.

And then I found the culprit:

I did set the default output to open drain, not the alternate…

Wrong:

Code: Select all

#define VAL_GPIOBCRL            0x55888833


Correct:

Code: Select all

#define VAL_GPIOBCRL            0xDD888833      /*  PB7...PB0 */


Thanks again for your time and the pointer to the right location. :)

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: I2C never sends a bit

Postby Giovanni » Mon May 30, 2022 3:45 pm

Hi,

You are welcome, I2C is always troublesome initially.

Giovanni


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 7 guests