コード例 #1
0
static int
disable_interrupt(struct sensor * sensor, uint8_t int_to_disable)
{
    struct lis2dw12 *lis2dw12;
    struct lis2dw12_private_driver_data *pdd;
    struct sensor_itf *itf;
    int rc;

    if (int_to_disable == 0) {
        return SYS_EINVAL;
    }
    
    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &lis2dw12->pdd;

    pdd->int_enable &= ~int_to_disable;
    
    /* disable int pin */
    if (pdd->int_enable == 0) {
        hal_gpio_irq_disable(itf->si_ints[pdd->int_num].host_pin);
           
        rc = lis2dw12_set_int_enable(itf, 0);
        if (rc) {
            return rc;
        }
    }
    
    /* update interrupt setup in device */
    return lis2dw12_set_int1_pin_cfg(itf, pdd->int_enable);
}
コード例 #2
0
static int
sim_accel_sensor_read(struct sensor *sensor, sensor_type_t type,
        sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
{
    struct sim_accel *sa;
    struct sensor_accel_data sad;
    os_time_t now;
    uint32_t num_samples;
    int i;
    int rc;

    /* If the read isn't looking for accel data, then don't do anything. */
    if (!(type & SENSOR_TYPE_ACCELEROMETER)) {
        rc = SYS_EINVAL;
        goto err;
    }

    sa = (struct sim_accel *) SENSOR_GET_DEVICE(sensor);

    /* When a sensor is "read", we get the last 'n' samples from the device
     * and pass them to the sensor data function.  Based on the sample
     * interval provided to sim_accel_config() and the last time this function
     * was called, 'n' samples are generated.
     */
    now = os_time_get();

    num_samples = (now - sa->sa_last_read_time) / sa->sa_cfg.sac_sample_itvl;
    num_samples = min(num_samples, sa->sa_cfg.sac_nr_samples);

    /* By default only readings are provided for 1-axis (x), however,
     * if number of axises is configured, up to 3-axises of data can be
     * returned.
     */
    sad.sad_x = 0.0;
    sad.sad_y = 0.0;
    sad.sad_z = 0.0;

    sad.sad_x_is_valid = 1;
    sad.sad_y_is_valid = 0;
    sad.sad_z_is_valid = 0;

    if (sa->sa_cfg.sac_nr_axises > 1) {
        sad.sad_y = 0.0;
    }
    if (sa->sa_cfg.sac_nr_axises > 2) {
        sad.sad_z = 0.0;
    }

    /* Call data function for each of the generated readings. */
    for (i = 0; i < num_samples; i++) {
        rc = data_func(sensor, data_arg, &sad, SENSOR_TYPE_ACCELEROMETER);
        if (rc != 0) {
            goto err;
        }
    }

    return (0);
err:
    return (rc);
}
コード例 #3
0
static int
lis2dw12_sensor_handle_interrupt(struct sensor * sensor)
{
    struct lis2dw12 * lis2dw12;
    struct lis2dw12_private_driver_data *pdd;
    struct sensor_itf *itf;
    uint8_t int_src;
    
    int rc;

    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);

    pdd = &lis2dw12->pdd;

    rc = lis2dw12_clear_int(itf, &int_src);
    if (rc) {
        LIS2DW12_ERR("Cound not read int status err=0x%02x\n", rc);
        return rc;
    }

    if ((pdd->registered_mask & LIS2DW12_NOTIFY_MASK) &&
        ((int_src & LIS2DW12_INT_SRC_STAP) ||
         (int_src & LIS2DW12_INT_SRC_DTAP))) {
        sensor_mgr_put_notify_evt(&pdd->notify_ctx);
    }

    return 0;
}
コード例 #4
0
/**
 * Disables notifications on tap or double tap events
 *
 * @param Pointer to sensor structure
 * @param which event to get notifications for
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_unset_notification(struct sensor * sensor,
                                  sensor_event_type_t sensor_event_type)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    uint8_t ints_to_disable = 0;

    if ((sensor_event_type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
                               SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
        return SYS_EINVAL;
    }

    /*XXX for now we do not support registering for both events */
    if (sensor_event_type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
                                        SENSOR_EVENT_TYPE_SINGLE_TAP)) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);

    adxl345->pdd.notify_ctx.snec_evtype &= ~sensor_event_type;
    adxl345->pdd.registered_mask &= ~ADXL345_NOTIFY_MASK;

    ints_to_disable |= ADXL345_INT_SINGLE_TAP_BIT;
    ints_to_disable |= ADXL345_INT_DOUBLE_TAP_BIT;
   
    return disable_interrupt(sensor, ints_to_disable);
    
