Add definition and function for new i2c api.
[bertos.git] / bertos / cpu / arm / drv / i2c_lpc2.c
index 270f4c02bd11076fd1563fa2c7a1b2b46572429b..d4936d05602607453ad9908e9d0c52abda0d3984 100644 (file)
  * 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);