nanohub: drivers/lps22hb: Use dynamic I2C transfer buffer allocation

I2C transfers use a structure which is now dynamically allocated
in order to avoid contention issues because the asynchronous nature
of the I2C core operations. The SPI communication part has been removed.

Change-Id: I96bfeed13df8d590ab8e9b0718b9b95bd0c15924
Signed-off-by: Armando Visconti <armando.visconti@st.com>
diff --git a/firmware/os/drivers/st_lps22hb/README b/firmware/os/drivers/st_lps22hb/README
index f0d55ae..bbf2552 100644
--- a/firmware/os/drivers/st_lps22hb/README
+++ b/firmware/os/drivers/st_lps22hb/README
@@ -4,7 +4,7 @@
 
 A. Report Pressure and Temperature data
 B. Different data rates: 1/10/25/50/75 Hz
-C. I2C and SPI protocols
+C. I2C protocol
 
 This driver does not support the DRDy interrupt.
 Instead, a timer callback is used to read the data.
@@ -15,16 +15,10 @@
 The driver requires that following macros are defined in the variant.h
 file of the specific variant:
 
-  LPS22HB_USE_I2C       /* specify whether I2C or SPI mode has to be used */
-
   LPS22HB_I2C_BUS_ID    /* specify I2C Bus ID */
   LPS22HB_I2C_SPEED     /* specify I2C Bus speed in hz */
   LPS22HB_I2C_ADDR      /* specify device I2C address */
 
-  LPS22HB_SPI_BUS_ID    /* specify SPI Bus ID */
-  LPS22HB_SPI_SPEED_HZ  /* specify SPI Bus speed in hz */
-  LPS22HB_SPI_GPIO_NSS  /* specify which gpio is used as SPI device chip select */
-
 Example:
 
   /*
@@ -37,11 +31,6 @@
   #define LPS22HB_I2C_SPEED       400000
   #define LPS22HB_I2C_ADDR        0x5C
 
-  /* SPI defs to be used when device is plugged on U1 slot */
-  #define LPS22HB_SPI_BUS_ID      0
-  #define LPS22HB_SPI_SPEED_HZ    8000000
-  #define LPS22HB_SPI_GPIO_NSS    GPIO_PB(6)
-
 If these macros are not defined in the current variant the driver forces a compilation
 error.
 
diff --git a/firmware/os/drivers/st_lps22hb/lps22hb.c b/firmware/os/drivers/st_lps22hb/lps22hb.c
index 1838031..1967c75 100644
--- a/firmware/os/drivers/st_lps22hb/lps22hb.c
+++ b/firmware/os/drivers/st_lps22hb/lps22hb.c
@@ -23,7 +23,6 @@
 #include <plat/syscfg.h>
 #include <sensors.h>
 #include <seos.h>
-#include <spi.h>
 #include <i2c.h>
 #include <timer.h>
 #include <stdlib.h>
@@ -85,7 +84,6 @@
     SENSOR_DO_NOTHING,
 };
 
-#if defined(LPS22HB_USE_I2C)
 #ifndef LPS22HB_I2C_BUS_ID
 #error "LPS22HB_I2C_BUS_ID is not defined; please define in variant.h"
 #endif
@@ -98,25 +96,6 @@
 #error "LPS22HB_I2C_ADDR is not defined; please define in variant.h"
 #endif
 
-#else  /* #if defined(LPS22HB_USE_I2C) */
-
-#define SPI_READ        0x80
-#define SPI_WRITE       0x00
-#define SPI_MAX_PCK_NUM     1
-
-#ifndef LPS22HB_SPI_BUS_ID
-#error "LPS22HB_SPI_BUS_ID define missing: forced definition in driver"
-#endif
-
-#ifndef LPS22HB_SPI_SPEED_HZ
-#error "LPS22HB_SPI_SPEED_HZ define missing: forced definition in driver"
-#endif
-
-#ifndef LPS22HB_SPI_GPIO_NSS
-#error "LPS22HB_SPI_GPIO_NSS define missing: forced definition in driver"
-#endif
-#endif /* #if defined(LPS22HB_USE_I2C) */
-
 enum lps22hbSensorIndex {
     BARO = 0,
     TEMP,
@@ -129,6 +108,19 @@
     uint32_t handle;
 };
 
