Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

Commit 7e59fbd

Browse files
committed
[Sensor] Added support for trigger mode
Added trigger support, since currently in Zephyr, triggers can only be signaledfrom interrupt from x86 side, all the x86 side code is wrapped with BUILD_MODULE_SENSOR_TRIGGER #ifdef so that it can be turn off later when Zephyr changes. The trigger are set to sample in 50Hz, any higher frequency will cause the ring buffer to start dropping change events. Signed-off-by: Jimmy Huang <jimmy.huang@intel.com>
1 parent 6037375 commit 7e59fbd

File tree

6 files changed

+233
-65
lines changed

6 files changed

+233
-65
lines changed

arc/src/main.c

Lines changed: 153 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,12 @@
2626
#define SLEEP_TICKS 1 // 10ms sleep time in cpu ticks
2727
#define UPDATE_INTERVAL 200 // 2sec interval in between notifications
2828

29-
#ifdef BUILD_MODULE_AIO
3029
#define ADC_DEVICE_NAME "ADC_0"
3130
#define ADC_BUFFER_SIZE 2
32-
#endif
3331

34-
#ifdef BUILD_MODULE_I2C
3532
#define MAX_I2C_BUS 1
36-
#endif
3733

38-
#ifdef BUILD_MODULE_GROVE_LCD
3934
#define MAX_BUFFER_SIZE 256
40-
#endif
4135

4236
static struct nano_sem arc_sem;
4337
static struct zjs_ipm_message msg_queue[QUEUE_SIZE];
@@ -63,8 +57,8 @@ static char str[MAX_BUFFER_SIZE];
6357

6458
#ifdef BUILD_MODULE_SENSOR
6559
static struct device *bmi160 = NULL;
66-
static bool accel_poll = false;
67-
static bool gyro_poll = false;
60+
static bool accel_trigger = false;
61+
static bool gyro_trigger = false;
6862
static double accel_last_value[3];
6963
static double gyro_last_value[3];
7064
#endif
@@ -428,7 +422,7 @@ static void handle_glcd(struct zjs_ipm_message* msg)
428422
}
429423
#endif
430424

431-
#ifdef BUILD_MODULE_SENSOR
425+
#ifdef BUILD_MODULE_SENSOR
432426
#ifdef DEBUG_BUILD
433427
static inline int sensor_value_snprintf(char *buf, size_t len,
434428
const struct sensor_value *val)
@@ -533,19 +527,14 @@ static void process_accel_data(struct device *dev)
533527
double dval[3];
534528

535529
if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_ANY, val) < 0) {
536-
ZJS_PRINT("Cannot read accelerometer channels.\n");
530+
ZJS_PRINT("failed to read accelerometer channels\n");
537531
return;
538532
}
539533

540534
dval[0] = convert_sensor_value(&val[0]);
541535
dval[1] = convert_sensor_value(&val[1]);
542536
dval[2] = convert_sensor_value(&val[2]);
543537

544-
if (dval[0] == 0 && dval[1] == 0 && dval[2] == 0) {
545-
// FIXME: BUG? why sometimes it reports 0, 0, 0 on all axes
546-
return;
547-
}
548-
549538
// set slope threshold to 0.1G (0.1 * 9.80665 = 4.903325 m/s^2)
550539
double threshold = 0.980665;
551540
if (ABS(dval[0] - accel_last_value[0]) > threshold ||
@@ -574,7 +563,7 @@ static void process_gyro_data(struct device *dev)
574563
double dval[3];
575564

576565
if (sensor_channel_get(dev, SENSOR_CHAN_GYRO_ANY, val) < 0) {
577-
ZJS_PRINT("Cannot read gyroscope channels.\n");
566+
ZJS_PRINT("failed to read gyroscope channels.\n");
578567
return;
579568
}
580569

@@ -598,20 +587,26 @@ static void process_gyro_data(struct device *dev)
598587
sensor_value_snprintf(buf_x, sizeof(buf_x), &val[0]);
599588
sensor_value_snprintf(buf_y, sizeof(buf_y), &val[1]);
600589
sensor_value_snprintf(buf_z, sizeof(buf_z), &val[2]);
601-
ZJS_PRINT("Sending gyro : X=%s, Y=%s, Z=%s\n", buf_x, buf_y, buf_z);
590+
ZJS_PRINT("sending gyro : X=%s, Y=%s, Z=%s\n", buf_x, buf_y, buf_z);
602591
#endif
603592
}
604593

