diff options
| author | Joey Castillo <jose.castillo@gmail.com> | 2021-10-01 17:09:05 -0400 | 
|---|---|---|
| committer | Joey Castillo <jose.castillo@gmail.com> | 2021-10-01 20:53:32 -0400 | 
| commit | 84c0fbfa2a68dc3c29b989947567d111e70a037b (patch) | |
| tree | fa68060b8a32b0450d58b50b571f0700c8280354 | |
| parent | 15ae7ab84b13953ec309a5823ade6ddb60f6a68c (diff) | |
| download | Sensor-Watch-84c0fbfa2a68dc3c29b989947567d111e70a037b.tar.gz Sensor-Watch-84c0fbfa2a68dc3c29b989947567d111e70a037b.tar.bz2 Sensor-Watch-84c0fbfa2a68dc3c29b989947567d111e70a037b.zip | |
slcd: add autonomous blinking and animation
| -rw-r--r-- | watch-library/config/hpl_slcd_config.h | 4 | ||||
| -rw-r--r-- | watch-library/watch/watch_slcd.c | 49 | ||||
| -rw-r--r-- | watch-library/watch/watch_slcd.h | 35 | 
3 files changed, 86 insertions, 2 deletions
| diff --git a/watch-library/config/hpl_slcd_config.h b/watch-library/config/hpl_slcd_config.h index 5e3b2ca2..33b6a817 100644 --- a/watch-library/config/hpl_slcd_config.h +++ b/watch-library/config/hpl_slcd_config.h @@ -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 */ diff --git a/watch-library/watch/watch_slcd.c b/watch-library/watch/watch_slcd.c index ba9d12b2..58e1da7f 100644 --- a/watch-library/watch/watch_slcd.c +++ b/watch-library/watch/watch_slcd.c @@ -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); +} diff --git a/watch-library/watch/watch_slcd.h b/watch-library/watch/watch_slcd.h index 4f5a617c..4e710936 100644 --- a/watch-library/watch/watch_slcd.h +++ b/watch-library/watch/watch_slcd.h @@ -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 | 
