aboutsummaryrefslogtreecommitdiffstats
path: root/src/rp2040
diff options
context:
space:
mode:
Diffstat (limited to 'src/rp2040')
-rw-r--r--src/rp2040/i2c.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/src/rp2040/i2c.c b/src/rp2040/i2c.c
index 81e2dab6..8ec2bd7a 100644
--- a/src/rp2040/i2c.c
+++ b/src/rp2040/i2c.c
@@ -133,8 +133,8 @@ i2c_stop(i2c_hw_t *i2c)
i2c->enable = 0;
}
-static void
-i2c_do_write(i2c_hw_t *i2c, uint8_t addr, uint8_t write_len, uint8_t *write
+static int
+i2c_do_write(i2c_hw_t *i2c, uint8_t write_len, uint8_t *write
, uint8_t send_stop, uint32_t timeout)
{
for (int i = 0; i < write_len; i++) {
@@ -144,7 +144,7 @@ i2c_do_write(i2c_hw_t *i2c, uint8_t addr, uint8_t write_len, uint8_t *write
// Wait until there's a spot in the TX FIFO
while (i2c->txflr == 16) {
if (!timer_is_before(timer_read_time(), timeout))
- shutdown("i2c timeout");
+ return I2C_BUS_TIMEOUT;
}
i2c->data_cmd = first << I2C_IC_DATA_CMD_RESTART_LSB
@@ -153,12 +153,12 @@ i2c_do_write(i2c_hw_t *i2c, uint8_t addr, uint8_t write_len, uint8_t *write
}
if (!send_stop)
- return;
+ return I2C_BUS_SUCCESS;
// Drain the transmit buffer
while (i2c->txflr != 0) {
if (!timer_is_before(timer_read_time(), timeout))
- shutdown("i2c timeout");
+ return I2C_BUS_TIMEOUT;
}
if (i2c->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS) {
@@ -166,25 +166,26 @@ i2c_do_write(i2c_hw_t *i2c, uint8_t addr, uint8_t write_len, uint8_t *write
if (abort_source & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS)
{
i2c->clr_tx_abrt;
- shutdown("i2c Start NACK");
+ return I2C_BUS_START_NACK;
}
if (abort_source & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS)
{
i2c->clr_tx_abrt;
- shutdown("i2c NACK");
+ return I2C_BUS_NACK;
}
}
+ return I2C_BUS_SUCCESS;
}
-static void
-i2c_do_read(i2c_hw_t *i2c, uint8_t addr, uint8_t read_len, uint8_t *read
+static int
+i2c_do_read(i2c_hw_t *i2c, uint8_t read_len, uint8_t *read
, uint32_t timeout)
{
int have_read = 0;
int to_send = read_len;
while (have_read < read_len) {
if (!timer_is_before(timer_read_time(), timeout))
- shutdown("i2c timeout");
+ return I2C_BUS_TIMEOUT;
if (to_send > 0 && i2c->txflr < 16) {
int first = to_send == read_len;
@@ -206,10 +207,12 @@ i2c_do_read(i2c_hw_t *i2c, uint8_t addr, uint8_t read_len, uint8_t *read
uint32_t abort_source = i2c->tx_abrt_source;
if (abort_source & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
i2c->clr_tx_abrt;
- shutdown("i2c Start Read NACK");
+ return I2C_BUS_START_READ_NACK;
}
}
}
+
+ return I2C_BUS_SUCCESS;
}
int
@@ -217,12 +220,12 @@ i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write)
{
i2c_hw_t *i2c = (i2c_hw_t*)config.i2c;
uint32_t timeout = timer_read_time() + timer_from_us(5000);
+ int ret;
i2c_start(i2c, config.addr);
- i2c_do_write(i2c, config.addr, write_len, write, 1, timeout);
+ ret = i2c_do_write(i2c, write_len, write, 1, timeout);
i2c_stop(i2c);
-
- return I2C_BUS_SUCCESS;
+ return ret;
}
int
@@ -231,12 +234,15 @@ i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg
{
i2c_hw_t *i2c = (i2c_hw_t*)config.i2c;
uint32_t timeout = timer_read_time() + timer_from_us(5000);
+ int ret = I2C_BUS_SUCCESS;
i2c_start(i2c, config.addr);
if (reg_len != 0)
- i2c_do_write(i2c, config.addr, reg_len, reg, 0, timeout);
- i2c_do_read(i2c, config.addr, read_len, read, timeout);
+ ret = i2c_do_write(i2c, reg_len, reg, 0, timeout);
+ if (ret != I2C_BUS_SUCCESS)
+ goto out;
+ ret = i2c_do_read(i2c, read_len, read, timeout);
+out:
i2c_stop(i2c);
-
- return I2C_BUS_SUCCESS;
+ return ret;
}