@@ -39,9 +39,13 @@ typedef struct _microbit_accelerometer_obj_t {
3939volatile bool accelerometer_up_to_date = false ;
4040volatile bool accelerometer_updating = false ;
4141
42+ #define GESTURE_LIST_SIZE (8 )
43+
4244// We store this state globally instead of in a microbit_accelerometer_obj_t
4345// struct so that that whole struct does not need to go in RAM.
44- volatile uint8_t gesture_state[GESTURE_SHAKE + 1 ] = {0 };
46+ volatile uint16_t gesture_state = 0 ; // 1 bit per gesture
47+ volatile uint8_t gesture_list_cur = 0 ; // index into gesture_list
48+ volatile uint8_t gesture_list[GESTURE_LIST_SIZE] = {0 }; // list of pending gestures, 4-bits per element
4549
4650static void update (microbit_accelerometer_obj_t *self) {
4751 /* The only time it is possible for accelerometer_updating to be true here
@@ -58,8 +62,12 @@ static void update(microbit_accelerometer_obj_t *self) {
5862}
5963
6064STATIC void accelerometer_listener (MicroBitEvent evt) {
61- if (evt.value <= GESTURE_SHAKE) {
62- gesture_state[evt.value ] = (gesture_state[evt.value ] + 2 ) | 1 ;
65+ if (evt.value > GESTURE_NONE && evt.value <= GESTURE_SHAKE) {
66+ gesture_state |= 1 << evt.value ;
67+ if (gesture_list_cur < 2 * GESTURE_LIST_SIZE) {
68+ gesture_list[gesture_list_cur >> 1 ] |= evt.value << (4 * (gesture_list_cur & 1 ));
69+ ++gesture_list_cur;
70+ }
6371 }
6472}
6573
@@ -99,31 +107,38 @@ mp_obj_t microbit_accelerometer_get_values(mp_obj_t self_in) {
99107}
100108MP_DEFINE_CONST_FUN_OBJ_1 (microbit_accelerometer_get_values_obj, microbit_accelerometer_get_values);
101109
102- STATIC const char * gesture_name_map[] = {
103- [GESTURE_NONE] = NULL ,
104- [GESTURE_UP] = " up " ,
105- [GESTURE_DOWN] = " down " ,
106- [GESTURE_LEFT] = " left " ,
107- [GESTURE_RIGHT] = " right " ,
108- [GESTURE_FACE_UP] = " face up " ,
109- [GESTURE_FACE_DOWN] = " face down " ,
110- [GESTURE_FREEFALL] = " freefall " ,
111- [GESTURE_3G] = " 3g " ,
112- [GESTURE_6G] = " 6g " ,
113- [GESTURE_8G] = " 8g " ,
114- [GESTURE_SHAKE] = " shake " ,
110+ STATIC const qstr gesture_name_map[] = {
111+ [GESTURE_NONE] = MP_QSTR_NULL ,
112+ [GESTURE_UP] = MP_QSTR_up ,
113+ [GESTURE_DOWN] = MP_QSTR_down ,
114+ [GESTURE_LEFT] = MP_QSTR_left ,
115+ [GESTURE_RIGHT] = MP_QSTR_right ,
116+ [GESTURE_FACE_UP] = MP_QSTR_face_space_up ,
117+ [GESTURE_FACE_DOWN] = MP_QSTR_face_space_down ,
118+ [GESTURE_FREEFALL] = MP_QSTR_freefall ,
119+ [GESTURE_3G] = MP_QSTR_3g ,
120+ [GESTURE_6G] = MP_QSTR_6g ,
121+ [GESTURE_8G] = MP_QSTR_8g ,
122+ [GESTURE_SHAKE] = MP_QSTR_shake ,
115123};
116124
117125STATIC BasicGesture gesture_from_obj (mp_obj_t gesture_in) {
118- const char * gesture = mp_obj_str_get_str (gesture_in);
126+ qstr gesture = mp_obj_str_get_qstr (gesture_in);
119127 for (uint i = 0 ; i < MP_ARRAY_SIZE (gesture_name_map); ++i) {
120- if (gesture_name_map[i] != NULL && strcmp (gesture, gesture_name_map[i]) == 0 ) {
128+ if (gesture == gesture_name_map[i]) {
121129 return (BasicGesture)i;
122130 }
123131 }
124132 nlr_raise (mp_obj_new_exception_msg (&mp_type_ValueError, " invalid gesture" ));
125133}
126134
135+ mp_obj_t microbit_accelerometer_current_gesture (mp_obj_t self_in) {
136+ microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
137+ update (self);
138+ return MP_OBJ_NEW_QSTR (gesture_name_map[self->accelerometer ->getGesture ()]);
139+ }
140+ MP_DEFINE_CONST_FUN_OBJ_1 (microbit_accelerometer_current_gesture_obj, microbit_accelerometer_current_gesture);
141+
127142mp_obj_t microbit_accelerometer_is_gesture (mp_obj_t self_in, mp_obj_t gesture_in) {
128143 microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
129144 BasicGesture gesture = gesture_from_obj (gesture_in);
@@ -136,35 +151,42 @@ mp_obj_t microbit_accelerometer_was_gesture(mp_obj_t self_in, mp_obj_t gesture_i
136151 microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
137152 BasicGesture gesture = gesture_from_obj (gesture_in);
138153 update (self);
139- uint8_t state = gesture_state[ gesture] ;
140- mp_obj_t result = mp_obj_new_bool (state & 1 );
141- gesture_state[gesture] = state & - 2 ;
154+ mp_obj_t result = mp_obj_new_bool ( gesture_state & ( 1 << gesture)) ;
155+ gesture_state &= (~( 1 << gesture) );
156+ gesture_list_cur = 0 ;
142157 return result;
143158}
144159MP_DEFINE_CONST_FUN_OBJ_2 (microbit_accelerometer_was_gesture_obj, microbit_accelerometer_was_gesture);
145160
146- mp_obj_t microbit_accelerometer_get_gestures (mp_obj_t self_in, mp_obj_t gesture_in ) {
161+ mp_obj_t microbit_accelerometer_get_gestures (mp_obj_t self_in) {
147162 microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
148- BasicGesture gesture = gesture_from_obj (gesture_in);
149163 update (self);
150- return mp_obj_new_int (gesture_state[gesture] >> 1 );
164+ if (gesture_list_cur == 0 ) {
165+ return mp_const_empty_tuple;
166+ }
167+ mp_obj_tuple_t *o = (mp_obj_tuple_t *)mp_obj_new_tuple (gesture_list_cur, NULL );
168+ for (uint i = 0 ; i < gesture_list_cur; ++i) {
169+ uint gesture = (gesture_list[i >> 1 ] >> (4 * (i & 1 ))) & 0x0f ;
170+ o->items [i] = MP_OBJ_NEW_QSTR (gesture_name_map[gesture]);
171+ }
172+ return o;
151173}
152- MP_DEFINE_CONST_FUN_OBJ_2 (microbit_accelerometer_get_gestures_obj, microbit_accelerometer_get_gestures);
174+ MP_DEFINE_CONST_FUN_OBJ_1 (microbit_accelerometer_get_gestures_obj, microbit_accelerometer_get_gestures);
153175
154- mp_obj_t microbit_accelerometer_reset_gestures (mp_obj_t self_in, mp_obj_t gesture_in ) {
176+ mp_obj_t microbit_accelerometer_reset_gestures (mp_obj_t self_in) {
155177 microbit_accelerometer_obj_t *self = (microbit_accelerometer_obj_t *)self_in;
156- BasicGesture gesture = gesture_from_obj (gesture_in);
157178 update (self);
158- gesture_state[gesture] &= 1 ;
179+ gesture_list_cur = 0 ;
159180 return mp_const_none;
160181}
161- MP_DEFINE_CONST_FUN_OBJ_2 (microbit_accelerometer_reset_gestures_obj, microbit_accelerometer_reset_gestures);
182+ MP_DEFINE_CONST_FUN_OBJ_1 (microbit_accelerometer_reset_gestures_obj, microbit_accelerometer_reset_gestures);
162183
163184STATIC const mp_map_elem_t microbit_accelerometer_locals_dict_table[] = {
164185 { MP_OBJ_NEW_QSTR (MP_QSTR_get_x), (mp_obj_t )µbit_accelerometer_get_x_obj },
165186 { MP_OBJ_NEW_QSTR (MP_QSTR_get_y), (mp_obj_t )µbit_accelerometer_get_y_obj },
166187 { MP_OBJ_NEW_QSTR (MP_QSTR_get_z), (mp_obj_t )µbit_accelerometer_get_z_obj },
167188 { MP_OBJ_NEW_QSTR (MP_QSTR_get_values), (mp_obj_t )µbit_accelerometer_get_values_obj },
189+ { MP_OBJ_NEW_QSTR (MP_QSTR_current_gesture), (mp_obj_t )µbit_accelerometer_current_gesture_obj },
168190 { MP_OBJ_NEW_QSTR (MP_QSTR_is_gesture), (mp_obj_t )µbit_accelerometer_is_gesture_obj },
169191 { MP_OBJ_NEW_QSTR (MP_QSTR_was_gesture), (mp_obj_t )µbit_accelerometer_was_gesture_obj },
170192 { MP_OBJ_NEW_QSTR (MP_QSTR_get_gestures), (mp_obj_t )µbit_accelerometer_get_gestures_obj },
0 commit comments