]> git.earman.xyz Git - sensor-watch.git/commitdiff
slcd: add autonomous blinking and animation
authorJoey Castillo <jose.castillo@gmail.com>
Fri, 1 Oct 2021 21:09:05 +0000 (17:09 -0400)
committerJoey Castillo <jose.castillo@gmail.com>
Sat, 2 Oct 2021 00:53:32 +0000 (20:53 -0400)
watch-library/config/hpl_slcd_config.h
watch-library/watch/watch_slcd.c
watch-library/watch/watch_slcd.h

index 5e3b2ca266db66f15a83d165d7924a221b43af91..33b6a817998b950a9f0fd445ffe697adb78817ac 100644 (file)
@@ -80,7 +80,7 @@
 // <3=>128
 // <id> slcd_arch_presc
 #ifndef CONF_SLCD_PRESC
-#define CONF_SLCD_PRESC 2
+#define CONF_SLCD_PRESC 1
 #endif
 
 // <o> Clock Divider
@@ -95,7 +95,7 @@
 // <7=>8
 // <id> slcd_arch_ckdiv
 #ifndef CONF_SLCD_CKDIV
-#define CONF_SLCD_CKDIV 3
+#define CONF_SLCD_CKDIV 5
 #endif
 
 /* TODO add frame frequency check */
index ba9d12b25e6f04ffcacca6a89a771968c7b52fef..58e1da7ff5ab88f5bfae85ec11db8bb03bcee030 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "watch_slcd.h"
+#include "hpl_slcd_config.h"
 
  //////////////////////////////////////////////////////////////////////////////////////////
 // Segmented Display
@@ -149,6 +150,10 @@ static const uint32_t IndicatorSegments[6] = {
     SLCD_SEGID(1, 10), // WATCH_INDICATOR_LAP
 };
 
+void _sync_slcd() {
+    while (SLCD->SYNCBUSY.reg);
+}
+
 void watch_enable_display() {
     SEGMENT_LCD_0_init();
     slcd_sync_enable(&SEGMENT_LCD_0);
@@ -218,3 +223,47 @@ void watch_clear_all_indicators() {
     slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(0, 16));
     slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(1, 10));
 }
+
+void watch_start_character_blink(char character, uint32_t duration) {
+    SLCD->CTRLD.bit.FC0EN = 0;
+    _sync_slcd();
+
+    if (duration <= SLCD_FC_BYPASS_MAX_MS) {
+        SLCD->FC0.reg = SLCD_FC0_PB | ((duration / (1000 / SLCD_FRAME_FREQUENCY)) - 1);
+    } else {
+        SLCD->FC0.reg = (((duration / (1000 / SLCD_FRAME_FREQUENCY)) / 8 - 1));
+    }
+    SLCD->CTRLD.bit.FC0EN = 1;
+
+    watch_display_character(character, 7);
+    watch_clear_pixel(2, 10); // clear segment B of position 7 since it can't blink
+
+    SLCD->CTRLD.bit.BLINK = 0;
+    SLCD->CTRLA.bit.ENABLE = 0;
+    _sync_slcd();
+
+    SLCD->BCFG.bit.BSS0 = 0x07;
+    SLCD->BCFG.bit.BSS1 = 0x07;
+
+    SLCD->CTRLD.bit.BLINK = 1;
+    _sync_slcd();
+    SLCD->CTRLA.bit.ENABLE = 1;
+    _sync_slcd();
+}
+
+void watch_stop_blink() {
+    SLCD->CTRLD.bit.FC0EN = 0;
+    SLCD->CTRLD.bit.BLINK = 0;
+}
+
+void watch_start_tick_animation(uint32_t duration) {
+    watch_display_character(' ', 8);
+    const uint32_t segs[] = { SLCD_SEGID(0, 2)};
+    slcd_sync_start_animation(&SEGMENT_LCD_0, segs, 1, duration);
+}
+
+void watch_stop_tick_animation() {
+    const uint32_t segs[] = { SLCD_SEGID(0, 2)};
+    slcd_sync_stop_animation(&SEGMENT_LCD_0, segs, 1);
+    watch_display_character(' ', 8);
+}
index 4f5a617c072a7806351c26e583210e2f8c7f2060..4e7109363b22979fa67d262ae61689ca480b91f8 100644 (file)
@@ -103,5 +103,40 @@ void watch_clear_indicator(WatchIndicatorSegment indicator);
   */
 void watch_clear_all_indicators();
 
+/** @brief Blinks a single character in position 7. Does not affect other positions.
+  * @details Six of the seven segments in position 7 (and only position 7) are capable of autonomous
+  *          blinking. This blinking does not require any CPU resources, and will continue even in
+  *          standby and shallow sleep mode (if the LCD remains on).
+  * @param character The character you wish to blink.
+  * @param duration The duration of the on/off cycle in milliseconds, from 50 to ~4250 ms.
+  * @note Segment B of position 7 cannot blink autonomously, so not all characters will work well.
+  *       Supported characters for blinking:
+  *        * Punctuation: underscore, apostrophe, comma, hyphen, equals sign, tilde (top segment only)
+  *        * Numbers: 5, 6, ampersand (lowercase 7)
+  *        * Letters: b, C, c, E, F, h, i, L, l, n, o, S, t
+  */
+void watch_start_character_blink(char character, uint32_t duration);
+
+/** @brief Stops and clears all blinking segments.
+  * @details This will stop all blinking in position 7, and clear all segments in that digit.
+  */
+void watch_stop_blink();
+
+/** @brief Begins a two-segment "tick-tock" animation in position 8.
+  * @details Six of the seven segments in position 8 (and only position 8) are capable of autonomous
+  *          animation. This animation is very basic, and consists of moving a bit pattern forward
+  *          or backward in a shift register whose positions map to fixed segments on the LCD. Given
+  *          this constraint, an animation across all six segments does not make sense; so the watch
+  *          library offers only a simple "tick/tock" in segments D and E. This animation does not
+  *          require any CPU resources, and will continue even in standby and shallow sleep mode
+  *          (if the LCD remains on).
+  * @param duration The duration of each frame in ms. 500 milliseconds produces a classic tick/tock.
+  */
+void watch_start_tick_animation(uint32_t duration);
+
+/** @brief Stops the tick/tock animation and clears all animating segments.
+  * @details This will stop the animation and clear all segments in position 8.
+  */
+void watch_stop_tick_animation();
 /// @}
 #endif