+#define LPS22HB_MAX_PENDING_I2C_REQUESTS   4
+#define LPS22HB_MAX_I2C_TRANSFER_SIZE      6
+
+struct I2cTransfer
+{
+    size_t tx;
+    size_t rx;
+    int err;
+    uint8_t txrxBuf[LPS22HB_MAX_I2C_TRANSFER_SIZE];
+    uint8_t state;
+    bool inUse;
+};
+
 /* Task structure */
 struct lps22hbTask {
     uint32_t tid;
@@ -147,18 +139,11 @@
 
     //int sensLastRead;
 
-#if !defined(LPS22HB_USE_I2C)
-    /* SPI */
-    spi_cs_t            cs;
-    struct SpiMode      mode;
-    struct SpiDevice    *spiDev;
-    struct SpiPacket    spi_pck[SPI_MAX_PCK_NUM];
-#endif
-    unsigned char       sens_buf[6];
+    struct I2cTransfer transfers[LPS22HB_MAX_PENDING_I2C_REQUESTS];
 
     /* Communication functions */
-    void (*comm_tx)(uint8_t addr, uint8_t data, uint32_t delay, void *cookie);
-    void (*comm_rx)(uint8_t addr, uint16_t len, uint32_t delay, void *cookie);
+    void (*comm_tx)(uint8_t addr, uint8_t data, uint32_t delay, uint8_t state);
+    void (*comm_rx)(uint8_t addr, uint16_t len, uint32_t delay, uint8_t state);
 
     /* sensors */
     struct lps22hbSensor sensors[NUM_OF_SENSOR];
@@ -166,67 +151,62 @@
 
 static struct lps22hbTask mTask;
 
-#if defined(LPS22HB_USE_I2C)
+// Allocate a buffer and mark it as in use with the given state, or return NULL
+// if no buffers available. Must *not* be called from interrupt context.
+static struct I2cTransfer *allocXfer(uint8_t state)
+{
+    size_t i;
+
+    for (i = 0; i < ARRAY_SIZE(mTask.transfers); i++) {
+        if (!mTask.transfers[i].inUse) {
+            mTask.transfers[i].inUse = true;
+            mTask.transfers[i].state = state;
+            return &mTask.transfers[i];
+        }
+    }
+
+    osLog(LOG_ERROR, "[LPS22HB]: Ran out of i2c buffers!");
+    return NULL;
+}
+
 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err)
