STM32F413 I2C. ACK from slave is not recognized.
Hello everybody,
I am having an issue when I try to establish a communication with the NFC chip M24SR64 via I2C. After I have sent the address (0xAC), the flag AF is set, indicating that the ACK of the slave was not read. However, I can see the ACK from the slave in the Oscilloscope, i.e., during the 9th SCL pulse the SDA line is in low (see attached picture). Then, in the error handler subroutine for the AF case, a STOP condition is generated. I repeat the process many times but always the AF flag is set.
I am pretty sure my I2C settings are right (PF0 and PF1 as open drain outputs, high speed, alternative function, etc). In fact, the I2C driver works flawlessly in the STM32F446. I compared the two reference manuals and there is no difference in the I2C modules of the controllers.
The pull-up resistors value remained the same (3K) . I also attached my initialization code.
Thanks for your help.
// Set I2C eState Busy
NFCL_tIICHandle.eState = I2C_STATE_BUSY;
// Disable the selected I2C peripheral
I2C_NFC->CR1 &= ~I2C_CR1_PE; // 0: PE: = 0: Peripheral disable
I2C_NFC->CR1 |= I2C_CR1_SWRST;
I2C_NFC->CR1 &= ~I2C_CR1_SWRST;
// Get PCLK1 frequency
u32Presc = ((RCC->CFGR & RCC_CFGR_PPRE1)>> POSITION_VAL(RCC_CFGR_PPRE1));
u32Pclk1 = (UINT32)(RCC_SYS_CLK >> i2c_au8APBAHBPrescTable[u32Presc]); // PRQA S 3393 //RCC_SYS_CLK causes the warning!
// Calculate frequency range
u32FreqRange = I2C_FREQRANGE(u32Pclk1);
// Configure I2C2: Frequency range
I2C_NFC->CR2 = u32FreqRange; // PCLK1 = 50 MHz
// Configure I2C2: Rise Time
I2C_NFC->TRISE = I2C_TIME_RISE; // TRISE = 0x10
// Configure I2C2: Speed I2C clock control
I2C_NFC->CCR = 0x2A // 0-11: CCR = 0x2A (42): Clock Control Register (2500ns / (3 * 20ns) = 42)
// 14: DUTY = 0: Fast Mode Duty Cycle
| I2C_CCR_FS; // 15: FS = 1: Master mode selection
// Configure I2C2: Generalcall and NoStretch mode
I2C_NFC->CR1 = I2C_GENERALCALL_DISABLE // 0: PE: = 0: General call disabled. Address 00h is NACKed.
// 1: SMBUS: = 0: I2C mode
// 2: Reserved, must be kept at reset value
// 3: SMBTYPE: = 0:
// 4: ENARP: = 0: ARP disable
// 5: ENPEC: = 0: PEC calculation disabled
// 6: ENGC: = 0: General call disabled. Address 00h is NACKed.
| I2C_NOSTRETCH_DISABLE // 7: NOSTRETCH: = 0: Clock stretching enabled
// 8: START: = 0: In Master Mode: 0: No Start generation
// 9: STOP: = 0: In Master Mode: 0: No Stop generation.
| 0; // 10: ACK: = 0: No acknowledge returned
// 11: POS: = 0: ACK bit controls the (N)ACK of the current byte being received in the shift register.
// 12: PEC: = 0: No PEC transfer
// 13: ALERT: = 0: SMBus alert, Releases SMBA pin high
// 14: Reserved, must be kept at reset value
// 15: SWRST: = 0: I2C Peripheral not under reset
// Configure I2C2: Own Address1 and addressing mode
I2C_NFC->OAR1 = 0; // 0: ADD0: = 0: Interface address. 7-bit addressing mode: don’t care
// 1-7: ADD[7:1]: = 0: Interface address.
// 8-9: ADD[9:8]: = 0: Interface address. 7-bit addressing mode: don’t care
// 10:13:Reserved, must be kept at reset value
// 14: Should always be kept at 1 by software.
// 15: ADDMODE: = 0: 7-bit slave address (10-bit address not acknowledged)
// Configure I2C2x: Dual mode and Own Address2
I2C_NFC->OAR2 = I2C_DUALADDRESS_DISABLE; // 0: ENDUAL: = 0: Dual addressing mode enable
// 1-7: ADD2[7:1]: = FE: Interface address in dual addressing mode
// 8:15: Reserved, must be kept at reset value
//I2C_NFC->CR1 |= I2C_CR1_ACK;
gpio_vConfigI2cSdaIoAsOut();
IO_INACTIVE(I2C_NFC_SDA);
//TODO CN: add delay if needed
IO_ACTIVE(I2C_NFC_SDA);
gpio_vConfigI2cSdaIoAsAf();
// Enable the I2C2 peripheral
I2C_NFC->CR1 |= I2C_CR1_PE; // 0: PE: = 1: Peripheral enable
// Set I2C u32Error None
NFCL_tIICHandle.u32ErrorCode = I2C_ERROR_NONE;
// Set I2C eState Ready
NFCL_tIICHandle.eState = I2C_STATE_READY;
// Set I2C u32PreviousState None
NFCL_tIICHandle.u32PreviousState = I2C_STATE_NONE;