fix i2c routines

This commit is contained in:
true 2024-08-10 07:08:02 -07:00
parent c5bfc4cb73
commit 5365ab2d5b
2 changed files with 43 additions and 24 deletions

View File

@ -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,11 +80,9 @@ 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);
}
}
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;
}

View File

@ -1,8 +1,5 @@
/*
* i2c.h
*
* Created on: Jul 27, 2024
* Author: true
*/
#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);