605-
static void fetch_sensor(struct device *dev) {
594+
static void trigger_hdlr(struct device *dev,
595+
struct sensor_trigger *trigger)
596+
{
597+
if (trigger->type != SENSOR_TRIG_DELTA &&
598+
trigger->type != SENSOR_TRIG_DATA_READY) {
599+
return;
600+
}
601+
606602
if (sensor_sample_fetch(dev) < 0) {
607603
ZJS_PRINT("failed to fetch sensor data\n");
608604
return;
609605
}
610606

611-
if (accel_poll) {
607+
if (trigger->chan == SENSOR_CHAN_ACCEL_ANY) {
612608
process_accel_data(dev);
613-
}
614-
if (gyro_poll) {
609+
} else if (trigger->chan == SENSOR_CHAN_GYRO_ANY) {
615610
process_gyro_data(dev);
616611
}
617612
}
@@ -627,12 +622,12 @@ struct sensor_value acc_calib[] = {
627622
{SENSOR_VALUE_TYPE_INT_PLUS_MICRO, { {9, 806650} } }, /* Z */
628623
};
629624

630-
static bool auto_calibration(struct device *dev)
625+
static int auto_calibration(struct device *dev)
631626
{
632627
/* calibrate accelerometer */
633628
if (sensor_attr_set(dev, SENSOR_CHAN_ACCEL_ANY,
634629
SENSOR_ATTR_CALIB_TARGET, acc_calib) < 0) {
635-
return false;
630+
return -1;
636631
}
637632

638633
/*
@@ -642,18 +637,137 @@ static bool auto_calibration(struct device *dev)
642637
*/
643638
if (sensor_attr_set(dev, SENSOR_CHAN_GYRO_ANY,
644639
SENSOR_ATTR_CALIB_TARGET, NULL) < 0) {
645-
return false;
640+
return -1;
646641
}
647642

648-
return true;
643+
return 0;
644+
}
645+
646+
static int start_accel_trigger(struct device *dev)
647+
{
648+
struct sensor_value attr;
649+
struct sensor_trigger trig;
650+
651+
// set accelerometer range to +/- 16G. Since the sensor API needs SI
652+
// units, convert the range to m/s^2.
653+
sensor_g_to_ms2(16, &attr);
654+
655+
if (sensor_attr_set(dev, SENSOR_CHAN_ACCEL_ANY,
656+
SENSOR_ATTR_FULL_SCALE, &attr) < 0) {
657+
ZJS_PRINT("failed to set accelerometer range\n");
658+
return -1;
659+
}
660+
661+
// set sampling frequency to 50Hz for accelerometer
662+
attr.type = SENSOR_VALUE_TYPE_INT_PLUS_MICRO;
663+
attr.val1 = 50;
664+
attr.val2 = 0;
665+
666+
if (sensor_attr_set(dev, SENSOR_CHAN_ACCEL_ANY,
667+
SENSOR_ATTR_SAMPLING_FREQUENCY, &attr) < 0) {
668+
ZJS_PRINT("failed to set accelerometer sampling frequency\n");
669+
return -1;
670+
}
671+
672+
// set slope threshold to 0.1G (0.1 * 9.80665 = 4.903325 m/s^2).
673+
attr.type = SENSOR_VALUE_TYPE_INT_PLUS_MICRO;
674+
attr.val1 = 0;
675+
attr.val2 = 980665;
676+
if (sensor_attr_set(dev, SENSOR_CHAN_ACCEL_ANY,
677+
SENSOR_ATTR_SLOPE_TH, &attr) < 0) {
678+
ZJS_PRINT("failed set slope threshold\n");
679+
return -1;
680+
}
681+
682+
// set slope duration to 2 consecutive samples
683+
attr.type = SENSOR_VALUE_TYPE_INT;
684+
attr.val1 = 2;
685+
if (sensor_attr_set(dev, SENSOR_CHAN_ACCEL_ANY,
686+
SENSOR_ATTR_SLOPE_DUR, &attr) < 0) {
687+
ZJS_PRINT("failed to set slope duration\n");
688+
return -1;
689+
}
690+
691+
// set data ready trigger handler
692+
trig.type = SENSOR_TRIG_DATA_READY;
693+
trig.chan = SENSOR_CHAN_ACCEL_ANY;
694+
695+
if (sensor_trigger_set(dev, &trig, trigger_hdlr) < 0) {
696+
ZJS_PRINT("failed to enable accelerometer trigger\n");
697+
return -1;
698+
}
699+
700+
accel_trigger = true;
701+
return 0;
702+
}
703+
704+
static int stop_accel_trigger(struct device *dev)
705+
{
706+
struct sensor_trigger trig;
707+
708+
trig.type = SENSOR_TRIG_DATA_READY;
709+
trig.chan = SENSOR_CHAN_ACCEL_ANY;
710+
711+
if (sensor_trigger_set(bmi160, &trig, NULL) < 0) {
712+
ZJS_PRINT("failed to disable accelerometer trigger\n");
713+
return -1;
714+
}
715+
716+
accel_trigger = false;
717+
return 0;
718+
}
719+
720+
static int start_gyro_trigger(struct device *dev)
721+
{
722+
struct sensor_value attr;
723+
struct sensor_trigger trig;
724+
725+
// set sampling frequency to 50Hz for gyroscope
726+
attr.type = SENSOR_VALUE_TYPE_INT_PLUS_MICRO;
727+
attr.val1 = 50;
728+
attr.val2 = 0;
729+
730+
if (sensor_attr_set(bmi160, SENSOR_CHAN_GYRO_ANY,
731+
SENSOR_ATTR_SAMPLING_FREQUENCY, &attr) < 0) {
732+
ZJS_PRINT("failed to set sampling frequency for gyroscope.\n");
733+
return -1;
734+
}
735+
736+
// set data ready trigger handler
737+
trig.type = SENSOR_TRIG_DATA_READY;
738+
trig.chan = SENSOR_CHAN_GYRO_ANY;
739+
740+
if (sensor_trigger_set(bmi160, &trig, trigger_hdlr) < 0) {
741+
ZJS_PRINT("failed to enable gyroscope trigger.\n");
742+
return -1;
743+
}
744+
745+
gyro_trigger = true;
746+
return 0;
747+
}
748+
749+
static int stop_gyro_trigger(struct device *dev)
750+
{
751+
struct sensor_trigger trig;
752+
753+
trig.type = SENSOR_TRIG_DATA_READY;
754+
trig.chan = SENSOR_CHAN_GYRO_ANY;
755+
756+
if (sensor_trigger_set(bmi160, &trig, NULL) < 0) {
757+
ZJS_PRINT("failed to disable gyroscope trigger\n");
758+
return -1;
759+
}
760+
761+
gyro_trigger = false;
762+
return 0;
649763
}
650764

651765
static void handle_sensor(struct zjs_ipm_message* msg)
652766
{
653767
uint32_t error_code = ERROR_IPM_NONE;
654768

655769
if (msg->type != TYPE_SENSOR_INIT && !bmi160) {
656-
ZJS_PRINT("Grove LCD device not found.\n");
770+
ZJS_PRINT("BMI160 sensor not found.\n");
657771
ipm_send_error_reply(msg, ERROR_IPM_OPERATION_FAILED);
658772
return;
659773
}
@@ -667,30 +781,36 @@ static void handle_sensor(struct zjs_ipm_message* msg)
667781
error_code = ERROR_IPM_OPERATION_FAILED;
668782
ZJS_PRINT("failed to initialize BMI160 sensor\n");
669783
} else {
670-
if (!auto_calibration(bmi160)) {
784+
if (auto_calibration(bmi160) != 0) {
671785
ZJS_PRINT("failed to perform auto calibration\n");
672786
}
673-
674-
accel_poll = gyro_poll = false;
675787
DBG_PRINT("BMI160 sensor initialized\n");
676788
}
677789
}
678790
break;
679791
case TYPE_SENSOR_START:
680792
if (msg->data.sensor.channel == SENSOR_CHAN_ACCEL_ANY) {
681-
accel_poll = true;
793+
if (!accel_trigger && start_accel_trigger(bmi160) != 0) {
794+
error_code = ERROR_IPM_OPERATION_FAILED;
795+
}
682796
} else if (msg->data.sensor.channel == SENSOR_CHAN_GYRO_ANY) {
683-
gyro_poll = true;
797+
if (!gyro_trigger && start_gyro_trigger(bmi160) != 0) {
798+
error_code = ERROR_IPM_OPERATION_FAILED;
799+
}
684800
} else {
685801
ZJS_PRINT("invalid sensor channel\n");
686802
error_code = ERROR_IPM_NOT_SUPPORTED;
687803
}
688804
break;
689805
case TYPE_SENSOR_STOP:
690806
if (msg->data.sensor.channel == SENSOR_CHAN_ACCEL_ANY) {
691-
accel_poll = false;
807+
if (accel_trigger && stop_accel_trigger(bmi160) != 0) {
808+
error_code = ERROR_IPM_OPERATION_FAILED;
809+
}
692810
} else if (msg->data.sensor.channel == SENSOR_CHAN_GYRO_ANY) {
693-
gyro_poll = false;
811+
if (gyro_trigger && stop_gyro_trigger(bmi160) != 0) {
812+
error_code = ERROR_IPM_OPERATION_FAILED;
813+
}
694814
} else {
695815
ZJS_PRINT("invalid sensor channel\n");
696816
error_code = ERROR_IPM_NOT_SUPPORTED;
@@ -776,11 +896,6 @@ void main(void)
776896
tick_count = 0;
777897
}
778898
tick_count += SLEEP_TICKS;
779-
#endif
780-
#ifdef BUILD_MODULE_SENSOR
781-
if (accel_poll || gyro_poll) {
782-
fetch_sensor(bmi160);
783-
}
784899
#endif
785900
task_sleep(SLEEP_TICKS);
786901
}

deps/zephyr

Submodule zephyr updated from 9cbd41a to dfa7ca4

samples/Gyroscope.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
console.log("Gyroscope test...");
77

88

9-
var sensor = new Gyroscope();
9+
var sensor = new Gyroscope({
10+
frequency: 50
11+
});
1012

1113
sensor.onchange = function(event) {
1214
console.log("rotation (rad/s): " +

scripts/analyze.sh

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,18 +187,29 @@ if [ $? -eq 0 ] && [[ $MODULE != *"BUILD_MODULE_BUFFER"* ]]; then
187187
>&2 echo Using module: Buffer
188188
MODULES+=" -DBUILD_MODULE_BUFFER"
189189
fi
190-
sensor=$(grep -E Accelerometer\|Gyroscope $SCRIPT)
190+
sensor=$(grep -E Accelerometer\|Gyroscope $SCRIPT)
191191
if [ $? -eq 0 ]; then
192192
>&2 echo Using module: Sensor
193193
MODULES+=" -DBUILD_MODULE_SENSOR"
194-
echo "CONFIG_SPI=y" >> arc/prj.conf.tmp
194+
MODULES+=" -DBUILD_MODULE_SENSOR_TRIGGER"
195195
echo "CONFIG_SENSOR=y" >> arc/prj.conf.tmp
196+
echo "CONFIG_GPIO=y" >> prj.conf.tmp
197+
echo "CONFIG_GPIO_QMSI=y" >> prj.conf.tmp
198+
echo "CONFIG_GPIO_QMSI_0_PRI=2" >> prj.conf.tmp
199+
echo "CONFIG_GPIO_QMSI_1=y" >> prj.conf.tmp
200+
echo "CONFIG_GPIO_QMSI_1_NAME=\"GPIO_1\"" >> prj.conf.tmp
201+
echo "CONFIG_GPIO_QMSI_1_PRI=2" >> prj.conf.tmp
202+
echo "CONFIG_SPI=y" >> arc/prj.conf.tmp
203+
echo "CONFIG_SPI_DW_ARC_AUX_REGS=y" >> arc/prj.conf.tmp
204+
echo "CONFIG_SPI_DW_INTERRUPT_SEPARATED_LINES=y" >> arc/prj.conf.tmp
196205
echo "CONFIG_BMI160=y" >> arc/prj.conf.tmp
197206
echo "CONFIG_BMI160_INIT_PRIORITY=80" >> arc/prj.conf.tmp
198207
echo "CONFIG_BMI160_NAME=\"bmi160\"" >> arc/prj.conf.tmp
199208
echo "CONFIG_BMI160_SPI_PORT_NAME=\"SPI_1\"" >> arc/prj.conf.tmp
200209
echo "CONFIG_BMI160_SLAVE=1" >> arc/prj.conf.tmp
201210
echo "CONFIG_BMI160_SPI_BUS_FREQ=88" >> arc/prj.conf.tmp
211+
echo "CONFIG_BMI160_TRIGGER=y" >> arc/prj.conf.tmp
212+
echo "CONFIG_BMI160_TRIGGER_OWN_FIBER=y" >> arc/prj.conf.tmp
202213
fi
203214

204215
console=$(grep console $SCRIPT)

src/zjs_ipm.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ typedef struct zjs_ipm_message {
109109
struct sensor_data {
110110
enum sensor_channel channel;
111111
uint32_t frequency;
112-
double value[3];
113112
union sensor_reading {
114113
// x y z axis for Accelerometer and Gyroscope
115114
struct {

0 commit comments

Comments
 (0)