aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimofey Titovets <nefelim4ag@gmail.com>2025-04-09 01:45:52 +0200
committerKevinOConnor <kevin@koconnor.net>2025-04-17 11:41:49 -0400
commit841adcfff759b7fc2a229a0627151600b8d1cc25 (patch)
treec68bc08ff6d1a57092d5b183055b633c7382bfdb
parent8ab12c86bfa843ee317b0ec539d9713cc960c8ee (diff)
downloadkutter-841adcfff759b7fc2a229a0627151600b8d1cc25.tar.gz
kutter-841adcfff759b7fc2a229a0627151600b8d1cc25.tar.xz
kutter-841adcfff759b7fc2a229a0627151600b8d1cc25.zip
i2c_software: reduce gpio calls count
gpio reset calls are heavy. gpio state are persistent between calls. Drop useless calls. Avoid calls if SDA does not changed. Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
-rw-r--r--src/i2c_software.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/src/i2c_software.c b/src/i2c_software.c
index 77da9447..805cef2d 100644
--- a/src/i2c_software.c
+++ b/src/i2c_software.c
@@ -65,9 +65,7 @@ i2c_delay(uint32_t ticks)
static void
i2c_software_send_ack(struct i2c_software *is, const uint8_t ack)
{
- if (ack) {
- gpio_in_reset(is->sda_in, 1);
- } else {
+ if (!ack) {
gpio_out_reset(is->sda_out, 0);
}
i2c_delay(is->ticks);
@@ -77,27 +75,32 @@ i2c_software_send_ack(struct i2c_software *is, const uint8_t ack)
}
static uint8_t
-i2c_software_read_ack(struct i2c_software *is)
+i2c_software_read_ack(struct i2c_software *is, uint_fast8_t state)
{
uint8_t nack = 0;
- gpio_in_reset(is->sda_in, 1);
+ if (state == 0)
+ gpio_in_reset(is->sda_in, 1);
i2c_delay(is->ticks);
gpio_in_reset(is->scl_in, 1);
nack = gpio_in_read(is->sda_in);
i2c_delay(is->ticks);
gpio_out_reset(is->scl_out, 0);
- gpio_in_reset(is->sda_in, 1);
return nack;
}
static int
i2c_software_send_byte(struct i2c_software *is, uint8_t b)
{
+ uint_fast8_t state = 2;
for (uint_fast8_t i = 0; i < 8; i++) {
if (b & 0x80) {
- gpio_in_reset(is->sda_in, 1);
+ if (state != 1)
+ gpio_in_reset(is->sda_in, 1);
+ state = 1;
} else {
- gpio_out_reset(is->sda_out, 0);
+ if (state > 0)
+ gpio_out_reset(is->sda_out, 0);
+ state = 0;
}
b <<= 1;
i2c_delay(is->ticks);
@@ -106,7 +109,7 @@ i2c_software_send_byte(struct i2c_software *is, uint8_t b)
gpio_out_reset(is->scl_out, 0);
}
- if (i2c_software_read_ack(is)) {
+ if (i2c_software_read_ack(is, state)) {
return I2C_BUS_NACK;
}
@@ -126,7 +129,6 @@ i2c_software_read_byte(struct i2c_software *is, uint8_t remaining)
b |= gpio_in_read(is->sda_in);
gpio_out_reset(is->scl_out, 0);
}
- gpio_in_reset(is->sda_in, 1);
i2c_software_send_ack(is, remaining == 0);
return b;
}