Skip to main content
Visitor II
February 4, 2025
Question

STM32G071G8U6TR trying to use I2C communication

  • February 4, 2025
  • 2 replies
  • 2530 views

I'm trying to use the I2C line of an STM32G071G8U6TR to talk with an external device. I've used the STMCube to configure the pins to be I2C with pull ups and high speed which created this Init

 

 

 

static void MX_I2C1_Init(void)
{

 /* USER CODE BEGIN I2C1_Init 0 */

 /* USER CODE END I2C1_Init 0 */

 /* USER CODE BEGIN I2C1_Init 1 */
	//hi2c1.Init.Timing = I2C_SPEEDCLOCK;
	//hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_10BIT;
	//hi2c1.Init.OwnAddress2 = 0xff;
 /* USER CODE END I2C1_Init 1 */
 hi2c1.Instance = I2C1;
 hi2c1.Init.Timing = 0x00503D58;
 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();
 }
 /* USER CODE BEGIN I2C1_Init 2 */
 if(HAL_I2C_Init(&hi2c1) != HAL_OK)
 {
 /* Initialization Error */
 Error_Handler();
 }
 /* USER CODE END I2C1_Init 2 */

}

 

 

 

However when I try and use this code to send commands to the device the status return is always returned as HAL_I2C_STATE_RESET, I've used a scope to check both the I2C lines and they are both high when this code is called.

 

 

void connect_vane()
{
	//status = HAL_I2C_Master_Transmit_IT(&I2cHandle, MOTOR_ADDRESS_WRITE, (uint8_t*)aTxBuffer, TXBUFFERSIZE);
	//if (HAL_OK == status)
	//{
	 //bytes_written = bytes_to_write;
		 //connect_vane();

		 //message_buf[0] = 0x66;			//Address 66
		 /*message_buf[0] = 0x3C;			// '<'
		message_buf[1] = 0x30;			// '0'
		message_buf[2] = 0x31;			// '1'
		message_buf[3] = 0x3E;			// '>'
			message_buf[4] = 0x0D;			// '/r'*/
		 //HAL_I2C_Master_Transmit(&hi2c1, MOTOR_ADDRESS_WRITE, message_buf, 5, 1000);
		 aTxBuffer[0] = 0x66;
		 aTxBuffer[1] = 0x3C;			// '<'
		 aTxBuffer[2] = 0x30;			// '0'
		 aTxBuffer[3] = 0x31;			// '1'
		 aTxBuffer[4] = 0x3E;			// '>'
		 aTxBuffer[5] = 0x0D;			// '/r'

		 do
		 {
			 if(HAL_I2C_Master_Transmit(&I2cHandle, MOTOR_ADDRESS_WRITE, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 1000)!= HAL_OK)
			 {
				 /* Error_Handler() function is called when error occurs. */
				 Error_Handler();
			 }

	 /*##-3- Wait for the end of the transfer #################################*/
	 /* Before starting a new communication transfer, you need to check the current
	 state of the peripheral; if it�s busy you need to wait for the end of current
	 transfer before starting a new one.
	 For simplicity reasons, this example is just waiting till the end of the
	 transfer, but application may perform other tasks while transfer operation
	 is ongoing. */
			 while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
			 {

			 }

	 /* When Acknowledge failure occurs (Slave don't acknowledge it's address)
	 Master restarts communication */
		 }
		 while(HAL_I2C_GetError(&I2cHandle) == HAL_I2C_ERROR_AF);

		 HAL_Delay(50);

		 do
		 {
			 if(HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)MOTOR_ADDRESS_WRITE, (uint8_t *)aRxBuffer, RXBUFFERSIZE, 1000) != HAL_OK)
			 {
				 /* Error_Handler() function is called when error occurs. */
				 Error_Handler();
			 }


	 /*##-5- Wait for the end of the transfer #################################*/
	 /* Before starting a new communication transfer, you need to check the current
	 state of the peripheral; if it�s busy you need to wait for the end of current
	 transfer before starting a new one.
	 For simplicity reasons, this example is just waiting till the end of the
	 transfer, but application may perform other tasks while transfer operation
	 is ongoing. */
			 while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
			 {

			 }

	 /* When Acknowledge failure occurs (Slave don't acknowledge it's address)
	 Master restarts communication */
		 }
		 while(HAL_I2C_GetError(&I2cHandle) == HAL_I2C_ERROR_AF);

}

 

 

 

    This topic has been closed for replies.

    2 replies

    Graduate II
    February 5, 2025

    Are you using internal or external pull-up resistors?

    What I2C device? What slave address is MOTOR_ADDRESS_WRITE defined as? 

    Do you see data activity?

     

    GTann.1Author
    Visitor II
    February 5, 2025

    I'm currently only using the STM32's internal pull up resistors.

     

    The device is a New Scale M3-LS-U2-8.

     

    MOTOR_ADDRESS_WRITE is defined as 66.

     

    With the code above it gets to:

    if(HAL_I2C_Master_Transmit(&I2cHandle, MOTOR_ADDRESS_WRITE, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 1000)!= HAL_OK)

    and returns busy. When I have added in a check status line above and debugged in the status is reading as "HAL_I2C_STATE_RESET"

    Super User
    February 5, 2025

    @GTann.1 wrote:

    I'm currently only using the STM32's internal pull up resistors."


    As @Ozone said, they are almost certainly too weak.

     


    @GTann.1 wrote:

    The device is a New Scale M3-LS-U2-8.


    So one of these: https://www.newscaletech.com/micro-motion-modules/m3-ls-linear-smart-stages/ ?

    https://www.newscaletech.com/wp-content/uploads/M3-LS-U2-datasheet.pdf

    Always best to give a link - so that people know exactly what you're referring to.

     

    Explorer
    February 5, 2025

    > I've used the STMCube to configure the pins to be I2C with pull ups ...

    That will not work.
    The internal pull-ups are an order of magnitude too weak. You need about 1k ... 5k externally.