cancel
Showing results for 
Search instead for 
Did you mean: 

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);

Ssiva.2
Associate II

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 */

5 REPLIES 5
TDK
Guru

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".

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 ..!!

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".

Thanks for your support, i am getting now

How can a transmit succeed before the receive is even started? Anyway HAL with it's idiot-designed API is ridiculously useless. A normal API would allow to turn on the continuous reception once and then only process the incoming data in interrupts indefinitely.

And those 50 ms delays are there for debouncing the buttons.