| /* |
| * 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. |
| */ |
| |
| #ifndef __BMA253_H__ |
| #define __BMA253_H__ |
| |
| #include "os/mynewt.h" |
| #include "sensor/sensor.h" |
| #include "sensor/accel.h" |
| #include "sensor/temperature.h" |
| |
| #ifdef __cplusplus |
| #extern "C" { |
| #endif |
| |
| /* XXX use some better defaults. For now it is min */ |
| #define BMA253_LOW_G_DELAY_MS_DEFAULT 2 |
| #define BMA253_HIGH_G_DELAY_MS_DEFAULT 2 |
| |
| /* Range of acceleration measurements */ |
| enum bma253_g_range { |
| BMA253_G_RANGE_2 = 0, |
| BMA253_G_RANGE_4 = 1, |
| BMA253_G_RANGE_8 = 2, |
| BMA253_G_RANGE_16 = 3, |
| }; |
| |
| /* How often acceleration measurements are taken */ |
| enum bma253_filter_bandwidth { |
| BMA253_FILTER_BANDWIDTH_7_81_HZ = 0, |
| BMA253_FILTER_BANDWIDTH_15_63_HZ = 1, |
| BMA253_FILTER_BANDWIDTH_31_25_HZ = 2, |
| BMA253_FILTER_BANDWIDTH_62_5_HZ = 3, |
| BMA253_FILTER_BANDWIDTH_125_HZ = 4, |
| BMA253_FILTER_BANDWIDTH_250_HZ = 5, |
| BMA253_FILTER_BANDWIDTH_500_HZ = 6, |
| BMA253_FILTER_BANDWIDTH_1000_HZ = 7, |
| }; |
| |
| /* Quiet time after a double/single tap */ |
| enum bma253_tap_quiet { |
| BMA253_TAP_QUIET_20_MS = 0, |
| BMA253_TAP_QUIET_30_MS = 1, |
| }; |
| |
| /* Settling time after a double/single tap */ |
| enum bma253_tap_shock { |
| BMA253_TAP_SHOCK_50_MS = 0, |
| BMA253_TAP_SHOCK_75_MS = 1, |
| }; |
| |
| /* How long to wait for the next tap in a double tap scenario */ |
| enum bma253_d_tap_window { |
| BMA253_D_TAP_WINDOW_50_MS = 0, |
| BMA253_D_TAP_WINDOW_100_MS = 1, |
| BMA253_D_TAP_WINDOW_150_MS = 2, |
| BMA253_D_TAP_WINDOW_200_MS = 3, |
| BMA253_D_TAP_WINDOW_250_MS = 4, |
| BMA253_D_TAP_WINDOW_375_MS = 5, |
| BMA253_D_TAP_WINDOW_500_MS = 6, |
| BMA253_D_TAP_WINDOW_700_MS = 7, |
| }; |
| |
| /* How many samples to use after a wake up from a low power mode to determine |
| * whether a tap occurred */ |
| enum bma253_tap_wake_samples { |
| BMA253_TAP_WAKE_SAMPLES_2 = 0, |
| BMA253_TAP_WAKE_SAMPLES_4 = 1, |
| BMA253_TAP_WAKE_SAMPLES_8 = 2, |
| BMA253_TAP_WAKE_SAMPLES_16 = 3, |
| }; |
| |
| /* Block generation of orientation events based on given criteria */ |
| enum bma253_orient_blocking { |
| BMA253_ORIENT_BLOCKING_NONE = 0, |
| BMA253_ORIENT_BLOCKING_ACCEL_ONLY = 1, |
| BMA253_ORIENT_BLOCKING_ACCEL_AND_SLOPE = 2, |
| BMA253_ORIENT_BLOCKING_ACCEL_AND_SLOPE_AND_STABLE = 3, |
| }; |
| |
| /* Orientation mode configuration, used to determine thresholds for |
| * transitions between different orientations */ |
| enum bma253_orient_mode { |
| BMA253_ORIENT_MODE_SYMMETRICAL = 0, |
| BMA253_ORIENT_MODE_HIGH_ASYMMETRICAL = 1, |
| BMA253_ORIENT_MODE_LOW_ASYMMETRICAL = 2, |
| }; |
| |
| /* Power mode for the device */ |
| enum bma253_power_mode { |
| BMA253_POWER_MODE_NORMAL = 0, |
| BMA253_POWER_MODE_DEEP_SUSPEND = 1, |
| BMA253_POWER_MODE_SUSPEND = 2, |
| BMA253_POWER_MODE_STANDBY = 3, |
| BMA253_POWER_MODE_LPM_1 = 4, |
| BMA253_POWER_MODE_LPM_2 = 5, |
| }; |
| |
| /* Duration of sleep whenever the device is in a power mode that alternates |
| * between wake and sleep (LPM 1 & 2) */ |
| enum bma253_sleep_duration { |
| BMA253_SLEEP_DURATION_0_5_MS = 0, |
| BMA253_SLEEP_DURATION_1_MS = 1, |
| BMA253_SLEEP_DURATION_2_MS = 2, |
| BMA253_SLEEP_DURATION_4_MS = 3, |
| BMA253_SLEEP_DURATION_6_MS = 4, |
| BMA253_SLEEP_DURATION_10_MS = 5, |
| BMA253_SLEEP_DURATION_25_MS = 6, |
| BMA253_SLEEP_DURATION_50_MS = 7, |
| BMA253_SLEEP_DURATION_100_MS = 8, |
| BMA253_SLEEP_DURATION_500_MS = 9, |
| BMA253_SLEEP_DURATION_1_S = 10, |
| }; |
| |
| /* Read moe for the sensor */ |
| enum bma253_read_mode { |
| BMA253_READ_M_POLL = 0, |
| BMA253_READ_M_STREAM = 1, |
| }; |
| |
| /* Default configuration values to use with the device */ |
| struct bma253_cfg { |
| /* Accelerometer configuration */ |
| enum bma253_g_range g_range; |
| enum bma253_filter_bandwidth filter_bandwidth; |
| /* Whether to use data that has not been filtered at all */ |
| bool use_unfiltered_data; |
| /* Low-g event configuration */ |
| uint16_t low_g_delay_ms; |
| float low_g_thresh_g; |
| float low_g_hyster_g; |
| /* High-g event configuration */ |
| float high_g_hyster_g; |
| uint16_t high_g_delay_ms; |
| float high_g_thresh_g; |
| /* Tap (double & single) event configuration */ |
| enum bma253_tap_quiet tap_quiet; |
| enum bma253_tap_shock tap_shock; |
| enum bma253_d_tap_window d_tap_window; |
| enum bma253_tap_wake_samples tap_wake_samples; |
| float tap_thresh_g; |
| /* Orientation event configuration */ |
| float orient_hyster_g; |
| enum bma253_orient_blocking orient_blocking; |
| enum bma253_orient_mode orient_mode; |
| bool orient_signal_ud; |
| /* Offsets for acceleration measurements, by axis */ |
| float offset_x_g; |
| float offset_y_g; |
| float offset_z_g; |
| /* Power management configuration */ |
| enum bma253_power_mode power_mode; |
| enum bma253_sleep_duration sleep_duration; |
| /* Select read mode */ |
| enum bma253_read_mode read_mode; |
| /* Applicable sensor types supported */ |
| sensor_type_t sensor_mask; |
| }; |
| |
| /* Used to track interrupt state to wake any present waiters */ |
| struct bma253_int { |
| /* Synchronize access to this structure */ |
| os_sr_t lock; |
| /* Sleep waiting for an interrupt to occur */ |
| struct os_sem wait; |
| /* Is the interrupt currently active */ |
| bool active; |
| /* Is there a waiter currently sleeping */ |
| bool asleep; |
| /* Configured interrupts */ |
| struct sensor_int *ints; |
| }; |
| |
| /* Device private data */ |
| struct bma253_private_driver_data { |
| struct bma253_int * interrupt; |
| struct sensor_notify_ev_ctx notify_ctx; |
| struct sensor_read_ev_ctx read_ctx; |
| uint8_t registered_mask; |
| |
| uint8_t int_num; |
| uint8_t int_route; |
| uint8_t int_ref_cnt; |
| }; |
| |
| /* The device itself */ |
| struct bma253 { |
| /* Underlying OS device */ |
| struct os_dev dev; |
| /* The sensor infrastructure */ |
| struct sensor sensor; |
| /* Default configuration values */ |
| struct bma253_cfg cfg; |
| /* Active interrupt state */ |
| struct bma253_int intr; |
| /* Active power mode, could be different from default configured |
| * power mode if a function that requires a higher power mode is |
| * currently running. */ |
| enum bma253_power_mode power; |
| |
| /* Private driver data */ |
| struct bma253_private_driver_data pdd; |
| }; |
| |
| /* Offset compensation is performed to target this given value, by axis */ |
| enum bma253_offset_comp_target { |
| BMA253_OFFSET_COMP_TARGET_0_G = 0, |
| BMA253_OFFSET_COMP_TARGET_NEG_1_G = 1, |
| BMA253_OFFSET_COMP_TARGET_POS_1_G = 2, |
| }; |
| |
| /* The device's X/Y orientation, in form of rotation */ |
| enum bma253_orient_xy { |
| BMA253_ORIENT_XY_PORTRAIT_UPRIGHT = 0, |
| BMA253_ORIENT_XY_PORTRAIT_UPSIDE_DOWN = 1, |
| BMA253_ORIENT_XY_LANDSCAPE_LEFT = 2, |
| BMA253_ORIENT_XY_LANDSCAPE_RIGHT = 3, |
| }; |
| |
| /* The device's full orientation */ |
| struct bma253_orient_xyz { |
| /* The X/Y orientation */ |
| enum bma253_orient_xy orient_xy; |
| /* Is device facing upward or downward */ |
| bool downward_z; |
| }; |
| |
| /* Type of tap event to look for */ |
| enum bma253_tap_type { |
| BMA253_TAP_TYPE_DOUBLE = 0, |
| BMA253_TAP_TYPE_SINGLE = 1, |
| }; |
| |
| /** |
| * Perform a self test of the device and report on its health. |
| * |
| * @param The device object. |
| * @param Multiplier on the high amplitude self test minimums; 1.0 for default. |
| * @param Multiplier on the low amplitude self test minimums; 0.0 for default. |
| * @param The result of the self-test: false if passed, true if failed. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_self_test(struct bma253 * bma253, |
| float delta_high_mult, |
| float delta_low_mult, |
| bool * self_test_fail); |
| |
| /** |
| * Perform an offset compensation and use the resulting offsets. |
| * |
| * @param The device object. |
| * @param The correct target value for the X axis. |
| * @param The correct target value for the Y axis. |
| * @param The correct target value for the Z axis. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_offset_compensation(struct bma253 * bma253, |
| enum bma253_offset_comp_target target_x, |
| enum bma253_offset_comp_target target_y, |
| enum bma253_offset_comp_target target_z); |
| |
| /** |
| * Return the current compensation offsets in use. |
| * |
| * @param The device object. |
| * @param The offset for the X axis, filled in by this function. |
| * @param The offset for the Y axis, filled in by this function. |
| * @param The offset for the Z axis, filled in by this function. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_query_offsets(struct bma253 * bma253, |
| float * offset_x_g, |
| float * offset_y_g, |
| float * offset_z_g); |
| |
| /** |
| * Store and use the provided compensation offsets. |
| * |
| * @param The device object. |
| * @param The offset for the X axis. |
| * @param The offset for the Y axis. |
| * @param the offset for the Z axis. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_write_offsets(struct bma253 * bma253, |
| float offset_x_g, |
| float offset_y_g, |
| float offset_z_g); |
| |
| /** |
| * Provide a continuous stream of accelerometer readings. |
| * |
| * @param The sensor ptr |
| * @param The sensor type |
| * @param The function pointer to invoke for each accelerometer reading. |
| * @param The opaque pointer that will be passed in to the function. |
| * @param If non-zero, how long the stream should run in milliseconds. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_stream_read(struct sensor *sensor, |
| sensor_type_t sensor_type, |
| sensor_data_func_t read_func, |
| void *read_arg, |
| uint32_t time_ms); |
| |
| /** |
| * Do accelerometer polling reads |
| * |
| * @param The sensor ptr |
| * @param The sensor type |
| * @param The function pointer to invoke for each accelerometer reading. |
| * @param The opaque pointer that will be passed in to the function. |
| * @param If non-zero, how long the stream should run in milliseconds. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_poll_read(struct sensor * sensor, |
| sensor_type_t sensor_type, |
| sensor_data_func_t data_func, |
| void * data_arg, |
| uint32_t timeout); |
| |
| /** |
| * Get the current temperature at the device. |
| * |
| * @param The device object. |
| * @param The current temperature in celsius, filled in by this function. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_current_temp(struct bma253 * bma253, |
| float * temp_c); |
| |
| /** |
| * Get the current device orientation. |
| * |
| * @param The device object. |
| * @param The current orientation, filled in by this function. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_current_orient(struct bma253 * bma253, |
| struct bma253_orient_xyz * orient_xyz); |
| |
| /** |
| * Block until the device orientation changes. |
| * |
| * @param The device object. |
| * @param The new orientation, filled in by this function. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_wait_for_orient(struct bma253 * bma253, |
| struct bma253_orient_xyz * orient_xyz); |
| |
| /** |
| * Block until a high-g event occurs. |
| * |
| * @param The device object. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_wait_for_high_g(struct bma253 * bma253); |
| |
| /** |
| * Block until a low-g event occurs. |
| * |
| * @param The device object. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_wait_for_low_g(struct bma253 * bma253); |
| |
| /** |
| * Block until a single or double tap event occurs. |
| * |
| * @param The device object. |
| * @param The type of tap event to look for. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_wait_for_tap(struct bma253 * bma253, |
| enum bma253_tap_type tap_type); |
| |
| /** |
| * Change the default power settings. |
| * |
| * @param The device object. |
| * @param The new power mode, which the device resides in unless a different |
| * and more aggressive power mode is required to satisfy a running API |
| * function. |
| * @param The new sleep duration, used whenever device is in LPM_1/2 mode |
| * either due to default power mode or due to being in a temporarily |
| * overridden power mode. |
| */ |
| int |
| bma253_power_settings(struct bma253 * bma253, |
| enum bma253_power_mode power_mode, |
| enum bma253_sleep_duration sleep_duration); |
| |
| /** |
| * Configure the sensor. |
| * |
| * @param ptr to sensor driver |
| * @param ptr to sensor driver config |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_config(struct bma253 * bma253, struct bma253_cfg * cfg); |
| |
| /** |
| * Expects to be called back through os_dev_create(). |
| * |
| * @param ptr to the device object associated with this accelerometer |
| * @param argument passed to OS device init |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_init(struct os_dev * dev, void * arg); |
| |
| #if MYNEWT_VAL(BMA253_CLI) |
| /** |
| * Initialize the BMA253 shell extensions. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int |
| bma253_shell_init(void); |
| #endif |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif |