X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Farm%2Fdrv%2Fi2c_lpc2.c;h=d4936d05602607453ad9908e9d0c52abda0d3984;hb=76b88779d675d0ea69747841bbb163cee90aca34;hp=270f4c02bd11076fd1563fa2c7a1b2b46572429b;hpb=bc29f088a13db6ebf7296d11fc29c49b53d298cb;p=bertos.git diff --git a/bertos/cpu/arm/drv/i2c_lpc2.c b/bertos/cpu/arm/drv/i2c_lpc2.c index 270f4c02..d4936d05 100644 --- a/bertos/cpu/arm/drv/i2c_lpc2.c +++ b/bertos/cpu/arm/drv/i2c_lpc2.c @@ -85,7 +85,18 @@ * state F8 does not set SI since there is nothing for an interrupt service * routine to do in that case. */ -#define WAIT_SI() while( !(I2C_CONSET & BV(I2CON_SI)) ) +#define WAIT_SI() \ + do { \ + ticks_t start = timer_clock(); \ + while( !(I2C_CONSET & BV(I2CON_SI)) ) \ + { \ + if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT)) \ + { \ + LOG_ERR("Timeout SI assert\n"); \ + break; \ + } \ + } \ + } while (0) static uint8_t i2c_builtin_start(void) { @@ -129,7 +140,8 @@ bool i2c_builtin_start_w(uint8_t id) LOG_ERR("Arbitration lost\n"); break; } - else if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT)) + + if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT)) { LOG_ERR("Timeout on I2C START\n"); break; @@ -191,108 +203,69 @@ void i2c_builtin_stop(void) bool i2c_builtin_put(const uint8_t data) { - (void)data; - return true; -} - + I2C_DAT = data; + I2C_CONCLR = BV(I2CON_SIC); -int i2c_builtin_get(bool ack) -{ - (void)ack; - return 0; -} + WAIT_SI(); -/* - * With this function is allowed only the atomic write. - */ -bool i2c_send(const void *_buf, size_t count) -{ - const uint8_t *buf = (const uint8_t *)_buf; - uint8_t status = 0; + uint32_t status = GET_STATUS(); - while (count) + if (status == I2C_STAT_DATA_ACK) + return true; + else if (status == I2C_STAT_DATA_NACK) { - I2C_DAT = *buf++; - I2C_CONCLR = BV(I2CON_SIC); - count--; - - WAIT_SI(); - - status = GET_STATUS(); - - if (status == I2C_STAT_DATA_ACK) - continue; - else if (status == I2C_STAT_DATA_NACK) - { - LOG_ERR("Data NACK\n"); - return false; - } - else if (status == I2C_STAT_ERROR) - { - LOG_ERR("I2C error.\n"); - return false; - } - else if (status == I2C_STAT_UNKNOW) - { - LOG_ERR("I2C unable to read status.\n"); - return false; - } - + LOG_ERR("Data NACK\n"); + return false; + } + else if (status == I2C_STAT_ERROR) + { + LOG_ERR("I2C error.\n"); + return false; + } + else if (status == I2C_STAT_UNKNOW) + { + LOG_ERR("I2C unable to read status.\n"); + return false; } - return true; + return false; } -/** - * In order to read bytes from the i2c we should make some tricks. - */ -bool i2c_recv(void *_buf, size_t count) + +int i2c_builtin_get(bool ack) { - uint8_t *buf = (uint8_t *)_buf; - uint8_t status = GET_STATUS(); - /* Ready for read */ - I2C_CONSET = BV(I2CON_AA); + /* + * Set ack bit if we want read more byte, otherwise + * we disable it + */ + if (ack) + I2C_CONSET = BV(I2CON_AA); + else + I2C_CONCLR = BV(I2CON_AAC); + I2C_CONCLR = BV(I2CON_SIC); WAIT_SI(); - while (count) - { - *buf++ = I2C_DAT; - /* - * Set ack bit if we want read more byte, otherwise - * we disable it - */ - if (count > 1) - I2C_CONSET = BV(I2CON_AA); - else - I2C_CONCLR = BV(I2CON_AAC); - - I2C_CONCLR = BV(I2CON_SIC); - count--; + uint32_t status = GET_STATUS(); - WAIT_SI(); - - status = GET_STATUS(); - - if (status == I2C_STAT_RDATA_ACK) - continue; - else if (status == I2C_STAT_RDATA_NACK) - return true; - else if (status == I2C_STAT_ERROR) - { - LOG_ERR("I2C error.\n"); - return false; - } - else if (status == I2C_STAT_UNKNOW) - { - LOG_ERR("I2C unable to read status.\n"); - return false; - } + if (status == I2C_STAT_RDATA_ACK) + return (uint8_t)I2C_DAT; + else if (status == I2C_STAT_RDATA_NACK) + return true; + else if (status == I2C_STAT_ERROR) + { + LOG_ERR("I2C error.\n"); + return EOF; + } + else if (status == I2C_STAT_UNKNOW) + { + LOG_ERR("I2C unable to read status.\n"); + return EOF; } - return true; + return EOF; } MOD_DEFINE(i2c);