Skip to main content
Explorer
June 5, 2020
Question

Program stm32g474re from Bootloader via I2C

  • June 5, 2020
  • 1 reply
  • 1562 views

Good afternoon.

I am trying to program STM32G47X through the built-in bootloader using a protocol I2C from another microcontroller.

Document 2606 on page 212 indicates the slave address 0b1010100x. I managed to get through only at 0b1010011x. Is this a bug in the documentation?

Document 4221 also has very little information. I enter bootloader mode by setting boot1 to 1 and releasing the reset.

//i2c 100kHz
 
HAL_StatusTypeDef status;
 
uint8_t tmp[2];
uint8_t dat[21];
uint8_t ACK;
 
	while(HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY);
	status = HAL_I2C_Master_Transmit_IT(I2cHandle, 0xa6, dat, 1);
	while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) ;
	status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa7, &ACK, 1);
while(1)
	{
		tmp[0] = 1;
		tmp[1] = 0xfe;//XOR tmp[0]
		while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) ;
		status = HAL_I2C_Master_Transmit_IT(I2cHandle, 0xa6, tmp, 2);
		memset(dat, 0, sizeof(dat));
		while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) ;
		status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa7, &ACK, 1);
		if (ACK == 0x79)
		{			
			while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) ;
			status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa7, dat, 2);	
//I accept only zeros!
		}
		else if (ACK == 0x1f)//nack
		{
//Sometimes I get here
		}
		else if(ACK == 0x76)//busy
		{
		}
			else
		{
		}

Often, the slave controller presses the SCL line to the ground. And you have to wait up to 10 seconds.

Maybe someone has an example working?

I don’t understand how to receive data after the response ACK == 0x79

    This topic has been closed for replies.

    1 reply

    Super User
    June 5, 2020

    If you want to use I2C in blocking mode, use HAL_I2C_Master_Transmit instead of HAL_I2C_Master_Transmit_IT. The latter transfers asynchronously and you need to wait for completion before accessing the data. Which you do in most places, but not all.

    > I don’t understand how to receive data after the response ACK == 0x79

    Not sure what you mean. You receive data with HAL_I2C_Master_Receive.

    From the app note:

    Note: The host frame can be one of the following:

    • Send Command frame: The host initiates communication as master transmitter, and sends two bytes to the device: command code + XOR.

    • Wait for ACK/NACK frame: The host initiates an I2C communication as master receiver, and receives one byte from the device: ACK or NACK or BUSY.

    • Receive Data frame: The host initiates an I2C communication as master receiver, and receives the response from the device. The number of received bytes depends on the command.

    • Send Data frame: The host initiates an I2C communication as master transmitter, and sends the needed bytes to the device. The number of transmitted bytes depends on the command.

    AZHUK.1Author
    Explorer
    June 9, 2020

    It seems to figure it out. The loader sends data by one byte

    if (ACK == 0x79)
    		{			
    			status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, &dat[0], 1);
    //https://www.st.com/resource/en/application_note/dm00072315-i2c-protocol-used-in-the-stm32-bootloader-stmicroelectronics.pdf
    //page 11
    //Byte 2: Bootloader version (0 < Version ≤ 255) (for example, 0x10 = Version 1.0)
     while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ;
     status = HAL_I2C_Master_Receive_IT(I2cHandle, 0xa6, &dat[1], 1);	
    //Byte 3: ACK
     while (HAL_I2C_GetState(I2cHandle) != HAL_I2C_STATE_READY) ;
    		}