Drop I2C bit functions, to make timing easier to modify

I2C to the charger now has clean 100kHz timing. One read command now takes
400us, and one write command takes 300us to execute.
This commit is contained in:
Ondrej Jirman 2021-09-05 02:26:55 +02:00
parent 78c72fe448
commit 31c41b7d9e
2 changed files with 53 additions and 43 deletions

View File

@ -1006,7 +1006,7 @@ static __bit poll_scl_busy(void)
} }
*/ */
void i2c_start_condition(void) static void i2c_start_condition(void)
{ {
CHG_RELEASE_SDA; CHG_RELEASE_SDA;
delay_us(5); delay_us(5);
@ -1021,7 +1021,7 @@ void i2c_start_condition(void)
delay_us(5); delay_us(5);
} }
void i2c_stop_condition(void) static void i2c_stop_condition(void)
{ {
CHG_PULL_SDA; CHG_PULL_SDA;
delay_us(5); delay_us(5);
@ -1033,68 +1033,78 @@ void i2c_stop_condition(void)
delay_us(5); delay_us(5);
} }
void i2c_write_bit(__bit b) static __bit i2c_write_byte(uint8_t data)
{ {
if (b) uint8_t i;
CHG_RELEASE_SDA; __bit ack = 1;
else
CHG_PULL_SDA; // write data
for (i = 0; i < 8; i++) {
// write the most-significant bit
if (data & 0x80)
CHG_RELEASE_SDA;
else
CHG_PULL_SDA;
delay_us(1);
CHG_RELEASE_SCL;
delay_us(5);
CHG_PULL_SCL;
delay_us(1);
data <<= 1;
}
delay_us(1); delay_us(1);
CHG_RELEASE_SCL; // read ack bit
delay_us(5);
CHG_PULL_SCL;
delay_us(1);
}
__bit i2c_read_bit(void)
{
__bit b;
CHG_RELEASE_SDA; CHG_RELEASE_SDA;
CHG_RELEASE_SCL; CHG_RELEASE_SCL;
delay_us(4); delay_us(3);
if (CHG_PORT & CHG_SDA) if (CHG_PORT & CHG_SDA)
b = 1; ack = 0;
else
b = 0;
CHG_PULL_SCL; CHG_PULL_SCL;
delay_us(2); delay_us(2);
return b; return ack;
} }
__bit i2c_write_byte(uint8_t data) static uint8_t i2c_read_byte(__bit ack)
{
uint8_t i;
// write data
for (i = 0; i < 8; i++) {
i2c_write_bit(data & 0x80); // write the most-significant bit
data <<= 1;
}
// read ack bit
return !i2c_read_bit();
}
uint8_t i2c_read_byte(__bit ack)
{ {
uint8_t data = 0; uint8_t data = 0;
uint8_t i; uint8_t i;
CHG_RELEASE_SDA;
// read data // read data
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
data <<= 1; data <<= 1;
data |= i2c_read_bit();
CHG_RELEASE_SCL;
delay_us(4);
if (CHG_PORT & CHG_SDA)
data |= 1;
CHG_PULL_SCL;
delay_us(2);
} }
// send ack // send ack
i2c_write_bit(!ack); if (ack)
CHG_PULL_SDA;
else
CHG_RELEASE_SDA;
delay_us(1);
CHG_RELEASE_SCL;
delay_us(5);
CHG_PULL_SCL;
delay_us(1);
return data; return data;
} }

View File

@ -130,7 +130,7 @@ uint8_t read_power(int fd, uint8_t reg)
syscall_error(ret < 0, "I2C_RDWR failed"); syscall_error(ret < 0, "I2C_RDWR failed");
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
usleep(2000); usleep(700);
// read the result // read the result
uint8_t buf2[1] = { REG_SYS_CHG_DATA, }; uint8_t buf2[1] = { REG_SYS_CHG_DATA, };
@ -183,7 +183,7 @@ void write_power(int fd, uint8_t reg, uint8_t val)
syscall_error(ret < 0, "I2C_RDWR failed"); syscall_error(ret < 0, "I2C_RDWR failed");
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
usleep(2000); usleep(700);
// read the result // read the result
uint8_t buf2[1] = { REG_SYS_COMMAND, }; uint8_t buf2[1] = { REG_SYS_COMMAND, };