AnsweredAssumed Answered

STM32F407VG + M24SR

Question asked by Egor Vasilyev on Apr 16, 2018
Latest reply on Apr 17, 2018 by NFC software support 3

I'm trying to connect m24sr to stm32f407vgt.
I switch to I2C2, clocking from an external resonator at 8 MHz, SYSCLK 72 MHz, I use a converted library for Open107V. For stm32f107vc this code worked, but when switching to stm32f407 i2c does not work (most likely there is no response from m24sr and a timeout error occurs).

I've been puzzling for several days, I can not find the error.

Defines for i2c

#define M24SR_SDA_PIN GPIO_Pin_11
#define M24SR_SDA_PIN_SOURCE GPIO_PinSource11
#define M24SR_SDA_PIN_PORT GPIOB

#define M24SR_SCL_PIN GPIO_Pin_10
#define M24SR_SCL_PIN_SOURCE GPIO_PinSource10
#define M24SR_SCL_PIN_PORT GPIOB

#define M24SR_GPO_PIN GPIO_Pin_15
#define M24SR_GPO_PIN_PORT GPIOD

#define M24SR_RFDIS_PIN GPIO_Pin_14
#define M24SR_RFDIS_PIN_PORT GPIOD

#if defined STM32F40_41xxx
#define M24SR_GPIO_BLOCK_CLK (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD)
#else
#define M24SR_GPIO_BLOCK_CLK (RCC_APB2Periph_GPIOB | RCC_AHB1Periph_GPIOD)
#endif

/ * I2C config ---------------------------------------------- -------------------------------- * /
#define M24SR_I2C I2C2
#define M24SR_I2C_BLOCK_CLK RCC_APB1Periph_I2C2
#define M24SR_I2C_CLOCKSPEED 400,000

The code itself

void M24SR_Init (void)
{
M24SR_I2CInit ();

M24SR_InitStructure ();

#ifdef I2C_GPO_SYNCHRO_ALLOWED
M24SR_KillSession ();
M24SR_RFConfig (0);
M24SR_ManageI2CGPO (I2C_ANSWER_READY);


M24SR_Deselect ();
 
#endif / * I2C_GPO_SYNCHRO_ALLOWED * /
}


void M24SR_I2CInit (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;

  / * GPIO Periph clock enable * /
#if defined STM32F40_41xxx
RCC_AHB1PeriphClockCmd (M24SR_GPIO_BLOCK_CLK, ENABLE);
#else
RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO | M24SR_GPIO_BLOCK_CLK, ENABLE);
#endif

  / * I2C Periph clock enable * /
  RCC_APB1PeriphClockCmd (M24SR_I2C_BLOCK_CLK, ENABLE);

  / * Configure I2C pins: SCL and SDA * /
  GPIO_InitStructure.GPIO_Pin = M24SR_SCL_PIN | M24SR_SDA_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
#if defined STM32F40_41xxx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
#else
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
#endif
  GPIO_Init (M24SR_SDA_PIN_PORT, & GPIO_InitStructure);

#if defined STM32F40_41xxx
/ * Connect I2C pins to AF * /
  GPIO_PinAFConfig (M24SR_SCL_PIN_PORT, M24SR_SCL_PIN_SOURCE, GPIO_AF_I2C2);
  GPIO_PinAFConfig (M24SR_SDA_PIN_PORT, M24SR_SDA_PIN_SOURCE, GPIO_AF_I2C2);
#endif

  / * Configure GPIO for M24SR GPO as Input pull-up, used as Interuption comming from the M24SR * /
  GPIO_InitStructure.GPIO_Pin = M24SR_GPO_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
#if defined STM32F40_41xxx
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
#else
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
#endif
  GPIO_Init (M24SR_GPO_PIN_PORT, & GPIO_InitStructure);

/ * Configure GPIO for M24SR RF Disable signal * /
  GPIO_InitStructure.GPIO_Pin = M24SR_RFDIS_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
#if defined STM32F40_41xxx
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
#else
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
#endif
  GPIO_Init (M24SR_RFDIS_PIN_PORT, & GPIO_InitStructure);

  I2C_DeInit (M24SR_I2C);

  / * I2C Init * /
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = M24SR_I2C_CLOCKSPEED;
  I2C_Init (M24SR_I2C, & I2C_InitStructure);

  / * I2C Init * /
  I2C_Cmd (M24SR_I2C, ENABLE);

}


static void M24SR_InitStructure (void)
{
/ * build the command * /
Command.Header.CLA = 0x00;
Command.Header.INS = 0x00;
/ * copy the offset * /
Command.Header.P1 = 0x00;
Command.Header.P2 = 0x00;
/ * copy the number of byte of the data field * /
Command.Body.LC = 0x00;
/ * copy the number of byte to read * /
Command.Body.LE = 0x00;
Command.Body.pData = DataBuffer;
}


uint16_t M24SR_KillSession (void)
{
uint8_t pBuffer [] = {M24SR_KILLSESSION};
int8_t status;

errchk (M24SR_SendI2Ccommand (0x01, pBuffer));

/ * insure no access will be done just after open session * /
/ * The only way here is to poll I2C to know when M24SR is ready * /
/ * GPO can not be used with KillSession command * /
errchk (M24SR_PollI2C ());

return M24SR_ACTION_COMPLETED;
Error:
/ * Send STOP Condition * /
  I2C_GenerateSTOP (M24SR_I2C, ENABLE);
return M24SR_ERROR_I2CTIMEOUT;
}

Outcomes