-#else
-static void spiCallback(void *cookie, int err)
-#endif
 {
+    struct I2cTransfer *xfer = cookie;
+
+    xfer->tx = tx;
+    xfer->rx = rx;
+    xfer->err = err;
+
     osEnqueuePrivateEvt(EVT_COMM_DONE, cookie, NULL, mTask.tid);
+    if (err != 0)
+        osLog(LOG_INFO, "[LPS22HB] i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err);
 }
 
-#if defined(LPS22HB_USE_I2C)
-static void i2c_read(uint8_t addr, uint16_t len, uint32_t delay, void *cookie)
+static void i2c_read(uint8_t addr, uint16_t len, uint32_t delay, uint8_t state)
 {
-    mTask.sens_buf[0] = 0x80 | addr;
-    i2cMasterTxRx(LPS22HB_I2C_BUS_ID, LPS22HB_I2C_ADDR, &mTask.sens_buf[0], 1,
-                        &mTask.sens_buf[1], len, &i2cCallback, cookie);
+    struct I2cTransfer *xfer = allocXfer(state);
+    //int ret = -1;
+
+    if (xfer != NULL) {
+        xfer->txrxBuf[0] = 0x80 | addr;
+        i2cMasterTxRx(LPS22HB_I2C_BUS_ID, LPS22HB_I2C_ADDR, xfer->txrxBuf, 1, xfer->txrxBuf, len, i2cCallback, xfer);
+    }
 }
 
-static void i2c_write(uint8_t addr, uint8_t data, uint32_t delay, void *cookie)
+static void i2c_write(uint8_t addr, uint8_t data, uint32_t delay, uint8_t state)
 {
-    mTask.sens_buf[0] = addr;
-    mTask.sens_buf[1] = data;
-    i2cMasterTx(LPS22HB_I2C_BUS_ID, LPS22HB_I2C_ADDR, mTask.sens_buf, 2, &i2cCallback, cookie);
+    struct I2cTransfer *xfer = allocXfer(state);
+    //int ret = -1;
+
+    if (xfer != NULL) {
+        xfer->txrxBuf[0] = addr;
+        xfer->txrxBuf[1] = data;
+        i2cMasterTx(LPS22HB_I2C_BUS_ID, LPS22HB_I2C_ADDR, xfer->txrxBuf, 2, i2cCallback, xfer);
+    }
+
+    //return (ret == 0);
 }
 
-#else
-static void spi_read(uint8_t addr, uint16_t len, uint32_t delay, void *cookie)
-{
-    mTask.sens_buf[0] = SPI_READ | addr;
-
-    mTask.spi_pck[0].size = len + 1;
-    mTask.spi_pck[0].txBuf = mTask.spi_pck[0].rxBuf = &mTask.sens_buf[0];
-    mTask.spi_pck[0].delay = delay * 1000;
-
-    spiMasterRxTx(mTask.spiDev, mTask.cs, &mTask.spi_pck[0], 1/*mTask.spi_pck_num*/, &mTask.mode, spiCallback, cookie);
-}
-
-static void spi_write(uint8_t addr, uint8_t data, uint32_t delay, void *cookie)
-{
-    mTask.sens_buf[0] = SPI_WRITE | addr;
-    mTask.sens_buf[1] = data;
-
-    mTask.spi_pck[0].size = 2;
-    mTask.spi_pck[0].txBuf = mTask.spi_pck[0].rxBuf = &mTask.sens_buf[0];
-    mTask.spi_pck[0].delay = delay * 1000;
-
-    spiMasterRxTx(mTask.spiDev, mTask.cs, &mTask.spi_pck[0], 1/*mTask.spi_pck_num*/, &mTask.mode, spiCallback, cookie);
-}
-
-static void spi_init(void)
-{
-    mTask.mode.speed = LPS22HB_SPI_SPEED_HZ;
-    mTask.mode.bitsPerWord = 8;
-    mTask.mode.cpol = SPI_CPOL_IDLE_HI;
-    mTask.mode.cpha = SPI_CPHA_TRAILING_EDGE;
-    mTask.mode.nssChange = true;
-    mTask.mode.format = SPI_FORMAT_MSB_FIRST;
-    mTask.cs = LPS22HB_SPI_GPIO_NSS;
-    spiMasterRequest(LPS22HB_SPI_BUS_ID, &(mTask.spiDev));
-}
-#endif
-
 /* Sensor Info */
 static void sensorBaroTimerCallback(uint32_t timerId, void *data)
 {
@@ -293,9 +273,9 @@
 
     if (oldMode != newMode) {
         if (on)
-            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_10_HZ, 0, (void *)state);
+            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_10_HZ, 0, state);
         else
-            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_ONE_SHOT, 0, (void *)state);
+            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_ONE_SHOT, 0, state);
     } else
         sensorSignalInternalEvt(mTask.sensors[BARO].handle,
                     SENSOR_INTERNAL_EVT_POWER_STATE_CHG, on, 0);
@@ -343,9 +323,9 @@
 
     if (oldMode != newMode) {
         if (on)
-            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_10_HZ, 0, (void *)state);
+            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_10_HZ, 0, state);
         else
-            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_ONE_SHOT, 0, (void *)state);
+            mTask.comm_tx(LPS22HB_ODR_REG_ADDR, LPS22HB_ODR_ONE_SHOT, 0, state);
     } else
         sensorSignalInternalEvt(mTask.sensors[TEMP].handle,
                     SENSOR_INTERNAL_EVT_POWER_STATE_CHG, on, 0);
@@ -392,7 +372,6 @@
     { DEC_OPS(tempPower, tempFwUpload, tempSetRate, tempFlush, NULL, NULL) },
 };
 
-static uint8_t *wai;
 static uint8_t *baro_samples;
 static uint8_t *temp_samples;
 static void handleCommDoneEvt(const void* evtData)
@@ -400,32 +379,27 @@
     uint8_t i;
     int baro_val;
     short temp_val;
-    uint32_t state = (uint32_t)evtData;
+    //uint32_t state = (uint32_t)evtData;
     union EmbeddedDataPoint sample;
+	struct I2cTransfer *xfer = (struct I2cTransfer *)evtData;
 
