Fixes #2421 - Full check of I2C errors / infinite wait. In case of

eeprom read/write error, the I2C is reinitialized and the operation
started again.
This commit is contained in:
bsongis
2015-07-06 07:55:02 +02:00
parent e090078401
commit 01b0c015f6
+82 -44
View File
@@ -1,10 +1,12 @@
#include "board_taranis.h"
void I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite);
void I2C_EE_WaitEepromStandbyState(void);
void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite);
void eepromWaitEepromStandbyState(void);
void eepromInit(void)
{
I2C_DeInit(I2C);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_GPIO_PIN_WP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
@@ -36,7 +38,7 @@ void eepromInit(void)
}
#define I2C_TIMEOUT_MAX 1000
bool I2C_CheckEventTimeout(uint32_t event)
bool I2C_WaitEvent(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (!I2C_CheckEvent(I2C, event)) {
@@ -45,6 +47,15 @@ bool I2C_CheckEventTimeout(uint32_t event)
return true;
}
bool I2C_WaitEventCleared(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (I2C_CheckEvent(I2C, event)) {
if ((timeout--) == 0) return false;
}
return true;
}
/**
* @brief Reads a block of data from the EEPROM.
* @param pBuffer : pointer to the buffer that receives the data read
@@ -53,32 +64,33 @@ bool I2C_CheckEventTimeout(uint32_t event)
* @param NumByteToRead : number of bytes to read from the EEPROM.
* @retval None
*/
void eepromReadBlock(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead)
bool I2C_EE_ReadBlock(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead)
{
while (I2C_CheckEvent(I2C, I2C_FLAG_BUSY));
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
return false;
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_MODE_SELECT))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return false;
I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return false;
I2C_SendData(I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return false;
I2C_SendData(I2C, (uint8_t)(ReadAddr & 0x00FF));
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return false;
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_MODE_SELECT))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return false;
I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Receiver);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
return false;
if (NumByteToRead > 1) {
I2C_AcknowledgeConfig(I2C, ENABLE);
@@ -88,13 +100,21 @@ void eepromReadBlock(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead
if (NumByteToRead == 1) {
I2C_AcknowledgeConfig(I2C, DISABLE);
}
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_RECEIVED))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
return false;
*pBuffer++ = I2C_ReceiveData(I2C);
NumByteToRead--;
}
I2C_GenerateSTOP(I2C, ENABLE);
return true;
}
void eepromReadBlock(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead)
{
while (!I2C_EE_ReadBlock(pBuffer, ReadAddr, NumByteToRead)) {
eepromInit();
}
}
/**
@@ -113,8 +133,8 @@ void eepromWriteBlock(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWr
count = NumByteToWrite;
}
while (count > 0) {
I2C_EE_PageWrite(pBuffer, WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
eepromPageWrite(pBuffer, WriteAddr, count);
eepromWaitEepromStandbyState();
WriteAddr += count;
pBuffer += count;
NumByteToWrite -= count;
@@ -134,37 +154,46 @@ void eepromWriteBlock(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWr
* @param NumByteToWrite : number of bytes to write to the EEPROM.
* @retval None
*/
void I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite)
bool I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite)
{
while (I2C_CheckEvent(I2C, I2C_FLAG_BUSY));
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
return false;
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_MODE_SELECT))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return false;
I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return false;
I2C_SendData(I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8));
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return false;
I2C_SendData(I2C, (uint8_t)(WriteAddr & 0x00FF));
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return false;
/* While there is data to be written */
while (NumByteToWrite--) {
I2C_SendData(I2C, *pBuffer);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return false;
pBuffer++;
}
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return false;
I2C_GenerateSTOP(I2C, ENABLE);
return true;
}
void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite)
{
while (!I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite)) {
eepromInit();
}
}
/**
@@ -172,17 +201,25 @@ void I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWri
* @param None
* @retval None
*/
void I2C_EE_WaitEepromStandbyState(void)
bool I2C_EE_WaitEepromStandbyState(void)
{
do {
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_MODE_SELECT))
return;
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return false;
I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter);
} while (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
} while (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_GenerateSTOP(I2C, ENABLE);
return true;
}
void eepromWaitEepromStandbyState(void)
{
while (!I2C_EE_WaitEepromStandbyState()) {
eepromInit();
}
}
void setVolume(uint8_t volume)
@@ -191,21 +228,22 @@ void setVolume(uint8_t volume)
volume = VOLUME_LEVEL_MAX;
}
while (I2C_CheckEvent(I2C, I2C_FLAG_BUSY));
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
return;
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_MODE_SELECT))
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
return;
I2C_Send7bitAddress(I2C, I2C_ADDRESS_CAT5137, I2C_Direction_Transmitter);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
return;
I2C_SendData(I2C, 0);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
return;
I2C_SendData(I2C, volumeScale[volume]);
if (!I2C_CheckEventTimeout(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
return;
I2C_GenerateSTOP(I2C, ENABLE);