cancel
Showing results for 
Search instead for 
Did you mean: 

I2C (slave mode) behavior at beginning of transfer

HWidj.2
Associate III

I'm configuring I2C4 as a slave receiver, using interrupt method. I noticed that when the I2C master (another MCU) sends the slave address, I2C4 detects an address match and sets the ADDR flag in the I2C4->ISR register. What baffles me is that at this point I2C4 holds the SCK line low and communication will not proceed. The only way I can avoid this 'stuck' situation is to enable the ADDRIE interrupt which will fire on an address match and I manually clear the ADDR flag.

I'm familiar with I2C protocol, but this is my first experience with STM32 I2C peripheral, and I thought it's strange that an address match event must be explicitly acknowledged (by clearing a flag) by software. Is this the normal behavior of I2C slave in STM32H7? I'm using the STM32H723ZG Nucleo board.

Below is my initialization code (for brevity I omitted the clock and pin configuration from the listing, they checked out all right).

   // Disable I2C4.
   I2C4->CR1 &= ~I2C_CR1_PE;  
   while(I2C4->CR1 & I2C_CR1_PE) {}
 
   // Enable receive complete interrupt.
   I2C4->CR1 |= I2C_CR1_RXIE;  
 
   // Set own address.
   I2C4->OAR1 |= (LL_I2C_OWNADDRESS1_7BIT | (MY_ADDRESS << I2C_OAR1_OA1_Pos)); 
 
   // Enable Own address 1.
   2C4->OAR1 |= I2C_OAR1_OA1EN;
 
   // Set timing register.
   I2C4->TIMINGR = 0x00601956;
 
   // Enable I2C4
   I2C4->CR1 |= I2C_CR1_PE; 

Here's the register contents when address match event occurs.

0693W00000DlV4PQAV.png

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

That's how it works with NOSTRETCH=0 (default). You can set NOSTRETCH=1 if you want, but the real solution would be to clear the flag and send data on TXDR or read from RXDR. See "I2C Slave Mode" in the reference manual.

0693W00000DlW04QAF.png

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

View solution in original post

1 REPLY 1
TDK
Guru

That's how it works with NOSTRETCH=0 (default). You can set NOSTRETCH=1 if you want, but the real solution would be to clear the flag and send data on TXDR or read from RXDR. See "I2C Slave Mode" in the reference manual.

0693W00000DlW04QAF.png

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