]> git.earman.xyz Git - sensor-watch.git/commitdiff
add buzzer volume control
authorjoeycastillo <joeycastillo@utexas.edu>
Sun, 22 Sep 2024 17:34:46 +0000 (13:34 -0400)
committerjoeycastillo <joeycastillo@utexas.edu>
Sun, 22 Sep 2024 17:34:46 +0000 (13:34 -0400)
movement/watch_faces/complication/activity_face.c
movement/watch_faces/complication/tuning_tones_face.c
movement/watch_faces/demo/chirpy_demo_face.c
watch-library/hardware/watch/watch_tcc.c
watch-library/shared/watch/watch_tcc.h
watch-library/simulator/watch/watch_tcc.c

index f92984cd9f6f29ca6eb64db5970fa30c534aa266..136352f78f2aeb536352db48b9cd6b9cbcf68cb6 100644 (file)
@@ -334,7 +334,7 @@ static void _activity_chirp_tick_transmit(void *context) {
         return;
     }
     uint16_t period = chirpy_get_tone_period(tone);
-    watch_set_buzzer_period(period);
+    watch_set_buzzer_period_and_duty_cycle(period, 25);
     watch_set_buzzer_on();
 }
 
@@ -351,7 +351,7 @@ static void _activity_chirp_tick_countdown(void *context) {
     }
     // Sound or turn off buzzer
     if ((state->chirpy_tick_state.seq_pos % 8) == 0) {
-        watch_set_buzzer_period(NotePeriods[BUZZER_NOTE_A5]);
+        watch_set_buzzer_period_and_duty_cycle(NotePeriods[BUZZER_NOTE_A5], 25);
         watch_set_buzzer_on();
         if (state->chirpy_tick_state.seq_pos == 0) {
             watch_display_string(" ---  ", 4);
index a139427a830061500e75d7ae4d0c63cc1fe5e3d4..a12c076a49a57923ff5fece4485b72a42393ffaf 100644 (file)
@@ -84,7 +84,7 @@ static void update_buzzer(const tuning_tones_state_t *state)
 {
     if (state->playing) {
         watch_set_buzzer_off();
-        watch_set_buzzer_period(NotePeriods[notes[state->note_ind].note]);
+        watch_set_buzzer_period_and_duty_cycle(NotePeriods[notes[state->note_ind].note], 25);
         watch_set_buzzer_on();
     }
 }
index ee3e5b419e7f57dc1ca54a2b61f182ebfd80f1a0..5c6990187312f17e8ec3e7021e78634942031d2b 100644 (file)
@@ -168,7 +168,7 @@ static void _cdf_scale_tick(void *context) {
     }
     uint32_t freq = 700 + tick_state->seq_pos * 200;
     uint32_t period = 1000000 / freq;
-    watch_set_buzzer_period(period);
+    watch_set_buzzer_period_and_duty_cycle(period, 25);
     watch_set_buzzer_on();
     ++tick_state->seq_pos;
 }
@@ -183,7 +183,7 @@ static void _cdf_data_tick(void *context) {
         return;
     }
     uint16_t period = chirpy_get_tone_period(tone);
-    watch_set_buzzer_period(period);
+    watch_set_buzzer_period_and_duty_cycle(period, 25);
     watch_set_buzzer_on();
 }
 
@@ -234,7 +234,7 @@ static void _cdf_countdown_tick(void *context) {
     }
     // Sound or turn off buzzer
     if ((tick_state->seq_pos % 8) == 0) {
-        watch_set_buzzer_period(NotePeriods[BUZZER_NOTE_A5]);
+        watch_set_buzzer_period_and_duty_cycle(NotePeriods[BUZZER_NOTE_A5], 25);
         watch_set_buzzer_on();
     } else if ((tick_state->seq_pos % 8) == 1) {
         watch_set_buzzer_off();
index efee7a98fe157671c894012f0616042b4eef1611..41f8f933aeafa144ade65f722f0b62ff936bbc73 100644 (file)
@@ -110,7 +110,7 @@ void cb_watch_buzzer_seq(void) {
             // read note
             BuzzerNote note = _sequence[_seq_position];
             if (note != BUZZER_NOTE_REST) {
-                watch_set_buzzer_period(NotePeriods[note]);
+                watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
                 watch_set_buzzer_on();
             } else watch_set_buzzer_off();
             // set duration ticks and move to next tone
@@ -148,9 +148,9 @@ inline void watch_enable_buzzer(void) {
     }
 }
 
-inline void watch_set_buzzer_period(uint32_t period) {
+void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty) {
     tcc_set_period(0, period, true);
-    tcc_set_cc(0, (WATCH_BUZZER_TCC_CHANNEL) % 4, period / 2, true);
+    tcc_set_cc(0, (WATCH_BUZZER_TCC_CHANNEL) % 4, period / (100 / duty), true);
 }
 
 void watch_disable_buzzer(void) {
@@ -168,10 +168,14 @@ inline void watch_set_buzzer_off(void) {
 }
 
 void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
+    watch_buzzer_play_note_with_volume(note, duration_ms, WATCH_BUZZER_VOLUME_LOUD);
+}
+
+void watch_buzzer_play_note_with_volume(BuzzerNote note, uint16_t duration_ms, watch_buzzer_volume_t volume) {
     if (note == BUZZER_NOTE_REST) {
         watch_set_buzzer_off();
-    } else {
-        watch_set_buzzer_period(NotePeriods[note]);
+    } else  {
+        watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], volume == WATCH_BUZZER_VOLUME_SOFT ? 5 : 25);
         watch_set_buzzer_on();
     }
     delay_ms(duration_ms);
