summaryrefslogtreecommitdiffstats
path: root/watch-library
diff options
context:
space:
mode:
authorMikhail Svarichevsky <3@14.by>2023-01-11 00:56:26 +0300
committerGitHub <noreply@github.com>2023-01-10 16:56:26 -0500
commit6b71711079bd35cab61356e7b47c27445fd5eee5 (patch)
treea090a8d78d2e08db52e2b7640babfea448665fd6 /watch-library
parentfee6145e4d79a0d67d7e390692152bfdf94676a3 (diff)
downloadSensor-Watch-6b71711079bd35cab61356e7b47c27445fd5eee5.tar.gz
Sensor-Watch-6b71711079bd35cab61356e7b47c27445fd5eee5.tar.bz2
Sensor-Watch-6b71711079bd35cab61356e7b47c27445fd5eee5.zip
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 <neutral@fastmail.com> Co-authored-by: joeycastillo <joeycastillo@utexas.edu>
Diffstat (limited to 'watch-library')
-rw-r--r--watch-library/hardware/watch/watch_rtc.c27
-rw-r--r--watch-library/shared/watch/watch_private_display.c34
-rw-r--r--watch-library/shared/watch/watch_private_display.h2
-rw-r--r--watch-library/shared/watch/watch_rtc.h10
-rw-r--r--watch-library/simulator/watch/watch_rtc.c10
5 files changed, 80 insertions, 3 deletions
diff --git a/watch-library/hardware/watch/watch_rtc.c b/watch-library/hardware/watch/watch_rtc.c
index 8382e571..881e2575 100644
--- a/watch-library/hardware/watch/watch_rtc.c
+++ b/watch-library/hardware/watch/watch_rtc.c
@@ -57,6 +57,7 @@ void _watch_rtc_init(void) {
}
void watch_rtc_set_date_time(watch_date_time date_time) {
+ _sync_rtc(); // Double sync as without it at high Hz faces setting time is unrealiable (specifically, set_time_hackwatch)
RTC->MODE2.CLOCK.reg = date_time.reg;
_sync_rtc();
}
@@ -137,7 +138,7 @@ void RTC_Handler(void) {
tick_callbacks[i]();
}
RTC->MODE2.INTFLAG.reg = 1 << i;
- break;
+// break; Uncertain if this fix is requried. We were discussing in discord. Might slightly increase power consumption.
}
}
} else if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_TAMPER) {
@@ -160,3 +161,27 @@ void RTC_Handler(void) {
RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM0;
}
}
+
+void watch_rtc_enable(bool en)
+{
+ // Writing it twice - as it's quite dangerous operation.
+ // If write fails - we might hang with RTC off, which means no recovery possible
+ while (RTC->MODE2.SYNCBUSY.reg);
+ RTC->MODE2.CTRLA.bit.ENABLE = en ? 1 : 0;
+ while (RTC->MODE2.SYNCBUSY.reg);
+ RTC->MODE2.CTRLA.bit.ENABLE = en ? 1 : 0;
+ while (RTC->MODE2.SYNCBUSY.reg);
+}
+
+void watch_rtc_freqcorr_write(int16_t value, int16_t sign)
+{
+ RTC_FREQCORR_Type data;
+
+ data.bit.VALUE = value;
+ data.bit.SIGN = sign;
+
+ RTC->MODE2.FREQCORR.reg = data.reg; // Setting correction in single write operation
+
+ // We do not sycnronize. We are not in a hurry
+}
+
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
diff --git a/watch-library/simulator/watch/watch_rtc.c b/watch-library/simulator/watch/watch_rtc.c
index 107ae56c..fa80d6b4 100644
--- a/watch-library/simulator/watch/watch_rtc.c
+++ b/watch-library/simulator/watch/watch_rtc.c
@@ -197,3 +197,13 @@ void watch_rtc_disable_alarm_callback(void) {
alarm_interval_id = -1;
}
}
+
+void watch_rtc_enable(bool en)
+{
+ //Not simulated
+}
+
+void watch_rtc_freqcorr_write(int16_t value, int16_t sign)
+{
+ //Not simulated
+}