# STM32f030C8 I2C EEPROM -no data received when read after a write

I am developing library for I2C eeprom at24c04 with stm32f030c8. My read and write functions work but when i try to read immediately after a write to eeprom, the eeprom doest return any data. however i could immediately do a write consecutively. The problem occurs only when i read after a write statement. i tried enabling and disabling the I2C enable bit but problem still exist. Can anyone tell me whats the issue.

void main()
{
Configure_GPIO_I2C2();
Configure_I2C2_Master(0xA0,1);

I2C_WriteByte(5,'k');
charr= I2C_ReadByte(5);//the program get stuck here because no byte is
UART_Send_String(1,&charr);

}

{
I2C2->ISR=0x01;
I2C2_StartWrite(2);//start

while(!(I2C2->ISR & I2C_ISR_TXE));

//I2C2_StartWrite(1);

I2C2->TXDR = bytetowrite;
while(!(I2C2->ISR & I2C_ISR_TXE));

I2C2->CR2 |= I2C_CR2_STOP;//stop
while(I2C2->CR2 & I2C_CR2_STOP);

}

{
I2C2->ISR=0x01;
I2C2_StartWrite(1);

while(!(I2C2->ISR & I2C_ISR_TXE));

while(!(I2C2->ISR & I2C_ISR_RXNE));
UART_Send_String(1,"r strt");
uint8_t recv_data=I2C2->RXDR;

I2C2->CR2 |= I2C_CR2_STOP;
while(I2C2->CR2 & I2C_CR2_STOP);

return recv_data;

}

/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
void Configure_GPIO_I2C2(void)
{

RCC->AHBENR |= RCC_AHBENR_GPIOFEN;
GPIOF->MODER |= (2<<12) | (2<<14);
GPIOF->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7;

GPIOF->OSPEEDR &=  ~(1<<12);
GPIOF->OSPEEDR &=  ~(1<<14);

GPIOF->PUPDR &= ~(1<<12);
GPIOF->PUPDR &= ~(1<<12);
}

{

RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;

/* (1) Timing register value is computed with the AN4235 xls file,
fast Mode @400kHz with I2CCLK = 48MHz, rise time = 140ns, fall time = 40ns */
I2C2->CR1 &= ~I2C_CR1_PE;
I2C2->TIMINGR |= (uint32_t)0x00B01A4B; /* (1) */
I2C2->CR2 |= no_of_bytes<<16;
I2C2->CR1 |= I2C_CR1_PE;
//NVIC_SetPriority(I2C2_IRQn, 0); /* (7) */
//NVIC_EnableIRQ(I2C2_IRQn); /* (8) */
}

void I2C2_StartWrite(int bytesToWrite)
{

I2C2->CR2 &= ~I2C_CR2_RD_WRN;

I2C2->CR2 |= bytesToWrite<<16;

I2C2->CR2 |= I2C_CR2_START;
while(I2C2->CR2 & I2C_CR2_START);
}

{
I2C2->CR2 |= I2C_CR2_RD_WRN;

I2C2->CR2 |= I2C_CR2_START;
while(I2C2->CR2 & I2C_CR2_START);
}

• Are you doing any sort of check to ensure the write has finished before you read it so soon? – DiBosco Jun 21 '18 at 8:32
• i did try an acknowledgement polling as mentioned in data sheet. and even a delay. but the result is same – Nikhil Ben George Jun 21 '18 at 8:40
• What does I2C2_StartWrite do? Are you aware of the exact sequence of writing and reading with I2C? It should look like the waveforms on page 11 of the datsasheet. Then do you know how a read is done? Again, details are on the datasheet. What does your scope show is actually happening as opposed to what you think should be happening? – DiBosco Jun 21 '18 at 8:51
• i added the I2C2_StartWrite and I2C2_StartRead functions. I developed the code from tutorial and from datasheet. i believe i m following the right method because i was able to write and read individually. Im following the i2c cycle shown in datasheet. @DiBosco – Nikhil Ben George Jun 21 '18 at 9:16
• First of all, I'd like to repeat: What does your scope show? I hope I'm wrong, but I suspect because you dodged that question you've not used it yet. Second, I don't see enough accesses to TXDR. My suspcion is you don't quite understand how you need to write the hardware address, then the internal address, then the data. Reading data is even more complicated. I2C takes a lot of getting used to, it's quite a mind **** when you first try it. This tutorial IMHO is good: robot-electronics.co.uk/i2c-tutorial – DiBosco Jun 21 '18 at 9:31

My read and write functions work but when i try to read immediately after a write to eeprom, the eeprom doest return any data. however i could immediately do a write consecutively.

This smells like you are not waiting for the EEPROM to finish the write. I didn't look at your EEPROM, but with all the ones I've ever used, a write or erase sequence only starts the action. The EEPROM is then busy for some time afterward.

Most EEPROMs have something like a status register where you can poll a bit to see if it is busy. This read action can be performed whether busy or not.

The most general software architecture always polls the busy bit before trying to do anything. If the EEPROM is busy, it keeps polling until it is not, then proceeds with whatever action was requested. More sophisticated implementations set a flag on write and erase, indicating that the EEPROM might be busy. Busy checking is only done when this flag is set. Naive implementations always just wait after a erase or write.

Look at your code carefully, especially what exactly is sent to the EEPROM when a write is immediately followed by a read. My guess is that the busy checking is somehow skipped in that case.