X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fdrv%2Fi2c_bitbang.c;h=9456d362aabc5aa52f8c8f53e69ca1aa7689ed63;hb=8ad8e5d325736480a881a7f30bd757f96b87376e;hp=f84abe9ad62feae47e9d439a8d24b0f49fc70cb3;hpb=26d999589c974fc163fdf7e91a439f11d69c3f7b;p=bertos.git diff --git a/bertos/drv/i2c_bitbang.c b/bertos/drv/i2c_bitbang.c index f84abe9a..9456d362 100644 --- a/bertos/drv/i2c_bitbang.c +++ b/bertos/drv/i2c_bitbang.c @@ -198,6 +198,9 @@ static void i2c_bitbang_stop_1(struct I2c *i2c) INLINE bool i2c_bitbang_start_1(struct I2c *i2c) { bool ret; + /* Clear all error, we restart */ + i2c->errors &= ~(I2C_NO_ACK | I2C_ARB_LOST); + if (old_api) { SDA_HI; @@ -215,6 +218,7 @@ INLINE bool i2c_bitbang_start_1(struct I2c *i2c) i2c_halfbitDelay(I2C_DEV(i2c)); i2c_sdaLo(I2C_DEV(i2c)); i2c_halfbitDelay(I2C_DEV(i2c)); + ret = !i2c_sdaIn(I2C_DEV(i2c)); } @@ -289,7 +293,7 @@ static uint8_t i2c_bitbang_getc(struct I2c *i2c) return data; } -static void i2c_bitbang_putc(struct I2c *i2c, uint8_t _data) +INLINE void i2c_bitbang_putcStop(struct I2c *i2c, uint8_t _data, bool stop) { /* Add ACK bit */ uint16_t data = (_data << 1) | 1; @@ -328,23 +332,25 @@ static void i2c_bitbang_putc(struct I2c *i2c, uint8_t _data) i2c_sclHi(I2C_DEV(i2c)); i2c_halfbitDelay(I2C_DEV(i2c)); } - ack = !i2c_sdaIn(I2C_DEV(i2c)); + i2c_sclLo(I2C_DEV(i2c)); i2c_halfbitDelay(I2C_DEV(i2c)); } if (!ack) - { - LOG_ERR("NO ACK received\n"); i2c->errors |= I2C_NO_ACK; - } /* Generate stop condition (if requested) */ - if (((i2c->xfer_size == 1) && (i2c->flags & I2C_STOP)) || i2c->errors) + if (stop || i2c->errors) i2c_bitbang_stop_1(i2c); } +static void i2c_bitbang_putc(struct I2c *i2c, uint8_t data) +{ + i2c_bitbang_putcStop(i2c, data, + (i2c->xfer_size == 1) && (i2c->flags & I2C_STOP)); +} static void i2c_bitbang_start_2(struct I2c *i2c, uint16_t slave_addr) { @@ -357,12 +363,12 @@ static void i2c_bitbang_start_2(struct I2c *i2c, uint16_t slave_addr) * Loop on the select write sequence: when the device is busy * writing previously sent data it will reply to the SLA_W * control byte with a NACK. In this case, we must - * keep trying until the deveice responds with an ACK. + * keep trying until the device responds with an ACK. */ ticks_t start = timer_clock(); while (i2c_bitbang_start_1(i2c)) { - i2c_bitbang_putc(i2c, slave_addr); + i2c_bitbang_putcStop(i2c, slave_addr, false); if (!(i2c->errors & I2C_NO_ACK)) return;