]> git.earman.xyz Git - sensor-watch.git/commitdiff
Enable custom signal tones in LE mode.
authorWesley Aptekar-Cassels <me@wesleyac.com>
Mon, 13 Nov 2023 05:48:57 +0000 (00:48 -0500)
committerWesley Aptekar-Cassels <me@wesleyac.com>
Tue, 9 Jan 2024 21:22:21 +0000 (16:22 -0500)
This makes movement_play_signal synchronous when in LE mode, despite
using the underlying asynchronous API. It's a bit of a hack, but it
should work well enough for now.

This also moves the enabling/disabling of the buzzer into the
movement_play_signal function, so that watch faces no longer have to do
it.

movement/movement.c
movement/movement_config.h
movement/watch_faces/clock/repetition_minute_face.c
movement/watch_faces/clock/simple_clock_bin_led_face.c
movement/watch_faces/clock/simple_clock_face.c
movement/watch_faces/clock/weeknumber_clock_face.c
watch-library/hardware/watch/watch_buzzer.c
watch-library/shared/watch/watch_buzzer.h

index 235716c852552fbcc7c51902e862ebf542ca4c55..0e40d46282531ac7f9355c4b1a23ea7a94f9358a 100644 (file)
@@ -294,14 +294,31 @@ void movement_request_wake() {
 }
 
 void movement_play_signal(void) {
-#ifdef SIGNAL_TUNE_DEFAULT
-    watch_buzzer_play_note(BUZZER_NOTE_C8, 75);
-    watch_buzzer_play_note(BUZZER_NOTE_REST, 100);
-    watch_buzzer_play_note(BUZZER_NOTE_C8, 100);
-#else
-    // Does not work in LE mode.
-    watch_buzzer_play_sequence(signal_tune, NULL);
-#endif // SIGNAL_TUNE_DEFAULT
+    watch_enable_buzzer();
+    watch_buzzer_play_sequence(signal_tune, watch_disable_buzzer);
+    if (movement_state.le_mode_ticks == -1) {
+       // This is somewhat of a hack. In order to play a sequence, we need to
+       // be awake. We should ideally be able to tell movement that we need to
+       // be awake for a given amount of time, but there's no good way to do
+       // this, so we block instead. This might be bad in the case that a
+       // watch face has housekeeping to do after calling this, since it could
+       // in theory do that housekeeping concurrently, but alas.
+       //
+       // You might wonder, why not just put the instruction to go back to
+       // sleep in the callback? It's a good idea, but I can't figure out how
+       // to get it to work - you're basically kicking the can down the road,
+       // since at some point movement will be done doing what it's doing and
+       // have to wait. At that point, you're delaying anyways, but it's
+       // harder to figure out how much time to delay for, since you don't
+       // know how much time has elapsed since starting the sequence. I'd
+       // rather this block than have to read from the RTC to figure that
+       // out.
+       //
+       // Don't ask me what the +50ms is doing. The sequence gets cut short
+       // with the exact time, I have no idea why. 50 extra millisecons seems
+       // like a safe value.
+        delay_ms(sequence_length(signal_tune) * 1000 / 64 + 50);
+    }
 }
 
 void movement_play_alarm(void) {
index bafbc5e536d0ca3c18d3b920d3d1a9316448ddb9..067ca44b2ec4adb0f900d425fe32c6147ebf12ca 100644 (file)
@@ -49,8 +49,7 @@ const watch_face_t watch_faces[] = {
  */
 #define MOVEMENT_SECONDARY_FACE_INDEX (MOVEMENT_NUM_FACES - 2) // or (0)
 
-/* Custom hourly chime tune. Check movement_custom_signal_tunes.h for options.
- * Custom tunes do not currently work in LE mode. */
+/* Custom hourly chime tune. Check movement_custom_signal_tunes.h for options. */
 #define SIGNAL_TUNE_DEFAULT
 
 #endif // MOVEMENT_CONFIG_H_
index a0fbe077058c079e2306292d437865ae92bc41c9..e9e5e3197507fd99296498205f063da1c8249482 100644 (file)
@@ -153,17 +153,7 @@ bool repetition_minute_face_loop(movement_event_t event, movement_settings_t *se
         case EVENT_BACKGROUND_TASK:
             // uncomment this line to snap back to the clock face when the hour signal sounds:
             // movement_move_to_face(state->watch_face_index);
-            if (watch_is_buzzer_or_led_enabled()) {
-                // if we are in the foreground, we can just beep.
-                movement_play_signal();
-            } else {
-                // if we were in the background, we need to enable the buzzer peripheral first,
-                watch_enable_buzzer();
-                // beep quickly (this call blocks for 275 ms),
-                movement_play_signal();
-                // and then turn the buzzer peripheral off again.
-                watch_disable_buzzer();
-            }
+            movement_play_signal();
             break;
         case EVENT_LIGHT_LONG_UP:
             /*
index 640f0d77f7ea95cb71732a15753ce61cf6327723..cf39c1886bb8aa8908a2a47b91a494f9a967e2bf 100644 (file)
@@ -180,17 +180,7 @@ bool simple_clock_bin_led_face_loop(movement_event_t event, movement_settings_t
         case EVENT_BACKGROUND_TASK:
             // uncomment this line to snap back to the clock face when the hour signal sounds:
             // movement_move_to_face(state->watch_face_index);
-            if (watch_is_buzzer_or_led_enabled()) {
-                // if we are in the foreground, we can just beep.
-                movement_play_signal();
-            } else {
-                // if we were in the background, we need to enable the buzzer peripheral first,
-                watch_enable_buzzer();
-                // beep quickly (this call blocks for 275 ms),
-                movement_play_signal();
-                // and then turn the buzzer peripheral off again.
-                watch_disable_buzzer();
-            }
+            movement_play_signal();
             break;
         case EVENT_LIGHT_LONG_PRESS:
             if (state->flashing_state == 0) {
index 91400b6c316b51ae081cb0424d5cb68363c0072c..fbc2c4b3ea71aefb8b32615b8c413e1cd2c8a0f5 100644 (file)
@@ -136,17 +136,7 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting
         case EVENT_BACKGROUND_TASK:
             // uncomment this line to snap back to the clock face when the hour signal sounds:
             // movement_move_to_face(state->watch_face_index);
-            if (watch_is_buzzer_or_led_enabled()) {
-                // if we are in the foreground, we can just beep.
-                movement_play_signal();
-            } else {
-                // if we were in the background, we need to enable the buzzer peripheral first,
-                watch_enable_buzzer();
-                // beep quickly (this call blocks for 275 ms),
-                movement_play_signal();
-                // and then turn the buzzer peripheral off again.
-                watch_disable_buzzer();
-            }
+            movement_play_signal();
             break;
         default:
             return movement_default_loop_handler(event, settings);
index 4e40ebdcaa21a6b3cc56667b6637a215890730e8..81df58475ba962dcea335112280e891d76927f7e 100644 (file)
@@ -130,17 +130,7 @@ bool weeknumber_clock_face_loop(movement_event_t event, movement_settings_t *set
         case EVENT_BACKGROUND_TASK:
             // uncomment this line to snap back to the clock face when the hour signal sounds:
             // movement_move_to_face(state->watch_face_index);
-            if (watch_is_buzzer_or_led_enabled()) {
-                // if we are in the foreground, we can just beep.
-                movement_play_signal();
-            } else {
-                // if we were in the background, we need to enable the buzzer peripheral first,
-                watch_enable_buzzer();
-                // beep quickly (this call blocks for 275 ms),
-                movement_play_signal();
-                // and then turn the buzzer peripheral off again.
-                watch_disable_buzzer();
-            }
+            movement_play_signal();
             break;
         default:
             movement_default_loop_handler(event, settings);
index 18fb4db0c0138a8f355713b9bec97006964ff046..63506a5118c154dc27ccd9c82175b87389c3addb 100644 (file)
@@ -90,6 +90,15 @@ void watch_buzzer_play_sequence(int8_t *note_sequence, void (*callback_on_end)(v
     _tc3_start();
 }
 
+uint16_t sequence_length(int8_t *sequence) {
+    uint16_t result = 0;
+    int i = 0;
+    while (sequence[i++]) {
+        result += sequence[i++];
+    }
+    return result;
+}
+
 void cb_watch_buzzer_seq(void) {
     // callback for reading the note sequence
     if (_tone_ticks == 0) {
index 7ba9a52ed0777a16f29780deca5926f9b235a44c..4c39475c2a87cb154012ee4050912c042f3e8574 100644 (file)
@@ -175,6 +175,8 @@ extern const uint16_t NotePeriods[108];
   */
 void watch_buzzer_play_sequence(int8_t *note_sequence, void (*callback_on_end)(void));
 
+uint16_t sequence_length(int8_t *sequence);
+
 /** @brief Aborts a playing sequence.
   */
 void watch_buzzer_abort_sequence(void);