comparison Discovery/Src/t7.c @ 805:dd7ce655db26

Adds a simple countdown timer, available as a custom view in surface and dive mode. This can be used to time safety stops, or to prebreathe a CCR (or to boil your breakfast eggs if you are so inclined). The duration of the timer is configurable from 1 second to 9:59 minutes in the System menu. The timer is started by switching to the custom view, and remaining on it until a 10 second delay has elapsed. Once the timer has started the custom view can be changed and the timer will continue running in the background. After the timer has run out 'Finished' will be shown for 10 seconds in the timer custom view, and then automatic switching of custom views (if configured) resumes. In surface mode the dive computer will not go to sleep while the timer is running, and a mini timer will be shown when the timer custom view is not showing. (mikeller)
author heinrichsweikamp
date Mon, 21 Aug 2023 17:20:07 +0200
parents 1e3c12d772eb
children 24b39a432bc2
comparison
equal deleted inserted replaced
804:391b3d420a39 805:dd7ce655db26
26 /// along with this program. If not, see <http://www.gnu.org/licenses/>. 26 /// along with this program. If not, see <http://www.gnu.org/licenses/>.
27 ////////////////////////////////////////////////////////////////////////////// 27 //////////////////////////////////////////////////////////////////////////////
28 28
29 /* Includes ------------------------------------------------------------------*/ 29 /* Includes ------------------------------------------------------------------*/
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <stdbool.h>
32 31
33 #include "t7.h" 32 #include "t7.h"
34 #include "t3.h" 33 #include "t3.h"
35 #include "settings.h" 34 #include "settings.h"
36 #include "data_exchange_main.h" 35 #include "data_exchange_main.h"
46 #include "motion.h" 45 #include "motion.h"
47 #include "configuration.h" 46 #include "configuration.h"
48 #include "base.h" 47 #include "base.h"
49 #include "tMenuEditSetpoint.h" 48 #include "tMenuEditSetpoint.h"
50 49
50 #define TIMER_ACTION_DELAY_S 10
51
51 /* Private function prototypes -----------------------------------------------*/ 52 /* Private function prototypes -----------------------------------------------*/
52 53
53 void t7_refresh_surface(void); 54 void t7_refresh_surface(void);
54 void t7_refresh_surface_debugmode(void); 55 void t7_refresh_surface_debugmode(void);
55 void t7_refresh_divemode(void); 56 void t7_refresh_divemode(void);
128 CVIEW_Profile, 129 CVIEW_Profile,
129 CVIEW_Gaslist, 130 CVIEW_Gaslist,
130 CVIEW_sensors_mV, 131 CVIEW_sensors_mV,
131 CVIEW_EADTime, 132 CVIEW_EADTime,
132 CVIEW_SummaryOfLeftCorner, 133 CVIEW_SummaryOfLeftCorner,
134 CVIEW_Timer,
133 CVIEW_noneOrDebug, 135 CVIEW_noneOrDebug,
134 CVIEW_END, 136 CVIEW_END,
135 CVIEW_END 137 CVIEW_END
136 }; 138 };
137 139
144 CVIEW_Tissues, 146 CVIEW_Tissues,
145 CVIEW_Gaslist, 147 CVIEW_Gaslist,
146 CVIEW_sensors_mV, 148 CVIEW_sensors_mV,
147 CVIEW_Charger, 149 CVIEW_Charger,
148 CVIEW_CcrSummary, 150 CVIEW_CcrSummary,
151 CVIEW_Timer,
149 CVIEW_END 152 CVIEW_END
150 }; 153 };
151 154
152 155
153 static uint8_t selection_custom_field = LLC_Temperature; 156 static uint8_t selection_custom_field = LLC_Temperature;
994 text[3] = '\016'; 997 text[3] = '\016';
995 text[4] = TXT_2BYTE; 998 text[4] = TXT_2BYTE;
996 text[5] = TXT2BYTE_TimeSinceLastDive; 999 text[5] = TXT2BYTE_TimeSinceLastDive;
997 text[6] = 0; 1000 text[6] = 0;
998 GFX_write_string(&FontT48,&t7surfaceR,text,1); 1001 GFX_write_string(&FontT48,&t7surfaceR,text,1);
1002 }
1003
1004 if (stateUsed->timerState == TIMER_STATE_RUNNING && selection_customview != CVIEW_Timer) {
1005 int timerRemainingS = pSettings->timerDurationS - (current_second() - stateUsed->timerStartedS);
1006 snprintf(text, 20, "\001%u:%02u", timerRemainingS / 60, timerRemainingS % 60);
1007 GFX_write_string(&FontT54, &t7surfaceR, text, 8);
999 } 1008 }
1000 1009
1001 /* beta version */ 1010 /* beta version */
1002 if( firmwareDataGetPointer()->versionBeta ) 1011 if( firmwareDataGetPointer()->versionBeta )
1003 { 1012 {
1971 1980
1972 GFX_write_string(&FontT42, &t7cY0free, data, 1); 1981 GFX_write_string(&FontT42, &t7cY0free, data, 1);
1973 } 1982 }
1974 1983
1975 1984
1985 static void setTimerPrestart(int startTimeS)
1986 {
1987 stateUsedWrite->timerState = TIMER_STATE_PRESTART;
1988 stateUsedWrite->timerStartedS = startTimeS;
1989 }
1990
1991
1992 static void setTimerFinished(int startTimeS)
1993 {
1994 stateUsedWrite->timerState = TIMER_STATE_FINISHED;
1995 stateUsedWrite->timerStartedS = startTimeS;
1996 }
1997
1998
1999 static void updateTimer(SSettings *settings, int nowS, bool switchedToTimerView)
2000 {
2001 int timerElapsedS = nowS - stateUsed->timerStartedS;
2002
2003 if (stateUsed->timerState && timerElapsedS < 0) {
2004 disableTimer();
2005 } else {
2006 switch (stateUsed->timerState) {
2007 case TIMER_STATE_OFF:
2008 if (switchedToTimerView) {
2009 setTimerPrestart(nowS);
2010 }
2011
2012 break;
2013 case TIMER_STATE_PRESTART:
2014 if (timerElapsedS <= TIMER_ACTION_DELAY_S) {
2015 if (switchedToTimerView) {
2016 setTimerPrestart(nowS);
2017 }
2018 } else {
2019 if (selection_customview == CVIEW_Timer) {
2020 stateUsedWrite->timerState = TIMER_STATE_RUNNING;
2021 stateUsedWrite->timerStartedS = stateUsed->timerStartedS + TIMER_ACTION_DELAY_S;
2022 } else {
2023 disableTimer();
2024 }
2025 }
2026
2027 break;
2028 case TIMER_STATE_RUNNING:
2029 if (timerElapsedS >= settings->timerDurationS) {
2030 if (selection_customview == CVIEW_Timer) {
2031 setTimerFinished(stateUsed->timerStartedS + settings->timerDurationS);
2032 } else {
2033 stateUsedWrite->timerState = TIMER_STATE_WAIT_FINISHED;
2034 }
2035 }
2036
2037 break;
2038 case TIMER_STATE_WAIT_FINISHED:
2039 if (switchedToTimerView) {
2040 setTimerFinished(nowS);
2041 }
2042
2043 break;
2044 case TIMER_STATE_FINISHED:
2045 if (timerElapsedS <= TIMER_ACTION_DELAY_S) {
2046 if (switchedToTimerView) {
2047 setTimerPrestart(stateUsed->timerStartedS);
2048 }
2049 } else {
2050 disableTimer();
2051 }
2052
2053 break;
2054 }
2055 }
2056 }
2057
2058
2059 bool t7_isTimerRunning(bool includeBackground)
2060 {
2061 return stateUsed->timerState && (selection_customview == CVIEW_Timer || (includeBackground && stateUsed->timerState == TIMER_STATE_RUNNING));
2062 }
2063
2064
2065 static void showTimer(SSettings *settings, int nowS)
2066 {
2067 char heading[32];
2068 unsigned headingIndex = 0;
2069
2070 char data[32];
2071 unsigned dataIndex = 0;
2072
2073 heading[headingIndex++] = '\032';
2074 heading[headingIndex++] = '\016';
2075 heading[headingIndex++] = '\016';
2076
2077 data[dataIndex++] = '\t';
2078
2079 int timerRemainingS = settings->timerDurationS;
2080 switch (stateUsed->timerState) {
2081 case TIMER_STATE_RUNNING:
2082 timerRemainingS = settings->timerDurationS - (nowS - stateUsed->timerStartedS);
2083
2084 break;
2085 case TIMER_STATE_PRESTART:
2086 case TIMER_STATE_FINISHED:
2087 if (stateUsed->timerState == TIMER_STATE_PRESTART) {
2088 heading[headingIndex++] = TXT_2BYTE;
2089 heading[headingIndex++] = TXT2BYTE_Starting;
2090 } else {
2091 heading[headingIndex++] = TXT_2BYTE;
2092 heading[headingIndex++] = TXT2BYTE_Finished;
2093
2094 timerRemainingS = 0;
2095 }
2096
2097 dataIndex += snprintf(&data[dataIndex], 10, "\020%u", TIMER_ACTION_DELAY_S - (nowS - stateUsed->timerStartedS));
2098
2099 break;
2100 default:
2101
2102 break;
2103 }
2104
2105 char timer[16];
2106 snprintf(timer, 10, "\001\020%u:%02u", timerRemainingS / 60, timerRemainingS % 60);
2107
2108 heading[headingIndex++] = 0;
2109
2110 data[dataIndex++] = 0;
2111
2112 t7cY0free.WindowLineSpacing = 48;
2113 t7cY0free.WindowNumberOfTextLines = 6;
2114 t7cY0free.WindowTab = 375;
2115
2116 t7cY0free.WindowY0 = t7cC.WindowY0 - 10;
2117 if (!settings->FlipDisplay) {
2118 t7cY0free.WindowX0 += 10;
2119 t7cY0free.WindowY0 += 10;
2120 t7cY0free.WindowY1 = 355;
2121 GFX_write_string(&FontT24, &t7cY0free, heading, 1);
2122 t7cY0free.WindowX0 -= 10;
2123 t7cY0free.WindowY0 -= 10;
2124 } else {
2125 t7cY0free.WindowY1 -= 10;
2126 t7cY0free.WindowX1 -= 10;
2127 GFX_write_string(&FontT24, &t7cY0free, heading, 1);
2128 t7cY0free.WindowY1 += 10;
2129 t7cY0free.WindowX1 += 10;
2130 }
2131
2132 t7_colorscheme_mod(data);
2133
2134 GFX_write_string(&FontT42, &t7cY0free, data, 1);
2135
2136 t7_colorscheme_mod(timer);
2137
2138 GFX_write_string(&FontT105, &t7cY0free, timer, 4);
2139 }
2140
2141
1976 void t7_refresh_customview(void) 2142 void t7_refresh_customview(void)
1977 { 2143 {
1978 static uint8_t last_customview = CVIEW_END; 2144 static uint8_t last_customview = CVIEW_END;
1979 2145
1980 char text[256]; 2146 char text[256];
2013 { 2179 {
2014 if(t7_customview_disabled(selection_customview)) 2180 if(t7_customview_disabled(selection_customview))
2015 { 2181 {
2016 t7_change_customview(ACTION_BUTTON_ENTER); 2182 t7_change_customview(ACTION_BUTTON_ENTER);
2017 } 2183 }
2018 last_customview = selection_customview;
2019 } 2184 }
2020 switch(selection_customview) 2185 switch(selection_customview)
2021 { 2186 {
2022 case CVIEW_noneOrDebug: 2187 case CVIEW_noneOrDebug:
2023 if(settingsGetPointer()->showDebugInfo) 2188 if(settingsGetPointer()->showDebugInfo)
2511 GFX_write_string(&FontT42, &t7cH, text, 0); 2676 GFX_write_string(&FontT42, &t7cH, text, 0);
2512 2677
2513 t7_CcrSummary(pSettings); 2678 t7_CcrSummary(pSettings);
2514 2679
2515 break; 2680 break;
2516 } 2681 case CVIEW_Timer:
2682 snprintf(text, 100, "\032\f\001%c%c", TXT_2BYTE, TXT2BYTE_Timer);
2683 GFX_write_string(&FontT42, &t7cH, text, 0);
2684
2685 int nowS = current_second();
2686
2687 updateTimer(pSettings, nowS, last_customview != CVIEW_Timer);
2688
2689 showTimer(pSettings, nowS);
2690
2691 break;
2692 }
2693
2694 last_customview = selection_customview;
2517 } 2695 }
2518
2519 2696
2520 2697
2521 /* DIVE MODE 2698 /* DIVE MODE
2522 */ 2699 */
2523 void t7_refresh_divemode(void) 2700 void t7_refresh_divemode(void)
4481 GFX_graph_print(&t7screen, &wintemp, 1,1,0, 10, getChargeLog(), 60, CLUT_Font031, NULL); 4658 GFX_graph_print(&t7screen, &wintemp, 1,1,0, 10, getChargeLog(), 60, CLUT_Font031, NULL);
4482 } 4659 }
4483 4660
4484 } 4661 }
4485 4662
4663
4486 bool t7_isCompassShowing(void) 4664 bool t7_isCompassShowing(void)
4487 { 4665 {
4488 return selection_customview == CVIEW_Compass || selection_custom_field == LLC_Compass; 4666 return selection_customview == CVIEW_Compass || selection_custom_field == LLC_Compass;
4489 } 4667 }
4668
4669
4670 void t7_tick(void)
4671 {
4672 SSettings *settings = settingsGetPointer();
4673
4674 int nowS = current_second();
4675 updateTimer(settings, nowS, false);
4676 }