cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Gives No Output

CCend.2
Associate III

For the life of me I cannot get the I2C pins on my microcontroller to output anything.

I am using I2C1 on pins PB6 (SCL) and PB9 (SDA) on the STM32F746VGT microcontroller. The pins are hooked up to a TXS0108E level shifter that has built-in pull up resistors. I have a very simple CubeMX project that initializes I2C1 to Standard Mode and attempts to transmit some data on it every second.

All I want to see are some signals on the SDA/SCL lines but I get nothing. I can change the I2C pins to open drain GPIO pins and toggle those and see it on the scope, but when I switch back to I2C I see nothing again.

I see the lines stuck either low or high depending on which one I'm probing at the moment. If I reset the MCU then probe the lines, they're both stuck high. They're also stuck high if I reset the MCU while probing SDA. But if I reset the MCU while probing SCL, then both lines get stuck low. So it seems like my oscilloscope has an effect on the transmission. Not sure if that's related to my current issue or not. Either way, not a single bit gets transmitted and not a single clock is pulsed.

I believe the fact that I can toggle the pins in GPIO open drain mode tells me that it is not a circuit problem. In software I'm using the most default, basic configuration I possibly can. So I don't know what could be wrong in software. Does anyone have any ideas for what to do next?

1 ACCEPTED SOLUTION

Accepted Solutions
CCend.2
Associate III

Thank you so much for your help, everyone. I ended up solving the issue in the most anticlimactic way possible: the oscilloscope was bad. After switching to one that I've used before and know how to use better, I could see the I2C lines just fine. They were probably there the entire time.

As you can imagine, this came after days of hair-pulling and careful debugging. Only when you get truly desperate do you start questioning your test equipment.

I then discovered that the REAL reason I2C wasn't working in the first place was because one of the (non-I2C) pins on a very small 40-pin connector on my PCB was making a poor connection to the board. Two subtle issues back-to-back!

Sorry the solution wasn't something more exciting, but in electronics it's usually the *** issues we spend the most time on.

 

View solution in original post

11 REPLIES 11
Pavel A.
Evangelist III

Please have a look at I2C examples for this MCU  in the STM32Cube library package. At least one of the examples should work. 

If you suspect that something is wrong with the board, disconnect the pins. Hopefully internal pullups are enough to see the pulses on the scope.

Richard Li
Senior

After use CubeMX create project, you need add code in one place .

For my project, there noticed 

"/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{"

Yours may different.

 

In this loop, I add code"

uint8_t sensor_number = 1;

ret = HAL_I2C_IsDeviceReady (&hi2c1, 0x56, 8, 100); // wait for I2C bus to be ready

ret = HAL_I2C_Master_Transmit_IT(&hi2c1, 0x56,&sensor_number, 1);

HAL_Delay(35);

 

You can upload your project file in here, I think "main.c" should enough.

CCend.2
Associate III

I disconnected the level shifter chip and probed the SDA/SCL lines directly with pull-ups enabled and tried to send I2C data. Still nothing, both lines stuck high. They go low when I hold down the reset button, then get stuck high as soon as I release.

Next, I change the pins to GPIO open drain output with pulls-ups enabled and I'm able to see pulses when I toggle the pins. So it appears the internal pull-ups are enough to see pulses on the scope but for some reason the I2C still refuses to do anything.

I have attached my main.c, it's as minimal as I could make it.

CCend.2
Associate III

The code fails here inside HAL_I2C_Master_Transmit:

while (hi2c->XferCount > 0U)
{
    /* Wait until TXIS flag is set */
    if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
    {
        return HAL_ERROR;
    }
    ...
}

 It never detects the TXIS flag and returns HAL_ERROR every time. So that tells me it sent an address, waited for an ACK, saw no reply, and returned an error. But my oscilloscope probes saw nothing happen on the SDA/SCL lines.

Right now, the chip pins are completely isolated and I'm probing them directly. Internal pull-ups are enabled. I tried yesterday with external pull-ups and still saw the same result. I would say it's a problem with the chip or those specific pins except for the fact that GPIO open drain outputs works just fine.

I did use CubeMX create one I2C1 project for STM32F746VG, the I2C1 assign to PB6,PB7. Looks you connect to wrong pin, so PB7 without pull up resistor.

You can check your CubeMX set, or create new one.

I did one new post "Why assign 4 pins for STM32746VGT I2C1",

St employee should give feedback.

As STTwo-32 replay in new post "Why assign 4 pins for STM32746VGT I2C1",

The PB6,PB9 combination is possible, please check your code, if you intend make this combination, check GPIOB_MODER register and GPIOB_AFRL; GPIOB_AFRH.

If you not sure, you can show these register value in here.

163
Associate

Hi, I think CubeMX is supposed to generate code to initialise the pins with their alternate function mode & open drain etc, but for some reason it isn't doing it (for me either).  The MX_GPIO_Init() function should contain something like (in my case):

 

GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 

What's weird is it *does* create this code for me if I *disable* the I2C peripheral (so the two assigned pins PB6 and PB7 go yellow on the pinout view).