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
4236static struct nano_sem arc_sem ;
4337static struct zjs_ipm_message msg_queue [QUEUE_SIZE ];
@@ -63,8 +57,8 @@ static char str[MAX_BUFFER_SIZE];
6357
6458#ifdef BUILD_MODULE_SENSOR
6559static 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;
6862static double accel_last_value [3 ];
6963static 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
433427static 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
651765static 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 }
0 commit comments