cancel
Showing results for 
Search instead for 
Did you mean: 

Special I2C slave , how solve wakeing masters

MM..1
Chief

My problem is i require emulate with STM I2C chip , that requires wake adr send before comm. But normal slave code isnt handle this.

Signals on bus (FYI master is other device no STM)

MM1_0-1700064978907.png

as can see master send one adr without data and repeat, first reply is ok, but next reply is always E0 what is fault

semantic my code based on example IT slave receive from HAL. Can somebody help handle this.

while
start IT slave receive wait 1 byte

pool 

set tx byte based on rx

start slave send reply 1 byte IT

pool

repeat

5 REPLIES 5
Bob S
Principal

That first single-byte transaction might not be a "wakeup" but rather a normal "see if that device is ready to respond" query.  All it does is see if the slave device "ACKs" its address.

> repeat, first reply is ok, but next reply is always E0 

What? I don't see two replies.  I see an address then a WRITE byte value 0x00, then a repeat-start, address and READ byte of 0xE0.  Then I see another "is this device ready" transaction with just the address byte.

Is that not what you are expecting?

If not, as always on this forum, post your actual code (using the code formatting button that looks like "</>", click on the "..." to see it).  This helps us help you.

Bob S
Principal

Hmmm, maybe I mis-interpreted.  Is that I2C sequence showing the behavior of the device that you need to emulate?  And you are having trouble providing the same response?

The HAL I2C code should handle the "is this device ready" sequences, though I don't recall exactly how.  The HAL receive call may return with an error code, or it may return with a data length of zero.  The answer is still "post your code".

Thanks Bob

while (1)
  {
  /*##-2- Put I2C peripheral in reception process ###########################*/  
  if(HAL_I2C_Slave_Receive_IT(&hi2c1, (uint8_t *)aRxBuffer, 10) != HAL_OK)
  {
    /* Transfer error in reception process */
    Error_Handler();
  }
  
  /*##-3- Wait for the end of the transfer ###################################*/  
  /*  Before starting a new communication transfer, you need to check the current   
      state of the peripheral; if it’s busy you need to wait for the end of current
      transfer before starting a new one.
      For simplicity reasons, this example is just waiting till the end of the
      transfer, but application may perform other tasks while transfer operation
      is ongoing. */
  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
  {
  }
  
  /*##-4- Start the transmission process #####################################*/  
  /* While the I2C in reception process, user can transmit data through 
     "aTxBuffer" buffer */
	aTxBuffer[0]=0xEE;
	if(aRxBuffer[0]==0) aTxBuffer[0]=0xE0;
	if(aRxBuffer[0]==0x97) aTxBuffer[0]=0x03;
	if(aRxBuffer[0]==0xAA) aTxBuffer[0]=0x00;
	if(aTxBuffer[0]==0xEE) continue;
  if(HAL_I2C_Slave_Transmit_IT(&hi2c1, (uint8_t*)aTxBuffer, 1)!= HAL_OK)
  {
    /* Transfer error in transmission process */
    Error_Handler();    
  }

  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
  {
  }

	/* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

here may code that react to master and next DW you dont have on image is 97 reply required is 03, but this code reply E0 

MM..1
Chief

Ofcourse real IC wake and master send 3 ping with addr for this. Two is NACK.

I change code to 

 

 

  while (1)
  {
  /*##-2- Put I2C peripheral in reception process ###########################*/  
	
	aRxBuffer[0]=5;
  I2C1->RXDR=0;
	HAL_I2C_Slave_Receive(&hi2c1, (uint8_t *)aRxBuffer, 1,1);
  /*##-4- Start the transmission process #####################################*/  
  /* While the I2C in reception process, user can transmit data through 
     "aTxBuffer" buffer */
	aTxBuffer[0]=0xEE;
	if(aRxBuffer[0]==0) aTxBuffer[0]=0xE0;
	if(aRxBuffer[0]==0x97) aTxBuffer[0]=0x03;
	if(aRxBuffer[0]==0xAA) aTxBuffer[0]=0x40;
	if(aTxBuffer[0]==0xEE) continue;
  if(HAL_I2C_Slave_Transmit_IT(&hi2c1, (uint8_t*)aTxBuffer, 1)!= HAL_OK)
  {
    /* Transfer error in transmission process */
    Error_Handler();    
  }

  while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
  {
  }
	/* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

 

 

now it relative works , but reply is delayd Howto solve ? I mean no HAL is required here.

problem2.png

Bob S
Principal

Some of that delay is the HAL functions and your code responding to the other device's read request.  Though 1ms delay seems a bit much even for HAL.  It has been a while since I've done I2C slave code so I'm not sure I remember all the needed steps.  You code does look similar to some of the Cube example code.

What is your CPU's clock rate?