cancel
Showing results for 
Search instead for 
Did you mean: 

I2C master transmit and slave receive functions work. Master receive and slave transmit don't.

MC.4
Associate II
//MASTER
while (1)
  {
    /* USER CODE END WHILE */
 
	  ret = HAL_I2C_Master_Transmit(&hi2c1, peripheralNucleoAddress << 1, bufferTx, 1, HAL_MAX_DELAY);
	  if (ret != HAL_OK)
	  {
		  strcpy((char*) bufferTx, "Tx");
		  HAL_UART_Transmit(&huart2, bufferTx, strlen((char*) bufferTx), 1000);
		  HAL_Delay(500);
		  //Error_Handler();
	  }
 
 
	  
	  ret = HAL_I2C_Master_Receive(&hi2c1, peripheralNucleoAddress << 1, bufferRx, 1, 1000);
	  if (ret != HAL_OK)
	  {
		  strcpy((char*) bufferRx, "Rx");
		  HAL_UART_Transmit(&huart2, bufferRx, strlen((char*) bufferRx), 1000);
		  HAL_Delay(500);
		  //Error_Handler();
	  }
 
 
    /* USER CODE BEGIN 3 */
  }
 
 
---------------SEPARATE FILE----------------------------------------------------------------------------
 
 
//SLAVE
  while (1)
  {
 
    /* USER CODE END WHILE */
	  ret = HAL_I2C_Slave_Receive(&hi2c1, bufferRx, 1, HAL_MAX_DELAY);
 
	  if (ret != HAL_OK)
	  {
		uint8_t message[9];
		strcpy((char*) message, "Fail RX!");
		HAL_UART_Transmit(&huart2, message, strlen((char*) message), 5000);
		//Error_Handler();
	  }
 
	  if (bufferRx[0] == 0x00)
	  {
		uint8_t message[16];
		strcpy((char*) message, "Buffer is zero!");
		HAL_UART_Transmit(&huart2, message, strlen((char*) message), 5000);
		//Error_Handler();
	  }
 
	  else if (bufferRx[0] == 0xAA)
	  {
		uint8_t message[16];
		strcpy((char*) message, "Buffer is 0xAA!");
		HAL_UART_Transmit(&huart2, message, strlen((char*) message), 5000);
		//Error_Handler();
	  }
 
	  else if (bufferRx[0] == 0xFF)
	  {
		uint8_t message[16];
		strcpy((char*) message, "Buffer is 0xFF!");
		HAL_UART_Transmit(&huart2, message, strlen((char*) message), 5000);
		//Error_Handler();
	  }
 
 
	  ret = HAL_I2C_Slave_Transmit(&hi2c1, bufferTx,1, 1000);
	  if (ret != HAL_OK)
	  {
		uint8_t message[9];
		strcpy((char*) message, "Fail TX!");
		HAL_UART_Transmit(&huart2, message, strlen((char*) message), 5000);
		//Error_Handler();
	  }
 
 
 
	  HAL_Delay(500);
    /* USER CODE BEGIN 3 */
  }

I am using two NucleoG071 boards to create an I2C communication, in which one acts as the master and the other as the slave. For some reason the I2C master receive function and slave transmit do not work even though the master transmit and slave receive do. Any tips are highly appreciated.

4 REPLIES 4
Andrew Neil
Evangelist III

"Any tips are highly appreciated"

As I said in your previous thread, the Key Tip: Don't try to implement both ends of the link at once!

https://community.st.com/s/question/0D53W00001ddlCxSAI/connecting-two-nucleo-boards-using-i2c

Otherwise, you have too many unknowns - when something doesn't work, you can't tell if it's because

  • the master is wrong/broken
  • the slave is wrong/broken
  • both are wrong/broken
  • other things are wrong/broken...

Concentrate on getting just one end working & thoroughly debugged - using a known-good standard implementation at the other end.

Again, see: https://www.avrfreaks.net/comment/2320631#comment-2320631

The other key tip: This is not just a software problem - you also need to be looking at the wires with an oscilloscope and/or analyser to see what's actually happening in the hardware.

MC.4
Associate II

So after I couldn't make it work like that I did end up following your tip from my previous post and tried making only the Master Receive work. However, I still had no luck as my clock line for some reason gets pulled low when I add a second board even though I am using pull up resistors.

When I try using the Master board by itself the clock and read and write requests work as well (though they don't get acknowledged since there is only one board connected).

To look at what's happening I am currently using the terminal for printing and a Logic Analyzer.

What "second board" ?

Have you tested your Master with a known-good, simple slave - like some standard, well-known I2C chip?

At this stage, an oscilloscope is probably better, as you can see any analogue nasties - such as wrong pullup values.

By putting a resistor in series with the lines, you can see which end is doing the pulling-down ...

"an oscilloscope is probably better, as you can see any analogue nasties - such as wrong pullup values"

For example: 

0693W00000Nt1crQAB.pnghttps://electronics.stackexchange.com/questions/1849/is-there-a-correct-resistance-value-for-i2c-pull-up-resistors