minor changes and typos

This commit is contained in:
Gunar Schorcht 2017-12-30 17:35:56 +01:00
parent 2ae145dcc0
commit 561c700531
5 changed files with 519 additions and 428 deletions

View file

@ -30,13 +30,13 @@
/* -- use following constants to define the example mode ----------- */
// #define SPI_USED // if defined SPI is used, otherwise I2C
// #define DATA_INT // data ready and FIFO status interrupts
// #define CLICK_INT // click detection interrupt
// #define ACTIVITY_INT // wake-up, free fall or 6D/4D orientation detection
// #define SPI_USED // SPI interface is used, otherwise I2C
// #define FIFO_MODE // multiple sample read mode
// #define INT_DATA // data interrupts used (data ready and FIFO status)
// #define INT_EVENT // inertial event interrupts used (wake-up, free fall or 6D/4D orientation)
// #define INT_CLICK // click detection interrupts used
#if defined(DATA_INT) || defined(ACTIVITY_INT) || defined(CLICK_INT)
#if defined(INT_DATA) || defined(INT_EVENT) || defined(INT_CLICK)
#define INT_USED
#endif
@ -146,23 +146,40 @@ void user_task_interrupt (void *pvParameters)
{
if (xQueueReceive(gpio_evt_queue, &gpio_num, portMAX_DELAY))
{
lis3dh_int_activity_source_t activity_src;
lis3dh_int_data_source_t data_src;
lis3dh_int_click_source_t click_src;
lis3dh_int_data_source_t data_src = {};
lis3dh_int_event_source_t event_src = {};
lis3dh_int_click_source_t click_src = {};
// get the source of the interrupt and reset INT signals
lis3dh_get_int_activity_source (sensor, &activity_src, lis3dh_int1_signal);
lis3dh_get_int_data_source (sensor, &data_src);
lis3dh_get_int_click_source (sensor, &click_src);
// get the source of the interrupt and reset *INTx* signals
#ifdef INT_DATA
lis3dh_get_int_data_source (sensor, &data_src);
#elif INT_EVENT
lis3dh_get_int_event_source (sensor, &event_src, lis3dh_int_event1_gen);
#elif INT_CLICK
lis3dh_get_int_click_source (sensor, &click_src);
#endif
// in case of DRDY interrupt or activity interrupt read one data sample
if (data_src.data_ready || activity_src.active)
// in case of DRDY interrupt or inertial event interrupt read one data sample
if (data_src.data_ready)
read_data ();
// in case of FIFO interrupts read the whole FIFO
else if (data_src.fifo_watermark || data_src.fifo_overrun)
read_data ();
// in case of event interrupt
else if (event_src.active)
{
printf("%.3f LIS3DH ", (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 LIS3DH %s\n", (double)sdk_system_get_time()*1e-3,
click_src.s_click ? "single click" : "double click");
@ -260,41 +277,42 @@ void user_init(void)
// set polarity of INT signals if necessary
// lis3dh_config_int_signals (sensor, lis3dh_high_active);
#ifdef DATA_INT
#ifdef INT_DATA
// enable data interrupts on INT1 (data ready or FIFO status interrupts)
// data ready and FIFO status interrupts must not be enabled at the same time
#ifdef FIFO_MODE
lis3dh_enable_int_data (sensor, lis3dh_fifo_overrun, true);
lis3dh_enable_int_data (sensor, lis3dh_fifo_watermark, true);
lis3dh_enable_int (sensor, lis3dh_int_fifo_overrun , lis3dh_int1_signal, true);
lis3dh_enable_int (sensor, lis3dh_int_fifo_watermark, lis3dh_int1_signal, true);
#else
lis3dh_enable_int_data (sensor, lis3dh_data_ready, true);
lis3dh_enable_int (sensor, lis3dh_int_data_ready, lis3dh_int1_signal, true);
#endif // FIFO_MODE
#endif // DATA_INT
#endif // INT_DATA
#ifdef ACTIVITY_INT
#ifdef INT_EVENT
// enable data interrupts on INT1
lis3dh_int_activity_config_t act_config;
lis3dh_int_event_config_t event_config;
act_config.activity = lis3dh_wake_up;
// act_config.activity = lis3dh_free_fall;
// act_config.activity = lis3dh_6d_movement;
// act_config.activity = lis3dh_6d_position;
// act_config.activity = lis3dh_4d_movement;
// act_config.activity = lis3dh_4d_position;
act_config.threshold = 10;
act_config.x_low_enabled = false;
act_config.x_high_enabled = true;
act_config.y_low_enabled = false;
act_config.y_high_enabled = true;
act_config.z_low_enabled = false;
act_config.z_high_enabled = true;
act_config.duration = 0;
act_config.latch = true;
event_config.mode = lis3dh_wake_up;
// event_config.mode = lis3dh_free_fall;
// event_config.mode = lis3dh_6d_movement;
// event_config.mode = lis3dh_6d_position;
// event_config.mode = lis3dh_4d_movement;
// event_config.mode = lis3dh_4d_position;
event_config.threshold = 10;
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;
lis3dh_set_int_activity_config (sensor, lis3dh_int1_signal, &act_config);
#endif // ACTIVITY_INT
lis3dh_set_int_event_config (sensor, &event_config, lis3dh_int_event1_gen);
lis3dh_enable_int (sensor, lis3dh_int_event1, lis3dh_int1_signal, true);
#endif // INT_EVENT
#ifdef CLICK_INT
#ifdef INT_CLICK
// enable click interrupt on INT1
lis3dh_int_click_config_t click_config;
@ -310,8 +328,9 @@ void user_init(void)
click_config.time_latency = 1;
click_config.time_window = 3;
lis3dh_set_int_click_config (sensor, lis3dh_int1_signal, &click_config);
#endif // CLICK_INT
lis3dh_set_int_click_config (sensor, &click_config);
lis3dh_enable_int (sensor, lis3dh_int_click, lis3dh_int1_signal, true);
#endif // INT_CLICK
#ifdef FIFO_MODE
// clear FIFO and activate FIFO mode if needed

View file

@ -153,7 +153,7 @@ The high pass filter can independently apply to
- the raw output data,
- the data used for click detection, and
- the data used for interrupt generation like wake-up, free fall or 6D/4D orientation detection.
- the data used for inertial interrupt generation like wake-up, free fall or 6D/4D orientation detection.
The mode and the cutoff frequency of the high pass filter can be configured using function ```lis3dh_config_hpf```. Following HPF modes are available:
@ -241,26 +241,26 @@ void user_task_periodic (void *pvParameters)
The LIS3DH supports two dedicated interrupt signals **```INT1```** and **```INT2```** and three different types of interrupts:
- data ready and FIFO status interrupts,
- activity detection interrupts like wake-up, free fall, and 6D/4D orientation detection, and
- data interrupts (data ready and FIFO status),
- inertial event interrupts (axis movement, wake-up, free fall, and 6D/4D orientation detection), and
- click detection interrupts.
While activity detection and click detection interrupts can be configured for both interrupt signals, data ready and FIFO status interrupts can be configured only for interrupt signal ```INT1```.
While inertial event interrupts and click detection interrupts can be configured for both interrupt signals, data ready and FIFO status interrupts can be configured only for interrupt signal ```INT1```.
#### Data ready and FIFO status interrupts
#### Data interrupts (data ready and FIFO status)
Following sources can generate an interrupt on signal ```INT1```:
Interrupt source | Driver symbol
:-----------------|:-------------
Output data become ready to read | lis3dh_data_ready
FIFO content exceeds the watermark level | lis3dh_fifo_watermark
FIFO is completely filled | lis3dh_fifo_overrun
Output data become ready to read | lis3dh_int_data_ready
FIFO content exceeds the watermark level | lis3dh_int_fifo_watermark
FIFO is completely filled | lis3dh_int_fifo_overrun
Each of these interrupt sources can be enabled or disabled separately with function ```lis3dh_enable_int_data```. By default all interrupt sources are disabled.
Each of these interrupt sources can be enabled or disabled separately with function ```lis3dh_enable_int```. By default all interrupt sources are disabled.
```
lis3dh_enable_int_data (sensor, lis3dh_data_ready, true);
lis3dh_enable_int (sensor, lis3dh_int_data_ready, lis3dh_int1_signal, true);
```
Whenever an interrupt is generated at interrupt signal ```INT1```, the function ```lis3dh_get_int_data_source``` can be used to determine the source of the interrupt. This function returns a data structure of type ```lis3dh_int_data_source_t``` that contain a boolean member for each source that can be tested for true.
@ -270,114 +270,118 @@ void int1_handler ()
{
lis3dh_int_data_source_t data_src;
// get interrupt source of INT1
// get the interrupt source of INT1
lis3dh_get_int_data_source (sensor, &data_src);
// if data ready interrupt, get the results and do something with them
// in case of data ready interrupt, get the results and do something with them
if (data_src.data_ready)
// ... read data
// in case of FIFO interrupts read the whole FIFO
else if (data_src.fifo_watermark || data_src.fifo_overrun)
// read FIFO data
// ... read FIFO data
...
}
```
#### Activity detection interrupts
#### Inertial event interrupts
Activity detection allows to generate interrupts whenever a configured condition occur. If activated, the acceleration of each axis is compared with a defined threshold to check whether it is below or above the threshold. The results of all activated comparisons are then combined OR or AND to generate the interrupt signal.
Inertial interrupt generators allow to generate interrupts when certain inertial event occures (event interrupts), that is, the acceleration of defined axes is higher or lower than a defined threshold. If activated, the acceleration of each axis is compared with a defined threshold to check whether it is below or above the threshold. The results of all activated comparisons are then combined OR or AND to generate the interrupt signal.
The configuration of the threshold valid for all axes, the activated comparisons and the selected AND/OR combination allows to recognize special situations:
- **Wake-up detection** refers the special condition that the acceleration measured along any axis is above the defined threshold (```lis3dh_wake_up```).
- **Free fall detection** refers the special condition that the acceleration measured along all the axes goes to zero (```lis3dh_free_fall```).
- **6D/4D Orientation Detection** refers to the special condition that the measured acceleration along certain axes is above and along the other axes is below the threshold which indicates a particular orientation (```lis3dh_6d_movement```, ```lis3dh_6d_position```, ```lis3dh_4d_movement```, ```lis3dh_4d_position```).
- **6D/4D orientation detection** refers to the special condition that the measured acceleration along certain axes is above and along the other axes is below the threshold which indicates a particular orientation (```lis3dh_6d_movement```, ```lis3dh_6d_position```, ```lis3dh_4d_movement```, ```lis3dh_4d_position```).
Activity detection interrupts can be configured with the function ```lis3dh_get_int_activity_config```. This function requires as parameters the configuration of type ```lis3dh_int_activity_config_t``` and the interrupt signal to be used for activity detection interrupts.
Inertial event interrupts can be configured with the function ```lis3dh_get_int_event_config```. This function requires as parameters the configuration of type ```lis3dh_int_event_config_t``` and the interrupt generator to be used for inertial event interrupts.
Inertial event interrupts have to be enabled or disabled using function ```lis3dh_enable_int```. The interrupt signal on which the interrupts are generated is given as parameter.
For example, wake-up detection interrupt on signal ```INT1``` could be configured as following:
```
lis3dh_int_activity_config_t act_config;
lis3dh_int_event_config_t event_config;
act_config.activity = lis3dh_wake_up;
act_config.threshold = 10;
act_config.x_low_enabled = false;
act_config.x_high_enabled = true;
act_config.y_low_enabled = false;
act_config.y_high_enabled = true;
act_config.z_low_enabled = false;
act_config.z_high_enabled = true;
event_config.mode = lis3dh_wake_up;
event_config.threshold = 10;
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;
act_config.duration = 0;
act_config.latch = true;
event_config.duration = 0;
event_config.latch = true;
lis3dh_set_int_activity_config (sensor, lis3dh_int1_signal, &act_config);
```
lis3dh_set_int_event_config (sensor, &event_config, lis3dh_int_event1_gen);
lis3dh_enable_int (sensor, lis3dh_int_event1, lis3dh_int1_signal, true);
```
The parameter of type ```lis3dh_int_activity_config_t``` also configures
The parameter of type ```lis3dh_int_event_config_t``` also configures
- whether the interrupt signal should latched until the interrupt source is read, and
- which time in 1/ODR an interrupt condition has to be given before the interrupt is generated.
- whether the interrupt should be latched until the interrupt source is read, and
- which time given in 1/ODR an interrupt condition has to be given before the interrupt is generated.
As with data ready and FIFO status interrupts, function ```lis3dh_get_int_activity_source``` can be used to determine the source of an activity interrupt whenever it is generated. This function returns a data structure of type ```lis3dh_int_activity_source_t``` which contains a boolean member for each source that can be tested for true.
As with data ready and FIFO status interrupts, function ```lis3dh_get_int_event_source``` can be used to determine the source of an inertial event interrupt whenever it is generated. This function returns a data structure of type ```lis3dh_int_event_source_t``` which contains a boolean member for each source that can be tested for true.
```
void int1_handler ()
{
lis3dh_int_data_source_t data_src;
lis3dh_int_activity_source_t activity_src;
lis3dh_int_data_source_t data_src;
lis3dh_int_event_source_t event_src;
// get interrupt source of INT1
lis3dh_get_int_data_source (sensor, &data_src);
lis3dh_get_int_activity_source (sensor, &activity_src, lis3dh_int1_signal);
// get the interrupt source of INT1
lis3dh_get_int_data_source (sensor, &data_src);
lis3dh_get_int_event_source (sensor, &event_src, lis3dh_int_event1_gen);
// if data ready interrupt, get the results and do something with them
// in case of data ready interrupt, get the results and do something with them
if (data_src.data_ready)
// ... read data
// in case of FIFO interrupts read the whole FIFO
else if (data_src.fifo_watermark || data_src.fifo_overrun)
// read FIFO data
// ... read FIFO data
// in case of activity interrupt
else if (activity_src.active)
// in case of inertial event interrupt
else if (event_src.active)
// ... read data
...
}
```
**Please note** Activating all threshold comparisons and the OR combination (```lis3dh_wake_up```) is the most flexible way to deal with activity interrupts. Functions such as free fall detection and so on can then be realized by suitably combining the various interrupt sources by the user task. Following example realizes the free fall detection in user task.
**Please note** Activating all threshold comparisons and the OR combination (```lis3dh_wake_up```) is the most flexible way to deal with inertial event interrupts. Functions such as free fall detection and so on can then be realized by suitably combining the various interrupt sources by the user task. Following example realizes the free fall detection in user task.
```
lis3dh_int_activity_config_t act_config;
lis3dh_int_event_config_t event_config;
act_config.activity = lis3dh_wake_up;
act_config.threshold = 10;
act_config.x_low_enabled = true;
act_config.x_high_enabled = true;
act_config.y_low_enabled = true;
act_config.y_high_enabled = true;
act_config.z_low_enabled = true;
act_config.z_high_enabled = true;
event_config.mode = lis3dh_wake_up;
event_config.threshold = 10;
event_config.x_low_enabled = true;
event_config.x_high_enabled = true;
event_config.y_low_enabled = true;
event_config.y_high_enabled = true;
event_config.z_low_enabled = true;
event_config.z_high_enabled = true;
act_config.duration = 0;
act_config.latch = true;
event_config.duration = 0;
event_config.latch = true;
lis3dh_set_int_activity_config (sensor, lis3dh_int1_signal, &act_config);
lis3dh_set_int_event_config (sensor, &event_config, lis3dh_int_event1_gen);
lis3dh_enable_int (sensor, lis3dh_int_event1, lis3dh_int1_signal, true);
```
```
void int1_handler ()
{
lis3dh_int_activity_source_t activity_src;
lis3dh_int_event_source_t event_src;
// get interrupt source of INT1
lis3dh_get_int_activity_source (sensor, &activity_src, lis3dh_int1_signal);
// get the interrupt source of INT1
lis3dh_get_int_event_source (sensor, &event_src, lis3dh_int1_signal);
// detect free fall (all accelerations are below the threshold)
if (activity_src.x_low && activity_src.y_low && activity_src.z_low)
if (event_src.x_low && event_src.y_low && event_src.z_low)
...
...
}
@ -390,6 +394,8 @@ A sequence of acceleration values over time measured along certain axes can be u
Click detection interrupts are configured with function ```lis3dh_set_int_click_config```. This function requires as parameters the configuration of type ```lis3dh_int_click_config_t``` and the interrupt signal to be used for click detection interrupts.
Inertial event interrupts have to be enabled or disabled using function ```lis3dh_enable_int```. The interrupt signal on which the interrupts are generated is given as parameter.
In following example, the single click detection for z-axis is enabled with a time limit of 1/ODR, a time latency of 1/ODR and a time window of 3/ODR.
```
@ -407,7 +413,8 @@ click_config.time_limit = 1;
click_config.time_latency = 1;
click_config.time_window = 3;
lis3dh_set_int_click_config (sensor, lis3dh_int1_signal, &click_config);
lis3dh_set_int_click_config (sensor, &click_config);
lis3dh_enable_int (sensor, lis3dh_int_click, lis3dh_int1_signal, true);
```
As with other interrupts, the function ```lis3dh_get_int_click_source``` can be used to determine the source of the interrupt signal whenever it is generated. This function returns a data structure of type ```lis3dh_int_click_source_t``` that contains a boolean member for each source that can be tested for true.
@ -417,7 +424,7 @@ void int1_handler ()
{
lis3dh_int_click_source_t click_src;
// get interrupt source of INT1
// get the interrupt source of INT1
lis3dh_get_int_click_source (sensor, &click_src);
// detect single click along z-axis
@ -690,15 +697,13 @@ lis3dh_set_mode (sensor, lis3dh_odr_10, lis3dh_high_res, true, true, true);
## Full Example
```
/* -- use following constants to define the example mode ----------- */
// #define SPI_USED // if defined SPI is used, otherwise I2C
#define DATA_INT // data ready and FIFO status interrupts
// #define CLICK_INT // click detection interrupt
// #define ACTIVITY_INT // wake-up, free fall or 6D/4D orientation detection
// #define SPI_USED // SPI interface is used, otherwise I2C
// #define FIFO_MODE // multiple sample read mode
// #define INT_DATA // data interrupts used (data ready and FIFO status)
// #define INT_EVENT // inertial event interrupts used (wake-up, free fall or 6D/4D orientation)
// #define INT_CLICK // click detection interrupts used
#if defined(DATA_INT) || defined(ACTIVITY_INT) || defined(CLICK_INT)
#if defined(INT_DATA) || defined(INT_EVENT) || defined(INT_CLICK)
#define INT_USED
#endif
@ -744,7 +749,7 @@ lis3dh_set_mode (sensor, lis3dh_odr_10, lis3dh_high_res, true, true, true);
#define INT1_PIN 5
#define INT2_PIN 4
/* -- user tasks ---------------------------------------------- */
/* -- user tasks --------------------------------------------------- */
static lis3dh_sensor_t* sensor;
@ -802,29 +807,46 @@ static QueueHandle_t gpio_evt_queue = NULL;
void user_task_interrupt (void *pvParameters)
{
uint32_t gpio_num;
uint8_t gpio_num;
while (1)
{
if (xQueueReceive(gpio_evt_queue, &gpio_num, portMAX_DELAY))
{
lis3dh_int_activity_source_t activity_src;
lis3dh_int_data_source_t data_src;
lis3dh_int_click_source_t click_src;
lis3dh_int_data_source_t data_src = {};
lis3dh_int_event_source_t event_src = {};
lis3dh_int_click_source_t click_src = {};
// get the source of the interrupt and reset INT signals
lis3dh_get_int_activity_source (sensor, &activity_src, lis3dh_int1_signal);
lis3dh_get_int_data_source (sensor, &data_src);
lis3dh_get_int_click_source (sensor, &click_src);
// get the source of the interrupt and reset *INTx* signals
#ifdef INT_DATA
lis3dh_get_int_data_source (sensor, &data_src);
#elif INT_EVENT
lis3dh_get_int_event_source (sensor, &event_src, lis3dh_int_event1_gen);
#elif INT_CLICK
lis3dh_get_int_click_source (sensor, &click_src);
#endif
// in case of DRDY interrupt or activity interrupt read one data sample
if (data_src.data_ready || activity_src.active)
// in case of DRDY interrupt or inertial event interrupt read one data sample
if (data_src.data_ready)
read_data ();
// in case of FIFO interrupts read the whole FIFO
else if (data_src.fifo_watermark || data_src.fifo_overrun)
read_data ();
// in case of event interrupt
else if (event_src.active)
{
printf("%.3f LIS3DH ", (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 LIS3DH %s\n", (double)sdk_system_get_time()*1e-3,
click_src.s_click ? "single click" : "double click");
@ -862,7 +884,7 @@ void user_task_periodic(void *pvParameters)
#endif // INT_USED
/* -- main program ---------------------------------------------- */
/* -- main program ------------------------------------------------- */
void user_init(void)
{
@ -922,41 +944,42 @@ void user_init(void)
// set polarity of INT signals if necessary
// lis3dh_config_int_signals (sensor, lis3dh_high_active);
#ifdef DATA_INT
#ifdef INT_DATA
// enable data interrupts on INT1 (data ready or FIFO status interrupts)
// data ready and FIFO status interrupts must not be enabled at the same time
#ifdef FIFO_MODE
lis3dh_enable_int_data (sensor, lis3dh_fifo_overrun, true);
lis3dh_enable_int_data (sensor, lis3dh_fifo_watermark, true);
lis3dh_enable_int (sensor, lis3dh_int_fifo_overrun , lis3dh_int1_signal, true);
lis3dh_enable_int (sensor, lis3dh_int_fifo_watermark, lis3dh_int1_signal, true);
#else
lis3dh_enable_int_data (sensor, lis3dh_data_ready, true);
lis3dh_enable_int (sensor, lis3dh_int_data_ready, lis3dh_int1_signal, true);
#endif // FIFO_MODE
#endif // DATA_INT
#endif // INT_DATA
#ifdef ACTIVITY_INT
#ifdef INT_EVENT
// enable data interrupts on INT1
lis3dh_int_activity_config_t act_config;
lis3dh_int_event_config_t event_config;
act_config.activity = lis3dh_wake_up;
// act_config.activity = lis3dh_free_fall;
// act_config.activity = lis3dh_6d_movement;
// act_config.activity = lis3dh_6d_position;
// act_config.activity = lis3dh_4d_movement;
// act_config.activity = lis3dh_4d_position;
act_config.threshold = 10;
act_config.x_low_enabled = false;
act_config.x_high_enabled = true;
act_config.y_low_enabled = false;
act_config.y_high_enabled = true;
act_config.z_low_enabled = false;
act_config.z_high_enabled = true;
act_config.duration = 0;
act_config.latch = true;
event_config.mode = lis3dh_wake_up;
// event_config.mode = lis3dh_free_fall;
// event_config.mode = lis3dh_6d_movement;
// event_config.mode = lis3dh_6d_position;
// event_config.mode = lis3dh_4d_movement;
// event_config.mode = lis3dh_4d_position;
event_config.threshold = 10;
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;
lis3dh_set_int_activity_config (sensor, lis3dh_int1_signal, &act_config);
#endif // ACTIVITY_INT
lis3dh_set_int_event_config (sensor, &event_config, lis3dh_int_event1_gen);
lis3dh_enable_int (sensor, lis3dh_int_event1, lis3dh_int1_signal, true);
#endif // INT_EVENT
#ifdef CLICK_INT
#ifdef INT_CLICK
// enable click interrupt on INT1
lis3dh_int_click_config_t click_config;
@ -972,8 +995,9 @@ void user_init(void)
click_config.time_latency = 1;
click_config.time_window = 3;
lis3dh_set_int_click_config (sensor, lis3dh_int1_signal, &click_config);
#endif // CLICK_INT
lis3dh_set_int_click_config (sensor, &click_config);
lis3dh_enable_int (sensor, lis3dh_int_click, lis3dh_int1_signal, true);
#endif // INT_CLICK
#ifdef FIFO_MODE
// clear FIFO and activate FIFO mode if needed

View file

@ -258,10 +258,10 @@ static bool lis3dh_spi_write (lis3dh_sensor_t* dev, uint8_t reg, uint8_t *d
#define lis3dh_update_reg(dev,addr,type,elem,value) \
{ \
struct type __reg; \
if (!lis3dh_read_reg (dev, (addr), (uint8_t*)&__reg, 1)) \
if (!lis3dh_reg_read (dev, (addr), (uint8_t*)&__reg, 1)) \
return false; \
__reg.elem = (value); \
if (!lis3dh_write_reg (dev, (addr), (uint8_t*)&__reg, 1)) \
if (!lis3dh_reg_write (dev, (addr), (uint8_t*)&__reg, 1)) \
return false; \
}
@ -325,7 +325,7 @@ bool lis3dh_set_mode (lis3dh_sensor_t* dev,
uint8_t old_odr;
// read current register values
if (!lis3dh_read_reg (dev, LIS3DH_REG_CTRL1, (uint8_t*)&reg, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_CTRL1, (uint8_t*)&reg, 1))
return false;
old_odr = reg.ODR;
@ -340,7 +340,7 @@ bool lis3dh_set_mode (lis3dh_sensor_t* dev,
lis3dh_update_reg (dev, LIS3DH_REG_CTRL4, lis3dh_reg_ctrl4,
HR, (res == lis3dh_high_res));
if (!lis3dh_write_reg (dev, LIS3DH_REG_CTRL1, (uint8_t*)&reg, 1))
if (!lis3dh_reg_write (dev, LIS3DH_REG_CTRL1, (uint8_t*)&reg, 1))
return false;
// if sensor was in power down mode it takes at least 100 ms to start in another mode
@ -366,7 +366,7 @@ bool lis3dh_set_scale (lis3dh_sensor_t* dev, lis3dh_scale_t scale)
bool lis3dh_set_fifo_mode (lis3dh_sensor_t* dev, lis3dh_fifo_mode_t mode,
uint8_t thresh, lis3dh_int_signals_t trigger)
uint8_t thresh, lis3dh_int_signal_t trigger)
{
if (!dev) return false;
@ -383,7 +383,7 @@ bool lis3dh_set_fifo_mode (lis3dh_sensor_t* dev, lis3dh_fifo_mode_t mode,
};
// write FIFO_CTRL register
if (!lis3dh_write_reg (dev, LIS3DH_REG_FIFO_CTRL, (uint8_t*)&fifo_ctrl, 1))
if (!lis3dh_reg_write (dev, LIS3DH_REG_FIFO_CTRL, (uint8_t*)&fifo_ctrl, 1))
return false;
return true;
@ -400,7 +400,7 @@ bool lis3dh_new_data (lis3dh_sensor_t* dev)
{
struct lis3dh_reg_status status;
if (!lis3dh_read_reg (dev, LIS3DH_REG_STATUS, (uint8_t*)&status, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_STATUS, (uint8_t*)&status, 1))
{
error_dev ("Could not get sensor status", __FUNCTION__, dev);
return false;
@ -411,7 +411,7 @@ bool lis3dh_new_data (lis3dh_sensor_t* dev)
{
struct lis3dh_reg_fifo_src fifo_src;
if (!lis3dh_read_reg (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1))
{
error_dev ("Could not get fifo source register data", __FUNCTION__, dev);
return false;
@ -483,7 +483,7 @@ bool lis3dh_get_raw_data (lis3dh_sensor_t* dev, lis3dh_raw_data_t* raw)
}
// read raw data sample
if (!lis3dh_read_reg (dev, LIS3DH_REG_OUT_X_L, (uint8_t*)raw, 6))
if (!lis3dh_reg_read (dev, LIS3DH_REG_OUT_X_L, (uint8_t*)raw, 6))
{
error_dev ("Could not get raw data sample", __FUNCTION__, dev);
dev->error_code |= LIS3DH_GET_RAW_DATA_FAILED;
@ -507,7 +507,7 @@ uint8_t lis3dh_get_raw_data_fifo (lis3dh_sensor_t* dev, lis3dh_raw_data_fifo_t r
struct lis3dh_reg_fifo_src fifo_src;
// read FIFO state
if (!lis3dh_read_reg (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1))
{
error_dev ("Could not get fifo source register data", __FUNCTION__, dev);
return 0;
@ -521,14 +521,14 @@ uint8_t lis3dh_get_raw_data_fifo (lis3dh_sensor_t* dev, lis3dh_raw_data_fifo_t r
// read samples from FIFO
for (int i = 0; i < samples; i++)
if (!lis3dh_read_reg (dev, LIS3DH_REG_OUT_X_L, (uint8_t*)&raw[i], 6))
if (!lis3dh_reg_read (dev, LIS3DH_REG_OUT_X_L, (uint8_t*)&raw[i], 6))
{
error_dev ("Could not get raw data samples", __FUNCTION__, dev);
dev->error_code |= LIS3DH_GET_RAW_DATA_FIFO_FAILED;
return i;
}
lis3dh_read_reg (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1);
lis3dh_reg_read (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1);
// if FFS is not 0 after all samples read, ODR is higher than fetching rate
if (fifo_src.FFS)
@ -550,9 +550,124 @@ uint8_t lis3dh_get_raw_data_fifo (lis3dh_sensor_t* dev, lis3dh_raw_data_fifo_t r
}
bool lis3dh_set_int_activity_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_activity_config_t* config)
bool lis3dh_enable_int (lis3dh_sensor_t* dev,
lis3dh_int_type_t type,
lis3dh_int_signal_t signal, bool value)
{
if (!dev) return false;
dev->error_code = LIS3DH_OK;
struct lis3dh_reg_ctrl3 ctrl3;
struct lis3dh_reg_ctrl6 ctrl6;
uint8_t* reg = NULL;
uint8_t addr;
// determine the addr of the register to change
if (type == lis3dh_int_data_ready ||
type == lis3dh_int_fifo_watermark ||
type == lis3dh_int_fifo_overrun)
{
reg = (uint8_t*)&ctrl3;
addr = LIS3DH_REG_CTRL3;
}
else if (signal == lis3dh_int1_signal)
{
reg = (uint8_t*)&ctrl3;
addr = LIS3DH_REG_CTRL3;
}
else
{
reg = (uint8_t*)&ctrl6;
addr = LIS3DH_REG_CTRL6;
}
// read the register
if (!lis3dh_reg_read (dev, addr, reg, 1))
{
error_dev ("Could not read interrupt control registers", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_INT_FAILED;
return false;
}
// change the register
switch (type)
{
case lis3dh_int_data_ready: ctrl3.IT_DRDY1 = value;
break;
case lis3dh_int_fifo_watermark: ctrl3.I1_WTM1 = value;
break;
case lis3dh_int_fifo_overrun: ctrl3.I1_OVERRUN = value;
break;
case lis3dh_int_event1: if (signal == lis3dh_int1_signal)
ctrl3.I1_AOI1 = value;
else
ctrl6.I2_AOI1 = value;
break;
case lis3dh_int_event2: if (signal == lis3dh_int1_signal)
ctrl3.I1_AOI2 = value;
else
ctrl6.I2_AOI2 = value;
break;
case lis3dh_int_click: if (signal == lis3dh_int1_signal)
ctrl3.I1_CLICK = value;
else
ctrl6.I2_CLICK = value;
break;
default: dev->error_code = LIS3DH_WRONG_INT_TYPE;
error_dev ("Wrong interrupt type", __FUNCTION__, dev);
return false;
}
if (!lis3dh_reg_write (dev, addr, reg, 1))
{
error_dev ("Could not enable/disable interrupt", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_INT_FAILED;
return false;
}
return true;
}
bool lis3dh_get_int_data_source (lis3dh_sensor_t* dev,
lis3dh_int_data_source_t* source)
{
if (!dev || !source) return false;
dev->error_code = LIS3DH_OK;
struct lis3dh_reg_ctrl3 ctrl3;
struct lis3dh_reg_status status;
struct lis3dh_reg_fifo_src fifo_src;
if (!lis3dh_reg_read (dev, LIS3DH_REG_CTRL3 , (uint8_t*)&ctrl3 , 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_STATUS , (uint8_t*)&status , 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1))
{
error_dev ("Could not read source of interrupt INT2 from sensor", __FUNCTION__, dev);
dev->error_code |= LIS3DH_INT_SOURCE_FAILED;
return false;
}
source->data_ready = status.ZYXDA & ctrl3.IT_DRDY1;
source->fifo_watermark = fifo_src.WTM & ctrl3.I1_WTM1;
source->fifo_overrun = fifo_src.OVRN_FIFO & ctrl3.I1_OVERRUN;
return true;
}
bool lis3dh_set_int_event_config (lis3dh_sensor_t* dev,
lis3dh_int_event_config_t* config,
lis3dh_int_event_gen_t gen)
{
if (!dev || !config) return false;
@ -571,7 +686,7 @@ bool lis3dh_set_int_activity_config (lis3dh_sensor_t* dev,
bool d4d_int = false;
switch (config->activity)
switch (config->mode)
{
case lis3dh_wake_up : intx_cfg.AOI = 0; intx_cfg.SIXD = 0; break;
case lis3dh_free_fall : intx_cfg.AOI = 1; intx_cfg.SIXD = 0; break;
@ -583,66 +698,58 @@ bool lis3dh_set_int_activity_config (lis3dh_sensor_t* dev,
case lis3dh_6d_position : intx_cfg.AOI = 1; intx_cfg.SIXD = 1; break;
}
uint8_t intx_cfg_addr = !signal ? LIS3DH_REG_INT1_CFG : LIS3DH_REG_INT2_CFG;
uint8_t intx_ths_addr = !signal ? LIS3DH_REG_INT1_THS : LIS3DH_REG_INT2_THS;
uint8_t intx_dur_addr = !signal ? LIS3DH_REG_INT1_DUR : LIS3DH_REG_INT2_DUR;
uint8_t intx_cfg_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_CFG : LIS3DH_REG_INT2_CFG;
uint8_t intx_ths_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_THS : LIS3DH_REG_INT2_THS;
uint8_t intx_dur_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_DUR : LIS3DH_REG_INT2_DUR;
if (// write the thresholds to registers IG_THS_*
!lis3dh_write_reg (dev, intx_ths_addr, &config->threshold, 1) ||
!lis3dh_reg_write (dev, intx_ths_addr, &config->threshold, 1) ||
// write duration configuration to IG_DURATION
!lis3dh_write_reg (dev, intx_dur_addr, &config->duration, 1) ||
!lis3dh_reg_write (dev, intx_dur_addr, &config->duration, 1) ||
// write INT1 configuration to IG_CFG
!lis3dh_write_reg (dev, intx_cfg_addr, (uint8_t*)&intx_cfg, 1))
!lis3dh_reg_write (dev, intx_cfg_addr, (uint8_t*)&intx_cfg, 1))
{
error_dev ("Could not configure interrupt INT1", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_INT_FAILED;
return false;
}
bool enable = intx_cfg.XLIE || intx_cfg.XHIE ||
intx_cfg.YLIE || intx_cfg.YHIE ||
intx_cfg.ZLIE || intx_cfg.ZHIE;
if (!signal)
if (gen == lis3dh_int_event1_gen)
{
lis3dh_update_reg (dev, LIS3DH_REG_CTRL5, lis3dh_reg_ctrl5, LIR_INT1, config->latch);
lis3dh_update_reg (dev, LIS3DH_REG_CTRL5, lis3dh_reg_ctrl5, D4D_INT1, d4d_int);
// enable or disable I1_AOI
lis3dh_update_reg (dev, LIS3DH_REG_CTRL3, lis3dh_reg_ctrl3, I1_AOI1, enable);
}
else
{
lis3dh_update_reg (dev, LIS3DH_REG_CTRL5, lis3dh_reg_ctrl5, LIR_INT2, config->latch);
lis3dh_update_reg (dev, LIS3DH_REG_CTRL5, lis3dh_reg_ctrl5, D4D_INT2, d4d_int);
// enable or disable I2_AOI
lis3dh_update_reg (dev, LIS3DH_REG_CTRL3, lis3dh_reg_ctrl6, I2_AOI1, enable);
}
return true;
}
bool lis3dh_get_int_activity_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_activity_config_t* config)
bool lis3dh_get_int_event_config (lis3dh_sensor_t* dev,
lis3dh_int_event_config_t* config,
lis3dh_int_event_gen_t gen)
{
if (!dev || !config) return false;
dev->error_code = LIS3DH_OK;
uint8_t intx_cfg_addr = !signal ? LIS3DH_REG_INT1_CFG : LIS3DH_REG_INT2_CFG;
uint8_t intx_ths_addr = !signal ? LIS3DH_REG_INT1_THS : LIS3DH_REG_INT2_THS;
uint8_t intx_dur_addr = !signal ? LIS3DH_REG_INT1_DUR : LIS3DH_REG_INT2_DUR;
uint8_t intx_cfg_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_CFG : LIS3DH_REG_INT2_CFG;
uint8_t intx_ths_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_THS : LIS3DH_REG_INT2_THS;
uint8_t intx_dur_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_DUR : LIS3DH_REG_INT2_DUR;
struct lis3dh_reg_intx_cfg intx_cfg;
struct lis3dh_reg_ctrl5 ctrl5;
if (!lis3dh_read_reg (dev, intx_cfg_addr, (uint8_t*)&intx_cfg, 1) ||
!lis3dh_read_reg (dev, intx_ths_addr, (uint8_t*)&config->threshold, 1) ||
!lis3dh_read_reg (dev, intx_dur_addr, (uint8_t*)&config->duration, 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_CTRL5, (uint8_t*)&ctrl5, 1))
if (!lis3dh_reg_read (dev, intx_cfg_addr, (uint8_t*)&intx_cfg, 1) ||
!lis3dh_reg_read (dev, intx_ths_addr, (uint8_t*)&config->threshold, 1) ||
!lis3dh_reg_read (dev, intx_dur_addr, (uint8_t*)&config->duration, 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_CTRL5, (uint8_t*)&ctrl5, 1))
{
error_dev ("Could not read interrupt configuration from sensor", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_INT_FAILED;
@ -660,7 +767,7 @@ bool lis3dh_get_int_activity_config (lis3dh_sensor_t* dev,
bool d4d_int = false;
if (!signal)
if (gen == lis3dh_int_event1_gen)
{
config->latch = ctrl5.LIR_INT1;
d4d_int = ctrl5.D4D_INT1;
@ -674,29 +781,29 @@ bool lis3dh_get_int_activity_config (lis3dh_sensor_t* dev,
if (intx_cfg.AOI)
{
if (intx_cfg.SIXD && d4d_int)
config->activity = lis3dh_4d_position;
config->mode = lis3dh_4d_position;
else if (intx_cfg.SIXD && !d4d_int)
config->activity = lis3dh_6d_position;
config->mode = lis3dh_6d_position;
else
config->activity = lis3dh_free_fall;
config->mode = lis3dh_free_fall;
}
else
{
if (intx_cfg.SIXD && d4d_int)
config->activity = lis3dh_4d_movement;
config->mode = lis3dh_4d_movement;
else if (intx_cfg.SIXD && !d4d_int)
config->activity = lis3dh_6d_movement;
config->mode = lis3dh_6d_movement;
else
config->activity = lis3dh_wake_up;
config->mode = lis3dh_wake_up;
}
return true;
}
bool lis3dh_get_int_activity_source (lis3dh_sensor_t* dev,
lis3dh_int_activity_source_t* source,
lis3dh_int_signals_t signal)
bool lis3dh_get_int_event_source (lis3dh_sensor_t* dev,
lis3dh_int_event_source_t* source,
lis3dh_int_event_gen_t gen)
{
if (!dev || !source) return false;
@ -705,11 +812,11 @@ bool lis3dh_get_int_activity_source (lis3dh_sensor_t* dev,
struct lis3dh_reg_intx_cfg intx_cfg;
struct lis3dh_reg_intx_src intx_src;
uint8_t intx_cfg_addr = (!signal) ? LIS3DH_REG_INT1_CFG : LIS3DH_REG_INT2_CFG;
uint8_t intx_src_addr = (!signal) ? LIS3DH_REG_INT1_SRC : LIS3DH_REG_INT2_SRC;
uint8_t intx_cfg_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_CFG : LIS3DH_REG_INT2_CFG;
uint8_t intx_src_addr = (gen == lis3dh_int_event1_gen) ? LIS3DH_REG_INT1_SRC : LIS3DH_REG_INT2_SRC;
if (!lis3dh_read_reg (dev, intx_src_addr, (uint8_t*)&intx_src, 1) ||
!lis3dh_read_reg (dev, intx_cfg_addr, (uint8_t*)&intx_cfg, 1))
if (!lis3dh_reg_read (dev, intx_src_addr, (uint8_t*)&intx_src, 1) ||
!lis3dh_reg_read (dev, intx_cfg_addr, (uint8_t*)&intx_cfg, 1))
{
error_dev ("Could not read source of interrupt INT1/INT2 from sensor", __FUNCTION__, dev);
dev->error_code |= LIS3DH_INT_SOURCE_FAILED;
@ -728,66 +835,7 @@ bool lis3dh_get_int_activity_source (lis3dh_sensor_t* dev,
}
bool lis3dh_enable_int_data (lis3dh_sensor_t* dev,
lis3dh_int_data_t type, bool value)
{
if (!dev) return false;
dev->error_code = LIS3DH_OK;
switch (type)
{
case lis3dh_data_ready: lis3dh_update_reg (dev, LIS3DH_REG_CTRL3,
lis3dh_reg_ctrl3,
IT_DRDY1, value);
break;
case lis3dh_fifo_watermark: lis3dh_update_reg (dev, LIS3DH_REG_CTRL3,
lis3dh_reg_ctrl3,
I1_WTM1, value);
break;
case lis3dh_fifo_overrun: lis3dh_update_reg (dev, LIS3DH_REG_CTRL3,
lis3dh_reg_ctrl3,
I1_OVERRUN, value);
break;
default: dev->error_code = LIS3DH_WRONG_INT_TYPE;
error_dev ("Wrong interrupt type", __FUNCTION__, dev);
return false;
}
return true;
}
bool lis3dh_get_int_data_source (lis3dh_sensor_t* dev,
lis3dh_int_data_source_t* source)
{
if (!dev || !source) return false;
dev->error_code = LIS3DH_OK;
struct lis3dh_reg_ctrl3 ctrl3;
struct lis3dh_reg_status status;
struct lis3dh_reg_fifo_src fifo_src;
if (!lis3dh_read_reg (dev, LIS3DH_REG_CTRL3 , (uint8_t*)&ctrl3 , 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_STATUS , (uint8_t*)&status , 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_FIFO_SRC, (uint8_t*)&fifo_src, 1))
{
error_dev ("Could not read source of interrupt INT2 from sensor", __FUNCTION__, dev);
dev->error_code |= LIS3DH_INT_SOURCE_FAILED;
return false;
}
source->data_ready = status.ZYXDA & ctrl3.IT_DRDY1;
source->fifo_watermark = fifo_src.WTM & ctrl3.I1_WTM1;
source->fifo_overrun = fifo_src.OVRN_FIFO & ctrl3.I1_OVERRUN;
return true;
}
bool lis3dh_set_int_click_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_click_config_t* config)
{
if (!dev || !config) return false;
@ -807,34 +855,21 @@ bool lis3dh_set_int_click_config (lis3dh_sensor_t* dev,
uint8_t click_ths = config->threshold | ((config->latch) ? 0x80 : 0x00);
if (!lis3dh_write_reg (dev, LIS3DH_REG_CLICK_CFG , (uint8_t*)&click_cfg, 1) ||
!lis3dh_write_reg (dev, LIS3DH_REG_CLICK_THS , (uint8_t*)&click_ths, 1) ||
!lis3dh_write_reg (dev, LIS3DH_REG_TIME_LIMIT , (uint8_t*)&config->time_limit, 1) ||
!lis3dh_write_reg (dev, LIS3DH_REG_TIME_LATENCY, (uint8_t*)&config->time_latency, 1) ||
!lis3dh_write_reg (dev, LIS3DH_REG_TIME_WINDOW , (uint8_t*)&config->time_window, 1))
if (!lis3dh_reg_write (dev, LIS3DH_REG_CLICK_CFG , (uint8_t*)&click_cfg, 1) ||
!lis3dh_reg_write (dev, LIS3DH_REG_CLICK_THS , (uint8_t*)&click_ths, 1) ||
!lis3dh_reg_write (dev, LIS3DH_REG_TIME_LIMIT , (uint8_t*)&config->time_limit, 1) ||
!lis3dh_reg_write (dev, LIS3DH_REG_TIME_LATENCY, (uint8_t*)&config->time_latency, 1) ||
!lis3dh_reg_write (dev, LIS3DH_REG_TIME_WINDOW , (uint8_t*)&config->time_window, 1))
{
error_dev ("Could not configure click detection interrupt", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_CLICK_FAILED;
return false;
}
bool enable = click_cfg.XS || click_cfg.XD ||
click_cfg.YS || click_cfg.YD ||
click_cfg.ZS || click_cfg.ZD;
if (!signal)
{
lis3dh_update_reg (dev, LIS3DH_REG_CTRL3, lis3dh_reg_ctrl3, I1_CLICK, enable);
}
else
{
lis3dh_update_reg (dev, LIS3DH_REG_CTRL3, lis3dh_reg_ctrl6, I2_CLICK, enable);
}
return true;
}
bool lis3dh_get_int_click_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_click_config_t* config)
{
if (!dev || !config) return false;
@ -844,11 +879,11 @@ bool lis3dh_get_int_click_config (lis3dh_sensor_t* dev,
struct lis3dh_reg_click_cfg click_cfg;
uint8_t click_ths;
if (!lis3dh_read_reg (dev, LIS3DH_REG_CLICK_CFG , (uint8_t*)&click_cfg, 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_CLICK_THS , (uint8_t*)&click_ths, 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_TIME_LIMIT , (uint8_t*)&config->time_limit, 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_TIME_LATENCY, (uint8_t*)&config->time_latency, 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_TIME_WINDOW , (uint8_t*)&config->time_window, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_CLICK_CFG , (uint8_t*)&click_cfg, 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_CLICK_THS , (uint8_t*)&click_ths, 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_TIME_LIMIT , (uint8_t*)&config->time_limit, 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_TIME_LATENCY, (uint8_t*)&config->time_latency, 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_TIME_WINDOW , (uint8_t*)&config->time_window, 1))
{
error_dev ("Could not configure click detection interrupt", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_CLICK_FAILED;
@ -877,7 +912,7 @@ bool lis3dh_get_int_click_source (lis3dh_sensor_t* dev,
dev->error_code = LIS3DH_OK;
if (!lis3dh_read_reg (dev, LIS3DH_REG_CLICK_SRC, (uint8_t*)source, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_CLICK_SRC, (uint8_t*)source, 1))
{
error_dev ("Could not read source of click interrupt from sensor", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CLICK_SOURCE_FAILED;
@ -918,7 +953,7 @@ bool lis3dh_config_hpf (lis3dh_sensor_t* dev,
reg.HPIS1 = int1;
reg.HPIS2 = int2;
if (!lis3dh_write_reg (dev, LIS3DH_REG_CTRL2, (uint8_t*)&reg, 1))
if (!lis3dh_reg_write (dev, LIS3DH_REG_CTRL2, (uint8_t*)&reg, 1))
{
error_dev ("Could not configure high pass filter", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_HPF_FAILED;
@ -935,7 +970,7 @@ bool lis3dh_set_hpf_ref (lis3dh_sensor_t* dev, int8_t ref)
dev->error_code = LIS3DH_OK;
if (!lis3dh_write_reg (dev, LIS3DH_REG_REFERENCE, (uint8_t*)&ref, 1))
if (!lis3dh_reg_write (dev, LIS3DH_REG_REFERENCE, (uint8_t*)&ref, 1))
{
error_dev ("Could not set high pass filter reference", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_HPF_FAILED;
@ -954,7 +989,7 @@ int8_t lis3dh_get_hpf_ref (lis3dh_sensor_t* dev)
int8_t ref;
if (!lis3dh_read_reg (dev, LIS3DH_REG_REFERENCE, (uint8_t*)&ref, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_REFERENCE, (uint8_t*)&ref, 1))
{
error_dev ("Could not get high pass filter reference", __FUNCTION__, dev);
dev->error_code |= LIS3DH_CONFIG_HPF_FAILED;
@ -975,7 +1010,7 @@ int8_t lis3dh_enable_adc (lis3dh_sensor_t* dev, bool adc, bool tmp)
reg |= (adc) ? 0x80 : 0;
reg |= (tmp) ? 0x40 : 0;
return lis3dh_write_reg (dev, LIS3DH_REG_TEMP_CFG, (uint8_t*)&reg, 1);
return lis3dh_reg_write (dev, LIS3DH_REG_TEMP_CFG, (uint8_t*)&reg, 1);
}
@ -990,9 +1025,9 @@ bool lis3dh_get_adc (lis3dh_sensor_t* dev,
uint8_t temp_cfg;
struct lis3dh_reg_ctrl1 ctrl1;
if (!lis3dh_read_reg (dev, LIS3DH_REG_OUT_ADC1_L, data, 6) ||
!lis3dh_read_reg (dev, LIS3DH_REG_CTRL1, (uint8_t*)&ctrl1, 1) ||
!lis3dh_read_reg (dev, LIS3DH_REG_TEMP_CFG, &temp_cfg, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_OUT_ADC1_L, data, 6) ||
!lis3dh_reg_read (dev, LIS3DH_REG_CTRL1, (uint8_t*)&ctrl1, 1) ||
!lis3dh_reg_read (dev, LIS3DH_REG_TEMP_CFG, &temp_cfg, 1))
{
error_dev ("Could not get adc data", __FUNCTION__, dev);
dev->error_code |= LIS3DH_GET_ADC_DATA_FAILED;
@ -1025,7 +1060,7 @@ static bool lis3dh_is_available (lis3dh_sensor_t* dev)
dev->error_code = LIS3DH_OK;
if (!lis3dh_read_reg (dev, LIS3DH_REG_WHO_AM_I, &chip_id, 1))
if (!lis3dh_reg_read (dev, LIS3DH_REG_WHO_AM_I, &chip_id, 1))
return false;
if (chip_id != LIS3DH_CHIP_ID)
@ -1048,20 +1083,20 @@ static bool lis3dh_reset (lis3dh_sensor_t* dev)
uint8_t reg[8] = { 0 };
// initialize sensor completely including setting in power down mode
lis3dh_write_reg (dev, LIS3DH_REG_TEMP_CFG , reg, 8);
lis3dh_write_reg (dev, LIS3DH_REG_FIFO_CTRL, reg, 1);
lis3dh_write_reg (dev, LIS3DH_REG_INT1_CFG , reg, 1);
lis3dh_write_reg (dev, LIS3DH_REG_INT1_THS , reg, 2);
lis3dh_write_reg (dev, LIS3DH_REG_INT2_CFG , reg, 1);
lis3dh_write_reg (dev, LIS3DH_REG_INT2_THS , reg, 2);
lis3dh_write_reg (dev, LIS3DH_REG_CLICK_CFG, reg, 1);
lis3dh_write_reg (dev, LIS3DH_REG_CLICK_THS, reg, 4);
lis3dh_reg_write (dev, LIS3DH_REG_TEMP_CFG , reg, 8);
lis3dh_reg_write (dev, LIS3DH_REG_FIFO_CTRL, reg, 1);
lis3dh_reg_write (dev, LIS3DH_REG_INT1_CFG , reg, 1);
lis3dh_reg_write (dev, LIS3DH_REG_INT1_THS , reg, 2);
lis3dh_reg_write (dev, LIS3DH_REG_INT2_CFG , reg, 1);
lis3dh_reg_write (dev, LIS3DH_REG_INT2_THS , reg, 2);
lis3dh_reg_write (dev, LIS3DH_REG_CLICK_CFG, reg, 1);
lis3dh_reg_write (dev, LIS3DH_REG_CLICK_THS, reg, 4);
return true;
}
bool lis3dh_read_reg(lis3dh_sensor_t* dev, uint8_t reg, uint8_t *data, uint16_t len)
bool lis3dh_reg_read(lis3dh_sensor_t* dev, uint8_t reg, uint8_t *data, uint16_t len)
{
if (!dev || !data) return false;
@ -1070,7 +1105,7 @@ bool lis3dh_read_reg(lis3dh_sensor_t* dev, uint8_t reg, uint8_t *data, uint16_t
}
bool lis3dh_write_reg(lis3dh_sensor_t* dev, uint8_t reg, uint8_t *data, uint16_t len)
bool lis3dh_reg_write(lis3dh_sensor_t* dev, uint8_t reg, uint8_t *data, uint16_t len)
{
if (!dev || !data) return false;

View file

@ -154,7 +154,7 @@ bool lis3dh_set_scale (lis3dh_sensor_t* dev, lis3dh_scale_t scale);
* @return true on success, false on error
*/
bool lis3dh_set_fifo_mode (lis3dh_sensor_t* dev, lis3dh_fifo_mode_t mode,
uint8_t thresh, lis3dh_int_signals_t trigger);
uint8_t thresh, lis3dh_int_signal_t trigger);
/**
@ -167,7 +167,7 @@ bool lis3dh_new_data (lis3dh_sensor_t* dev);
/**
* @brief Get one sample of sensor data as floating point values (unit 1g)
* @brief Get one sample of sensor data as floating point values (unit g)
*
* Function works only in bypass mode and fails in FIFO modes. In FIFO modes,
* function *lis3dh_get_float_data_fifo* has to be used instead to get data.
@ -220,74 +220,21 @@ uint8_t lis3dh_get_raw_data_fifo (lis3dh_sensor_t* dev,
/**
* @brief Set configuration for activity (inertial) interrupt INT1/INT2
* @brief Enable / disable an interrupt on signal INT1 or INT2
*
* Set the configuration for interrupts that are generated when a certain
* acceleration is higher or lower than defined threshold and one of the
* following activities are recognized: wake-up, free fall or 6D/4D
* orientation detection
*
* @param dev pointer to the sensor device data structure
* @param signal specifies the interrupt signal used in function
* @param config configuration for the specified interrupt signal
* @return true on success, false on error
* @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 lis3dh_set_int_activity_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_activity_config_t* config);
/**
* @brief Get cofiguration for activity (inertial) interrupt INT1/INT2
*
* Get the configuration for interrupts that are generated when a certain
* acceleration is higher or lower than defined threshold and one of the
* following activities is recognized: wake-up, free fall or 6D/4D orientation
* detection
*
* @param dev pointer to the sensor device data structure
* @param signal specifies the interrupt signal used in function
* @param config configuration for the specified interrupt signal
* @return true on success, false on error
*/
bool lis3dh_get_int_activity_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_activity_config_t* config);
/**
* @brief Get the source of the activity (inertial) interrupt INT1/INT2
*
* Returns a byte with flags that indicate the activity which triggered
* the interrupt signal (see INTx_SRC register in datasheet for details)
*
* @param dev pointer to the sensor device data structure
* @param source pointer to the interrupt source
* @param signal specifies the interrupt signal used in function
* @return true on success, false on error
*/
bool lis3dh_get_int_activity_source (lis3dh_sensor_t* dev,
lis3dh_int_activity_source_t* source,
lis3dh_int_signals_t signal);
/**
* @brief Enable/disable an data interrupt on signal INT1
*
* Enables or diables interrupts that are generated either when data are
* ready to read or FIFO activities like overrun an watermark happen.
*
* @param dev pointer to the sensor device data structure
* @param type type of interrupt to be enabled/disabled
* @param value true to enable/false to disable the interrupt
* @return true on success, false on error
*/
bool lis3dh_enable_int_data (lis3dh_sensor_t* dev,
lis3dh_int_data_t type, bool value);
bool lis3dh_enable_int (lis3dh_sensor_t* dev,
lis3dh_int_type_t type,
lis3dh_int_signal_t signal, bool value);
/**
* @brief Get the source of the data interrupt on signal INT1
* @brief Get the source of data ready and FIFO interrupts on INT1
*
* @param dev pointer to the sensor device data structure
* @param source pointer to the interrupt source
@ -298,44 +245,91 @@ bool lis3dh_get_int_data_source (lis3dh_sensor_t* dev,
/**
* @brief Set configuration for click detection interrupt INT1/INT2
* @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 / wake up, free fall, 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 lis3dh_set_int_event_config (lis3dh_sensor_t* dev,
lis3dh_int_event_config_t* config,
lis3dh_int_event_gen_t gen);
/**
* @brief Get 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 / wake up, free fall, 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 lis3dh_get_int_event_config (lis3dh_sensor_t* dev,
lis3dh_int_event_config_t* config,
lis3dh_int_event_gen_t gen);
/**
* @brief Get the source of an inertial event interrupt INT1/INT2
*
* Returns a byte with flags that indicate the event which triggered
* the interrupt signal (see INTx_SRC 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 lis3dh_get_int_event_source (lis3dh_sensor_t* dev,
lis3dh_int_event_source_t* source,
lis3dh_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 signal specifies the interrupt signal used in function
* @param config configuration for the specified interrupt signal
* @param config pointer to the interrupt generator configuration
* @return true on success, false on error
*/
bool lis3dh_set_int_click_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_click_config_t* config);
/**
* @brief Set configuration for click detection interrupt INT1/INT2
* @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 signal specifies the interrupt signal used in function
* @param config configuration for the specified interrupt signal
* @param config pointer to the interrupt generator configuration
* @return true on success, false on error
*/
bool lis3dh_get_int_click_config (lis3dh_sensor_t* dev,
lis3dh_int_signals_t signal,
lis3dh_int_click_config_t* config);
/**
* @brief Get the source of the click detection interrupt INT1/INT2
* @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 signal specifies the interrupt signal used in function
* @param source pointer to the interrupt source
* @return true on success, false on error
*/
@ -395,9 +389,8 @@ bool lis3dh_set_hpf_ref (lis3dh_sensor_t* dev, int8_t ref);
*/
int8_t lis3dh_get_hpf_ref (lis3dh_sensor_t* dev);
/**
* @brief Enable / disable ADC or temperatury sensor
* @brief Enable / disable ADC or temperature sensor
*
* @param dev pointer to the sensor device data structure
* @param enable if true, ADC inputs are enabled
@ -419,6 +412,7 @@ int8_t lis3dh_enable_adc (lis3dh_sensor_t* dev, bool enable, bool temp);
bool lis3dh_get_adc (lis3dh_sensor_t* dev,
uint16_t* adc1, uint16_t* adc2, uint16_t* adc3);
// ---- Low level interface functions -----------------------------
/**
@ -435,7 +429,7 @@ bool lis3dh_get_adc (lis3dh_sensor_t* dev,
* @param len number of bytes to be written to the register
* @return true on success, false on error
*/
bool lis3dh_write_reg (lis3dh_sensor_t* dev,
bool lis3dh_reg_write (lis3dh_sensor_t* dev,
uint8_t reg, uint8_t *data, uint16_t len);
/**
@ -452,7 +446,7 @@ bool lis3dh_write_reg (lis3dh_sensor_t* dev,
* @param len number of bytes to be read from the register
* @return true on success, false on error
*/
bool lis3dh_read_reg (lis3dh_sensor_t* dev,
bool lis3dh_reg_read (lis3dh_sensor_t* dev,
uint8_t reg, uint8_t *data, uint16_t len);
#ifdef __cplusplus

View file

@ -115,17 +115,59 @@ typedef enum {
lis3dh_int1_signal = 0,
lis3dh_int2_signal = 1
} lis3dh_int_signals_t;
} lis3dh_int_signal_t;
/**
* @brief Activity interrupt configuration for INT1/INT2 signals
*
* Activity interrupts are: axes movement wake-up, free-fall, 6D/4D detection.
* @brief Inertial event interrupt generators
*/
typedef enum {
lis3dh_int_event1_gen = 0,
lis3dh_int_event2_gen = 1
} lis3dh_int_event_gen_t;
/**
* @brief Interrupt types for interrupt signals INT1/INT2
*/
typedef enum {
lis3dh_int_data_ready, // data ready for read interrupt (only INT1)
lis3dh_int_fifo_watermark, // FIFO exceeds the threshold (only INT1)
lis3dh_int_fifo_overrun, // FIFO is completely filled (only INT1)
lis3dh_int_event1, // inertial event interrupt 1
lis3dh_int_event2, // inertial event interrupt 2
lis3dh_int_click // click detection interrupt
} lis3dh_int_type_t;
/**
* @brief Data ready and FIFO status interrupt source for INT1
*/
typedef struct {
enum { // activity type for the interrupt
bool data_ready; // true when acceleration data are ready to read
bool fifo_watermark; // true when FIFO exceeds the FIFO threshold
bool fifo_overrun; // true when FIFO is completely filled
} lis3dh_int_data_source_t;
/**
* @brief Inertial interrupt generator configuration for INT1/INT2
*
* Inertial events are: wake-up, free-fall, 6D/4D detection.
*/
typedef struct {
enum { // interrupt mode
lis3dh_wake_up, // AOI = 0, 6D = 0
lis3dh_free_fall, // AOI = 1, 6D = 0
@ -136,7 +178,7 @@ typedef struct {
lis3dh_4d_movement, // AOI = 0, 6D = 1, D4D = 1
lis3dh_4d_position, // AOI = 1, 6D = 1, D4D = 1
} activity;
} mode;
uint8_t threshold; // threshold used for comparison for all axes
@ -154,50 +196,26 @@ typedef struct {
uint8_t duration; // duration in 1/ODR an interrupt condition has
// to be given before the interrupt is generated
} lis3dh_int_activity_config_t;
} lis3dh_int_event_config_t;
/**
* @brief Activity interrupt source type for interrupt signals INT1/INT2
* @brief Inertial event source type for interrupt generator INT1/INT2
*/
typedef struct {
bool active:1; // true - one ore more activities occured
bool active:1; // true - one ore more events occured
bool x_low :1; // true - x low activity occured
bool x_high:1; // true - x high activity occured
bool x_low :1; // true - x lower than threshold event
bool x_high:1; // true - x higher than threshold event
bool y_low :1; // true - z low activity occured
bool y_high:1; // true - z high activity occured
bool y_low :1; // true - z lower than threshold event
bool y_high:1; // true - z higher than threshold event
bool z_low :1; // true - z low activity occured
bool z_high:1; // true - z high activity occured
bool z_low :1; // true - z lower than threshold event
bool z_high:1; // true - z higher than threshold event
} lis3dh_int_activity_source_t;
/**
* @brief Data interrupt types for INT1 signal
*/
typedef enum {
lis3dh_data_ready, // interrupt when data are ready to read
lis3dh_fifo_watermark, // interrupt when FIFO exceeds the FIFO threashold
lis3dh_fifo_overrun // interrupt when FIFO is completely filled
} lis3dh_int_data_t;
/**
* @brief Data interrupt source type for INT1 signal
*/
typedef struct {
bool data_ready; // true when data are ready to read
bool fifo_watermark; // true when FIFO exceeds the FIFO threashold
bool fifo_overrun; // true when FIFO is completely filled
} lis3dh_int_data_source_t;
} lis3dh_int_event_source_t;
/**
@ -230,7 +248,7 @@ typedef struct {
/**
* @brief Click interrupt configuration for interrupt signals INT1/INT2
* @brief Click interrupt source for interrupt signals INT1/INT2
*/
typedef struct {
@ -243,7 +261,7 @@ typedef struct {
bool s_click:1; // single click detected
bool d_click:1; // double click detected
bool active :1; // true - one ore more Activities occured
bool active :1; // true - one ore more event occured
} lis3dh_int_click_source_t;
@ -278,7 +296,7 @@ typedef lis3dh_raw_data_t lis3dh_raw_data_fifo_t[32];
/**
* @brief Floating point output value set in degree
* @brief Floating point output value set in g
*/
typedef struct {
@ -321,8 +339,9 @@ typedef struct {
uint8_t cs; // ESP8266, ESP32: GPIO used as SPI CS
// __linux__: device index
lis3dh_scale_t scale; // fill range scale (default 245 dps)
lis3dh_scale_t scale; // full range scale (default 2 g)
lis3dh_resolution_t res; // resolution used
lis3dh_fifo_mode_t fifo_mode; // FIFO operation mode (default bypass)
bool fifo_first; // first FIFO access