2022-10-21 02:27 AM
Hi,
I am trying to write some datato external eeprom with I2C_EEPROM_WritePage function, but it doesn't write everytime. Sometimes it can write and sometimes it can't. I am using standart peripheral I2C library and using the write page function below. Any advise ?
void I2C_EEPROM_WritePage(unsigned char* pBuffer, unsigned short MemAddr, unsigned short NumData, unsigned char mode)
{
unsigned char byteRemain;
if(I2C_EE_State & I2C_STATE_ERROR)
{
I2C_EEPROM_ErrorCallback();
}
if((NumData == 0) || ((MemAddr+ NumData) > (I2C_DRIVER_MAX_SUPPORTED_SIZE - 1)))
return; /* nothing to write or not allowed */
while(NumData > 0)
{
/* calculate remaining bytes till page end */
byteRemain = I2C_currentSettings->EE_pageSize - ((unsigned short)MemAddr % I2C_currentSettings->EE_pageSize);
/* bytes fit in page */
if(byteRemain >= NumData)
{
if(I2C_EEPROM_Write(pBuffer, MemAddr, NumData, mode) == I2C_ERROR)
{
// write error
I2C_EEPROM_ErrorCallback();
WDG_RESET();
}
NumData = 0;
}
/* bytes overlap with next page */
else
{
/* write bytes into page till page end */
if(I2C_EEPROM_Write(pBuffer, MemAddr, byteRemain, mode) == I2C_ERROR)
{
// write error
I2C_EEPROM_ErrorCallback();
}
NumData -= byteRemain;
MemAddr += byteRemain;
if(mode == I2C_MODE_NORMAL)
{
pBuffer += byteRemain;
}
}
}
return;
}
I2C_eResult I2C_EEPROM_Write(unsigned char *pBuffer, unsigned short MemAddr, unsigned short NumData, unsigned char mode)
{
/* check I2C Driver state */
if((I2C_EE_State & I2C_STATE_READY) && !(I2C_EE_State & I2C_STATE_ERROR))
{
if(NumData == 0)
{
return I2C_DENIED; /* nothing to read */
}
else
{
/* update state machine */
I2C_EE_State |= I2C_STATE_BUSY;
I2C_EE_State &= ~I2C_STATE_READY;
}
/* generate start condition TX */
if(I2C_EEPROM_Start(I2C_Direction_Transmitter) == I2C_ERROR)
{
return I2C_ERROR; /* communication error */
}
I2C_EEPROM_SendAddr(MemAddr); /* send 16 bit address */
while(NumData > 0)
{
I2C_SendMasterByte(*pBuffer);
NumData--;
if(mode == I2C_MODE_NORMAL)
{
pBuffer++;
}
}
/* wait until byte transmitted */
I2C_EE_Timeout = I2C_currentSettings->I2C_timeoutWr + 1; // +1 with I2C_timeoutWr = 1 allows
// that for sending timer interrupt can occure at least once
while(!I2C_CheckEvent(I2C_DEV_EEPROM, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && I2C_EE_Timeout > 0)
{
}
/* Send STOP Condition */
I2C_GenerateSTOP(I2C_DEV_EEPROM, ENABLE);
/* Wait to make sure that STOP control bit has been cleared */
I2C_EE_Timeout = I2C_currentSettings->I2C_timeoutDefault;
while((I2C_ReadRegister(I2C_DEV_EEPROM, I2C_Register_CR1)) & I2C_CR1_STOP)
{
if(I2C_EE_Timeout == 0)
{
I2C_EE_State |= I2C_STATE_ERROR | I2C_ERR_TX;
return I2C_ERROR;
}
}
// reset write control
I2C_EEPROM_WriteControl(DISABLE);
/* update state machine */
I2C_EE_State |= I2C_STATE_READY;
I2C_EE_State &= ~I2C_STATE_BUSY;
return I2C_SUCCESS;
}
else
{
/* driver not ready */
/* update state machine */
I2C_EE_State |= I2C_STATE_ERROR;
return I2C_ERROR;
}
}