@@ -36,45 +36,49 @@ typedef struct _microbit_accelerometer_obj_t {
36
36
MicroBitAccelerometer *accelerometer;
37
37
} microbit_accelerometer_obj_t ;
38
38
39
- bool accelerometer_up_to_date = false ;
39
+ volatile bool accelerometer_up_to_date = false ;
40
+ volatile bool accelerometer_updating = false ;
40
41
41
- mp_obj_t microbit_accelerometer_get_x (mp_obj_t self_in) {
42
- microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
43
- if (!accelerometer_up_to_date) {
44
- self->accelerometer ->idleTick ();
42
+ static void update (microbit_accelerometer_obj_t *self) {
43
+ /* The only time it is possible for accelerometer_updating to be true here
44
+ * is if this is called in an interrupt when it is already updating in
45
+ * the main execution thread. This is extremely unlikely, so we just
46
+ * accept that a slightly out-of-date result will be returned
47
+ */
48
+ if (!accelerometer_up_to_date && !accelerometer_updating) {
45
49
accelerometer_up_to_date = true ;
50
+ accelerometer_updating = true ;
51
+ self->accelerometer ->idleTick ();
52
+ accelerometer_updating = false ;
46
53
}
54
+ }
55
+
56
+
57
+ mp_obj_t microbit_accelerometer_get_x (mp_obj_t self_in) {
58
+ microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
59
+ update (self);
47
60
return mp_obj_new_int (self->accelerometer ->getX ());
48
61
}
49
62
MP_DEFINE_CONST_FUN_OBJ_1 (microbit_accelerometer_get_x_obj, microbit_accelerometer_get_x);
50
63
51
64
mp_obj_t microbit_accelerometer_get_y (mp_obj_t self_in) {
52
65
microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
53
- if (!accelerometer_up_to_date) {
54
- self->accelerometer ->idleTick ();
55
- accelerometer_up_to_date = true ;
56
- }
66
+ update (self);
57
67
return mp_obj_new_int (self->accelerometer ->getY ());
58
68
}
59
69
MP_DEFINE_CONST_FUN_OBJ_1 (microbit_accelerometer_get_y_obj, microbit_accelerometer_get_y);
60
70
61
71
mp_obj_t microbit_accelerometer_get_z (mp_obj_t self_in) {
62
72
microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
63
- if (!accelerometer_up_to_date) {
64
- self->accelerometer ->idleTick ();
65
- accelerometer_up_to_date = true ;
66
- }
73
+ update (self);
67
74
return mp_obj_new_int (self->accelerometer ->getZ ());
68
75
}
69
76
MP_DEFINE_CONST_FUN_OBJ_1 (microbit_accelerometer_get_z_obj, microbit_accelerometer_get_z);
70
77
71
78
mp_obj_t microbit_accelerometer_get_values (mp_obj_t self_in) {
72
79
microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
73
80
mp_obj_tuple_t *tuple = (mp_obj_tuple_t *)mp_obj_new_tuple (3 , NULL );
74
- if (!accelerometer_up_to_date) {
75
- self->accelerometer ->idleTick ();
76
- accelerometer_up_to_date = true ;
77
- }
81
+ update (self);
78
82
tuple->items [0 ] = mp_obj_new_int (self->accelerometer ->getX ());
79
83
tuple->items [1 ] = mp_obj_new_int (self->accelerometer ->getY ());
80
84
tuple->items [2 ] = mp_obj_new_int (self->accelerometer ->getZ ());
0 commit comments