#else
    return SYS_ENODEV;
#endif
}
コード例 #5
0
/**
 * Disables an interrupt in ADXL345 device
 *
 * @param Pointer to sensor structure
 * @param which interrupt(s) to disable
 *
 * @return 0 on success, non-zero on failure
 */
static int
disable_interrupt(struct sensor * sensor, uint8_t ints_to_disable)
{
    struct adxl345_private_driver_data *pdd;
    struct adxl345 *adxl345;
    struct sensor_itf *itf;

    if (ints_to_disable == 0) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &adxl345->pdd;
    
    /* update which interrupts are enabled */
    pdd->int_enable &= ~ints_to_disable;

    /* if no interrupts are now in use disable int pin */
    if (pdd->int_enable == 0) {
        hal_gpio_irq_disable(adxl345->sensor.s_itf.si_ints[pdd->int_num].host_pin);
    }

    /* update interrupt setup in device */
    return adxl345_setup_interrupts(itf, pdd->int_enable, pdd->int_route);
}
コード例 #6
0
static int
lis2dw12_sensor_set_config(struct sensor *sensor, void *cfg)
{
    struct lis2dw12 *lis2dw12;

    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);

    return lis2dw12_config(lis2dw12, (struct lis2dw12_cfg*)cfg);
}
コード例 #7
0
static int
tcs34725_sensor_read(struct sensor *sensor, sensor_type_t type,
        sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
{
    struct tcs34725 *tcs34725;
    struct sensor_color_data scd;
    struct sensor_itf *itf;
    uint16_t r;
    uint16_t g;
    uint16_t b;
    uint16_t c;
    int rc;

    /* If the read isn't looking for accel or mag data, don't do anything. */
    if (!(type & SENSOR_TYPE_COLOR)) {
        rc = SYS_EINVAL;
        goto err;
    }

    itf = SENSOR_GET_ITF(sensor);
    tcs34725 = (struct tcs34725 *) SENSOR_GET_DEVICE(sensor);

    /* Get a new accelerometer sample */
    if (type & SENSOR_TYPE_COLOR) {
        r = g = b = c = 0;

        rc = tcs34725_get_rawdata(itf, &r, &g, &b, &c, tcs34725);
        if (rc) {
            goto err;
        }

        scd.scd_r = r;
        scd.scd_g = g;
        scd.scd_b = b;
        scd.scd_c = c;

        scd.scd_r_is_valid = 1;
        scd.scd_g_is_valid = 1;
        scd.scd_b_is_valid = 1;
        scd.scd_c_is_valid = 1;

        rc = tcs34725_calc_colortemp_lux(itf, &scd, tcs34725);
        if (rc) {
            goto err;
        }

        /* Call data function */
        rc = data_func(sensor, data_arg, &scd, SENSOR_TYPE_COLOR);
        if (rc != 0) {
            goto err;
        }
    }

    return 0;
err:
    return rc;
}
コード例 #8
0
/**
 * Enables notifications on tap or double tap events
 *
 * @param Pointer to sensor structure
 * @param which event to get notifications for
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_set_notification(struct sensor * sensor,
                                sensor_event_type_t sensor_event_type)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    uint8_t ints_to_enable = 0;
    struct adxl345_private_driver_data *pdd;
    int rc;

    ADXL345_LOG(ERROR, "Enabling notifications\n");
    
    if ((sensor_event_type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
                               SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
        return SYS_EINVAL;
    }

    /*XXX for now we do not support registering for both events */
    if (sensor_event_type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
                                        SENSOR_EVENT_TYPE_SINGLE_TAP)) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    pdd = &adxl345->pdd;

    if (pdd->registered_mask & ADXL345_NOTIFY_MASK) {
        return SYS_EBUSY;
    }

    /* Enable tap event*/
    if(sensor_event_type == SENSOR_EVENT_TYPE_DOUBLE_TAP) {
        ints_to_enable |= ADXL345_INT_DOUBLE_TAP_BIT;
    }
    if(sensor_event_type == SENSOR_EVENT_TYPE_SINGLE_TAP) {
        ints_to_enable |= ADXL345_INT_SINGLE_TAP_BIT;
    }

    rc = enable_interrupt(sensor, ints_to_enable);
    if (rc) {
        return rc;
    }

    pdd->notify_ctx.snec_evtype |= sensor_event_type;
    pdd->registered_mask |= ADXL345_NOTIFY_MASK;

    ADXL345_LOG(ERROR, "Enabled notifications\n");
    
    return 0;