-    switch (state) {
+    switch (xfer->state) {
     case SENSOR_BOOT:
-        mTask.comm_rx(LPS22HB_WAI_REG_ADDR, 1, 1, (void *)SENSOR_VERIFY_ID);
+        mTask.comm_rx(LPS22HB_WAI_REG_ADDR, 1, 1, SENSOR_VERIFY_ID);
         break;
 
     case SENSOR_VERIFY_ID:
-        wai = &mTask.sens_buf[1];
-
-        if (LPS22HB_WAI_REG_VAL != wai[0]) {
-            osLog(LOG_INFO, "WAI returned is: %02x\n", *wai);
+        /* Check the sensor ID */
+        if (xfer->err != 0 || xfer->txrxBuf[0] != LPS22HB_WAI_REG_VAL) {
+            osLog(LOG_INFO, "[LPS22HB] WAI returned is: %02x\n", xfer->txrxBuf[0]);
             break;
         }
 
-        osLog(LOG_INFO, "Device ID is correct! (%02x)\n", *wai);
+
+        osLog(LOG_INFO, "[LPS22HB] Device ID is correct! (%02x)\n", xfer->txrxBuf[0]);
         for (i = 0; i < NUM_OF_SENSOR; i++)
             sensorRegisterInitComplete(mTask.sensors[i].handle);
 
-#if !defined(LPS22HB_USE_I2C)
-        mTask.comm_tx(LPS22HB_SOFT_RESET_REG_ADDR,
-                    LPS22HB_I2C_DIS | LPS22HB_IF_ADD_INC, 0,
-                    (void *)SENSOR_DO_NOTHING);
-#endif
-
         /* TEST the environment in standalone mode */
         //osEnqueuePrivateEvt(EVT_TEST, NULL, NULL, mTask.tid);
         break;
@@ -458,7 +432,7 @@
     case SENSOR_READ_SAMPLES:
         if (mTask.baroOn && mTask.baroWantRead) {
             mTask.baroWantRead = false;
-            baro_samples = &mTask.sens_buf[1];
+            baro_samples = xfer->txrxBuf;
 
             baro_val = ((baro_samples[2] << 16) & 0xff0000) |
                     ((baro_samples[1] << 8) & 0xff00) |
@@ -472,7 +446,7 @@
 
         if (mTask.tempOn && mTask.tempWantRead) {
             mTask.tempWantRead = false;
-            temp_samples = &mTask.sens_buf[4];
+            temp_samples = &xfer->txrxBuf[3];
 
             temp_val  = ((temp_samples[1] << 8) & 0xff00) |
                     (temp_samples[0]);
@@ -489,6 +463,8 @@
     default:
         break;
     }
+
+    xfer->inUse = false;
 }
 
 static void handleEvent(uint32_t evtType, const void* evtData)
@@ -499,7 +475,7 @@
         osEventUnsubscribe(mTask.tid, EVT_APP_START);
 
         mTask.comm_tx(LPS22HB_SOFT_RESET_REG_ADDR,
-                    LPS22HB_SOFT_RESET_BIT, 0, (void *)SENSOR_BOOT);
+                    LPS22HB_SOFT_RESET_BIT, 0, SENSOR_BOOT);
         break;
 
     case EVT_COMM_DONE:
@@ -516,7 +492,7 @@
         if (!mTask.baroReading && !mTask.tempReading) {
             mTask.baroReading = true;
 
-            mTask.comm_rx(LPS22HB_PRESS_OUTXL_REG_ADDR, 5, 1, (void *)SENSOR_READ_SAMPLES);
+            mTask.comm_rx(LPS22HB_PRESS_OUTXL_REG_ADDR, 5, 1, SENSOR_READ_SAMPLES);
         }
 
         break;
@@ -530,7 +506,7 @@
         if (!mTask.baroReading && !mTask.tempReading) {
             mTask.tempReading = true;
 
-            mTask.comm_rx(LPS22HB_PRESS_OUTXL_REG_ADDR, 5, 1, (void *)SENSOR_READ_SAMPLES);
+            mTask.comm_rx(LPS22HB_PRESS_OUTXL_REG_ADDR, 5, 1, SENSOR_READ_SAMPLES);
         }
 
         break;
@@ -566,17 +542,10 @@
     mTask.baroReading = mTask.tempReading = false;
 
     /* Init the communication part */
-#if defined(LPS22HB_USE_I2C)
     i2cMasterRequest(LPS22HB_I2C_BUS_ID, LPS22HB_I2C_SPEED);
 
     mTask.comm_tx = i2c_write;
     mTask.comm_rx = i2c_read;
-#else
-    spi_init();
-
-    mTask.comm_tx = spi_write;
-    mTask.comm_rx = spi_read;
-#endif
 
     for (i = 0; i < NUM_OF_SENSOR; i++) {
         mTask.sensors[i].handle =
@@ -591,10 +560,6 @@
 static void endTask(void)
 {
     osLog(LOG_INFO, "LPS22HB DRIVER ended\n");
-#if defined(LPS22HB_USE_I2C)
-#else
-    spiMasterRelease(mTask.spiDev);
-#endif
 }
 
 INTERNAL_APP_INIT(LPS22HB_APP_ID, 0, startTask, endTask, handleEvent);