i2c.c: added timeouts

added timeouts to all the polling functions in the i2c code. hopefully if something hangs this gets it going again.

timeouts are not added on the data transfer portion, only on the initial setup portion. need to test if this is good enough.
This commit is contained in:
true 2024-07-28 16:49:17 -07:00
parent 2268b5368d
commit 20870dc3e3
1 changed files with 54 additions and 21 deletions

View File

@ -15,7 +15,10 @@
#define I2C_TIMEOUT 0xffff;
#define I2C_TIMEOUT 0xffff
#define I2C_TIMEOUT_ACK_POLL 0x180
static uint32_t timeout;
void i2c_init()
@ -42,25 +45,36 @@ void i2c_init()
/*
* reads data from devices which use a single-byte address
*/
void i2c_read_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len)
int8_t i2c_read_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);
timeout = I2C_TIMEOUT;
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
if (!timeout) return -1;
I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
if (!timeout) return -2;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, devaddr, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--);
if (!timeout) return -3;
I2C_SendData(I2C1, addr);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
if (!timeout) return -4;
I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
if (!timeout) return -5;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, devaddr, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) && timeout--);
if (!timeout) return -6;
while (len) {
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET) {
@ -74,20 +88,30 @@ void i2c_read_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len)
I2C_GenerateSTOP(I2C1, ENABLE);
}
}
return 0;
}
void i2c_write_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len)
int8_t i2c_write_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);
timeout = I2C_TIMEOUT;
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
if (!timeout) return -1;
I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
if (!timeout) return -2;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, devaddr, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--);
if (!timeout) return -3;
I2C_SendData(I2C1, addr);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
if (!timeout) return -4;
while (len) {
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) != RESET) {
@ -98,20 +122,29 @@ void i2c_write_addr1b(uint8_t devaddr, uint8_t addr, uint8_t *data, uint8_t len)
}
I2C_GenerateSTOP(I2C1, ENABLE);
return 0;
}
int8_t i2c_ack_poll(uint8_t devaddr)
{
int8_t addr_match = 0;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);
timeout = I2C_TIMEOUT;
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
if (!timeout) return -1;
I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
if (!timeout) return -2;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, devaddr, I2C_Direction_Receiver);
if (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
addr_match = -1;
timeout = I2C_TIMEOUT_ACK_POLL;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) && timeout--);
if (!timeout) {
addr_match = -128;
}
I2C_GenerateSTOP(I2C1, ENABLE);