#else
    return SYS_ENODEV;
#endif
}
コード例 #9
0
static int
tsl2561_sensor_read(struct sensor *sensor, sensor_type_t type,
        sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
{
    struct tsl2561 *tsl2561;
    struct sensor_light_data sld;
    struct sensor_itf *itf;
    uint16_t full;
    uint16_t ir;
    uint32_t lux;
    int rc;

    /* If the read isn't looking for accel or mag data, don't do anything. */
    if (!(type & SENSOR_TYPE_LIGHT)) {
        rc = SYS_EINVAL;
        goto err;
    }

    itf = SENSOR_GET_ITF(sensor);
    tsl2561 = (struct tsl2561 *)SENSOR_GET_DEVICE(sensor);

    /* Get a new accelerometer sample */
    if (type & SENSOR_TYPE_LIGHT) {
        full = ir = 0;

        rc = tsl2561_get_data(itf, &full, &ir);
        if (rc) {
            goto err;
        }

        lux = tsl2561_calculate_lux(full, ir, &(tsl2561->cfg));
        sld.sld_full = full;
        sld.sld_ir = ir;
        sld.sld_lux = lux;

        sld.sld_full_is_valid = 1;
        sld.sld_ir_is_valid   = 1;
        sld.sld_lux_is_valid  = 1;

        /* Call data function */
        rc = data_func(sensor, data_arg, &sld, SENSOR_TYPE_LIGHT);
        if (rc != 0) {
            goto err;
        }
    }

    return 0;
err:
    return rc;
}
コード例 #10
0
static int
lis2dw12_sensor_read(struct sensor *sensor, sensor_type_t type,
        sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
{
    int rc;
    const struct lis2dw12_cfg *cfg;
    struct lis2dw12 *lis2dw12;
    struct sensor_itf *itf;

    /* If the read isn't looking for accel data, don't do anything. */
    if (!(type & SENSOR_TYPE_ACCELEROMETER)) {
        rc = SYS_EINVAL;
        goto err;
    }

    itf = SENSOR_GET_ITF(sensor);

    if (itf->si_type == SENSOR_ITF_SPI) {
        
        rc = hal_spi_disable(sensor->s_itf.si_num);
        if (rc) {
            goto err;
        }

        rc = hal_spi_config(sensor->s_itf.si_num, &spi_lis2dw12_settings);
        if (rc == EINVAL) {
            /* If spi is already enabled, for nrf52, it returns -1, We should not
             * fail if the spi is already enabled
             */
            goto err;
        }

        rc = hal_spi_enable(sensor->s_itf.si_num);
        if (rc) {
            goto err;
        }
    }
    
    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    cfg = &lis2dw12->cfg;

    if (cfg->read_mode == LIS2DW12_READ_M_POLL) {
        rc = lis2dw12_poll_read(sensor, type, data_func, data_arg, timeout);
    } else {
        rc = lis2dw12_stream_read(sensor, type, data_func, data_arg, timeout);
    }

err:
    return rc;
}
コード例 #11
0
static void
lis2dw12_int_irq_handler(void *arg)
{
    struct sensor *sensor = arg;
    struct lis2dw12 *lis2dw12;

    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);

    if(lis2dw12->pdd.interrupt) {
        wake_interrupt(lis2dw12->pdd.interrupt);
    }
    
    sensor_mgr_put_interrupt_evt(sensor);
}
コード例 #12
0
static int
lis2dw12_sensor_set_notification(struct sensor *sensor, sensor_event_type_t type)
{
    struct lis2dw12 * lis2dw12;
    uint8_t int_cfg = 0;
    struct lis2dw12_private_driver_data *pdd;
    int rc;

    if ((type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
                  SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
        return SYS_EINVAL;
    }

    /*XXX for now we do not support registering for both events */
    if (type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
                 SENSOR_EVENT_TYPE_SINGLE_TAP)) {
        return SYS_EINVAL;
    }

    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    pdd = &lis2dw12->pdd;

    if (pdd->registered_mask & LIS2DW12_NOTIFY_MASK) {
        return SYS_EBUSY;
    }

    /* Enable tap interrupt */
    if(type == SENSOR_EVENT_TYPE_DOUBLE_TAP) {
        int_cfg |= LIS2DW12_INT1_CFG_DOUBLE_TAP;
    }
    if(type == SENSOR_EVENT_TYPE_SINGLE_TAP) {
        int_cfg |= LIS2DW12_INT1_CFG_SINGLE_TAP;
    }

    rc = enable_interrupt(sensor, int_cfg);
    if (rc) {
        return rc;
    }

    pdd->notify_ctx.snec_evtype |= type;
    pdd->registered_mask |= LIS2DW12_NOTIFY_MASK;

    return 0;
}
コード例 #13
0
/**
 * Handles and interrupt, firing correct events
 *
 * @param Pointer to sensor structure
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_handle_interrupt(struct sensor * sensor)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    struct adxl345_private_driver_data *pdd;
    struct sensor_itf *itf;
    uint8_t int_status;
    
    int rc;

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);

    pdd = &adxl345->pdd;

    rc = adxl345_clear_interrupts(itf, &int_status);
    if (rc != 0) {
        ADXL345_LOG(ERROR, "Cound not read int status err=0x%02x\n", rc);
        return rc;
    }

    if (pdd->registered_mask & ADXL345_NOTIFY_MASK) {
        if (int_status & ADXL345_INT_SINGLE_TAP_BIT) {
            sensor_mgr_put_notify_evt(&pdd->notify_ctx, SENSOR_EVENT_TYPE_SINGLE_TAP);
        }

        if (int_status & ADXL345_INT_DOUBLE_TAP_BIT) {
            sensor_mgr_put_notify_evt(&pdd->notify_ctx, SENSOR_EVENT_TYPE_DOUBLE_TAP);
        }
    }

    if ((pdd->registered_mask & ADXL345_READ_MASK) &&
        ((int_status & ADXL345_INT_ACTIVITY_BIT) ||
         (int_status & ADXL345_INT_INACTIVITY_BIT))) {
        ADXL345_LOG(ERROR, "READ EVT 0x%02x\n", int_status);
        sensor_mgr_put_read_evt(&pdd->read_ctx);
    }

    return 0;
#else
    return SYS_ENODEV;
#endif
}
コード例 #14
0
/**
 * Disable the high threshold interrupt
 *
 * @param ptr to sensor
 * @param the Sensor type
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_clear_high_thresh(struct sensor *sensor,
                                  sensor_type_t type)
{
    struct adxl345 *adxl345;
    uint8_t ints_to_disable = ADXL345_INT_ACTIVITY_BIT;

    if (type != SENSOR_TYPE_ACCELEROMETER) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);

    /* if neither high or low threshs are now set disable read mask */
    if((adxl345->pdd.int_enable & ADXL345_INT_INACTIVITY_BIT) == 0) {
        adxl345->pdd.read_ctx.srec_type &= ~type;
        adxl345->pdd.registered_mask &= ~ADXL345_READ_MASK;
    }

    return disable_interrupt(sensor, ints_to_disable);
}
コード例 #15
0
static int
enable_interrupt(struct sensor * sensor, uint8_t int_to_enable)
{
    struct lis2dw12 *lis2dw12;
    struct lis2dw12_private_driver_data *pdd;
    struct sensor_itf *itf;
    uint8_t reg;
    int rc;

    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &lis2dw12->pdd;

    rc = lis2dw12_clear_int(itf, &reg);
    if (rc) {
        return rc;
    }
    
    /* if no interrupts are currently in use enable int pin */
    if (pdd->int_enable == 0) {
        hal_gpio_irq_enable(itf->si_ints[pdd->int_num].host_pin);

        rc = lis2dw12_set_int_enable(itf, 1);
        if (rc) {
            return rc;
        }
    }

    /*update which interrupts are enabled */
    pdd->int_enable |= int_to_enable;
    
    /* enable interrupt in device */
    rc = lis2dw12_set_int1_pin_cfg(itf, pdd->int_enable);
    if (rc) {
        return rc;
    }

    return 0;
    
}
コード例 #16
0
static int
lis2dw12_sensor_unset_notification(struct sensor *sensor, sensor_event_type_t type)
{
    struct lis2dw12 * lis2dw12;
    
    if ((type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
                  SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
        return SYS_EINVAL;
    }
    
    /*XXX for now we do not support registering for both events */
    if (type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
                 SENSOR_EVENT_TYPE_SINGLE_TAP)) {
        return SYS_EINVAL;
    }
    
    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    
    lis2dw12->pdd.notify_ctx.snec_evtype &= ~type;
    lis2dw12->pdd.registered_mask &= ~LIS2DW12_NOTIFY_MASK;
    
    return disable_interrupt(sensor, 0);
}
コード例 #17
0
static int
mpu6050_sensor_read(struct sensor *sensor, sensor_type_t type,
        sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
{
    (void)timeout;
    int rc;
    int16_t x, y, z;
    uint8_t payload[6];
    float lsb;
    struct sensor_itf *itf;
    struct mpu6050 *mpu;
    union {
        struct sensor_accel_data sad;
        struct sensor_gyro_data sgd;
    } databuf;

    /* If the read isn't looking for accel or gyro, don't do anything. */
    if (!(type & SENSOR_TYPE_ACCELEROMETER) &&
       (!(type & SENSOR_TYPE_GYROSCOPE))) {
        return SYS_EINVAL;
    }

    itf = SENSOR_GET_ITF(sensor);
    mpu = (struct mpu6050 *) SENSOR_GET_DEVICE(sensor);

    /* Get a new accelerometer sample */
    if (type & SENSOR_TYPE_ACCELEROMETER) {
        rc = mpu6050_read48(itf, MPU6050_ACCEL_XOUT_H, payload);
        if (rc) {
            return rc;
        }

        x = (((int16_t)payload[0]) << 8) | payload[1];
        y = (((int16_t)payload[2]) << 8) | payload[3];
        z = (((int16_t)payload[4]) << 8) | payload[5];

        switch (mpu->cfg.accel_range) {
            case MPU6050_ACCEL_RANGE_2: /* +/- 2g - 16384 LSB/g */
            /* Falls through */
            default:
                lsb = 16384.0F;
            break;
            case MPU6050_ACCEL_RANGE_4: /* +/- 4g - 8192 LSB/g */
                lsb = 8192.0F;
            break;
            case MPU6050_ACCEL_RANGE_8: /* +/- 8g - 4096 LSB/g */
                lsb = 4096.0F;
            break;
            case MPU6050_ACCEL_RANGE_16: /* +/- 16g - 2048 LSB/g */
                lsb = 2048.0F;
            break;
        }

        databuf.sad.sad_x = (x / lsb) * STANDARD_ACCEL_GRAVITY;
        databuf.sad.sad_x_is_valid = 1;
        databuf.sad.sad_y = (y / lsb) * STANDARD_ACCEL_GRAVITY;
        databuf.sad.sad_y_is_valid = 1;
        databuf.sad.sad_z = (z / lsb) * STANDARD_ACCEL_GRAVITY;
        databuf.sad.sad_z_is_valid = 1;

        rc = data_func(sensor, data_arg, &databuf.sad,
                SENSOR_TYPE_ACCELEROMETER);
        if (rc) {
            return rc;
        }
    }

    /* Get a new gyroscope sample */
    if (type & SENSOR_TYPE_GYROSCOPE) {
        rc = mpu6050_read48(itf, MPU6050_GYRO_XOUT_H, payload);
        if (rc) {
            return rc;
        }

        x = (((int16_t)payload[0]) << 8) | payload[1];
        y = (((int16_t)payload[2]) << 8) | payload[3];
        z = (((int16_t)payload[4]) << 8) | payload[5];

        switch (mpu->cfg.gyro_range) {
            case MPU6050_GYRO_RANGE_250: /* +/- 250 Deg/s - 131 LSB/Deg/s */
            /* Falls through */
            default:
                lsb = 131.0F;
            break;
            case MPU6050_GYRO_RANGE_500: /* +/- 500 Deg/s - 65.5 LSB/Deg/s */
                lsb = 65.5F;
            break;
            case MPU6050_GYRO_RANGE_1000: /* +/- 1000 Deg/s - 32.8 LSB/Deg/s */
                lsb = 32.8F;
            break;
            case MPU6050_GYRO_RANGE_2000: /* +/- 2000 Deg/s - 16.4 LSB/Deg/s */
                lsb = 16.4F;
            break;
        }

        databuf.sgd.sgd_x = x / lsb;
        databuf.sgd.sgd_x_is_valid = 1;
        databuf.sgd.sgd_y = y / lsb;
        databuf.sgd.sgd_y_is_valid = 1;
        databuf.sgd.sgd_z = z / lsb;
        databuf.sgd.sgd_z_is_valid = 1;

        rc = data_func(sensor, data_arg, &databuf.sgd, SENSOR_TYPE_GYROSCOPE);
        if (rc) {
            return rc;
        }
    }

    return 0;
}
コード例 #18
0
int
lis2dw12_stream_read(struct sensor *sensor,
                   sensor_type_t sensor_type,
                   sensor_data_func_t read_func,
                   void *read_arg,
                   uint32_t time_ms)
{
    struct lis2dw12 *lis2dw12;
    struct sensor_itf *itf;
    int rc;
    os_time_t time_ticks;
    os_time_t stop_ticks = 0;
    struct lis2dw12_private_driver_data *pdd;
    uint8_t fifo_samples;

    /* If the read isn't looking for accel data, don't do anything. */
    if (!(sensor_type & SENSOR_TYPE_ACCELEROMETER)) {
        return SYS_EINVAL;
    }

    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &lis2dw12->pdd;

    undo_interrupt(&lis2dw12->intr);

    if (pdd->interrupt) {
        return SYS_EBUSY;
    }

    /* enable interrupt */
    pdd->interrupt = &lis2dw12->intr;

    rc = enable_interrupt(sensor, lis2dw12->cfg.stream_read_interrupt);
    if (rc) {
        goto done;
    }

    if (time_ms != 0) {
        rc = os_time_ms_to_ticks(time_ms, &time_ticks);
        if (rc) {
            goto done;
        }
        stop_ticks = os_time_get() + time_ticks;
    }

    for (;;) {
        wait_interrupt(&lis2dw12->intr, pdd->int_num);
        fifo_samples = 1;
        
        while(fifo_samples > 0) {
            rc = lis2dw12_do_read(sensor, read_func, read_arg);
            if (rc) {
                goto done;
            }

            rc = lis2dw12_get_fifo_samples(itf, &fifo_samples);
            if (rc) {
                goto done;
            }
        }
        
        if (time_ms != 0 && OS_TIME_TICK_GT(os_time_get(), stop_ticks)) {
                break;
        }
    }

done:
    /* disable interrupt */
    pdd->interrupt = NULL;
    rc = disable_interrupt(sensor, lis2dw12->cfg.stream_read_interrupt);

    return rc;
}
コード例 #19
0
/**
 * Sets up trigger thresholds and enables interrupts
 *
 * @param Pointer to sensor structure
 * @param type of sensor
 * @param threshold settings to configure
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_set_trigger_thresh(struct sensor * sensor,
                                  sensor_type_t sensor_type,
                                  struct sensor_type_traits * stt)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    struct sensor_itf *itf;
    int rc;
    const struct sensor_accel_data * low_thresh;
    const struct sensor_accel_data * high_thresh;
    uint8_t ints_to_enable = 0;
    float thresh;
    struct adxl345_private_driver_data *pdd;
    struct adxl345_act_inact_enables axis_enables = { 0 };

    if (sensor_type != SENSOR_TYPE_ACCELEROMETER) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &adxl345->pdd;

    low_thresh  = stt->stt_low_thresh.sad;
    high_thresh = stt->stt_high_thresh.sad;

    if (low_thresh->sad_x_is_valid |
        low_thresh->sad_y_is_valid |
        low_thresh->sad_z_is_valid) {
        thresh = INFINITY;

        if (low_thresh->sad_x_is_valid) {
            axis_enables.inact_x = 1;
            if (thresh > low_thresh->sad_x) {
                thresh = low_thresh->sad_x;
            }
        }
        if (low_thresh->sad_y_is_valid) {
            axis_enables.inact_y = 1;
            if (thresh > low_thresh->sad_y) {
                thresh = low_thresh->sad_y;
            }
        }
        if (low_thresh->sad_z_is_valid) {
            axis_enables.inact_z = 1;
            if (thresh > low_thresh->sad_z) {
                thresh = low_thresh->sad_z;
            }
        }

        rc = adxl345_set_inactive_settings(itf,
                adxl345_convert_ms2_to_reg(thresh, 62.5), 2);
        
        if (rc) {
            return rc;
        }

        ints_to_enable |= ADXL345_INT_INACTIVITY_BIT;
    }

    if (high_thresh->sad_x_is_valid |
        high_thresh->sad_y_is_valid |
        high_thresh->sad_z_is_valid) {
        thresh = 0.0;

        if (high_thresh->sad_x_is_valid) {
            axis_enables.act_x = 1;
            if (thresh < high_thresh->sad_x) {
                thresh = high_thresh->sad_x;
            }
        }
        if (high_thresh->sad_y_is_valid) {
            axis_enables.act_y = 1;
            if (thresh < high_thresh->sad_y) {
                thresh = high_thresh->sad_y;
            }
        }
        if (high_thresh->sad_z_is_valid) {
            axis_enables.act_z = 1;
            if (thresh < high_thresh->sad_z) {
                thresh = high_thresh->sad_z;
            }
        }

        rc = adxl345_set_active_threshold(itf,
                   adxl345_convert_ms2_to_reg(thresh, 62.5));
        if (rc) {
            return rc;
        }

        ints_to_enable |= ADXL345_INT_ACTIVITY_BIT;
       
    }

    rc = enable_interrupt(sensor, ints_to_enable);
    if (rc) {
        return rc;
    }

    rc = adxl345_set_act_inact_enables(itf, axis_enables);
    if (rc) {
        return rc;
    }
    
    pdd->read_ctx.srec_type |= sensor_type;
    pdd->registered_mask |= ADXL345_READ_MASK;

    return 0;
#else
    return SYS_ENODEV;
#endif
}