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

Commit 2a9bbc7

Browse files
Jimmy Huanggrgustaf
authored andcommitted
[sensor] Added support for trigger mode (#453)
Added trigger support, since currently in Zephyr, triggers can only be signaled from interrupt from x86 side, all the x86 side code is wrapped with BUILD_MODULE_SENSOR_TRIGGER #ifdef so that it can be turned off later when Zephyr changes. The triggers are set to sample at 50Hz; any higher frequency will cause the ring buffer to start dropping change events. Signed-off-by: Jimmy Huang <[email protected]>
1 parent 7f7911b commit 2a9bbc7

File tree

5 files changed

+241
-71
lines changed

5 files changed

+241
-71
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)) {
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
}

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: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,18 +187,31 @@ 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
195-
echo "CONFIG_SENSOR=y" >> arc/prj.conf.tmp
196-
echo "CONFIG_BMI160=y" >> arc/prj.conf.tmp
197-
echo "CONFIG_BMI160_INIT_PRIORITY=80" >> arc/prj.conf.tmp
198-
echo "CONFIG_BMI160_NAME=\"bmi160\"" >> arc/prj.conf.tmp
199-
echo "CONFIG_BMI160_SPI_PORT_NAME=\"SPI_1\"" >> arc/prj.conf.tmp
200-
echo "CONFIG_BMI160_SLAVE=1" >> arc/prj.conf.tmp
201-
echo "CONFIG_BMI160_SPI_BUS_FREQ=88" >> arc/prj.conf.tmp
194+
if [ $BOARD = "arduino_101" ]; then
195+
MODULES+=" -DBUILD_MODULE_SENSOR_TRIGGER"
196+
echo "CONFIG_SENSOR=y" >> arc/prj.conf.tmp
197+
echo "CONFIG_GPIO=y" >> prj.conf.tmp
198+
echo "CONFIG_GPIO_QMSI=y" >> prj.conf.tmp
199+
echo "CONFIG_GPIO_QMSI_0_PRI=2" >> prj.conf.tmp
200+
echo "CONFIG_GPIO_QMSI_1=y" >> prj.conf.tmp
201+
echo "CONFIG_GPIO_QMSI_1_NAME=\"GPIO_1\"" >> prj.conf.tmp
202+
echo "CONFIG_GPIO_QMSI_1_PRI=2" >> prj.conf.tmp
203+
echo "CONFIG_SPI=y" >> arc/prj.conf.tmp
204+
echo "CONFIG_SPI_DW_ARC_AUX_REGS=y" >> arc/prj.conf.tmp
205+
echo "CONFIG_SPI_DW_INTERRUPT_SEPARATED_LINES=y" >> arc/prj.conf.tmp
206+
echo "CONFIG_BMI160=y" >> arc/prj.conf.tmp
207+
echo "CONFIG_BMI160_INIT_PRIORITY=80" >> arc/prj.conf.tmp
208+
echo "CONFIG_BMI160_NAME=\"bmi160\"" >> arc/prj.conf.tmp
209+
echo "CONFIG_BMI160_SPI_PORT_NAME=\"SPI_1\"" >> arc/prj.conf.tmp
210+
echo "CONFIG_BMI160_SLAVE=1" >> arc/prj.conf.tmp
211+
echo "CONFIG_BMI160_SPI_BUS_FREQ=88" >> arc/prj.conf.tmp
212+
echo "CONFIG_BMI160_TRIGGER=y" >> arc/prj.conf.tmp
213+
echo "CONFIG_BMI160_TRIGGER_OWN_FIBER=y" >> arc/prj.conf.tmp
214+
fi
202215
fi
203216

204217
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)