You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/03/22 14:46:12 UTC

[GitHub] joshgrob commented on a change in pull request #699: Sensors/BMA2XX - New PR based on PR #697 changes

joshgrob commented on a change in pull request #699: Sensors/BMA2XX - New PR based on PR #697 changes
URL: https://github.com/apache/mynewt-core/pull/699#discussion_r176446725
 
 

 ##########
 File path: hw/drivers/sensors/bma2xx/src/bma2xx.c
 ##########
 @@ -0,0 +1,4940 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * resarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+#include <errno.h>
+
+
+#include "bma2xx/bma2xx.h"
+#include "bma2xx_priv.h"
+#include "defs/error.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_i2c.h"
+#include "hal/hal_spi.h"
+
+#if MYNEWT_VAL(BMA2XX_LOG)
+#include "log/log.h"
+#endif
+
+#if MYNEWT_VAL(BMA2XX_LOG)
+static struct log bma2xx_log;
+#define LOG_MODULE_BMA2XX (200)
+#define BMA2XX_ERROR(...) LOG_ERROR(&bma2xx_log, LOG_MODULE_BMA2XX, __VA_ARGS__)
+#define BMA2XX_INFO(...)  LOG_INFO(&bma2xx_log, LOG_MODULE_BMA2XX, __VA_ARGS__)
+#else
+#define BMA2XX_ERROR(...)
+#define BMA2XX_INFO(...)
+#endif
+
+#define BMA2XX_NOTIFY_MASK  0x01
+#define BMA2XX_READ_MASK    0x02
+
+#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_1_MASTER)
+static struct hal_spi_settings spi_bma2xx_settings = {
+        .data_order = HAL_SPI_MSB_FIRST,
+        .data_mode  = HAL_SPI_MODE0,
+        .baudrate   = 4000,
+        .word_size  = HAL_SPI_WORD_SIZE_8BIT,
+};
+#endif
+
+static void
+delay_msec(uint32_t delay)
+{
+    delay = (delay * OS_TICKS_PER_SEC) / 1000 + 1;
+    os_time_delay(delay);
+}
+
+#if MYNEWT_VAL(BMA2XX_INT_ENABLE)
+static void
+init_interrupt(struct bma2xx_int * interrupt, struct sensor_int *ints)
+{
+    os_error_t error;
+
+    error = os_sem_init(&interrupt->wait, 0);
+    assert(error == OS_OK);
+
+    interrupt->active = false;
+    interrupt->asleep = false;
+    interrupt->ints = ints;
+}
+
+static void
+undo_interrupt(struct bma2xx_int * interrupt)
+{
+    OS_ENTER_CRITICAL(interrupt->lock);
+    interrupt->active = false;
+    interrupt->asleep = false;
+    OS_EXIT_CRITICAL(interrupt->lock);
+}
+
+static void
+wait_interrupt(struct bma2xx_int * interrupt, enum bma2xx_int_num int_num)
+{
+    bool wait;
+
+    OS_ENTER_CRITICAL(interrupt->lock);
+
+    /* Check if we did not missed interrupt */
+    if (hal_gpio_read(interrupt->ints[int_num].host_pin) ==
+                                            interrupt->ints[int_num].active) {
+        OS_EXIT_CRITICAL(interrupt->lock);
+        return;
+    }
+
+    if (interrupt->active) {
+        interrupt->active = false;
+        wait = false;
+    } else {
+        interrupt->asleep = true;
+        wait = true;
+    }
+    OS_EXIT_CRITICAL(interrupt->lock);
+
+    if (wait) {
+        os_error_t error;
+
+        error = os_sem_pend(&interrupt->wait, -1);
+        assert(error == OS_OK);
+    }
+}
+
+static void
+wake_interrupt(struct bma2xx_int * interrupt)
+{
+    bool wake;
+
+    OS_ENTER_CRITICAL(interrupt->lock);
+    if (interrupt->asleep) {
+        interrupt->asleep = false;
+        wake = true;
+    } else {
+        interrupt->active = true;
+        wake = false;
+    }
+    OS_EXIT_CRITICAL(interrupt->lock);
+
+    if (wake) {
+        os_error_t error;
+
+        error = os_sem_release(&interrupt->wait);
+        assert(error == OS_OK);
+    }
+}
+
+static void
+interrupt_handler(void * arg)
+{
+    struct sensor *sensor = arg;
+    struct bma2xx *bma2xx;
+
+    bma2xx = (struct bma2xx *)SENSOR_GET_DEVICE(sensor);
+
+    if (bma2xx->pdd.interrupt) {
+        wake_interrupt(bma2xx->pdd.interrupt);
+    }
+
+    sensor_mgr_put_interrupt_evt(sensor);
+}
+#endif
+
+/**
+ * Read multiple length data over SPI
+ *
+ * @param register address
+ * @param variable length payload
+ * @param length of the payload to read
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+spi_readlen(const struct sensor_itf * itf, uint8_t addr, uint8_t *payload,
+            uint8_t len)
+{
+    int i;
+    uint16_t retval;
+    int rc;
+
+    rc = 0;
+
+    /* Select the device */
+    hal_gpio_write(itf->si_cs_pin, 0);
+
+    /* Send the address */
+    retval = hal_spi_tx_val(itf->si_num, addr | BMA2XX_SPI_READ_CMD_BIT);
+    if (retval == 0xFFFF) {
+        rc = SYS_EINVAL;
+        BMA2XX_ERROR("SPI_%u register write failed addr:0x%02X\n",
+                     itf->si_num, addr);
+        goto err;
+    }
+
+    for (i = 0; i < len; i++) {
+        /* Read data */
+        retval = hal_spi_tx_val(itf->si_num, 0);
+        if (retval == 0xFFFF) {
+            rc = SYS_EINVAL;
+            BMA2XX_ERROR("SPI_%u read failed addr:0x%02X\n",
+                         itf->si_num, addr);
+            goto err;
+        }
+        payload[i] = retval;
+    }
+
+    rc = 0;
+
+    err:
+    /* De-select the device */
+    hal_gpio_write(itf->si_cs_pin, 1);
+
+    return rc;
+}
+
+/**
+ * Write multiple length data SPI
+ *
+ * @param register address
+ * @param variable length payload
+ * @param length of the payload to write
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+spi_writereg(const struct sensor_itf * itf, uint8_t addr, uint8_t payload,
+             uint8_t len)
+{
+    int i;
+    int rc;
+
+    /* Select the device */
+    hal_gpio_write(itf->si_cs_pin, 0);
+
+    /* Send the address */
+    rc = hal_spi_tx_val(itf->si_num, addr);
+    if (rc == 0xFFFF) {
+        rc = SYS_EINVAL;
+        BMA2XX_ERROR("SPI_%u register write failed addr:0x%02X\n",
+                     itf->si_num, addr);
+        goto err;
+    }
+
+    for (i = 0; i < len; i++) {
+        /* Read data */
+        rc = hal_spi_tx_val(itf->si_num, payload);
+        if (rc == 0xFFFF) {
+            rc = SYS_EINVAL;
+            BMA2XX_ERROR("SPI_%u write failed addr:0x%02X:0x%02X\n",
+                         itf->si_num, addr);
+            goto err;
+        }
+    }
+
+
+    rc = 0;
+
+    err:
+    /* De-select the device */
+    hal_gpio_write(itf->si_cs_pin, 1);
+
+    os_time_delay((OS_TICKS_PER_SEC * 30)/1000 + 1);
+
+    return rc;
+}
+
+int
+i2c_readlen(const struct sensor_itf * itf, uint8_t addr, uint8_t *payload,
+            uint8_t len)
+{
+    struct hal_i2c_master_data oper;
+    int rc;
+
+    oper.address = itf->si_addr;
+    oper.len     = 1;
+    oper.buffer  = &addr;
+
+    rc = hal_i2c_master_write(itf->si_num, &oper,
+                              OS_TICKS_PER_SEC / 10, 1);
+    if (rc != 0) {
+        BMA2XX_ERROR("I2C access failed at address 0x%02X\n",
+                     addr);
+        return rc;
+    }
+
+    oper.address = itf->si_addr;
+    oper.len     = len;
+    oper.buffer  = payload;
+
+    rc = hal_i2c_master_read(itf->si_num, &oper,
+                             OS_TICKS_PER_SEC / 10, 1);
+    if (rc != 0) {
+        BMA2XX_ERROR("I2C read failed at address 0x%02X length %u\n",
+                     addr, len);
+        return rc;
+    }
+
+    return 0;
+}
+
+int
+i2c_writereg(const struct sensor_itf * itf, uint8_t addr, uint8_t data)
+{
+    uint8_t tuple[2];
+    struct hal_i2c_master_data oper;
+    int rc;
+
+    tuple[0] = addr;
+    tuple[1] = data;
+
+    oper.address = itf->si_addr;
+    oper.len     = 2;
+    oper.buffer  = tuple;
+
+    rc = hal_i2c_master_write(itf->si_num, &oper,
+                              OS_TICKS_PER_SEC / 10, 1);
+    if (rc != 0) {
+        BMA2XX_ERROR("I2C write failed at address 0x%02X single byte\n",
+                     addr);
+        return rc;
+    }
+
+    return 0;
+}
+
+static int
+get_register(const struct bma2xx * bma2xx,
+             uint8_t addr,
+             uint8_t * data)
+{
+    int rc;
+    const struct sensor_itf * itf;
+    itf = SENSOR_GET_ITF(&bma2xx->sensor);
+
+    if (itf->si_type == SENSOR_ITF_SPI) {
+        rc = spi_readlen(itf, addr, data, 1);
+    } else if (itf->si_type == SENSOR_ITF_I2C){
+        rc = i2c_readlen(itf, addr, data, 1);
+    } else {
+        rc = SYS_EINVAL;
+    }
+
+    return rc;
+}
+
+static int
+get_registers(const struct bma2xx * bma2xx,
+              uint8_t addr,
+              uint8_t * data,
+              uint8_t size)
+{
+    int rc;
+    const struct sensor_itf * itf;
+    itf = SENSOR_GET_ITF(&bma2xx->sensor);
+
+    if (itf->si_type == SENSOR_ITF_SPI) {
+        rc = spi_readlen(itf, addr, data, size);
+    } else if (itf->si_type == SENSOR_ITF_I2C){
+        rc = i2c_readlen(itf, addr, data, size);
+    } else {
+        rc = SYS_EINVAL;
+    }
+
+    return rc;
+}
+
+static int
+set_register(const struct bma2xx * bma2xx,
+             uint8_t addr,
+             uint8_t data)
+{
+    int rc;
+    const struct sensor_itf * itf;
+
+    itf = SENSOR_GET_ITF(&bma2xx->sensor);
+
+    if (itf->si_type == SENSOR_ITF_SPI) {
+        rc = spi_writereg(itf, addr, data, 1);
+    } else if (itf->si_type == SENSOR_ITF_I2C){
+        rc = i2c_writereg(itf, addr, data);
+    } else {
+        rc = SYS_EINVAL;
+    }
+
+    switch (bma2xx->power) {
+    case BMA2XX_POWER_MODE_SUSPEND:
+    case BMA2XX_POWER_MODE_LPM_1:
+        delay_msec(1);
+        break;
+    default:
+        break;
+    }
+
+    return rc;
+}
+
+int
+bma2xx_get_chip_id(const struct bma2xx * bma2xx,
+                   uint8_t * chip_id)
+{
+    return get_register(bma2xx, REG_ADDR_BGW_CHIPID, chip_id);
+}
+
+static void
+compute_accel_data(struct accel_data * accel_data,
+                   enum bma2xx_model model,
+                   const uint8_t * raw_data,
+                   float accel_scale)
+{
+    int16_t raw_accel;
+    uint8_t model_shift = 0;
+
+    switch (model) {
+        case BMA2XX_BMA280:
+            model_shift = BMA280_ACCEL_BIT_SHIFT;
+            break;
+        case BMA2XX_BMA253:
+            model_shift = BMA253_ACCEL_BIT_SHIFT;
+            break;
+        default:
+            break;
+    }
+
+    raw_accel = (int16_t)(raw_data[0] & 0xFC) | (int16_t)(raw_data[1] << 8);
+    raw_accel >>= model_shift;
+
+    accel_data->accel_g = (float)raw_accel * accel_scale;
+    accel_data->new_data = raw_data[0] & 0x01;
+}
+
+static int get_accel_scale(enum bma2xx_model model,
 
 Review comment:
   okay will add

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services