📄 stm32l152_eval_i2c_ee.c
字号:
/*!< Test on EV5 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send EEPROM address for write */
sEETimeout = sEE_FLAG_TIMEOUT;
I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
/*!< Test on EV6 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
#ifdef sEE_M24C08
/*!< Send the EEPROM's internal address to write to : only one byte Address */
I2C_SendData(sEE_I2C, WriteAddr);
#elif defined(sEE_M24C64_32)
/*!< Send the EEPROM's internal address to write to : MSB of the address first */
I2C_SendData(sEE_I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8));
/*!< Test on EV8 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send the EEPROM's internal address to write to : LSB of the address */
I2C_SendData(sEE_I2C, (uint8_t)(WriteAddr & 0x00FF));
#endif /*!< sEE_M24C08 */
/*!< Test on EV8 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Configure the DMA Tx Channel with the buffer address and the buffer size */
sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint8_t)(*NumByteToWrite), sEE_DIRECTION_TX);
/* Enable the DMA Tx Channel */
DMA_Cmd(sEE_I2C_DMA_CHANNEL_TX, ENABLE);
/* If all operations OK, return sEE_OK (0) */
return sEE_OK;
}
/**
* @brief Writes buffer of data to the I2C EEPROM.
* @param pBuffer : pointer to the buffer containing the data to be written
* to the EEPROM.
* @param WriteAddr : EEPROM's internal address to write to.
* @param NumByteToWrite : number of bytes to write to the EEPROM.
* @retval None
*/
void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{
uint8_t NumOfPage = 0, NumOfSingle = 0, count = 0;
uint16_t Addr = 0;
Addr = WriteAddr % sEE_PAGESIZE;
count = sEE_PAGESIZE - Addr;
NumOfPage = NumByteToWrite / sEE_PAGESIZE;
NumOfSingle = NumByteToWrite % sEE_PAGESIZE;
/*!< If WriteAddr is sEE_PAGESIZE aligned */
if(Addr == 0)
{
/*!< If NumByteToWrite < sEE_PAGESIZE */
if(NumOfPage == 0)
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
/* Start writing data */
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
}
/*!< If NumByteToWrite > sEE_PAGESIZE */
else
{
while(NumOfPage--)
{
/* Store the number of data to be written */
sEEDataNum = sEE_PAGESIZE;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
WriteAddr += sEE_PAGESIZE;
pBuffer += sEE_PAGESIZE;
}
if(NumOfSingle!=0)
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
}
}
}
/*!< If WriteAddr is not sEE_PAGESIZE aligned */
else
{
/*!< If NumByteToWrite < sEE_PAGESIZE */
if(NumOfPage== 0)
{
/*!< If the number of data to be written is more than the remaining space
in the current page: */
if (NumByteToWrite > count)
{
/* Store the number of data to be written */
sEEDataNum = count;
/*!< Write the data conained in same page */
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
/* Store the number of data to be written */
sEEDataNum = (NumByteToWrite - count);
/*!< Write the remaining data in the following page */
sEE_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
}
else
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
}
}
/*!< If NumByteToWrite > sEE_PAGESIZE */
else
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / sEE_PAGESIZE;
NumOfSingle = NumByteToWrite % sEE_PAGESIZE;
if(count != 0)
{
/* Store the number of data to be written */
sEEDataNum = count;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
WriteAddr += count;
pBuffer += count;
}
while(NumOfPage--)
{
/* Store the number of data to be written */
sEEDataNum = sEE_PAGESIZE;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
WriteAddr += sEE_PAGESIZE;
pBuffer += sEE_PAGESIZE;
}
if(NumOfSingle != 0)
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
/* Wait transfer through DMA to be complete */
sEETimeout = sEE_LONG_TIMEOUT;
while (sEEDataNum > 0)
{
if((sEETimeout--) == 0) {sEE_TIMEOUT_UserCallback(); return;};
}
sEE_WaitEepromStandbyState();
}
}
}
}
/**
* @brief Wait for EEPROM Standby state.
*
* @note This function allows to wait and check that EEPROM has finished the
* last operation. It is mostly used after Write operation: after receiving
* the buffer to be written, the EEPROM may need additional time to actually
* perform the write operation. During this time, it doesn't answer to
* I2C packets addressed to it. Once the write operation is complete
* the EEPROM responds to its address.
*
* @param None
* @retval sEE_OK (0) if operation is correctly performed, else return value
* different from sEE_OK (0) or the timeout user callback.
*/
uint32_t sEE_WaitEepromStandbyState(void)
{
__IO uint16_t tmpSR1 = 0;
__IO uint32_t sEETrials = 0;
/*!< While the bus is busy */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Keep looping till the slave acknowledge his address or maximum number
of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define
in stm32_eval_i2c_ee.h file) */
while (1)
{
/*!< Send START condition */
I2C_GenerateSTART(sEE_I2C, ENABLE);
/*!< Test on EV5 and clear it */
sEETimeout = sEE_FLAG_TIMEOUT;
while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/*!< Send EEPROM address for write */
I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
/* Wait for ADDR flag to be set (Slave acknowledged his address) */
sEETimeout = sEE_LONG_TIMEOUT;
do
{
/* Get the current value of the SR1 register */
tmpSR1 = sEE_I2C->SR1;
/* Update the timeout value and exit if it reach 0 */
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Keep looping till the Address is acknowledged or the AF flag is
set (address not acknowledged at time) */
while((tmpSR1 & (I2C_SR1_ADDR | I2C_SR1_AF)) == 0);
/* Check if the ADDR flag has been set */
if (tmpSR1 & I2C_SR1_ADDR)
{
/* Clear ADDR Flag by reading SR1 then SR2 registers (SR1 have already
been read) */
(void)sEE_I2C->SR2;
/*!< STOP condition */
I2C_GenerateSTOP(sEE_I2C, ENABLE);
/* Exit the function */
return sEE_OK;
}
else
{
/*!< Clear AF flag */
I2C_ClearFlag(sEE_I2C, I2C_FLAG_AF);
}
/* Check if the maximum allowed numbe of trials has bee reached */
if (sEETrials++ == sEE_MAX_TRIALS_NUMBER)
{
/* If the maximum number of trials has been reached, exit the function */
return sEE_TIMEOUT_UserCallback();
}
}
}
/**
* @brief This function handles the DMA Tx Channel interrupt Handler.
* @param None
* @retval None
*/
void sEE_I2C_DMA_TX_IRQHandler(void)
{
/* Check if the DMA transfer is complete */
if(DMA_GetFlagStatus(sEE_I2C_DMA_FLAG_TX_TC) != RESET)
{
/* Disable the DMA Tx Channel and Clear all its Flags */
DMA_Cmd(sEE_I2C_DMA_CHANNEL_TX, DISABLE);
DMA_ClearFlag(sEE_I2C_DMA_FLAG_TX_GL);
/*!< Wait till all data have been physically transferred on the bus */
sEETimeout = sEE_LONG_TIMEOUT;
while(!I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF))
{
if((sEETimeout--) == 0) sEE_TIMEOUT_UserCallback();
}
/*!< Send STOP condition */
I2C_GenerateSTOP(sEE_I2C, ENABLE);
/* Reset the variable holding the number of data to be written */
*sEEDataWritePointer = 0;
}
}
/**
* @brief This function handles the DMA Rx Channel interrupt Handler.
* @param None
* @retval None
*/
void sEE_I2C_DMA_RX_IRQHandler(void)
{
/* Check if the DMA transfer is complete */
if(DMA_GetFlagStatus(sEE_I2C_DMA_FLAG_RX_TC) != RESET)
{
/*!< Send STOP Condition */
I2C_GenerateSTOP(sEE_I2C, ENABLE);
/* Disable the DMA Rx Channel and Clear all its Flags */
DMA_Cmd(sEE_I2C_DMA_CHANNEL_RX, DISABLE);
DMA_ClearFlag(sEE_I2C_DMA_FLAG_RX_GL);
/* Reset the variable holding the number of data to be read */
*sEEDataReadPointer = 0;
}
}
#ifdef USE_DEFAULT_TIMEOUT_CALLBACK
/**
* @brief Basic management of the timeout situation.
* @param None.
* @retval None.
*/
uint32_t sEE_TIMEOUT_UserCallback(void)
{
/* Block communication and all processes */
while (1)
{
}
}
#endif /* USE_DEFAULT_TIMEOUT_CALLBACK */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -