AnsweredAssumed Answered

STM32F30x I2C BR24L04 EEPROM Read All Zeros

Question asked by kasapoglu.orkun on Mar 9, 2017
Latest reply on Mar 31, 2017 by kasapoglu.orkun

Hi all. I'm trying to read the eeprom I'm using the std_periph_library. I can send the address information to eeprom and get the ack bits correctly. I've connected pullups on the SCL and SDA pins. I'm using the I2C1 (I2Cx)

 

const uint8_t DEVICE[] = {0xA0, 0xA4};
const uint16_t WP[] = {GPIO_Pin_10, GPIO_Pin_11};

#define WP_PORT        GPIOB

#define WP_DISABLE(p) GPIO_WriteBit(WP_PORT, p, Bit_RESET)
#define WP_ENABLE(p) GPIO_WriteBit(WP_PORT, p, Bit_SET)

#define I2Cx_PIN_ENABLE() RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE)

#define I2Cx_SCL_PIN   GPIO_Pin_8
#define I2Cx_SDA_PIN   GPIO_Pin_9
#define I2Cx_PIN_PORT  GPIOB

#define I2Cx_CLK_ENABLE() RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE)

 

void RMSNO_Init(void)
{
 I2C_InitTypeDef i2c;
 GPIO_InitTypeDef gpio;
 NVIC_InitTypeDef nvic;

 gpio.GPIO_Pin = I2Cx_SCL_PIN | I2Cx_SDA_PIN;
 gpio.GPIO_Mode = GPIO_Mode_AF;
 gpio.GPIO_OType = GPIO_OType_PP;
 gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
 gpio.GPIO_Speed = GPIO_Speed_50MHz;

 I2Cx_PIN_ENABLE();

 GPIO_Init(I2Cx_PIN_PORT, &gpio);

 GPIO_PinAFConfig(I2Cx_PIN_PORT, GPIO_PinSource8, GPIO_AF_4);
 GPIO_PinAFConfig(I2Cx_PIN_PORT, GPIO_PinSource9, GPIO_AF_4);

 i2c.I2C_Timing = I2Cx_TIMING;
 i2c.I2C_Ack = I2C_Ack_Enable;
 i2c.I2C_Mode = I2C_Mode_I2C;
 i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
 i2c.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
 i2c.I2C_DigitalFilter = 0x00;
 i2c.I2C_OwnAddress1 = 0x00;

 I2Cx_CLK_ENABLE();

 RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
 
 I2C_Init(I2Cx, &i2c);

 I2C_Cmd(I2Cx, ENABLE);

 /* Enable transfer address matched, transfer completed */
 //I2C_ITConfig(I2Cx, I2C_IT_ADDR, ENABLE);
 //I2C_ITConfig(I2Cx, I2C_IT_TCI, ENABLE);

 /* Set transfer direction */
 I2C_MasterRequestConfig(I2Cx,
                         I2C_Direction_Transmitter | I2C_Direction_Receiver);

  /* Ehable auto end mode */
 I2C_AutoEndCmd(I2Cx, ENABLE);

 /* Set interrupt */
 nvic.NVIC_IRQChannel = I2C1_EV_IRQn;
 nvic.NVIC_IRQChannelCmd = ENABLE;
 nvic.NVIC_IRQChannelPreemptionPriority = 0x05;
 nvic.NVIC_IRQChannelSubPriority = 0x05;
 NVIC_Init(&nvic);

 gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
 gpio.GPIO_Mode = GPIO_Mode_OUT;
 gpio.GPIO_OType = GPIO_OType_PP;
 gpio.GPIO_PuPd = GPIO_PuPd_UP;

 GPIO_Init(WP_PORT, &gpio);

 WP_ENABLE(WP[0]);
 WP_ENABLE(WP[1]);
}

