Skip to main content
Ssiva.2
Associate II
July 25, 2021
Question

Two STM32L4 board I2C communication issue, Slave sending the data but master not receiving. can i transmit data from slave to master using this function ? HAL_I2C_Slave_Transmit(&hi2c3, (uint8_t *)Data, strlen(Data), I2C_TIMEOUT);

  • July 25, 2021
  • 1 reply
  • 2813 views

I have Configured one STM32 board as Master and another is a Slave . When the master send the data slave receiving its fine but when slave sends the data Master not receiving, Acknowledge i am not getting from the Slave when i use HAL_I2C_STATE_READY){} and HAL_I2C_STATE_BUSY {} flag the code stuck here. please find code snippet , can i transmit data from slave to master using this function

HAL_I2C_Slave_Transmit(&hi2c3, (uint8_t *)VALID_CMD, strlen(VALID_CMD), I2C_TIMEOUT);

please help me

MASTER BOARD:STM32L433RC 

===========================

#define SLAVE_ADDR 0x11

 uint8_t CMD1[10]="LEGS_DN";

 uint8_t CMD2[10]="LEGS_UP";

 uint8_t CMD3[10]="LEGS_ST";  

 printf("WLCM TO MASTER BOARD :\r\n");

 // I2C_HandleTypeDef * hi2c = &hi2c1;

 while (1)

 {

  printf("#####Master Board Running ####\r\n");

  printf("D->LEGS_DN\r\n"); 

  printf("U->LEGS_UP\r\n");

  printf("S->LEGS_ST\r\n");

  printf(" enter command:\r\n");

  while( HAL_UART_Receive(&huart2,&ch_r,1,0xffff) != HAL_OK);

  printf("UART Rcv buf in char = %c\r\n",ch_r); 

  memset(aRxBuffer,0,sizeof(aRxBuffer));

  

  if(ch_r == 'D') 

  { 

    if( HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)SLAVE_ADDR, (uint8_t*)CMD1, sizeof(CMD1), 10000) != HAL_OK)

    {

      printf("Tx error\r\n");

    }

    while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_BUSY){};

    

    if (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)SLAVE_ADDR, aRxBuffer, sizeof(aRxBuffer), 10000) != HAL_OK);

    {

    

    }

  }

  else if(ch_r == 'U') 

  { 

    if( HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)SLAVE_ADDR, (uint8_t*)CMD2, sizeof(CMD2), 10000) != HAL_OK)

    {

printf("Tx error\r\n");

    } 

    

    while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_BUSY){};

    

    if (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)SLAVE_ADDR, aRxBuffer, sizeof(aRxBuffer), 10000) != HAL_OK);

    {

    

    }

  }

SLAVE_BOARD:STM32L433RC 

========================

void I2C_Slave_Deivce()

{

 uint8_t Buffer_I2C[RXBUFFERSIZE]={0};

 uint8_t aTxBuffer[TXBUFFERSIZE]="SUCESS";

 uint8_t aTxBuffer[TXBUFFERSIZE]="VALID_CMD";

 uint8_t aTxBuffer[TXBUFFERSIZE]="INVALID_CMD";

 I2C_HandleTypeDef * hi2c = &hi2c3;

 memset(Buffer_I2C, 0, sizeof(Buffer_I2C));

 while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY){}; // Check if busy

 #if(I2C_3_USE_INT == 1)

 HAL_I2C_Slave_Receive_IT(&hi2c3, (uint8_t *)Buffer_I2C,sizeof(Buffer_I2C));

 #else

 HAL_I2C_Slave_Receive(&hi2c3,(uint8_t *)Buffer_I2C,sizeof((uint16_t)Buffer_I2C),I2C_TIMEOUT);

 #endif

 HAL_I2C_Slave_Transmit(&hi2c3, (uint8_t *)aTxBuffer, TXBUFFERSIZE, I2C_TIMEOUT);  

 if((Received_data_processing((char *)Buffer_I2C)) == SUCCESS)

 {

 if(etLegs_cmd == LEGS_ST)

 {

 Leg_Status();

 }

 else

 {

 HAL_I2C_Slave_Transmit(&hi2c3, (uint8_t *)VALID_CMD, strlen(VALID_CMD), I2C_TIMEOUT);

 }

 }

 else

 {

 HAL_I2C_Slave_Transmit(&hi2c3, (uint8_t *)INVALID_CMD, strlen(INVALID_CMD), I2C_TIMEOUT);

    

 }

} /*end of the Slave function */

This topic has been closed for replies.

1 reply

TDK
July 25, 2021

You need to ensure the master waits for the slave to be ready to send data first. The slave cannot initiate a transfer.

See here for an example:

https://github.com/STMicroelectronics/STM32CubeL4/blob/5e1553e07706491bd11f4edd304e093b6e4b83a4/Projects/NUCLEO-L452RE/Examples/I2C/I2C_TwoBoards_ComPolling/Src/main.c

"If you feel a post has answered your question, please click ""Accept as Solution""."
Ssiva.2
Ssiva.2Author
Associate II
July 25, 2021

Hi TDK,

Thanks for your response and support.

I have gone through the shared exampled code, In this code he is doing loop back test for master and slave its coming data fine. In my case i sending one command to the slave board i need response from the slave whether execution complete or not. How we will get response from the slave Board, if slave can't initiate communication ?

To get the response from the Slave board i am using this function HAL_I2C_Slave_Transmit(&hi2c3, (uint8_t *)aTxBuffer, TXBUFFERSIZE, I2C_TIMEOUT);  to transmit data to Master Board but its not working. is it correct approach ? i have stuck here .

please any suggestion it would be grateful.

Have a great day ..!!

TDK
July 25, 2021

In order for the slave to transmit data to the master, two things need to occur, in order:

  • First, the slave needs to execute HAL_I2C_Slave_Transmit.
  • Then, the master needs to execute HAL_I2C_Slave_Receive.

The number of bytes to send/receive should match between the two.

After that, both routines will complete and the data will be available on the master.

In the example code, they use a 50ms delay to ensure the slave transmit call happens before the master tries to receive the data. You will need to implement something similar.

https://github.com/STMicroelectronics/STM32CubeL4/blob/5e1553e07706491bd11f4edd304e093b6e4b83a4/Projects/NUCLEO-L452RE/Examples/I2C/I2C_TwoBoards_ComPolling/Src/main.c#L152

"If you feel a post has answered your question, please click ""Accept as Solution""."