From 6b71711079bd35cab61356e7b47c27445fd5eee5 Mon Sep 17 00:00:00 2001 From: Mikhail Svarichevsky <3@14.by> Date: Wed, 11 Jan 2023 00:56:26 +0300 Subject: Precision watch update (#152) * Intermediate changes * Databank working * Main commit for precision timing First version where all functions are supposed to be working * Fix math error in nanosec. File storage for location. * Remove obsolete comments * Missing page name on pages rotation - thanks to jeremy * Delete file.diff * Cleanup+tempchart 1) finetune must always reset last calibration time when doing non-0 time correction, even when you are not applying ppm correction. 2) Dithers over 31 periods not 10, more resolution with still no risk of overflow 3) Minute-boundery finetune fix. I also just got this 1-minute error after finetune... 4) Write frequency calibration value in 1 operation rather than 2. All RTC writes must be single operations to avoid partially correct data. 5) Some code cleanup 6) Tempchart face is added for temperature statistics * Update set_time_hackwatch_face.c * Math error in display code of finetune, allow to update correction time even without correction - by long alarm press * Increase reliability of stopping & starting RTC timer As it's quite dangerous operation * hackwatch - days adjust down fix by long alarm * unify style * More comments & last style change * Simulator support RTC operations (watch_rtc_enable and watch_rtc_freqcorr_write) are in common libs. * Unicode fix * Crystal aging is now adjustable (AA page in nanosec - annual aging, ppm/year) Aging is baked into fixed offset every time finetune is performed, as it relies on last adjustment time. * Blink on non-0 page every minute in finetune to measure clock error * Rolling back private changes * Cleanup * Cleanup * Quality of life changes in nanosec 1. Does not calculate & apply ppm correction if less than 6 hours passed since previous adjustment (as it gives very high correction values which are unrealistic and unhelpful) 2. Idle timeout resets to face 0 only if no correction was made * unify style * Fix low-power errors in nanosec infrastructure, faster display in finetune * Merge fix * unify style Co-authored-by: Jeremy O'Brien Co-authored-by: joeycastillo --- watch-library/shared/watch/watch_private_display.c | 34 ++++++++++++++++++++-- watch-library/shared/watch/watch_private_display.h | 2 ++ watch-library/shared/watch/watch_rtc.h | 10 +++++++ 3 files changed, 44 insertions(+), 2 deletions(-) (limited to 'watch-library/shared/watch') diff --git a/watch-library/shared/watch/watch_private_display.c b/watch-library/shared/watch/watch_private_display.c index 474e5ffd..245b20ed 100644 --- a/watch-library/shared/watch/watch_private_display.c +++ b/watch-library/shared/watch/watch_private_display.c @@ -82,8 +82,12 @@ void watch_display_character(uint8_t character, uint8_t position) { continue; } uint8_t seg = segmap & 0x3F; - watch_clear_pixel(com, seg); - if (segdata & 1) watch_set_pixel(com, seg); + + if (segdata & 1) + watch_set_pixel(com, seg); + else + watch_clear_pixel(com, seg); + segmap = segmap >> 8; segdata = segdata >> 1; } @@ -93,6 +97,32 @@ void watch_display_character(uint8_t character, uint8_t position) { else if (position == 1 && (character == 'B' || character == 'D' || character == '@')) watch_set_pixel(0, 12); // add funky ninth segment } +void watch_display_character_lp_seconds(uint8_t character, uint8_t position) { + // Will only work for digits and for positions 8 and 9 - but less code & checks to reduce power consumption + + uint64_t segmap = Segment_Map[position]; + uint64_t segdata = Character_Set[character - 0x20]; + + for (int i = 0; i < 8; i++) { + uint8_t com = (segmap & 0xFF) >> 6; + if (com > 2) { + // COM3 means no segment exists; skip it. + segmap = segmap >> 8; + segdata = segdata >> 1; + continue; + } + uint8_t seg = segmap & 0x3F; + + if (segdata & 1) + watch_set_pixel(com, seg); + else + watch_clear_pixel(com, seg); + + segmap = segmap >> 8; + segdata = segdata >> 1; + } +} + void watch_display_string(char *string, uint8_t position) { size_t i = 0; while(string[i] != 0) { diff --git a/watch-library/shared/watch/watch_private_display.h b/watch-library/shared/watch/watch_private_display.h index 11219cf1..606b8dc3 100644 --- a/watch-library/shared/watch/watch_private_display.h +++ b/watch-library/shared/watch/watch_private_display.h @@ -142,5 +142,7 @@ static const uint64_t Segment_Map[] = { static const uint8_t Num_Chars = 10; void watch_display_character(uint8_t character, uint8_t position); +void watch_display_character_lp_seconds(uint8_t character, uint8_t position); + #endif diff --git a/watch-library/shared/watch/watch_rtc.h b/watch-library/shared/watch/watch_rtc.h index 6609e6b6..3e63bb55 100644 --- a/watch-library/shared/watch/watch_rtc.h +++ b/watch-library/shared/watch/watch_rtc.h @@ -147,5 +147,15 @@ void watch_rtc_disable_matching_periodic_callbacks(uint8_t mask); */ void watch_rtc_disable_all_periodic_callbacks(void); +/** @brief Enable/disable RTC while in-flight. This is quite dangerous operation, so we repeat writing register twice. + * Used when temporarily pausing RTC when adjusting subsecond, which are not accessible otherwise. + */ +void watch_rtc_enable(bool en); + +/** @brief Adjusts frequency correction in single register write. Not waiting for syncronisation to save power - if you won't write new + * correction value in the same ~millisecond - will not cause issue. + */ +void watch_rtc_freqcorr_write(int16_t value, int16_t sign); + /// @} #endif -- cgit v1.2.3