diff --git a/code/firmware/user/src/i2c.c b/code/firmware/user/src/i2c.c index 3620857..767c46f 100644 --- a/code/firmware/user/src/i2c.c +++ b/code/firmware/user/src/i2c.c @@ -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);