diff --git a/firmware/user/src/i2c.c b/firmware/user/src/i2c.c index 68eb6d8..d00b5cf 100644 --- a/firmware/user/src/i2c.c +++ b/firmware/user/src/i2c.c @@ -18,7 +18,7 @@ #define I2C_TIMEOUT 0xefff #define I2C_TIMEOUT_ACK_POLL 0x180 -static uint16_t timeout; +static uint32_t timeout; void i2c_init() @@ -29,8 +29,7 @@ void i2c_init() i2c.I2C_ClockSpeed = 666666; i2c.I2C_Mode = I2C_Mode_I2C; - i2c.I2C_DutyCycle = I2C_DutyCycle_16_9; - i2c.I2C_OwnAddress1 = 0x7f; + i2c.I2C_DutyCycle = I2C_DutyCycle_2; // 16_9; i2c.I2C_Ack = I2C_Ack_Enable; i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2C1, &i2c); @@ -57,11 +56,13 @@ int8_t i2c_read_addr1b(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--); if (!timeout) return -3; + I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_SendData(I2C1, reg); timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--); if (!timeout) return -4; + I2C_AcknowledgeConfig(I2C1, ENABLE); I2C_GenerateSTART(I2C1, ENABLE); timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--); @@ -79,12 +80,10 @@ int8_t i2c_read_addr1b(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) *data++ = I2C_ReceiveData(I2C1); len--; - - if (!len) { - I2C_GenerateSTOP(I2C1, ENABLE); - } } + I2C_GenerateSTOP(I2C1, ENABLE); + return 0; } @@ -102,6 +101,8 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--); if (!timeout) return -1; + I2C_AcknowledgeConfig(I2C1, ENABLE); + I2C_GenerateSTART(I2C1, ENABLE); timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--); @@ -124,11 +125,10 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t I2C_SendData(I2C1, *data++); len--; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); + continue; } - // failed to acknowledge... reset bus + // failed to acknowledge... if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) { - I2C1->STAR1 = 0; - I2C_GenerateSTOP(I2C1, ENABLE); break; } } @@ -138,14 +138,20 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t return 0; } -void i2c_write_reg_8b(uint8_t addr, uint8_t reg, uint8_t dat) +void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat) { i2c_write_addr1b(addr, reg, &dat, 1); } -int8_t i2c_ack_poll(uint8_t addr) +int8_t i2c_addr_scan(uint8_t addr) { - int8_t addr_match = 0; + uint8_t found = 1; + uint32_t event; + + // no low addresses + if ((addr >> 4) == 0) return 0; + // no high addresses + if ((addr & 0xf8) == 0xf8) return 0; timeout = I2C_TIMEOUT; while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--); @@ -156,14 +162,30 @@ int8_t i2c_ack_poll(uint8_t addr) while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--); if (!timeout) return -2; - I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver); + I2C_Send7bitAddress(I2C1, (addr & 0xfe), (addr & 0x01)); timeout = I2C_TIMEOUT_ACK_POLL; - while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) && timeout--); - if (!timeout) { - addr_match = -128; + if (addr & 1) event = I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED; + else event = I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED; + + while ((I2C_CheckEvent(I2C1, event) == NoREADY) && timeout--) { + if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) { + found = 0; + break; + } } + if (!timeout) { + found = 0; + } + + // send a stop to make sure anything listening knows to stfu I2C_GenerateSTOP(I2C1, ENABLE); - return addr_match; + // reset flags; it might be in a fucked state + if (!found) { + I2C1->STAR1 = 0; + return 0; + } + + return addr; } diff --git a/firmware/user/src/i2c.h b/firmware/user/src/i2c.h index a17fe48..7ca772c 100644 --- a/firmware/user/src/i2c.h +++ b/firmware/user/src/i2c.h @@ -1,8 +1,5 @@ /* - * i2c.h - * - * Created on: Jul 27, 2024 - * Author: true + * Created on: Jul 27, 2024 */ #ifndef USER_SRC_I2C_H_ @@ -20,9 +17,9 @@ int8_t i2c_read_addr1b(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len); int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t len); uint8_t i2c_read_reg_8b(uint8_t addr, uint8_t reg); -void i2c_write_reg_8b(uint8_t addr, uint8_t reg, uint8_t dat); +void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat); -int8_t i2c_ack_poll(uint8_t devaddr); +int8_t i2c_addr_scan(uint8_t addr);