Boot Linux faster!

Check our new training course

Boot Linux faster!

Check our new training course
and Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

/*
 * Copyright (c) 2015 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>

#include <misc/printk.h>
#include <sys_clock.h>
#include <stdio.h>

#include <device.h>
#include <sensor.h>
#include <i2c.h>

#define MAX_TEST_TIME	15000
#define SLEEPTIME	300

static void print_gyro_data(struct device *bmg160)
{
	struct sensor_value val[3];

	if (sensor_channel_get(bmg160, SENSOR_CHAN_GYRO_XYZ, val) < 0) {
		printf("Cannot read bmg160 gyro channels.\n");
		return;
	}

	printf("Gyro (rad/s): X=%f, Y=%f, Z=%f\n",
	       val[0].val1 + val[0].val2 / 1000000.0,
	       val[1].val1 + val[1].val2 / 1000000.0,
	       val[2].val1 + val[2].val2 / 1000000.0);
}

static void print_temp_data(struct device *bmg160)
{
	struct sensor_value val;

	if (sensor_channel_get(bmg160, SENSOR_CHAN_TEMP, &val) < 0) {
		printf("Temperature channel read error.\n");
		return;
	}

	printf("Temperature (Celsius): %f\n",
	       val.val1 + val.val2 / 1000000.0);
}

static void test_polling_mode(struct device *bmg160)
{
	s32_t remaining_test_time = MAX_TEST_TIME;

	do {
		if (sensor_sample_fetch(bmg160) < 0) {
			printf("Gyro sample update error.\n");
		}

		print_gyro_data(bmg160);

		print_temp_data(bmg160);

		/* wait a while */
		k_sleep(SLEEPTIME);

		remaining_test_time -= SLEEPTIME;
	} while (remaining_test_time > 0);
}

static void trigger_handler(struct device *bmg160, struct sensor_trigger *trigger)
{
	if (trigger->type != SENSOR_TRIG_DATA_READY &&
	    trigger->type != SENSOR_TRIG_DELTA) {
		printf("Gyro: trigger handler: unknown trigger type.\n");
		return;
	}

	if (sensor_sample_fetch(bmg160) < 0) {
		printf("Gyro sample update error.\n");
	}

	print_gyro_data(bmg160);
}

static void test_trigger_mode(struct device *bmg160)
{
	s32_t remaining_test_time = MAX_TEST_TIME;
	struct sensor_trigger trig;
	struct sensor_value attr;

	trig.type = SENSOR_TRIG_DELTA;
	trig.chan = SENSOR_CHAN_GYRO_XYZ;

	printf("Gyro: Testing anymotion trigger.\n");

	/* set up the trigger */

	/* set slope threshold to 10 dps */

	sensor_degrees_to_rad(10, &attr); /* convert to rad/s */

	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
			    SENSOR_ATTR_SLOPE_TH, &attr) < 0) {
		printf("Gyro: cannot set slope threshold.\n");
		return;
	}

	/* set slope duration to 4 samples */
	attr.val1 = 4;
	attr.val2 = 0;

	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
			    SENSOR_ATTR_SLOPE_DUR, &attr) < 0) {
		printf("Gyro: cannot set slope duration.\n");
		return;
	}

	if (sensor_trigger_set(bmg160, &trig, trigger_handler) < 0) {
		printf("Gyro: cannot set trigger.\n");
		return;
	}

	printf("Gyro: rotate the device and wait for events.\n");
	do {
		k_sleep(SLEEPTIME);
		remaining_test_time -= SLEEPTIME;
	} while (remaining_test_time > 0);

	if (sensor_trigger_set(bmg160, &trig, NULL) < 0) {
		printf("Gyro: cannot clear trigger.\n");
		return;
	}

	printf("Gyro: Anymotion trigger test finished.\n");

	printf("Gyro: Testing data ready trigger.\n");

	attr.val1 = 100;
	attr.val2 = 0;

	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
			    SENSOR_ATTR_SAMPLING_FREQUENCY, &attr) < 0) {
		printf("Gyro: cannot set sampling frequency.\n");
		return;
	}

	trig.type = SENSOR_TRIG_DATA_READY;
	trig.chan = SENSOR_CHAN_GYRO_XYZ;

	if (sensor_trigger_set(bmg160, &trig, trigger_handler) < 0) {
		printf("Gyro: cannot set trigger.\n");
		return;
	}

	remaining_test_time = MAX_TEST_TIME;

	do {
		k_sleep(SLEEPTIME);
		remaining_test_time -= SLEEPTIME;
	} while (remaining_test_time > 0);

	if (sensor_trigger_set(bmg160, &trig, NULL) < 0) {
		printf("Gyro: cannot clear trigger.\n");
		return;
	}

	printf("Gyro: Data ready trigger test finished.\n");
}

void main(void)
{
	struct device *bmg160;
#if defined(CONFIG_BMG160_RANGE_RUNTIME)
	struct sensor_value attr;
#endif

	bmg160 = device_get_binding("bmg160");
	if (!bmg160) {
		printf("Device not found.\n");
		return;
	}

#if defined(CONFIG_BMG160_RANGE_RUNTIME)
	/*
	 * Set gyro range to +/- 250 degrees/s. Since the sensor API needs SI
	 * units, convert the range to rad/s.
	 */
	sensor_degrees_to_rad(250, &attr);

	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
			    SENSOR_ATTR_FULL_SCALE, &attr) < 0) {
		printf("Cannot set gyro range.\n");
		return;
	}
#endif

	printf("Testing the polling mode.\n");
	test_polling_mode(bmg160);
	printf("Polling mode test finished.\n");

	printf("Testing the trigger mode.\n");
	test_trigger_mode(bmg160);
	printf("Trigger mode test finished.\n");
}