cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476 I2C problem

Peter Curtis
Associate II

Hi All,

I've been struggling with this for a while now. I have designed a new board based on the STM32L476 to replace an old design using a PIC. I cannot for the life of me get the I2C to work.

I have used STMCubeMX to pinmux and configure / generate the startup code for the board and write my code in Keil.

The bus (I2C1) currently, only has an eeprom connected (CAT24C512 at address 0xA0). I have two 1K pull-ups, pulling up SDA and SCL. I am attempting to operate at standard I2C speed (100KHz).

I can get an 'ack' from the device, but when trying to use HAL_I2C_Mem_Write, the micro sends the first two address bytes, then nothing. SCL stays low after the second ack (before the repeated start).

Both SDA and SCL look good.

0690X000006BuyUQAS.png

Here is the application code:

uint8_t temp, i, buffer[100];
		char uartBuffer[100];
		
		for(i = 0; i < 100; i++){buffer[i] = 1;}
		
		for(i = 0; i< 100; i++)
		{
		     temp = HAL_I2C_Mem_Write(&hi2c1, 0x50<<1, 0x00FF, 0xFFFF, buffer, 99, 1000);
			   
			   sprintf(uartBuffer, "\r\nHAL = %d", temp);
			   HAL_UART_Transmit(&hlpuart1, (uint8_t*)uartBuffer, 10, 1000);
			
				 temp = HAL_I2C_GetError(&hi2c1);	
			
			   sprintf(uartBuffer, " : ERR = %d", temp);
			   HAL_UART_Transmit(&hlpuart1, (uint8_t*)uartBuffer, 11, 1000);
			
			HAL_Delay(500);

Here is the i2c init code:

void MX_I2C1_Init(void)
{
 
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00909BEB;
  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(__FILE__, __LINE__);
  }
 
    /**Configure Analogue filter 
    */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
    /**Configure Digital filter 
    */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}

I have attached a schematic containing the sheet with the STM32L476 and I2C memory on it.

I would really appreciate some constructive advice or pointers as I'm all out of ideas;

I have tried:

>Changing resistor values

>Changing resistor positions (around the board, from by the controller to the end of the chain)

>Playing with the clock speeds and config

>Discretely wiring the I2C bus (to eliminate capacitance from the equation)

> shortening the I2C bus to include only the EEPROM (cutting the tracks)

>building up a simplified version of the board using a bench power supply to power the devices instead of the onboard SMPS.

>adding and adjusting bypass and decoupling around the micro and EEPROM

Many thanks in advance

4 REPLIES 4

Maybe your HAL API is different from mine (F7) but shouldn't the 4th argument to HAL_I2C_Mem_Write() be something like I2C_MEMADD_SIZE_16BIT?

Peter Curtis
Associate II

Hi David,

Thank you for taking the time to answer.

Have I mis understood the HAL manual? I took the 'I2C_MEMADD_SIZE_16BIT' to mean the size of the available memory in the device (yes, I know 512K does not equate to 0xFFFF). is 'I2C_MEMADD_SIZE_16BIT' pre defined to mean the addressing mode of the device (i.e it could also be set to 8BIT)?

Many thanks,

Peter

john doe
Lead

you did indeed misunderstand. that parameter on the function call is for what size the registers on the slave are. read the data sheet for the eeprom - it probably uses 16 bit registers

Peter Curtis
Associate II

aghhhhhh!! i've spent weeks cutting, moving, reconfiguring, banging my head, cussing ST.

I'll re-compile in the morning.

Thanks again John/David for taking the time to answer.

Kind regards

Peter