static int EEPROMRead(uint8_t dev, uint16_t addr, uint8_t *buf, uint16_t n)
{
  uint8_t addrH;
 uint8_t addrL;
 int i;

 if (buf == NULL)
  return -1;

 /* Check busy flag */
 EEPROMTimeout = I2Cx_TIMEOUT;
 while(I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET)
 {
   if ((EEPROMTimeout--) == 0)
   return -2;
 }

 /*
    Configure the slave address, nbytes, reload,
    end mode and start stop generation
  */
 I2C_TransferHandling(I2Cx, dev, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
 EEPROMTimeout = I2Cx_TIMEOUT;
 while(I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET)
 {
   if ((EEPROMTimeout--) == 0)
   return -2;
 }

 addrH = (uint8_t)(addr >> 8);
 addrL = (uint8_t)addr;

 /* Send register address high byte */
 I2C_SendData(I2Cx, addrH);
 I2C_SendData(I2Cx, addrL);
 EEPROMTimeout = I2Cx_TIMEOUT;
 while(I2C_GetFlagStatus(I2C1, I2C_ISR_TC) == RESET)
 {
   if ((EEPROMTimeout--) == 0)
   return -2;
 }

 /* Set the page read bit */
 if (n > 1)
  dev |= (PAGE_MASK);
 
 I2C_TransferHandling(I2Cx, dev, n, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);

 for (i = 0; i < n; i++)
 {
  /* Wait until RXNE flag is set */
  EEPROMTimeout = I2Cx_TIMEOUT;
  while(I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET)
  {
    if ((EEPROMTimeout--) == 0)
    return -2;
  }
  /* Read data from RXDR */
   buf[i] = I2C_ReceiveData(I2Cx);
 }

 return 0;

}

 

These are the codes.

 

The waveforms attached. Device is not empty but I'm getting all zeros. WP pins are write protection pins and when they high level write is prohibited. When I want to call read;

 

WP_DISABLE(WP[device]);
 retval = EEPROMRead(DEVICE[device], addr, d, n);
 WP_ENABLE(WP[device]);

 

here is device is 0 or 1.

 

Edit: I've  checked the write function and I realized that the write did not complete. Timeout variable is going zero before TC is set. But STOPF is setting by hw. Here is my write function.

 

static int EEPROMWrite(uint8_t dev, uint16_t addr, uint8_t *buf, uint16_t n)
{
 uint8_t addH;
 uint8_t addL;
 int i;

 /* Check the buffer */
 if (buf == NULL)
  return -1;
 
 /* Check busy flag */
  EEPROMTimeout = I2Cx_TIMEOUT;
 while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET)
  {
  if ((EEPROMTimeout--) == 0)
   return -2;
  }

 /* Set the page bit */
 if (n > 1)
  dev |= PAGE_MASK;

 /* Configure the communication parameters */
 I2C_TransferHandling(I2Cx, dev, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);

 /* Wait until TXIS flag is set */
 EEPROMTimeout = I2Cx_TIMEOUT;
 while(I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET)
 {
   if ((EEPROMTimeout--) == 0)
   return -2;
 }

 addH = (uint8_t)(addr >> 8);
 addL = (uint8_t)addr;
 /* Send 16-bit register address */
 I2C_SendData(I2Cx, addH);
 I2C_SendData(I2Cx, addL);
 
 EEPROMTimeout = I2Cx_TIMEOUT;
 while(I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET)
 {
   if ((EEPROMTimeout--) == 0)
   return -2;
 }

 /* Configure the communication parameters */
 I2C_TransferHandling(I2Cx, dev, n, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);

 

 for (i = 0; i < n; i++)
  I2C_SendData(I2Cx, buf[i]);
 
 EEPROMTimeout = I2Cx_TIMEOUT;
 while(I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET)
 {
   if ((EEPROMTimeout--) == 0)
   return -2; // Here is timeout occuring.
 }

 return 0;
}

 

Should I check the TC flag for each data or is that true. EEPROM addresses are 16-bit.

Attachments

Outcomes