0
\$\begingroup\$

I have an STM32G4 using the HAL function HAL_I2C_Slave_Transmit to respond with some data when requested by a master on the I2C bus. In the image below you can see the device sends 0xFF followed by the actual data it was meant to send (the data I am expecting is 0x11 0x01 0x00).

Wave

I have tried this with the minimal test program below so I don't believe it's anything to do with my full program having a delay:

/* USER CODE BEGIN 2 */
  typedef struct {
      char id;
      char payload[2];
  } I2C_RSP_TO_MASTER;
  I2C_RSP_TO_MASTER  I2C_response;
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    I2C_response.id = 0x11;
    I2C_response.payload[0] = 0x01;
    I2C_response.payload[1] = 0x00;
 
    HAL_I2C_Slave_Transmit(&hi2c2, (uint8_t*) &I2C_response, 3, 10);
 
    while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY) {
      }
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

For my current testing the master is an Arduino Nano using the Arduino function:

Wire.requestFrom(ADDR, 4);

I am requesting 4 bytes because the initial byte is garbage (0xFF). The STM32 is clocked at 128MHz so I don't believe it is possible that it is running too slowly to respond to the first byte - I think it may be a problem with the HAL! Is there a way to fix this problem?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ This is likely a pipeline issue, possibly depending if you have clock stretching or not you may need to have set the first byte before the transfer even begins, which the HAL code may not do. I don't have the materials for the STM32 you are using at hand, but for example on a different one see the discussion on page 702 of RM0367 or search for the TXIS bit (or whatever it is called) in the reference manual for your chip. \$\endgroup\$ Commented Aug 11, 2020 at 15:21
  • \$\begingroup\$ It looks like the equivalent is RM0440 page 1874. I have clock no stretch mode enabled. Novice question - how would I set the TXE bit? I tried typing 'hi2c2->' and 'hi2c2.Instance->' but got no suggestions when hitting Ctrl+Space in STM32CubeIDE. \$\endgroup\$
    – BenAdamson
    Commented Aug 11, 2020 at 16:12
  • 2
    \$\begingroup\$ Why don't you try clock stretching? It seems that doing it the other way you'd have to rejigger a lot of the HAL code. Or just build expectation of this byte pipeline delay into your system. \$\endgroup\$ Commented Aug 11, 2020 at 16:59
  • \$\begingroup\$ Thanks, I had previously given up on permitting clock stretching as it wasn't working for me before but I think there was a difference between the number of bytes requested and number ready to be sent by the slave. Allowing clock stretching seems to get it to work without the 0xFF char. \$\endgroup\$
    – BenAdamson
    Commented Aug 11, 2020 at 17:28

1 Answer 1

2
\$\begingroup\$

If you have enabled "No Clock Stretch" mode, you can't expect the thing to react to it's address and send the first byte correctly, because it does not stretch the clock to make the master wait until the slave code has loaded the first byte into its I2C engine.

If you want to do it without clock stretching, be prepared to write your own I2C routines. The HAL functions can be used as a good starting point, but many times they just are not the best for special needs.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.