cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_IsDeviceReady timeout w/ eeprom

SVezi.1
Associate II

I've been using a Microchip I2C eeprom in a commercial product that uses an F730 for a bit over a year. I've been using the same code to flash hundreds of units and have never had any issues.

I've opened up my project recently and got prompted for an update by STM32CubeIDE, after which I've migrated my project to the latest fw package. I don't know if my issue is related to the update or if it's simply a coincidence.

My code now hangs during HAL_I2C_IsDeviceReady() and the I2C device never gets initialized and timeout eventually happens.

I tried launching a new barebones project with just I2C configured and I get the same results.

This is all I'm trying to do:

while (HAL_I2C_IsDeviceReady(&hi2c1, 0xA0, 2, 100)!=HAL_OK);

Here's the init code from Cube:

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{
 
  /* USER CODE BEGIN I2C1_Init 0 */
 
  /* USER CODE END I2C1_Init 0 */
 
  /* USER CODE BEGIN I2C1_Init 1 */
 
  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00100003;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_DISABLE) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */
 
  /* USER CODE END I2C1_Init 2 */
 
}

I'm really stumped. I swear this was working just a couple weeks ago and I haven't touched anything beyond updating and migrating to the latest fw package.

For what it's worth, I have the same issue using an L0 and the same eeprom on a product prototype I'm working on.

Any clue or help is appreciated! Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> I'm an idiot and didn't use source control. Would you believe I've been a developer for over 20 years? *facepalm*

I would believe that, but I wouldn't hire you. That's harsh, but 20 years of development is a long time and not using any form of source control or backup files in a production project is absurd.

> I remember reading somewhere that they weren't usually needed for a single I2C device.

[citation needed]

I2C pullup resistors are always needed as I2C pins operate in open-drain mode. This is a fundamental requirement as the master and slave share control of the SDA/SCL lines. You can use the internal pullups at a potentially reduced clock rate without modifying the hardware. CubeMX may not support lower clock rates out of the box, but the hardware does.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

7 REPLIES 7
TDK
Guru

What chip are you interfacing with exactly? Double check slave address.

Look at signals on the line to verify the STM32 is sending the correct signal. If the slave isn't responding, that's not an STM32 error, probably a hardware one.

I would also recommend not updating to the latest package unless there is a compelling reason to do so. I can't imagine HAL_I2C_IsDeviceReady has changed, but other things can.

If you feel a post has answered your question, please click "Accept as Solution".
SVezi.1
Associate II

Hello! Thank you for your reply!

> What chip are you interfacing with exactly? Double check slave address.

The chip is 24LC16B - all my address pins are connected to gnd so, as per datasheet, the read address should be 0xA1 and write address should be 0xA0 - I tried both out of desperation but to no avail.

> Look at signals on the line to verify the STM32 is sending the correct signal. If the slave isn't responding, that's not an STM32 error, probably a hardware one.

While this is very logical and sound, I have maybe 20 units stocked up on the shelf behind me right now that I flashed earlier this year and are working great - not counting for the couple hundreds that I shipped (and tested of course) since last January. If I take any one of them and flash them now with the software as it is, I get the same result. I just did the test so I guess I'm down to 19 units stocked haha

> I would also recommend not updating to the latest package unless there is a compelling reason to do so. I can't imagine HAL_I2C_IsDeviceReady has changed, but other things can.

Lesson learned! I did try downgrading to the previous version of the FW and it didn't help. However, the latest package is from February 2020: STM32CubeF7 Firmware Package V1.16.0 / 14-February-2020. I opened up my project many times between then and when the problems started happening so maybe something else got updated and caused issues?

TDK
Guru

Those points would suggest a software issue. Is it possible to diff your code from before and after migration? That would show the issues. In particular look at MX_I2C1_Init changing or not.

I don't see any issues in the code you posted, but I didn't/can't check the Timing value. The slave address looks correct.

If it were my project, I would definitely pull out the logic analyzer and see what is happening on SDA/SCL.

If you feel a post has answered your question, please click "Accept as Solution".
SVezi.1
Associate II

> Those points would suggest a software issue. Is it possible to diff your code from before and after migration? That would show the issues. In particular look at MX_I2C1_Init changing or not.

I'm an idiot and didn't use source control. Would you believe I've been a developer for over 20 years? *facepalm*

> I don't see any issues in the code you posted, but I didn't/can't check the Timing value. The slave address looks correct.

Right? I'm not 100% sure what timing is but it's greyed out in Cube and changes as a function of speed, rise and fall times settings (which I don't remember seeing before? Am I crazy?)

> If it were my project, I would definitely pull out the logic analyzer and see what is happening on SDA/SCL.

These being production pcbs I don't have much to hook onto but I guess I'll give it a shot

SVezi.1
Associate II

Well I've got some development.

I'm working with 2 PCBs for 2 different products both using ST mcus and the same EEPROM chip.

PCB1 is a commercial product I've been shipping for a year and worked really well until very recently. It runs an F730 and the I2C lines have no pull up resistors - reason being that back then I remember reading somewhere that they weren't usually needed for a single I2C device.

PCB2 is a prototype for an upcoming product. It runs an L0C6 and the I2C lines do have pull up resistors because there is a second i2c device on there. The resistors weren't soldered before. I installed a pair of 4.7k resistors and set rise and fall time to 100ns and voila, all of a sudden my eeprom responds. Which is good news.

The not-so-good news is that I have a large quantity of PCB1s already assembled because it used to work and I can't just slap resistors on there so I'm left with trying to figure out the correct rise and fall time for it to work, as it did before. I could swear that I didn't have to set rise and fall time to setup i2c before in cube.

TDK
Guru

> I'm an idiot and didn't use source control. Would you believe I've been a developer for over 20 years? *facepalm*

I would believe that, but I wouldn't hire you. That's harsh, but 20 years of development is a long time and not using any form of source control or backup files in a production project is absurd.

> I remember reading somewhere that they weren't usually needed for a single I2C device.

[citation needed]

I2C pullup resistors are always needed as I2C pins operate in open-drain mode. This is a fundamental requirement as the master and slave share control of the SDA/SCL lines. You can use the internal pullups at a potentially reduced clock rate without modifying the hardware. CubeMX may not support lower clock rates out of the box, but the hardware does.

If you feel a post has answered your question, please click "Accept as Solution".
SVezi.1
Associate II

> I would believe that, but I wouldn't hire you. That's harsh

I am in no way offended, it's absolutely not my usual MO. I was CTO of a digital agency before and had tech management roles before that and source control was always used properly. This time it got lost in the mountain of things that need doing as the owner of a small business. Entirely my bad. Either way, I digress.

> I2C pullup resistors are always needed as I2C pins operate in open-drain mode. 

> You can use the internal pullups at a potentially reduced clock rate without modifying the hardware. CubeMX may not support lower clock rates out of the box, but the hardware does.

Well look at that - I set the internal pull ups in Cube and it works again. I probably fiddled around while also doing something else and somehow turned them off - explaining why it was working before. I've learned a few big lessons today - the biggest of which is to not be lazy.

Thank you very, very, very much for your help. I am so very relieved right now.