cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 HAL I2C communication

danimihalca
Associate
Posted on January 09, 2016 at 20:34

Hello.

I recently started testing the communication over I2C on a NUCLEO-L476RG board using the HAL API.

Looking through the reference manual (http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00083560.pdf ) and through the examples provided withSTM32Cube_FW_L4_V1.1.0, you need to set a 32 bit timing register before initialization (this also applies for usage with the LL).

Later on, I found that there exists a ''tool'' which helps you generate register's value http://www.st.com/web/en/catalog/tools/PF258335 , but this is specified to be related for the  STM32F3xx and STM32F0xx series ( which have a maximum I2C clock frequency at 72MHz, while L4 works up to 80MHz).

To see a proper usage of the API, I looked at the I2C_TwoBoards_ComIT project and observer that the timing register value used was 0x00D00E28 (which should work at 1Mhz with Rise time = 120ns, Fall time = 25ns and use the I2C source clock frequency from the Sysclock set at 80MHz, as mentioned in the comments). Nevertheless, I have managed to run that example and successfully communicated with a secondary (slave) board.

I have several questions reqarding I2C:

1) Can I assume that the above provided timing register value is valid and outputs at the specified frequency with those rise/fall times?

2) Can I use that timing tool (Excel file) which is destined for STM32F3xx and STM32F0xx to calculate register values for my STM32L476RG? Will I obtain valid ones (the document is password protected)? 

3) Is there anywhere a tool to calculate the value for L4 which lets me set input clock frequency up to 80Mhz ?

4) The example I2C_TwoBoards_ComIT suggests that the board will communicate over I2C at 1Mhz frequency.  In the reference manual, it is specified that if you want to achieve 1Mhz, fast mode plus must be enabled (HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus) I have found the function in stm32l4xx_hal_i2c_ex.h). Why is that example working even though that function is nowhere called in the code?

5) I want to read/write over I2C from an AT24C256 EEPROM memory (http://www.atmel.com/Images/doc0670.pdf ). In order to make it work, I had used the above mentioned timing value and power the memory at 3.3V. Sometimes (2-3), I read different values than the ones which should be returned.

a) Why does the communication work at 3.3V and doesn't at 5V ( even though in the EEPROM's datasheet at Table 4, the clock frequency can be at most 1000KHz at 5V and this should mean that for 3.3V, it should be somewhere between 400-1000KHz) ?  The EEPROM memory works with an Arduino UNO, regardless of the powering mode (3.3V or 5V - in its sources, it is specified that the output frequency is at 100KHz). 

b) Can you suggest me a timing value (or output clock freq and rise/fall time) so that no data loss should happen when using the EEPROM memory , regardless of the powering mode of the EEPROM memory (the datasheet provides minimum or maximum values only for 1.8V, 2.5V and 5V) ?

Thank you!

#stm32l4-hal-i2c
3 REPLIES 3
danimihalca
Associate
Posted on January 21, 2016 at 10:41

Up...

Amel NASRI
ST Employee
Posted on February 10, 2016 at 18:10

Hi danimihalca,

The tool you mentioned is developed to calculate I2C timing values for I2C in STM32F3 and STM32F0 devices. So, it shouldn't be applied as it is for STM32L4.

Then, the

http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1533/PF259242

tool may be used as a solution. In fact, it allows you to generate code based on the configuration you want as a result (Ex: I2C at 1MHz) providing your inputs (Ex: system clock frequency 80MHz).

BTW: Now we have the STM32L4 series available in different lines: STM32L4x1 (Access line), STM32L4x2 (USB Device), STM32L4x3 (USB Device, LCD), STM32L4x5 (USB OTG) and STM32L4x6 (USB OTG, LCD).

You will ind also that small packages are now available (Ex: LQFP48).

http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1580

.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

AP_040
Senior

Hello,

I have just started to develop some application to read temperature sensor using STM32L462CE MCU. Below is the snippet code which I have written.

#define HTU21D 0x80

void main()

{

 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();

 MX_UART4_Init();

 MX_USART2_UART_Init();

 MX_I2C1_Init();

 UART_Print("*************** STM32L462CE_I2C_HTU21D ****************\r\n");

 status = HAL_I2C_IsDeviceReady(&hi2c1, HTU21D, 3, 1000);

 if(status != HAL_OK)

 {

 UART_Print("Err ...%d\r\n",__LINE__);

 }

 else

 {

 UART_Print("@@@@ HTU21D Device is Ready @@@@\r\n");

 }

 status = HTU21D_SoftReset();

 if(status != HAL_OK)

 {

 UART_Print("Err ...%d\r\n",__LINE__);

 }

 HTU21D_WR_USER_Reg(0x67);

 user_rd = HTU21D_RD_USER_Reg();

 UART_Print("----- USER register Data %x\r\n",user_rd);

}

static void MX_I2C1_Init(void)

{

hi2c1.Instance = I2C1;

hi2c1.Init.Timing = 0x00000E14;

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_ENABLE) != HAL_OK)

{

Error_Handler();

}

/**Configure Digital filter*/

if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)

{

Error_Handler();

}

}

So, after running this code, I am getting error in device ready check and write user register value. So, can you please help me on this?. Is there any mistake?.