mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
380 lines
8.8 KiB
C
380 lines
8.8 KiB
C
/*
|
|
* Copyright (C) 2020 ML!PA Consulting GmbH
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup tests
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Test application for LIS2DH12 accelerometer driver
|
|
*
|
|
* @author Jan Mohr <jan.mohr@ml-pa.com>
|
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <limits.h>
|
|
#include "fmt.h"
|
|
#include "thread.h"
|
|
#include "shell.h"
|
|
|
|
#include "lis2dh12.h"
|
|
#include "lis2dh12_params.h"
|
|
#include "lis2dh12_registers.h"
|
|
|
|
#define ENABLE_DEBUG 0
|
|
#include "debug.h"
|
|
|
|
/* device specific */
|
|
#define NUM_FIFO_VALUES 32
|
|
|
|
/* allocate device descriptor */
|
|
static lis2dh12_t dev;
|
|
|
|
void lis2dh12_test_init(void) {
|
|
|
|
if (IS_USED(MODULE_LIS2DH12_SPI)) {
|
|
puts("using SPI mode, for I2C mode select the lis2dh12_i2c module");
|
|
} else {
|
|
puts("using I2C mode, for SPI mode select the lis2dh12_spi module");
|
|
}
|
|
|
|
/* init lis */
|
|
if (lis2dh12_init(&dev, &lis2dh12_params[0]) == LIS2DH12_OK) {
|
|
puts("lis2dh12 [Initialized]");
|
|
}
|
|
else {
|
|
puts("lis2dh12 [Failed]");
|
|
}
|
|
|
|
/* change LIS settings */
|
|
lis2dh12_set_resolution(&dev, LIS2DH12_POWER_LOW);
|
|
lis2dh12_set_datarate(&dev, LIS2DH12_RATE_100HZ);
|
|
lis2dh12_set_scale(&dev, LIS2DH12_SCALE_16G);
|
|
|
|
/* configure FIFO */
|
|
lis2dh12_fifo_t fifo_cfg = {
|
|
.FIFO_mode = LIS2DH12_FIFO_MODE_STREAM,
|
|
};
|
|
|
|
lis2dh12_set_fifo(&dev, &fifo_cfg);
|
|
}
|
|
|
|
#ifdef MODULE_LIS2DH12_INT
|
|
void* lis2dh12_test_process(void* arg) {
|
|
(void) arg;
|
|
|
|
/* start processing */
|
|
DEBUG("[Process]: start process\n");
|
|
|
|
while (1) {
|
|
|
|
/* wait for interrupt */
|
|
int int1_src = lis2dh12_wait_event(&dev, LIS2DH12_INT1, false);
|
|
|
|
if (int1_src <= 0) {
|
|
printf("error: %d\n", int1_src);
|
|
continue;
|
|
}
|
|
|
|
if (LIS2DH12_INT_SRC_1(int1_src) & LIS2DH12_INT_SRC_IA) {
|
|
puts("event 1");
|
|
}
|
|
if (LIS2DH12_INT_SRC_2(int1_src) & LIS2DH12_INT_SRC_IA) {
|
|
puts("event 2");
|
|
}
|
|
if (LIS2DH12_INT_SRC_CLICK(int1_src) & LIS2DH12_INT_SRC_IA) {
|
|
puts("click event");
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif /* MODULE_LIS2DH12_INT */
|
|
|
|
static int shell_is2dh12_read(int argc, char **argv)
|
|
{
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
lis2dh12_fifo_data_t data;
|
|
|
|
lis2dh12_read(&dev, &data);
|
|
|
|
/* Memory to print current data */
|
|
char str_out[3][8];
|
|
|
|
/* format data */
|
|
for (unsigned j = 0; j < 3; ++j) {
|
|
size_t len = fmt_s16_dfp(str_out[j], data.data[j], -3);
|
|
str_out[j][len] = '\0';
|
|
}
|
|
|
|
printf("X: %6s Y: %6s Z: %6s\n", str_out[0], str_out[1], str_out[2]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_read_fifo(int argc, char **argv)
|
|
{
|
|
uint8_t num = NUM_FIFO_VALUES;
|
|
lis2dh12_fifo_data_t data[NUM_FIFO_VALUES];
|
|
|
|
if (argc > 1) {
|
|
num = atoi(argv[1]);
|
|
}
|
|
|
|
num = lis2dh12_read_fifo_data(&dev, data, num);
|
|
|
|
/* print data */
|
|
for (unsigned i = 0; i < num; ++i) {
|
|
|
|
/* Memory to print current data */
|
|
char str_out[3][8];
|
|
|
|
/* format data */
|
|
for (unsigned j = 0; j < 3; ++j) {
|
|
size_t len = fmt_s16_dfp(str_out[j], data[i].data[j], -3);
|
|
str_out[j][len] = '\0';
|
|
}
|
|
|
|
printf("[%2u] X: %6s Y: %6s Z: %6s\n", i, str_out[0], str_out[1], str_out[2]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_threshold(int argc, char **argv)
|
|
{
|
|
uint8_t slot;
|
|
uint32_t mg;
|
|
uint32_t us = 0;
|
|
uint8_t axis = LIS2DH12_INT_CFG_XHIE
|
|
| LIS2DH12_INT_CFG_YHIE
|
|
| LIS2DH12_INT_CFG_ZHIE;
|
|
|
|
if (argc < 3) {
|
|
printf("usage: %s <slot> <mg> [µs]\n", argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
slot = atoi(argv[1]);
|
|
mg = atoi(argv[2]);
|
|
|
|
if (argc > 3) {
|
|
us = atoi(argv[3]);
|
|
}
|
|
|
|
if (slot < 1 || slot > 2) {
|
|
puts("event slot must be either 1 or 2");
|
|
return -1;
|
|
}
|
|
|
|
lis2dh12_cfg_threshold_event(&dev, mg, us, axis, slot, LIS2DH12_INT1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_click(int argc, char **argv)
|
|
{
|
|
uint32_t mg;
|
|
uint32_t us = 0;
|
|
uint32_t us_delay = 0;
|
|
uint32_t us_double = 0;
|
|
uint8_t clicks = LIS2DH12_CLICK_X_SINGLE
|
|
| LIS2DH12_CLICK_Y_SINGLE
|
|
| LIS2DH12_CLICK_Z_SINGLE;
|
|
|
|
if (argc < 2) {
|
|
printf("usage: %s <mg> [µs] [dead time µs] [double click µs]\n", argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
mg = atoi(argv[1]);
|
|
|
|
if (argc > 2) {
|
|
us = atoi(argv[2]);
|
|
}
|
|
|
|
if (argc > 3) {
|
|
us_delay = atoi(argv[3]);
|
|
}
|
|
|
|
if (argc > 4) {
|
|
us_double = atoi(argv[4]);
|
|
clicks |= clicks << 1;
|
|
}
|
|
|
|
lis2dh12_cfg_click_event(&dev, mg, us, us_delay, us_double, clicks, LIS2DH12_INT1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_power(int argc, char **argv)
|
|
{
|
|
bool on;
|
|
|
|
if (argc > 1 && (!strcmp(argv[1], "on") || !strcmp(argv[1], "1"))) {
|
|
on = true;
|
|
} else if (argc > 1 && (!strcmp(argv[1], "off") || !strcmp(argv[1], "0"))) {
|
|
on = false;
|
|
} else {
|
|
printf("usage: %s <on|off>\n", argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
if (on) {
|
|
lis2dh12_poweron(&dev);
|
|
} else {
|
|
lis2dh12_poweroff(&dev);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_set_resolution(int argc, char **argv)
|
|
{
|
|
unsigned resolution = UINT_MAX;
|
|
|
|
const char* resolutions[4] = {
|
|
"off",
|
|
"8-bit",
|
|
"10-bit",
|
|
"12-bit",
|
|
};
|
|
|
|
if (argc > 1) {
|
|
resolution = atoi(argv[1]);
|
|
} else {
|
|
printf("current resolution: %s\n", resolutions[lis2dh12_get_resolution(&dev)]);
|
|
}
|
|
|
|
if (resolution > LIS2DH12_POWER_HIGH) {
|
|
printf("usage: %s <mode>\n", argv[0]);
|
|
puts("where <mode> is:");
|
|
for (unsigned i = 0; i < ARRAY_SIZE(resolutions); ++i) {
|
|
printf("\t%u: %s\n", i, resolutions[i]);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
lis2dh12_set_resolution(&dev, resolution);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_set_rate(int argc, char **argv)
|
|
{
|
|
unsigned rate = UINT_MAX;
|
|
|
|
if (argc > 1) {
|
|
rate = atoi(argv[1]);
|
|
} else {
|
|
printf("Current sampling rate: %u Hz\n", lis2dh12_get_datarate(&dev));
|
|
}
|
|
|
|
if (rate > LIS2DH12_RATE_VERYHIGH) {
|
|
printf("usage: %s <rate>\n", argv[0]);
|
|
puts("where <rate> is:");
|
|
puts("\t1: 1 Hz");
|
|
puts("\t2: 10 Hz");
|
|
puts("\t3: 25 Hz");
|
|
puts("\t4: 50 Hz");
|
|
puts("\t5: 100 Hz");
|
|
puts("\t6: 200 Hz");
|
|
puts("\t7: 400 Hz");
|
|
puts("\t8: 1620 Hz");
|
|
puts("\t9: 5376 Hz");
|
|
return -1;
|
|
}
|
|
|
|
lis2dh12_set_datarate(&dev, rate);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_set_scale(int argc, char **argv)
|
|
{
|
|
unsigned scale = UINT_MAX;
|
|
|
|
const uint8_t scales[] = {
|
|
2, 4, 8, 16
|
|
};
|
|
|
|
if (argc > 1) {
|
|
scale = atoi(argv[1]);
|
|
} else {
|
|
printf("current range: ± %ug\n", scales[lis2dh12_get_scale(&dev)]);
|
|
}
|
|
|
|
if (scale > LIS2DH12_SCALE_16G) {
|
|
printf("usage: %s <scale>\n", argv[0]);
|
|
puts("where <scale> is:");
|
|
for (unsigned i = 0; i < ARRAY_SIZE(scales); ++i) {
|
|
printf("\t%u: ± %ug\n", i, scales[i]);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
lis2dh12_set_scale(&dev, scale);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shell_is2dh12_read_temp(int argc, char **argv)
|
|
{
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
int16_t temp;
|
|
lis2dh12_read_temperature(&dev, &temp);
|
|
|
|
printf("%d.%02d °C\n", temp / 100, temp % 100);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const shell_command_t shell_commands[] = {
|
|
{ "read", "Read acceleration data", shell_is2dh12_read },
|
|
{ "read_fifo", "Read acceleration data from fifo", shell_is2dh12_read_fifo },
|
|
{ "threshold", "Configure threshold event", shell_is2dh12_threshold },
|
|
{ "click", "Configure click event", shell_is2dh12_click },
|
|
{ "power", "Enable / Disable the sensor", shell_is2dh12_power },
|
|
{ "resolution", "Get/Set resolution", shell_is2dh12_set_resolution },
|
|
{ "rate", "Get/Set sampline rate", shell_is2dh12_set_rate },
|
|
{ "scale", "Get/Set measuring range", shell_is2dh12_set_scale },
|
|
{ "temp", "Read temperature data", shell_is2dh12_read_temp },
|
|
{ NULL, NULL, NULL },
|
|
};
|
|
|
|
int main(void)
|
|
{
|
|
/* init lis */
|
|
lis2dh12_test_init();
|
|
|
|
#ifdef MODULE_LIS2DH12_INT
|
|
static char lis2dh12_process_stack[THREAD_STACKSIZE_MAIN];
|
|
|
|
/* processing lis2dh12 acceleration data */
|
|
thread_create(lis2dh12_process_stack, sizeof(lis2dh12_process_stack),
|
|
THREAD_PRIORITY_MAIN - 1, THREAD_CREATE_STACKTEST,
|
|
lis2dh12_test_process, NULL, "lis2dh12_process");
|
|
#endif /* MODULE_LIS2DH12_INT */
|
|
|
|
/* running shell */
|
|
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
|
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
|
|
|
return 0;
|
|
}
|