aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Kurz <michi.kurz@gmail.com>2021-04-21 00:11:26 +0200
committerKevinOConnor <kevin@koconnor.net>2021-04-25 10:37:28 -0400
commit308f0338cfae2aa59fb360bfa8f03046ba09fb16 (patch)
tree54c1382a238ebd21119e5b520594b44489c85482 /src
parentdd7085cbca1ead5735124c05a6b359002917a31b (diff)
downloadkutter-308f0338cfae2aa59fb360bfa8f03046ba09fb16.tar.gz
kutter-308f0338cfae2aa59fb360bfa8f03046ba09fb16.tar.xz
kutter-308f0338cfae2aa59fb360bfa8f03046ba09fb16.zip
lpc176x: Add i2c_read functionality
This adds the i2c_read command to the lp176x MCU. Signed-off-by: Michael Kurz <michi.kurz@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/lpc176x/i2c.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/lpc176x/i2c.c b/src/lpc176x/i2c.c
index 4d8dc361..7ed631af 100644
--- a/src/lpc176x/i2c.c
+++ b/src/lpc176x/i2c.c
@@ -100,6 +100,20 @@ i2c_send_byte(LPC_I2C_TypeDef *i2c, uint8_t b, uint32_t timeout)
return i2c->I2STAT;
}
+static uint8_t
+i2c_read_byte(LPC_I2C_TypeDef *i2c, uint32_t timeout, uint8_t remaining)
+{
+ if (remaining == 0)
+ i2c->I2CONCLR = IF_ACK | IF_IRQ;
+ else {
+ i2c->I2CONSET = IF_ACK;
+ i2c->I2CONCLR = IF_IRQ;
+ }
+ i2c_wait(i2c, IF_IRQ, timeout);
+ uint8_t b = i2c->I2DAT;
+ return b;
+}
+
static void
i2c_stop(LPC_I2C_TypeDef *i2c, uint32_t timeout)
{
@@ -125,5 +139,24 @@ void
i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg
, uint8_t read_len, uint8_t *read)
{
- shutdown("i2c_read not supported on lpc176x");
+ LPC_I2C_TypeDef *i2c = config.i2c;
+ uint32_t timeout = timer_read_time() + timer_from_us(5000);
+ uint8_t addr = config.addr | 0x01;
+
+ if (reg_len != 0) {
+ // write the register
+ i2c_start(i2c, timeout);
+ i2c_send_byte(i2c, config.addr, timeout);
+ while(reg_len--)
+ i2c_send_byte(i2c, *reg++, timeout);
+ i2c_stop(i2c, timeout);
+ }
+ // start/re-start and read data
+ i2c_start(i2c, timeout);
+ i2c_send_byte(i2c, addr, timeout);
+ while(read_len--) {
+ *read = i2c_read_byte(i2c, timeout, read_len);
+ read++;
+ }
+ i2c_stop(i2c, timeout);
}