LSM303D e-Compass driver added (#548)
This commit is contained in:
parent
39957e6203
commit
f5bbff8b87
9 changed files with 4587 additions and 0 deletions
3
examples/lsm303d/Makefile
Normal file
3
examples/lsm303d/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
PROGRAM=LSM303D
|
||||
EXTRA_COMPONENTS = extras/i2c extras/lsm303d
|
||||
include ../../common.mk
|
432
examples/lsm303d/lsm303d_example.c
Normal file
432
examples/lsm303d/lsm303d_example.c
Normal file
|
@ -0,0 +1,432 @@
|
|||
/**
|
||||
* Simple example with one sensor connected to I2C or SPI. It demonstrates the
|
||||
* different approaches to fetch the data. Either one of the interrupt signals
|
||||
* is used or new data are fetched periodically.
|
||||
*
|
||||
* Harware configuration:
|
||||
*
|
||||
* I2C
|
||||
*
|
||||
* +-----------------+ +----------+
|
||||
* | ESP8266 / ESP32 | | LSM303D |
|
||||
* | | | |
|
||||
* | GPIO 14 (SCL) ----> SCL |
|
||||
* | GPIO 13 (SDA) <---> SDA |
|
||||
* | GPIO 5 <---- INT1 |
|
||||
* | GPIO 4 <---- INT2 |
|
||||
* +-----------------+ +----------+
|
||||
*
|
||||
* SPI
|
||||
*
|
||||
* +-----------------+ +----------+ +-----------------+ +----------+
|
||||
* | ESP8266 | | LSM303D | | ESP32 | | LSM303D |
|
||||
* | | | | | | | |
|
||||
* | GPIO 14 (SCK) ----> SCK | | GPIO 16 (SCK) ----> SCK |
|
||||
* | GPIO 13 (MOSI)----> SDI | | GPIO 17 (MOSI)----> SDI |
|
||||
* | GPIO 12 (MISO)<---- SDO | | GPIO 18 (MISO)<---- SDO |
|
||||
* | GPIO 2 (CS) ----> CS | | GPIO 19 (CS) ----> CS |
|
||||
* | GPIO 5 <---- INT1 | | GPIO 5 <---- INT1 |
|
||||
* | GPIO 4 <---- INT2 | | GPIO 4 <---- INT2 |
|
||||
* +-----------------+ +---------+ +-----------------+ +----------+
|
||||
*/
|
||||
|
||||
/* -- use following constants to define the example mode ----------- */
|
||||
|
||||
// #define SPI_USED // SPI interface is used, otherwise I2C
|
||||
// #define FIFO_MODE // multiple sample read mode
|
||||
// #define TEMP_USED // temperature sensor used
|
||||
// #define INT_DATA // data interrupts used (data ready and FIFO status)
|
||||
// #define INT_EVENT // inertial event interrupts used (axis movement or 6D/4D orientation)
|
||||
// #define INT_CLICK // click detection interrupts used
|
||||
// #define INT_THRESH // magnetic value exceeds threshold interrupt used
|
||||
|
||||
#if defined(INT_DATA) || defined(INT_EVENT) || defined(INT_CLICK) || defined(INT_THRESH)
|
||||
#define INT_USED
|
||||
#endif
|
||||
|
||||
/* -- includes ----------------------------------------------------- */
|
||||
|
||||
#include "lsm303d.h"
|
||||
|
||||
/** -- platform dependent definitions ------------------------------ */
|
||||
|
||||
#ifdef ESP_PLATFORM // ESP32 (ESP-IDF)
|
||||
|
||||
// user task stack depth for ESP32
|
||||
#define TASK_STACK_DEPTH 2048
|
||||
|
||||
// SPI interface definitions for ESP32
|
||||
#define SPI_BUS HSPI_HOST
|
||||
#define SPI_SCK_GPIO 16
|
||||
#define SPI_MOSI_GPIO 17
|
||||
#define SPI_MISO_GPIO 18
|
||||
#define SPI_CS_GPIO 19
|
||||
|
||||
#else // ESP8266 (esp-open-rtos)
|
||||
|
||||
// user task stack depth for ESP8266
|
||||
#define TASK_STACK_DEPTH 256
|
||||
|
||||
// SPI interface definitions for ESP8266
|
||||
#define SPI_BUS 1
|
||||
#define SPI_SCK_GPIO 14
|
||||
#define SPI_MOSI_GPIO 13
|
||||
#define SPI_MISO_GPIO 12
|
||||
#define SPI_CS_GPIO 2 // GPIO 15, the default CS of SPI bus 1, can't be used
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
|
||||
// I2C interface defintions for ESP32 and ESP8266
|
||||
#define I2C_BUS 0
|
||||
#define I2C_SCL_PIN 14
|
||||
#define I2C_SDA_PIN 13
|
||||
#define I2C_FREQ I2C_FREQ_100K
|
||||
|
||||
// interrupt GPIOs defintions for ESP8266 and ESP32
|
||||
#define INT1_PIN 5
|
||||
#define INT2_PIN 4
|
||||
|
||||
/* -- user tasks --------------------------------------------------- */
|
||||
|
||||
static lsm303d_sensor_t* sensor;
|
||||
|
||||
/**
|
||||
* Common function used to get sensor data.
|
||||
*/
|
||||
void read_data ()
|
||||
{
|
||||
#ifdef FIFO_MODE
|
||||
|
||||
lsm303d_float_a_data_fifo_t fifo;
|
||||
|
||||
// test for new accelerator data data
|
||||
if (lsm303d_new_a_data (sensor))
|
||||
{
|
||||
// fetch the accelerator data stored in FIFO
|
||||
uint8_t num = lsm303d_get_float_a_data_fifo (sensor, fifo);
|
||||
|
||||
printf("%.3f LSM303D num=%d\n", (double)sdk_system_get_time()*1e-3, num);
|
||||
|
||||
for (int i=0; i < num; i++)
|
||||
// max. full scale is +-16 g and best resolution is 1 mg, i.e. 5 digits
|
||||
printf("%.3f LSM303D (xyz)[g] ax=%+7.3f ay=%+7.3f az=%+7.3f\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
fifo[i].ax, fifo[i].ay, fifo[i].az);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
lsm303d_float_a_data_t a_data;
|
||||
|
||||
// test for new accelerator data and fetch them
|
||||
if (lsm303d_new_a_data (sensor) &&
|
||||
lsm303d_get_float_a_data (sensor, &a_data))
|
||||
// max. full scale is +-16 g and best resolution is 1 mg, i.e. 5 digits
|
||||
printf("%.3f LSM303D (xyz)[g] ax=%+7.3f ay=%+7.3f az=%+7.3f\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
a_data.ax, a_data.ay, a_data.az);
|
||||
|
||||
#endif // FIFO_MODE
|
||||
|
||||
lsm303d_float_m_data_t m_data;
|
||||
|
||||
// test for new magnetometer data and fetch them
|
||||
if (lsm303d_new_m_data (sensor) &&
|
||||
lsm303d_get_float_m_data (sensor, &m_data))
|
||||
// max. full scale is +-12 Gs and best resolution is 1 mGs, i.e. 5 digits
|
||||
printf("%.3f LSM303D (xyz)[Gs] mx=%+7.3f my=%+7.3f mz=%+7.3f\n",
|
||||
(double)sdk_system_get_time()*1e-3,
|
||||
m_data.mx, m_data.my, m_data.mz);
|
||||
|
||||
#ifdef TEMP_USED
|
||||
float temp = lsm303d_get_temperature (sensor);
|
||||
|
||||
printf("%.3f LSM303D (tmp)[°C] %+7.3f\n", (double)sdk_system_get_time()*1e-3, temp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef INT_USED
|
||||
/**
|
||||
* In this case, any of the possible interrupts on interrupt signal *INT1* is
|
||||
* used to fetch the data.
|
||||
*
|
||||
* When interrupts are used, the user has to define interrupt handlers that
|
||||
* either fetches the data directly or triggers a task which is waiting to
|
||||
* fetch the data. In this example, the interrupt handler sends an event to
|
||||
* a waiting task to trigger the data gathering.
|
||||
*/
|
||||
|
||||
static QueueHandle_t gpio_evt_queue = NULL;
|
||||
|
||||
// User task that fetches the sensor values.
|
||||
|
||||
void user_task_interrupt (void *pvParameters)
|
||||
{
|
||||
uint8_t gpio;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (xQueueReceive(gpio_evt_queue, &gpio, portMAX_DELAY))
|
||||
{
|
||||
lsm303d_int_data_source_t data_src = {};
|
||||
lsm303d_int_event_source_t event_src = {};
|
||||
lsm303d_int_click_source_t click_src = {};
|
||||
lsm303d_int_m_thresh_source_t thresh_src = {};
|
||||
|
||||
// get the source of the interrupt that reset *INTx* signals
|
||||
#ifdef INT_DATA
|
||||
lsm303d_get_int_data_source (sensor, &data_src);
|
||||
#endif
|
||||
#ifdef INT_THRESH
|
||||
lsm303d_get_int_m_thresh_source(sensor, &thresh_src);
|
||||
#endif
|
||||
#ifdef INT_EVENT
|
||||
lsm303d_get_int_event_source (sensor, &event_src, lsm303d_int_event1_gen);
|
||||
#endif
|
||||
#ifdef INT_CLICK
|
||||
lsm303d_get_int_click_source (sensor, &click_src);
|
||||
#endif
|
||||
|
||||
// in case of DRDY interrupt
|
||||
if (data_src.a_data_ready || data_src.m_data_ready)
|
||||
read_data ();
|
||||
|
||||
// in case of FIFO interrupts read the whole FIFO
|
||||
else if (data_src.fifo_thresh || data_src.fifo_overrun)
|
||||
read_data ();
|
||||
|
||||
// in case of magnetic threshold interrupt
|
||||
else if (thresh_src.active)
|
||||
{
|
||||
printf("%.3f LSM303D ", (double)sdk_system_get_time()*1e-3);
|
||||
if (thresh_src.x_pos) printf("x exceeds threshold on positive side\n");
|
||||
if (thresh_src.y_pos) printf("y exceeds threshold on positive side\n");
|
||||
if (thresh_src.z_pos) printf("z exceeds threshold on positive side\n");
|
||||
if (thresh_src.x_neg) printf("x exceeds threshold on negative side\n");
|
||||
if (thresh_src.y_neg) printf("y exceeds threshold on negative side\n");
|
||||
if (thresh_src.z_neg) printf("z exceeds threshold on negative side\n");
|
||||
}
|
||||
|
||||
// in case of event interrupt
|
||||
else if (event_src.active)
|
||||
{
|
||||
printf("%.3f LSM303D ", (double)sdk_system_get_time()*1e-3);
|
||||
if (event_src.x_low) printf("x is lower than threshold\n");
|
||||
if (event_src.y_low) printf("y is lower than threshold\n");
|
||||
if (event_src.z_low) printf("z is lower than threshold\n");
|
||||
if (event_src.x_high) printf("x is higher than threshold\n");
|
||||
if (event_src.y_high) printf("y is higher than threshold\n");
|
||||
if (event_src.z_high) printf("z is higher than threshold\n");
|
||||
}
|
||||
|
||||
// in case of click detection interrupt
|
||||
else if (click_src.active)
|
||||
printf("%.3f LSM303D %s\n", (double)sdk_system_get_time()*1e-3,
|
||||
click_src.s_click ? "single click" : "double click");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt handler which resumes user_task_interrupt on interrupt
|
||||
|
||||
void IRAM int_signal_handler (uint8_t gpio)
|
||||
{
|
||||
// send an event with GPIO to the interrupt user task
|
||||
xQueueSendFromISR(gpio_evt_queue, &gpio, NULL);
|
||||
}
|
||||
|
||||
#else // !INT_USED
|
||||
|
||||
/*
|
||||
* In this example, user task fetches the sensor values every seconds.
|
||||
*/
|
||||
|
||||
void user_task_periodic(void *pvParameters)
|
||||
{
|
||||
vTaskDelay (100/portTICK_PERIOD_MS);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// read sensor data
|
||||
read_data ();
|
||||
|
||||
// passive waiting until 1 second is over
|
||||
vTaskDelay(200/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INT_USED
|
||||
|
||||
/* -- main program ------------------------------------------------- */
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
// Set UART Parameter.
|
||||
uart_set_baud(0, 115200);
|
||||
// Give the UART some time to settle
|
||||
vTaskDelay(1);
|
||||
|
||||
/** -- MANDATORY PART -- */
|
||||
|
||||
#ifdef SPI_USED
|
||||
|
||||
// init the SPI interface at which LMS303D sensors are connected
|
||||
spi_bus_init (SPI_BUS, SPI_SCK_GPIO, SPI_MISO_GPIO, SPI_MOSI_GPIO);
|
||||
|
||||
// init the sensor connected to SPI_BUS with SPI_CS_GPIO as chip select.
|
||||
sensor = lsm303d_init_sensor (SPI_BUS, 0, SPI_CS_GPIO);
|
||||
|
||||
#else
|
||||
|
||||
// init all I2C busses at which LSM303D sensors are connected
|
||||
i2c_init (I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ);
|
||||
|
||||
// init the sensor with slave address LSM303D_I2C_ADDRESS_2 connected to I2C_BUS.
|
||||
sensor = lsm303d_init_sensor (I2C_BUS, LSM303D_I2C_ADDRESS_2, 0);
|
||||
|
||||
#endif
|
||||
|
||||
if (sensor)
|
||||
{
|
||||
#ifdef INT_USED
|
||||
|
||||
/** --- INTERRUPT CONFIGURATION PART ---- */
|
||||
|
||||
// Interrupt configuration has to be done before the sensor is set
|
||||
// into measurement mode to avoid losing interrupts
|
||||
|
||||
// create an event queue to send interrupt events from interrupt
|
||||
// handler to the interrupt task
|
||||
gpio_evt_queue = xQueueCreate(10, sizeof(uint8_t));
|
||||
|
||||
// configure interupt pins for *INT1* and *INT2* signals and set the interrupt handler
|
||||
gpio_enable(INT1_PIN, GPIO_INPUT);
|
||||
gpio_enable(INT2_PIN, GPIO_INPUT);
|
||||
gpio_set_interrupt(INT1_PIN, GPIO_INTTYPE_EDGE_POS, int_signal_handler);
|
||||
gpio_set_interrupt(INT2_PIN, GPIO_INTTYPE_EDGE_POS, int_signal_handler);
|
||||
|
||||
#endif // INT_USED
|
||||
|
||||
/** -- SENSOR CONFIGURATION PART --- */
|
||||
|
||||
// set the type of INTx signals if necessary
|
||||
// lsm303d_config_int_signals (sensor, lsm303d_push_pull);
|
||||
|
||||
#ifdef INT_DATA
|
||||
// enable data interrupts on *INT2* (data ready or FIFO overrun and FIFO threshold)
|
||||
// data ready and FIFO status interrupts must not be enabled at the same time
|
||||
#ifdef FIFO_MODE
|
||||
lsm303d_enable_int (sensor, lsm303d_int_fifo_overrun, lsm303d_int2_signal, true);
|
||||
lsm303d_enable_int (sensor, lsm303d_int_fifo_thresh , lsm303d_int2_signal, true);
|
||||
#else
|
||||
lsm303d_enable_int (sensor, lsm303d_int_a_data_ready, lsm303d_int2_signal, true);
|
||||
lsm303d_enable_int (sensor, lsm303d_int_m_data_ready, lsm303d_int2_signal, true);
|
||||
#endif // FIFO_MODE
|
||||
#endif // INT_DATA
|
||||
|
||||
#ifdef INT_THRESH
|
||||
// enable magnetic threshold interrupts on signal *INT1*
|
||||
lsm303d_int_m_thresh_config_t m_thresh_config;
|
||||
|
||||
m_thresh_config.threshold = 2000;
|
||||
m_thresh_config.x_enabled = true;
|
||||
m_thresh_config.y_enabled = true;
|
||||
m_thresh_config.z_enabled = true;
|
||||
m_thresh_config.latch = true;
|
||||
m_thresh_config.signal_level = lsm303d_high_active;
|
||||
|
||||
lsm303d_set_int_m_thresh_config (sensor, &m_thresh_config);
|
||||
lsm303d_enable_int (sensor, lsm303d_int_m_thresh, lsm303d_int1_signal, true);
|
||||
#endif // INT_THRESH
|
||||
|
||||
#ifdef INT_EVENT
|
||||
// enable inertial event interrupts on *INT1*
|
||||
lsm303d_int_event_config_t event_config;
|
||||
|
||||
event_config.mode = lsm303d_or; // axes movement wake-up
|
||||
// event_config.mode = lsm303d_and; // free fall
|
||||
// event_config.mode = lsm303d_6d_movement;
|
||||
// event_config.mode = lsm303d_6d_position;
|
||||
// event_config.mode = lsm303d_4d_movement;
|
||||
// event_config.mode = lsm303d_4d_position;
|
||||
event_config.threshold = 50;
|
||||
event_config.x_low_enabled = false;
|
||||
event_config.x_high_enabled = true;
|
||||
event_config.y_low_enabled = false;
|
||||
event_config.y_high_enabled = true;
|
||||
event_config.z_low_enabled = false;
|
||||
event_config.z_high_enabled = true;
|
||||
event_config.duration = 0;
|
||||
event_config.latch = true;
|
||||
|
||||
lsm303d_set_int_event_config (sensor, &event_config, lsm303d_int_event1_gen);
|
||||
lsm303d_enable_int (sensor, lsm303d_int_event1, lsm303d_int1_signal, true);
|
||||
#endif // INT_EVENT
|
||||
|
||||
#ifdef INT_CLICK
|
||||
// enable single click interrupt for z-axis on signal *INT1*
|
||||
lsm303d_int_click_config_t click_config;
|
||||
|
||||
click_config.threshold = 10;
|
||||
click_config.x_single = false;
|
||||
click_config.x_double = false;
|
||||
click_config.y_single = false;
|
||||
click_config.y_double = false;
|
||||
click_config.z_single = true;
|
||||
click_config.z_double = false;
|
||||
click_config.latch = true;
|
||||
click_config.time_limit = 1;
|
||||
click_config.time_latency = 1;
|
||||
click_config.time_window = 3;
|
||||
|
||||
lsm303d_set_int_click_config (sensor, &click_config);
|
||||
lsm303d_enable_int (sensor, lsm303d_int_click, lsm303d_int1_signal, true);
|
||||
#endif // INT_CLICK
|
||||
|
||||
#ifdef FIFO_MODE
|
||||
// clear the FIFO
|
||||
lsm303d_set_fifo_mode (sensor, lsm303d_bypass, 0);
|
||||
|
||||
// activate the FIFO with a threshold of 10 samples (max. 31); if
|
||||
// interrupt *lsm303d_fifo_thresh* is enabled, an interrupt is
|
||||
// generated when the FIFO content exceeds this threshold, i.e.,
|
||||
// when 11 samples are stored in FIFO
|
||||
lsm303d_set_fifo_mode (sensor, lsm303d_stream, 10);
|
||||
#endif
|
||||
|
||||
// configure HPF and implicitly reset the reference by a dummy read
|
||||
lsm303d_config_a_hpf (sensor, lsm303d_hpf_normal, true, true, true, true);
|
||||
|
||||
#ifdef TEMP_USED
|
||||
// enable the temperature sensor
|
||||
lsm303d_enable_temperature (sensor, true);
|
||||
#endif
|
||||
|
||||
// LAST STEP: Finally set scale and mode to start measurements
|
||||
lsm303d_set_a_scale(sensor, lsm303d_a_scale_2_g);
|
||||
lsm303d_set_m_scale(sensor, lsm303d_m_scale_4_Gs);
|
||||
lsm303d_set_a_mode (sensor, lsm303d_a_odr_12_5, lsm303d_a_aaf_bw_773, true, true, true);
|
||||
lsm303d_set_m_mode (sensor, lsm303d_m_odr_12_5, lsm303d_m_low_res, lsm303d_m_continuous);
|
||||
|
||||
/** -- TASK CREATION PART --- */
|
||||
|
||||
// must be done last to avoid concurrency situations with the sensor
|
||||
// configuration part
|
||||
|
||||
#ifdef INT_USED
|
||||
|
||||
// create a task that is triggered only in case of interrupts to fetch the data
|
||||
xTaskCreate(user_task_interrupt, "user_task_interrupt", TASK_STACK_DEPTH, NULL, 2, NULL);
|
||||
|
||||
#else // INT_USED
|
||||
|
||||
// create a user task that fetches data from sensor periodically
|
||||
xTaskCreate(user_task_periodic, "user_task_periodic", TASK_STACK_DEPTH, NULL, 2, NULL);
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
printf("Could not initialize LSM303D sensor\n");
|
||||
}
|
||||
|
1216
extras/lsm303d/README.md
Normal file
1216
extras/lsm303d/README.md
Normal file
File diff suppressed because it is too large
Load diff
10
extras/lsm303d/component.mk
Normal file
10
extras/lsm303d/component.mk
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Component makefile for extras/lsm303d
|
||||
|
||||
# expected anyone using LIS3MDL driver includes it as 'lis3mld/lis3mld.h'
|
||||
INC_DIRS += $(lsm303d_ROOT)..
|
||||
INC_DIRS += $(lsm303d_ROOT)
|
||||
|
||||
# args for passing into compile rule generation
|
||||
lsm303d_SRC_DIR = $(lsm303d_ROOT)
|
||||
|
||||
$(eval $(call component_compile_rules,lsm303d))
|
1693
extras/lsm303d/lsm303d.c
Normal file
1693
extras/lsm303d/lsm303d.c
Normal file
File diff suppressed because it is too large
Load diff
587
extras/lsm303d/lsm303d.h
Normal file
587
extras/lsm303d/lsm303d.h
Normal file
|
@ -0,0 +1,587 @@
|
|||
/**
|
||||
* Driver for LSM303D 3-axes digital accelerometer and magnetometer connected
|
||||
* either to I2C or SPI.
|
||||
*
|
||||
* This driver is for the usage with the ESP8266 and FreeRTOS (esp-open-rtos)
|
||||
* [https://github.com/SuperHouse/esp-open-rtos]. It is also working with ESP32
|
||||
* and ESP-IDF [https://github.com/espressif/esp-idf.git] as well as Linux
|
||||
* based systems using a wrapper library for ESP8266 functions.
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
*
|
||||
* The BSD License (3-clause license)
|
||||
*
|
||||
* Copyright (c) 2018 Gunar Schorcht (https://github.com/gschorcht)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LSM303D_H__
|
||||
#define __LSM303D_H__
|
||||
|
||||
// Uncomment one of the following defines to enable debug output
|
||||
// #define LSM303D_DEBUG_LEVEL_1 // only error messages
|
||||
// #define LSM303D_DEBUG_LEVEL_2 // debug and error messages
|
||||
|
||||
// LSM303D addresses
|
||||
#define LSM303D_I2C_ADDRESS_1 0x1e // SDO pin is low
|
||||
#define LSM303D_I2C_ADDRESS_2 0x1d // SDO pin is high
|
||||
|
||||
// LSM303D chip id
|
||||
#define LSM303D_CHIP_ID 0x49 // LSM303D_REG_WHO_AM_I<7:0>
|
||||
|
||||
// Definition of error codes
|
||||
#define LSM303D_OK 0
|
||||
#define LSM303D_NOK -1
|
||||
|
||||
#define LSM303D_INT_ERROR_MASK 0x000f
|
||||
#define LSM303D_DRV_ERROR_MASK 0xfff0
|
||||
|
||||
// Error codes for I2C and SPI interfaces ORed with LSM303D driver error codes
|
||||
#define LSM303D_I2C_READ_FAILED 1
|
||||
#define LSM303D_I2C_WRITE_FAILED 2
|
||||
#define LSM303D_I2C_BUSY 3
|
||||
#define LSM303D_SPI_WRITE_FAILED 4
|
||||
#define LSM303D_SPI_READ_FAILED 5
|
||||
#define LSM303D_SPI_BUFFER_OVERFLOW 6
|
||||
|
||||
// LSM303D driver error codes ORed with error codes for I2C and SPI interfaces
|
||||
#define LSM303D_WRONG_CHIP_ID ( 1 << 8)
|
||||
#define LSM303D_WRONG_BANDWIDTH ( 2 << 8)
|
||||
#define LSM303D_GET_RAW_A_DATA_FAILED ( 3 << 8)
|
||||
#define LSM303D_GET_RAW_A_DATA_FIFO_FAILED ( 4 << 8)
|
||||
#define LSM303D_GET_RAW_M_DATA_FAILED ( 5 << 8)
|
||||
#define LSM303D_GET_RAW_T_DATA_FAILED ( 6 << 8)
|
||||
#define LSM303D_INT_TYPE_WRONG ( 8 << 8)
|
||||
#define LSM303D_INT_ENABLE_FAILED ( 9 << 8)
|
||||
#define LSM303D_CONFIG_INT_SIGNALS_FAILED (10 << 8)
|
||||
#define LSM303D_GET_INT_DATA_SOURCE_FAILED (11 << 8)
|
||||
#define LSM303D_SET_M_THRESH_CONFIG_FAILED (12 << 8)
|
||||
#define LSM303D_GET_M_THRESH_CONFIG_FAILED (13 << 8)
|
||||
#define LSM303D_GET_M_THRESH_SOURCE_FAILED (14 << 8)
|
||||
#define LSM303D_SET_EVENT_CONFIG_FAILED (15 << 8)
|
||||
#define LSM303D_GET_EVENT_CONFIG_FAILED (16 << 8)
|
||||
#define LSM303D_GET_EVENT_SOURCE_FAILED (17 << 8)
|
||||
#define LSM303D_SET_CLICK_CONFIG_FAILED (18 << 8)
|
||||
#define LSM303D_GET_CLICK_CONFIG_FAILED (19 << 8)
|
||||
#define LSM303D_GET_CLICK_SOURCE_FAILED (20 << 8)
|
||||
#define LSM303D_CONFIG_HPF_FAILED (21 << 8)
|
||||
#define LSM303D_SET_HPF_REF_FAILED (22 << 8)
|
||||
#define LSM303D_GET_HPF_REF_FAILED (23 << 8)
|
||||
#define LSM303D_SET_M_OFFSET_FAILED (24 << 8)
|
||||
#define LSM303D_GET_M_OFFSET_FAILED (25 << 8)
|
||||
#define LSM303D_GET_ADC_DATA_FAILED (26 << 8)
|
||||
#define LSM303D_SENSOR_IN_BYPASS_MODE (27 << 8)
|
||||
#define LSM303D_SENSOR_IN_FIFO_MODE (28 << 8)
|
||||
#define LSM303D_ODR_TOO_HIGH (29 << 8)
|
||||
#define LSM303D_FIFO_THRESHOLD_INVALID (30 << 8)
|
||||
#define LSM303D_FIFO_GET_SRC_FAILED (31 << 8)
|
||||
|
||||
#include "lsm303d_platform.h"
|
||||
#include "lsm303d_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the sensor
|
||||
*
|
||||
* Reset the sensor and switch to power down mode. All registers are reset to
|
||||
* default values. FIFO is cleared.
|
||||
*
|
||||
* @param bus I2C or SPI bus at which LSM303D sensor is connected
|
||||
* @param addr I2C addr of the LSM303D sensor, 0 for using SPI
|
||||
* @param cs SPI CS GPIO, ignored for I2C
|
||||
* @return pointer to sensor data structure, or NULL on error
|
||||
*/
|
||||
lsm303d_sensor_t* lsm303d_init_sensor (uint8_t bus, uint8_t addr, uint8_t cs);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set accelerator sensor mode
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param odr accelerator output data rate (ODR)
|
||||
* @param bw accelerator anti-alias filter bandwidth
|
||||
* @param x true enable x-axis, false disable x-axis
|
||||
* @param y true enable y-axis, false disable y-axis
|
||||
* @param z true enable z-axis, false disable z-axis
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_a_mode (lsm303d_sensor_t* dev,
|
||||
lsm303d_a_odr_t odr, lsm303d_a_aaf_bw_t bw,
|
||||
bool x, bool y, bool z);
|
||||
|
||||
/**
|
||||
* @brief Set magnetometer sensor mode
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param odr magnetometer output data rate (ODR)
|
||||
* @param res magnetometer resolution
|
||||
* @param mode magnetometer mode (ODR)
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_m_mode (lsm303d_sensor_t* dev,
|
||||
lsm303d_m_odr_t odr,
|
||||
lsm303d_m_resolution_t res,
|
||||
lsm303d_m_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Set accelerator scale (full scale)
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param scale full scale (default 2 g)
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_a_scale (lsm303d_sensor_t* dev, lsm303d_a_scale_t scale);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set magnetometer scale (full scale)
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param scale full scale (default 4 Gauss)
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_m_scale (lsm303d_sensor_t* dev, lsm303d_m_scale_t scale);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Test whether new acceleration data samples are available
|
||||
*
|
||||
* When the FIFO is used, it returns true if at least one acceleration
|
||||
* data sample is stored in the FIFO. Otherwise it returns true when new
|
||||
* acceleration data are available in the output registers.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @return true on new data, otherwise false
|
||||
*/
|
||||
bool lsm303d_new_a_data (lsm303d_sensor_t* dev);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Test whether new magnetometer data samples are available
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @return true on new data, otherwise false
|
||||
*/
|
||||
bool lsm303d_new_m_data (lsm303d_sensor_t* dev);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get one acceleration data sample as floating point values (unit g)
|
||||
*
|
||||
* Function works only in bypass mode and fails in FIFO modes. In FIFO modes,
|
||||
* function *lsm303d_get_a_float_data_fifo* has to be used instead to get data.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param data pointer to float data structure filled with g values
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_float_a_data (lsm303d_sensor_t* dev,
|
||||
lsm303d_float_a_data_t* data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get all samples of acceleration data stored in the FIFO (unit g)
|
||||
*
|
||||
* In bypass mode, it returns only one sensor data sample.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param data array of 32 float data structures filled with g values
|
||||
* @return number of data sets read from fifo on success or 0 on error
|
||||
*/
|
||||
uint8_t lsm303d_get_float_a_data_fifo (lsm303d_sensor_t* dev,
|
||||
lsm303d_float_a_data_fifo_t data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get one magnetic data sample as floating point values (unit Gauss)
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param data pointer to float data structure filled with magnetic values
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_float_m_data (lsm303d_sensor_t* dev,
|
||||
lsm303d_float_m_data_t* data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get one sample of raw acceleration data as 16 bit two's complements
|
||||
*
|
||||
* Function works only in bypass mode and fails in FIFO modes. In FIFO modes,
|
||||
* function *lsm303d_get_a_raw_data_fifo* has to be used instead to get data.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param raw pointer to raw data structure filled with values
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_raw_a_data (lsm303d_sensor_t* dev, lsm303d_raw_a_data_t* raw);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get all samples of raw sensor data stored in the FIFO
|
||||
*
|
||||
* In bypass mode, it returns only one raw data sample.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param raw array of 32 raw data structures
|
||||
* @return number of data sets read from fifo on success or 0 on error
|
||||
*/
|
||||
uint8_t lsm303d_get_raw_a_data_fifo (lsm303d_sensor_t* dev,
|
||||
lsm303d_raw_a_data_fifo_t raw);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get one sample of raw magnetic data as 16 bit two's complements
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param raw pointer to raw data structure filled with values
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_raw_m_data (lsm303d_sensor_t* dev, lsm303d_raw_m_data_t* raw);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set FIFO mode (for acceleration data only)
|
||||
*
|
||||
* FIFO threshold can be used to generate an interrupt when FIFO content
|
||||
* exceeds the value. It is ignored in bypass mode.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param mode FIFO mode
|
||||
* @param thresh FIFO threshold (ignored in bypass mode)
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_fifo_mode (lsm303d_sensor_t* dev, lsm303d_fifo_mode_t mode,
|
||||
uint8_t thresh);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable / disable an interrupt on signal INT1 or INT2
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param type interrupt to be enabled or disabled
|
||||
* @param signal interrupt signal that is activated for the interrupt
|
||||
* @param value true to enable or false to disable the interrupt
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_enable_int (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_type_t type,
|
||||
lsm303d_int_signal_t signal, bool value);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the source of data ready and FIFO interrupts on INT1 or INT2
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param source pointer to the interrupt source
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_int_data_source (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_data_source_t* source);
|
||||
|
||||
/**
|
||||
* @brief Set the configuration of the magnetic threshold interrupt generator
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param config pointer to the interrupt generator configuration
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_int_m_thresh_config (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_m_thresh_config_t* config);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the configuration of the magnetic threshold interrupt generator
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param config pointer to the interrupt generator configuration
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_int_m_thresh_config (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_m_thresh_config_t* config);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the source of the magnetic threshold interrupt on INT/INT2
|
||||
*
|
||||
* Returns a byte with flags that indicate the value(s) that triggered
|
||||
* the interrupt signal (see INT_SRC_M register in datasheet for details)
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param source pointer to the interrupt source
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_int_m_thresh_source (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_m_thresh_source_t* source);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the configuration of an inertial event interrupt generator
|
||||
*
|
||||
* Inertial interrupt generators produce interrupts when certain inertial event
|
||||
* occures (event interrupts), that is, the acceleration of defined axes is
|
||||
* higher or lower than a defined threshold and one of the following event is
|
||||
* recognized: axis movement or 6D/4D orientation detection.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param config pointer to the interrupt generator configuration
|
||||
* @param gen interrupt generator to which the function is applied
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_int_event_config (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_event_config_t* config,
|
||||
lsm303d_int_event_gen_t gen);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the configuration of an inertial interrupt generator
|
||||
*
|
||||
* Inertial interrupt generators produce interrupts when certain inertial event
|
||||
* occures (event interrupts), that is, the acceleration of defined axes is
|
||||
* higher or lower than a defined threshold and one of the following event is
|
||||
* recognized: axis movement or 6D/4D orientation detection.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param config pointer to the interrupt generator configuration
|
||||
* @param gen interrupt generator to which the function is applied
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_int_event_config (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_event_config_t* config,
|
||||
lsm303d_int_event_gen_t gen);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the source of an inertial event interrupt on signal INT1/INT2
|
||||
*
|
||||
* Returns a byte with flags that indicate the event that triggered
|
||||
* the interrupt signal (see IG_SRCx register in datasheet for details)
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param source pointer to the interrupt source data structure
|
||||
* @param gen interrupt generator to which the function is applied
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_int_event_source (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_event_source_t* source,
|
||||
lsm303d_int_event_gen_t gen);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the configuration of the click detection interrupt generator
|
||||
*
|
||||
* Set the configuration for interrupts that are generated when single or
|
||||
* double clicks are detected.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param config pointer to the interrupt generator configuration
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_int_click_config (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_click_config_t* config);
|
||||
|
||||
/**
|
||||
* @brief Get the configuration of the click detection interrupt generator
|
||||
*
|
||||
* Set the configuration for interrupts that are generated when single or
|
||||
* double clicks are detected.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param config pointer to the interrupt generator configuration
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_int_click_config (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_click_config_t* config);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the source of the click detection interrupt on signal INT1/INT2
|
||||
*
|
||||
* Returns a byte with flags that indicate the activity which triggered
|
||||
* the interrupt signal (see CLICK_SRC register in datasheet for details)
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param source pointer to the interrupt source
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_int_click_source (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_click_source_t* source);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set signal configuration for INT1 and INT2 signals
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param type define interrupt signal as pushed/pulled or open drain
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_config_int_signals (lsm303d_sensor_t* dev,
|
||||
lsm303d_int_signal_type_t type);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure HPF (high pass filter) for acceleration data
|
||||
*
|
||||
* The function resets implicitly reset the reference by a dummy read.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param mode filter mode
|
||||
* @param data if true, use filtered data as sensor output
|
||||
* @param click if true, use filtered data for CLICK function
|
||||
* @param int1 if true, use filtered data for interrupt generator INT1
|
||||
* @param int2 if true, use filtered data for interrupt generator INT2
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_config_a_hpf (lsm303d_sensor_t* dev,
|
||||
lsm303d_hpf_mode_t mode,
|
||||
bool data, bool click, bool int1, bool int2);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set HPF (high pass filter) reference for acceleration data
|
||||
*
|
||||
* Used to set the reference of HPF in reference mode *lsm303d_hpf_reference*.
|
||||
* Used to reset the HPF in autoreset mode *lsm303d_hpf_autoreset*.
|
||||
* Reference is given as two's complement.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param x_ref x reference *lsm303d_hpf_reference* mode, otherwise ignored
|
||||
* @param y_ref y reference *lsm303d_hpf_reference* mode, otherwise ignored
|
||||
* @param z_ref z reference *lsm303d_hpf_reference* mode, otherwise ignored
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_a_hpf_ref (lsm303d_sensor_t* dev,
|
||||
int8_t x_ref, int8_t y_ref, int8_t z_ref);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get HPF (high pass filter) reference
|
||||
*
|
||||
* Used to reset the HPF in normal mode *lsm303d_hpf_normal*.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param x_ref pointer to variable filled with x reference
|
||||
* @param y_ref pointer to variable filled with y reference
|
||||
* @param z_ref pointer to variable filled with z reference
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_a_hpf_ref (lsm303d_sensor_t* dev,
|
||||
int8_t* x_ref, int8_t* y_ref, int8_t* z_ref);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set magnetic offset
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param x magnetic offset for x axis
|
||||
* @param y magnetic offset for y axis
|
||||
* @param z magnetic offset for z axis
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_set_m_offset (lsm303d_sensor_t* dev,
|
||||
int16_t x, int16_t y, int16_t z);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get magnetic offset
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param x magnetic offset for x axis
|
||||
* @param y magnetic offset for y axis
|
||||
* @param z magnetic offset for z axis
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_get_m_offset (lsm303d_sensor_t* dev,
|
||||
int16_t* x, int16_t* y, int16_t* z);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable temperature sensor
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param enable if true, temperature sensor is enabled
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_enable_temperature (lsm303d_sensor_t* dev, bool enable);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get temperature
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @return temperature in degree
|
||||
*/
|
||||
float lsm303d_get_temperature (lsm303d_sensor_t* dev);
|
||||
|
||||
|
||||
// ---- Low level interface functions -----------------------------
|
||||
|
||||
/**
|
||||
* @brief Direct write to register
|
||||
*
|
||||
* PLEASE NOTE: This function should only be used to do something special that
|
||||
* is not covered by the high level interface AND if you exactly know what you
|
||||
* do and what effects it might have. Please be aware that it might affect the
|
||||
* high level interface.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param reg address of the first register to be changed
|
||||
* @param data pointer to the data to be written to the register
|
||||
* @param len number of bytes to be written to the register
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_reg_write (lsm303d_sensor_t* dev,
|
||||
uint8_t reg, uint8_t *data, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Direct read from register
|
||||
*
|
||||
* PLEASE NOTE: This function should only be used to do something special that
|
||||
* is not covered by the high level interface AND if you exactly know what you
|
||||
* do and what effects it might have. Please be aware that it might affect the
|
||||
* high level interface.
|
||||
*
|
||||
* @param dev pointer to the sensor device data structure
|
||||
* @param reg address of the first register to be read
|
||||
* @param data pointer to the data to be read from the register
|
||||
* @param len number of bytes to be read from the register
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool lsm303d_reg_read (lsm303d_sensor_t* dev,
|
||||
uint8_t reg, uint8_t *data, uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of CPP guard */
|
||||
|
||||
#endif /* __LSM303D_H__ */
|
82
extras/lsm303d/lsm303d_platform.c
Normal file
82
extras/lsm303d/lsm303d_platform.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* Driver for LSM303D 3-axes digital accelerometer and magnetometer connected
|
||||
* either to I2C or SPI.
|
||||
*
|
||||
* This driver is for the usage with the ESP8266 and FreeRTOS (esp-open-rtos)
|
||||
* [https://github.com/SuperHouse/esp-open-rtos]. It is also working with ESP32
|
||||
* and ESP-IDF [https://github.com/espressif/esp-idf.git] as well as Linux
|
||||
* based systems using a wrapper library for ESP8266 functions.
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
*
|
||||
* The BSD License (3-clause license)
|
||||
*
|
||||
* Copyright (c) 2017 Gunar Schorcht (https://github.com/gschorcht)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Platform file: platform specific definitions, includes and functions
|
||||
*/
|
||||
|
||||
#include "lsm303d_platform.h"
|
||||
|
||||
// platform specific SPI functions
|
||||
|
||||
static const spi_settings_t bus_settings = {
|
||||
.mode = SPI_MODE0,
|
||||
.freq_divider = SPI_FREQ_DIV_1M,
|
||||
.msb = true,
|
||||
.minimal_pins = false,
|
||||
.endianness = SPI_LITTLE_ENDIAN
|
||||
};
|
||||
|
||||
bool spi_device_init (uint8_t bus, uint8_t cs)
|
||||
{
|
||||
gpio_enable(cs, GPIO_OUTPUT);
|
||||
gpio_write (cs, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t spi_transfer_pf(uint8_t bus, uint8_t cs, const uint8_t *mosi, uint8_t *miso, uint16_t len)
|
||||
{
|
||||
spi_settings_t old_settings;
|
||||
|
||||
spi_get_settings(bus, &old_settings);
|
||||
spi_set_settings(bus, &bus_settings);
|
||||
gpio_write(cs, false);
|
||||
|
||||
size_t transfered = spi_transfer (bus, (const void*)mosi, (void*)miso, len, SPI_8BIT);
|
||||
|
||||
gpio_write(cs, true);
|
||||
spi_set_settings(bus, &old_settings);
|
||||
|
||||
return transfered;
|
||||
}
|
||||
|
81
extras/lsm303d/lsm303d_platform.h
Normal file
81
extras/lsm303d/lsm303d_platform.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* Driver for LSM303D 3-axes digital accelerometer and magnetometer connected
|
||||
* either to I2C or SPI.
|
||||
*
|
||||
* This driver is for the usage with the ESP8266 and FreeRTOS (esp-open-rtos)
|
||||
* [https://github.com/SuperHouse/esp-open-rtos]. It is also working with ESP32
|
||||
* and ESP-IDF [https://github.com/espressif/esp-idf.git] as well as Linux
|
||||
* based systems using a wrapper library for ESP8266 functions.
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
*
|
||||
* The BSD License (3-clause license)
|
||||
*
|
||||
* Copyright (c) 2017 Gunar Schorcht (https://github.com/gschorcht)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Platform file: platform specific definitions, includes and functions
|
||||
*/
|
||||
|
||||
#ifndef __LSM303D_PLATFORM_H__
|
||||
#define __LSM303D_PLATFORM_H__
|
||||
|
||||
#if !defined(ESP_OPEN_RTOS)
|
||||
#define ESP_OPEN_RTOS 1
|
||||
#endif
|
||||
|
||||
#ifdef ESP_OPEN_RTOS // ESP8266
|
||||
|
||||
// platform specific includes
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "espressif/sdk_private.h"
|
||||
|
||||
#include "esp/uart.h"
|
||||
#include "esp/spi.h"
|
||||
#include "i2c/i2c.h"
|
||||
|
||||
// platform specific SPI functions
|
||||
|
||||
#define spi_bus_init(bus,sck,miso,mosi) // not needed on ESP8266
|
||||
|
||||
extern bool spi_device_init (uint8_t bus, uint8_t cs);
|
||||
extern size_t spi_transfer_pf (uint8_t bus, uint8_t cs,
|
||||
const uint8_t *mosi, uint8_t *miso,
|
||||
uint16_t len);
|
||||
|
||||
#endif // ESP_OPEN_RTOS
|
||||
|
||||
#endif // __LSM303D_PLATFORM_H__
|
483
extras/lsm303d/lsm303d_types.h
Normal file
483
extras/lsm303d/lsm303d_types.h
Normal file
|
@ -0,0 +1,483 @@
|
|||
/**
|
||||
* Driver for LSM303D 3-axes digital accelerometer and magnetometer connected
|
||||
* either to I2C or SPI.
|
||||
*
|
||||
* This driver is for the usage with the ESP8266 and FreeRTOS (esp-open-rtos)
|
||||
* [https://github.com/SuperHouse/esp-open-rtos]. It is also working with ESP32
|
||||
* and ESP-IDF [https://github.com/espressif/esp-idf.git] as well as Linux
|
||||
* based systems using a wrapper library for ESP8266 functions.
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
*
|
||||
* The BSD License (3-clause license)
|
||||
*
|
||||
* Copyright (c) 2018 Gunar Schorcht (https://github.com/gschorcht)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO Activity SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LSM303D_TYPES_H__
|
||||
#define __LSM303D_TYPES_H__
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Accelerator output data rates (A_ODR)
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_a_power_down = 0, // power down mode (default)
|
||||
lsm303d_a_odr_3_125, // normal power mode 3.125 Hz
|
||||
lsm303d_a_odr_6_25, // normal power mode 6.25 Hz
|
||||
lsm303d_a_odr_12_5, // normal power mode 12.5 Hz
|
||||
lsm303d_a_odr_25, // normal power mode 25 Hz
|
||||
lsm303d_a_odr_50, // normal power mode 50 Hz
|
||||
lsm303d_a_odr_100, // normal power mode 100 Hz
|
||||
lsm303d_a_odr_200, // normal power mode 200 Hz
|
||||
lsm303d_a_odr_400, // normal power mode 400 Hz
|
||||
lsm303d_a_odr_800, // normal power mode 800 Hz
|
||||
lsm303d_a_odr_1600, // normal power mode 1.6 kHz
|
||||
|
||||
} lsm303d_a_odr_t;
|
||||
|
||||
/**
|
||||
* @brief Accelerator anti-alias filter (A_AAF) bandwidth (BW) in Hz
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_a_aaf_bw_773 = 0, // default
|
||||
lsm303d_a_aaf_bw_194,
|
||||
lsm303d_a_aaf_bw_362,
|
||||
lsm303d_a_aaf_bw_50
|
||||
|
||||
} lsm303d_a_aaf_bw_t;
|
||||
|
||||
/**
|
||||
* @brief Accelerator full scale ranges (A_SCALE) in g
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_a_scale_2_g = 0, // default
|
||||
lsm303d_a_scale_4_g,
|
||||
lsm303d_a_scale_6_g,
|
||||
lsm303d_a_scale_8_g,
|
||||
lsm303d_a_scale_16_g
|
||||
|
||||
} lsm303d_a_scale_t;
|
||||
|
||||
/**
|
||||
* @brief Magnetometer output data rates (M_ODR)
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_m_odr_3_125 = 0, // normal power mode at 3.125 Hz
|
||||
lsm303d_m_odr_6_25, // normal power mode at 6.25 Hz
|
||||
lsm303d_m_odr_12_5, // normal power mode at 12.5 Hz
|
||||
lsm303d_m_odr_25, // normal power mode at 25 Hz
|
||||
lsm303d_m_odr_50, // normal power mode at 50 Hz
|
||||
lsm303d_m_odr_100, // normal power mode at 100 Hz
|
||||
lsm303d_m_do_not_use, // power down mode (default)
|
||||
lsm303d_m_low_power // low power mode at 3.125 Hz
|
||||
|
||||
} lsm303d_m_odr_t;
|
||||
|
||||
/**
|
||||
* @brief Magnetometer sensor mode (M_MODE)
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_m_continuous = 0, // continuous conversion mode
|
||||
lsm303d_m_single, // single conversion mode (default)
|
||||
lsm303d_m_power_down // power-down mode
|
||||
|
||||
} lsm303d_m_mode_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Magnetometer resolution selection
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_m_low_res, // low resolution (default)
|
||||
lsm303d_m_high_res // high resolution
|
||||
|
||||
} lsm303d_m_resolution_t;
|
||||
|
||||
/**
|
||||
* @brief Magnetometer full scale ranges (M_SCALE) in Gauss (Gs)
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_m_scale_2_Gs = 0,
|
||||
lsm303d_m_scale_4_Gs, // default
|
||||
lsm303d_m_scale_8_Gs,
|
||||
lsm303d_m_scale_12_Gs
|
||||
|
||||
} lsm303d_m_scale_t;
|
||||
|
||||
/**
|
||||
* @brief FIFO mode for accelerator data
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_bypass = 0, // default
|
||||
lsm303d_fifo,
|
||||
lsm303d_stream,
|
||||
lsm303d_stream_to_fifo,
|
||||
lsm303d_bypass_to_stream
|
||||
|
||||
} lsm303d_fifo_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt signals
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_int1_signal = 0,
|
||||
lsm303d_int2_signal = 1
|
||||
|
||||
} lsm303d_int_signal_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief INT1, INT2 signal type
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_push_pull = 0,
|
||||
lsm303d_open_drain
|
||||
|
||||
} lsm303d_int_signal_type_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Inertial event interrupt generators
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_int_event1_gen = 0,
|
||||
lsm303d_int_event2_gen = 1
|
||||
|
||||
} lsm303d_int_event_gen_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interrupt types for interrupt signals INT1/INT2
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_int_a_data_ready, // acceleration data ready for read interrupt
|
||||
lsm303d_int_m_data_ready, // magnetic data ready for read interrupt
|
||||
|
||||
lsm303d_int_fifo_empty, // FIFO is empty (only INT1)
|
||||
lsm303d_int_fifo_thresh, // FIFO exceeds the threshold (only INT2)
|
||||
lsm303d_int_fifo_overrun, // FIFO is completely filled (only INT2)
|
||||
|
||||
lsm303d_int_event1, // inertial event interrupt 1
|
||||
lsm303d_int_event2, // inertial event interrupt 2
|
||||
|
||||
lsm303d_int_click, // click detection interrupt
|
||||
|
||||
lsm303d_int_m_thresh // magnetic threshold interrupt
|
||||
|
||||
} lsm303d_int_type_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Data ready and FIFO interrupt source for INT1/INT2
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
bool a_data_ready; // true when acceleration data are ready to read
|
||||
bool m_data_ready; // true when magnetic data are ready to read
|
||||
|
||||
bool fifo_empty; // true when FIFO is empty
|
||||
bool fifo_thresh; // true when FIFO exceeds the FIFO threshold
|
||||
bool fifo_overrun; // true when FIFO is completely filled
|
||||
|
||||
} lsm303d_int_data_source_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Magnetic threshold interrupt configuration for INT1/INT2 signals
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
uint16_t threshold; // threshold used for interrupt generation
|
||||
|
||||
bool x_enabled; // true - x exceeds threshold on positive side
|
||||
bool y_enabled; // true - y exceeds threshold on positive side
|
||||
bool z_enabled; // true - z exceeds threshold on positive side
|
||||
|
||||
bool latch; // true - latch the interrupt until the interrupt
|
||||
// source has been read
|
||||
enum
|
||||
{
|
||||
lsm303d_low_active = 0,
|
||||
lsm303d_high_active = 1
|
||||
|
||||
} signal_level; // level of interrupt signal
|
||||
|
||||
} lsm303d_int_m_thresh_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Magnetic threshold interrupt source of INT1/INT2 signals
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
bool x_pos :1; // true - x exceeds threshold on positive side
|
||||
bool y_pos :1; // true - y exceeds threshold on positive side
|
||||
bool z_pos :1; // true - z exceeds threshold on positive side
|
||||
|
||||
bool x_neg :1; // true - x exceeds threshold on negative side
|
||||
bool y_neg :1; // true - y exceeds threshold on negative side
|
||||
bool z_neg :1; // true - z exceeds threshold on negative side
|
||||
|
||||
bool mroi :1; // true - internal measurement range overflow
|
||||
bool active:1; // true - interrupt event occured
|
||||
|
||||
} lsm303d_int_m_thresh_source_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Inertial interrupt generator configuration for INT1/INT2
|
||||
*
|
||||
* Inertial events are: axis movement and 6D/4D detection.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
enum // interrupt mode
|
||||
{ // AOI (IG_CFGx), 6D (IG_CFGx), 4D (INT_CTRL_M)
|
||||
|
||||
lsm303d_or, // AOI = 0, 6D = 0, 4D = X
|
||||
lsm303d_and, // AOI = 1, 6D = 0, 4D = X
|
||||
|
||||
lsm303d_6d_movement, // AOI = 0, 6D = 1, 4D = 0
|
||||
lsm303d_6d_position, // AOI = 1, 6D = 1, 4D = 0
|
||||
|
||||
lsm303d_4d_movement, // AOI = 0, 6D = 1, 4D = 1
|
||||
lsm303d_4d_position, // AOI = 1, 6D = 1, 4D = 1
|
||||
|
||||
} mode;
|
||||
|
||||
uint8_t threshold; // threshold used for comparison for all axes
|
||||
|
||||
bool x_low_enabled; // x lower than threshold interrupt enabled
|
||||
bool x_high_enabled; // x higher than threshold interrupt enabled
|
||||
|
||||
bool y_low_enabled; // y lower than threshold interrupt enabled
|
||||
bool y_high_enabled; // y higher than threshold interrupt enabled
|
||||
|
||||
bool z_low_enabled; // z lower than threshold interrupt enabled
|
||||
bool z_high_enabled; // z higher than threshold interrupt enabled
|
||||
|
||||
bool latch; // latch the interrupt when true until the
|
||||
// interrupt source has been read
|
||||
|
||||
uint8_t duration; // duration in 1/ODR an interrupt condition has
|
||||
// to be given before the interrupt is generated
|
||||
|
||||
} lsm303d_int_event_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Inertial event source type for interrupt generator INT1/INT2
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
bool active:1; // true - one ore more events occured
|
||||
|
||||
bool x_low :1; // true - x is lower than threshold event
|
||||
bool x_high:1; // true - x is higher than threshold event
|
||||
|
||||
bool y_low :1; // true - z is lower than threshold event
|
||||
bool y_high:1; // true - z is higher than threshold event
|
||||
|
||||
bool z_low :1; // true - z is lower than threshold event
|
||||
bool z_high:1; // true - z is higher than threshold event
|
||||
|
||||
} lsm303d_int_event_source_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Click interrupt configuration for interrupt signals INT1/INT2
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
bool x_single; // x-axis single tap interrupt enabled
|
||||
bool x_double; // x-axis double tap interrupt enabled
|
||||
|
||||
bool y_single; // y-axis single tap interrupt enabled
|
||||
bool y_double; // y-axis double tap interrupt enabled
|
||||
|
||||
bool z_single; // z-axis single tap interrupt enabled
|
||||
bool z_double; // z-axis double tap interrupt enabled
|
||||
|
||||
uint8_t threshold; // threshold used for comparison for all axes
|
||||
|
||||
bool latch; // latch the interrupt when true until the
|
||||
// interrupt source has been read
|
||||
|
||||
uint8_t time_limit; // maximum time interval between the start and the
|
||||
// end of a cick (accel increases and falls back)
|
||||
uint8_t time_latency; // click detection is disabled for that time after
|
||||
// a was click detected (in 1/ODR)
|
||||
uint8_t time_window; // time interval in which the second click has to
|
||||
// to be detected in double clicks (in 1/ODR)
|
||||
|
||||
} lsm303d_int_click_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Click interrupt source for interrupt signals INT1/INT2
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
bool x_click:1; // click detected in x direction
|
||||
bool y_click:1; // click detected in y direction
|
||||
bool z_click:1; // click detected in z direction
|
||||
|
||||
bool sign :1; // click sign (0 - posisitive, 1 - negative)
|
||||
|
||||
bool s_click:1; // single click detected
|
||||
bool d_click:1; // double click detected
|
||||
|
||||
bool active :1; // true - one ore more event occured
|
||||
|
||||
} lsm303d_int_click_source_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief HPF (high pass filter) modes for acceleration data
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
lsm303d_hpf_normal = 0, // normal mode (reset by reading references)
|
||||
lsm303d_hpf_reference, // reference signal used for filtering
|
||||
lsm303d_hpf_normal_x, // normal mode
|
||||
lsm303d_hpf_autoreset // autoreset on interrupt event
|
||||
|
||||
} lsm303d_hpf_mode_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Raw accelerations data set of as two complements
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
int16_t ax; // acceleration on x axis
|
||||
int16_t ay; // acceleration on y axis
|
||||
int16_t az; // acceleration on z axis
|
||||
|
||||
} lsm303d_raw_a_data_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Raw acceleration data FIFO type
|
||||
*/
|
||||
typedef lsm303d_raw_a_data_t lsm303d_raw_a_data_fifo_t[32];
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating point accelerations output value set in g
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
float ax; // acceleration on x axis
|
||||
float ay; // acceleration on y axis
|
||||
float az; // acceleration on z axis
|
||||
|
||||
} lsm303d_float_a_data_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating point accelerations output value FIFO type
|
||||
*/
|
||||
typedef lsm303d_float_a_data_t lsm303d_float_a_data_fifo_t[32];
|
||||
|
||||
|
||||
/**
|
||||
* @brief Raw magnetic data set as two's complements
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
int16_t mx; // magnetic value on x axis
|
||||
int16_t my; // magnetic value on y axis
|
||||
int16_t mz; // magnetic value on z axis
|
||||
|
||||
} lsm303d_raw_m_data_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating point magnetic output value set in Gauss
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
float mx; // magnetic value on x axis
|
||||
float my; // magnetic value on y axis
|
||||
float mz; // magnetic value on z axis
|
||||
|
||||
} lsm303d_float_m_data_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief LSM303D sensor device data structure type
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
int error_code; // error code of last operation
|
||||
|
||||
uint8_t bus; // I2C = x, SPI = 1
|
||||
uint8_t addr; // I2C = slave address, SPI = 0
|
||||
|
||||
uint8_t cs; // ESP8266, ESP32: GPIO used as SPI CS
|
||||
// __linux__: device index
|
||||
|
||||
lsm303d_a_scale_t a_scale; // acceleration full scale (default 2 g)
|
||||
lsm303d_m_scale_t m_scale; // magnetic full scale (default 4 Gauss)
|
||||
lsm303d_m_resolution_t m_res; // magnetic resolution (default low)
|
||||
|
||||
lsm303d_fifo_mode_t fifo_mode; // FIFO operation mode (default bypass)
|
||||
bool fifo_first; // first FIFO access
|
||||
|
||||
} lsm303d_sensor_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of CPP guard */
|
||||
|
||||
#endif /* __LSM303D_TYPES_H__ */
|
Loading…
Reference in a new issue