STM32F30x I2C BR24L04 EEPROM Read All Zeros
- March 9, 2017
- 3 replies
- 1638 views
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};&sharpdefine WP_PORT GPIOB
&sharpdefine WP_DISABLE(p) GPIO_WriteBit(WP_PORT, p, Bit_RESET)
&sharpdefine WP_ENABLE(p) GPIO_WriteBit(WP_PORT, p, Bit_SET)&sharpdefine I2Cx_PIN_ENABLE() RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE)
&sharpdefine I2Cx_SCL_PIN GPIO_Pin_8
&sharpdefine I2Cx_SDA_PIN GPIO_Pin_9&sharpdefine I2Cx_PIN_PORT GPIOB&sharpdefine 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.
#stm32f30x #i2c #eeprom