index 6f965b66fa8e5fac01062b732c54ccf565c83187..7967637d3b948002c4ce80209112e573c79a9bc6 100644 (file)
@@ -36,7 +36,8 @@
 bool watch_is_buzzer_or_led_enabled(void);
 
 /** @addtogroup tcc Buzzer and LED Control (via the TCC peripheral)
-  * @brief This section covers functions related to the piezo buzzer embedded in the F-91W's back plate.
+  * @brief This section covers functions related to Timer Counter for Control peripheral, which drives the piezo buzzer
+  *        embedded in the F-91W's back plate as well as the LED that backlights the display.
   */
 /// @{
 /** @brief Enables the TCC peripheral, which drives the buzzer.
@@ -46,8 +47,11 @@ void watch_enable_buzzer(void);
 /** @brief Sets the period of the buzzer.
   * @param period The period of a single cycle for the TCC peripheral. You can determine the period for
   *               a desired frequency with the following formula: period = 1000000 / freq
+  * @param duty The duty cycle of the buzzer, from 0 to 50 (percent ON time). Do not use values over 50.
+  * @note Unless you _really_ know what you're doing, use 25% for the duty cycle. If you're just aiming
+  *       to play a tone at a given volume, use watch_buzzer_play_note_with_volume instead.
   */
-void watch_set_buzzer_period(uint32_t period);
+void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty);
 
 /** @brief Disables the TCC peripheral that drives the buzzer.
   * @note If you are using PWM to set custom LED colors, this method will also disable the LED PWM driver,
@@ -65,6 +69,12 @@ void watch_set_buzzer_on(void);
   */
 void watch_set_buzzer_off(void);
 
+/// @brief An enum for controlling the volume of the buzzer.
+typedef enum {
+    WATCH_BUZZER_VOLUME_SOFT = 0,
+    WATCH_BUZZER_VOLUME_LOUD
+} watch_buzzer_volume_t;
+
 /// @brief 87 notes for use with watch_buzzer_play_note
 typedef enum BuzzerNote {
     BUZZER_NOTE_A1,              ///< 55.00 Hz
@@ -157,7 +167,7 @@ typedef enum BuzzerNote {
     BUZZER_NOTE_REST             ///< no sound
 } BuzzerNote;
 
-/** @brief Plays the given note for a set duration.
+/** @brief Plays the given note for a set duration at the loudest possible volume.
   * @param note The note you wish to play, or BUZZER_NOTE_REST to disable output for the given duration.
   * @param duration_ms The duration of the note.
   * @note Note that this will block your UI for the duration of the note's play time, and it will
@@ -165,6 +175,15 @@ typedef enum BuzzerNote {
   */
 void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms);
 
+/** @brief Plays the given note for a set duration.
+  * @param note The note you wish to play, or BUZZER_NOTE_REST to disable output for the given duration.
+  * @param duration_ms The duration of the note.
+  * @param volume either WATCH_BUZZER_VOLUME_SOFT or WATCH_BUZZER_VOLUME_LOUD
+  * @note This will block your UI for the duration of the note's play time, and after this call, the
+  *       buzzer will stop sounding, but the TCC period will remain set to the period of this note.
+  */
+void watch_buzzer_play_note_with_volume(BuzzerNote note, uint16_t duration_ms, watch_buzzer_volume_t volume);
+
 /// @brief An array of periods for all the notes on a piano, corresponding to the names in BuzzerNote.
 extern const uint16_t NotePeriods[108];
 
index 77c06401a83180364114a2f17125ee5247abaff0..fa1e1a8c9680d787d7c1473850a7d4c9d59fa0ed 100644 (file)
@@ -89,7 +89,7 @@ void cb_watch_buzzer_seq(void *userData) {
             if (note == BUZZER_NOTE_REST) {
                 watch_set_buzzer_off();
             } else {
-                watch_set_buzzer_period(NotePeriods[note]);
+                watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
                 watch_set_buzzer_on();
             }
             // set duration ticks and move to next tone
@@ -118,7 +118,8 @@ void watch_enable_buzzer(void) {
     });
 }
 
-void watch_set_buzzer_period(uint32_t period) {
+void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty_cycle) {
+    (void) duty_cycle;
     if (!buzzer_enabled) return;
     buzzer_period = period;
 }
@@ -174,7 +175,7 @@ void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
     if (note == BUZZER_NOTE_REST) {
         watch_set_buzzer_off();
     } else {
-        watch_set_buzzer_period(NotePeriods[note]);
+        watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
         watch_set_buzzer_on();
     }