From 8f11ccce56ca1b4897852eaf06398a17f0463f13 Mon Sep 17 00:00:00 2001 From: Lephe Date: Fri, 17 Jul 2020 20:07:58 +0200 Subject: [PATCH] RTC tests using a small clock application --- assets-cg/img/rtc_arrows.png | Bin 0 -> 147 bytes assets-cg/img/rtc_segments.png | Bin 0 -> 641 bytes assets-fx/img/opt_gint_rtc.png | Bin 0 -> 13327 bytes assets-fx/img/rtc_arrows.png | Bin 0 -> 147 bytes assets-fx/img/rtc_segments.png | Bin 0 -> 4685 bytes include/gintctl/gint.h | 3 + src/gint/rtc.c | 572 +++++++++++++++++++++++++++++++++ src/gintctl.c | 2 +- 8 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 assets-cg/img/rtc_arrows.png create mode 100644 assets-cg/img/rtc_segments.png create mode 100644 assets-fx/img/opt_gint_rtc.png create mode 100644 assets-fx/img/rtc_arrows.png create mode 100644 assets-fx/img/rtc_segments.png create mode 100644 src/gint/rtc.c diff --git a/assets-cg/img/rtc_arrows.png b/assets-cg/img/rtc_arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..b0a8360beee3d3439732e393383577fe183db70a GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^{6NgY!2~4l6@R)1q&N#aB8wRqxP?KOkzv*x37{Z* ziKnkC`xABnZZpL!39&+;kddd0V+hCfu5e)(oq{I9Ej&=MgL{kAsgjr5FucKzY{ zfu^0&Z>j&xrs4WG`(IA~jf6Kg*=y+;34f}7)V|sJy?o<;qs}q`crFqSNH_oq2O!}9 zBpg5lA1nZ>v-6{JXE^YXcuzn5Mva66?%@C=9Kij&-o3Z?aNo26j|#an9PpM7K*9l( zNqF{*j=Y=3GxP_ak<#73KkonK<-t=~LI&1c)^DG5H_vnUfR}Ij+xovY9bbR{iHtv~ za_diQ{av2#@fjXyZpVWnWYS$1{g4rN_vjxsUxt2m{}l57LcW$Me-dE$XK==gL&r&g z)%B}S^1P@1Uj8hB$?W)e8XwZhg^l`${*=(q2+5&-_VE)~f5+$hBOlw_LZNtXZ#%<& zpLEiny84a&SMQ%ep6{<`IDkhY;edn#kZ=H_;cv@;@|fZTJU`x(DNcZUH~ju&Tzn6Isgd=AmIQc9Dsxac#C;m*Y;s_m&e4tSL-kOQT3m%p_V_{_3NMW_22K$ zvXw~ct#)?wL+Ve8_Xz%E*ROy2`hReSH*SC7B+UDS&a0n4{Hf?qng588UBIvt?fJu> bmgWBd{&jyzl){X%00000NkvXXu0mjfX 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 literal 0 HcmV?d00001 diff --git a/assets-fx/img/rtc_arrows.png b/assets-fx/img/rtc_arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..b0a8360beee3d3439732e393383577fe183db70a GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^{6NgY!2~4l6@R)1q&N#aB8wRqxP?KOkzv*x37{Z* ziKnkC`xABnZZpL!39&+;kddd0V+hCf zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3&sawIu&h5yGXbObmY>v6D}=>|H!z8Ar&?w%QG zT4rK)SCYxh2*CYq4nF6<{_{Tn!B+|%o|J1Vy_CRL>Z!-UH!b|}b$*_|*DR#>-(O$$ z^RGRB{zXhbzmB}(Jp1=!{q?&4y#DJ#<@Yle`WL^j{0|@S-}jGyzHuGDZyf)!B0u4V zKYz79{=av(d(XGKkqTuf-=@A>Jiji(8z)ur_hW@e<^Rn0^?h_6EsU@%g&kIyJeGBf z=HXhh{n)T;$2QN)7HdrL#L9DwEBgCd^BQ|x9^5?XVK-LqzP)+$6_2~8$K&s{*n8jp z-fvms&f9ovG%jX*x6F+VjxfJV%xr&P%U=LE@5?-Y__DgywfLeWaqrAx%xOU==Glsc8e=s} z9vclBtUP*(lMYzUakI#n+zY*F;D~$knQHHQV~*eJP=)?vFJ9?Q_d&B#%HXG_28KrV zoN~@3*W7Z?<0)QJ$)%K9#JN$urkZQ1wYJ*pXx>uGt+d)&>uvPd9ZKe2dhMA^e3m~r|{GtV;XY_rd?fX_-Rud?cDtFN)+_MLX#W!K$y-{aT;O3z6rpK|JH zr=M}b+Vz`mzU9{2ZolJq*M7SCPmljY*X*Zj@$Hn}SATbnS8LUU-bs$OgoqN=} z|A)@S=lDPL?O$|lO9|K8v5$qSX>iy#^09L1M}ICi+FWe2Ro0rO?R?f=m_n_HS*Av; zx$UvmZ1Ad#A<-Or-P=l;Fy)?Bo-oh7^TwY2o^@QcEBjd6l&zmVN*j?qwp3d_sjV?q zo3mQak!q}KE7zGeII7+5ihJHX``*&$F6U6j z+y}5capkrwPBsJjP*9=1`_g*Ci7mKF^4z+->{wUb^f6Gz3WTUFe5+Y?S>|Bp1j-Ts zBK4dt{-tAT*zd9lW01o&x%T?u8R4vV?#ZLo-YRp1&<~ZwFo(mk&=J3#DXl2iOnF2|Lna zcQH>-)S|c5QbEAe?7`-+=sV8M{ev%OYt~speRQW`Ylr7f1jOyQMxv1cTe>wi9nnJa4C}=C$2*X51;RZJ50p2eb$#Yf_mi>AjuPJQ?*JSLMS|8PlEUj zyUczB)v*eFxMM=vGHx}huv?>ZVa=IFUx5BusZ`=i1{y}!L1kS9NW+mx!SAGVeP9A5 z=DZrxduv#C=0a>@U1ZK#SQ*7$mwt}P=aY8S0Xfml*%~}A;9TW^9K9FEi5+=NK*UjG zLudM#s^tUdV0^7F;{$vjTTo0s`Dlf*l%8!9^yrvD@zqX3EBG$|nJCZ4l#eK=WCI=W zymh#>bG}%`D@Sv7ZR&DBsBjAD;m zX4u$WwSsm`zM-OlvO3%X#jP)5jXNI?AM{?d-}@J+kITEIz*YUk6cZ{^w&&#|uZ3A+ zGxngNIF~H1L?v^d0z-MhfR&a?j@_UPnvf}TK>GG*REg|s+8LclyWeLnX=|c{R4v?W z+Xr{!j;JB!lhT&y<1CtnD~FPAI&thQ77&0PZQpx5o~E-rh)6|jOt%u+w1_~N??6*< zd3INPL^KU^Eah6My~7=#FnYp+_jzErVgv9psLM0Hge#GY^GjLud?LkS@c8P8@(~m1 zTG|yb^$rsewty6qvk~A3WBLj&M2cS&U}fBvN`y=SF1sOg*0wSHPD%kR4htWu;elaeIMWqut=Z)Got4c<{;dln4sT=F;5-59~;u- zN-xpl0nEA}Hg@6L)LbstIG)W#8Vu0Z-ij{3=>AshC# zp_fl;^agfdi2?&0Ac)u0fg~l=jVA4M&U~FwGMkR$JJz@%m`1^TX6+jYz=nrxMYGv9 zS#oBD2vea^8g+G-;B24o?ziJuW|L#H-?lZdXqA9TG^pBv~AT$j6vlf^8zRE zuU1m8iA2*g(FY40r(U)OtO-l@MkKfsi7D9iRG>MrW0C`PP_9H`h$%_2q-Li2Km~E} z3CPfnhuDINCk;O$;1-AAf)iM}GKs$w9;e;+88uU4)+=N{fXGk71xSL1dpO)tDZg%} z6-;peVtzxakG;i(@f?PufNgNcf?}Nh-Lr!!Tq5CXR2bjL#1rjXqY`-&H5}joVUcr| zX-o?EAfmKMgHm*fDtdu$V9?z9DTX}m!-pvVk?BxlL$`1Miexz4%6Jvlx8L};?`DF6 zW87W?j+FGCxu5v1gggUG3IfF*NWNR)ABjZkV+Wu#QR`irK0jEJvmnMYB+;w6aZGl83}3R z!bsbxHM=KqSx|K0CSQ$oU)3o7)JW%CR{^_do+9g!KWcY!Y>JEq#8iB5C|9g|lz55^ zrzy2X=E?`dX9B%2=YQPTRf2m{HOs#lB{xm3vU)s$Fm`a+#|OfLVlZZpk&d!@w-}HO z+Of!d#!u^HT!q1lMj&ILN@-xXB%z=LDCHxYOQ^9tmFN?3H*DERs|)f}bQ8WaCk%xX z@{QIRnI(?Fon1v8AZqy`BfitjtQvc8YQV-&V&g;lC0kPr!Z=ih57}^Y5QP$u>MmpB zTz$`lX6ww5rZMcgLf_RykIT?MybS;|3n&r-^UamCo_GsCDqsNNm&zeaYAGvuf?@#d zbYP%uG7{u2pdV#S8#=IX6oQl$?gSgd&^0yuAn0U%aAx!I z9-C0FFrP@SKZT?+ba+E}V|tYypc4V~r_S!GB(q?A%S!x5W@c8qvN&x;X zpJLF#JSD=5I2W03Zjd#Ub5(TIr%RDFe{Z1s9$X9ub`%?ULwzY;$k;yvMA1ci%wUxz zfFbTe2cgiwpR+cKHe97FO+H>(Ykrt~$>A^oz&X(fMa69{rkX*7Vcj)fMicS@oODg&7@ixf!Cx`?cFF>h1Pk?tauSqunq|%k| z=Y!Z{Yd;zGn*qoRqG_WzE6OLyT$!9k`A8T`GPrkXM0=#-pw}4W76*dH83i$*-=umqPjzQEWm4UR{X?UNFxreBw z*^uzC-m@=iz4x<=oK@$6?_SvnaWB1-uZ9d}F?>iz3!v5S8?o-eM=_8B+dSB!Z9S9vE$Iz@3XXlk)`ul>XsA)C2WQ0Pyrqqs$t42FiZErfPU`JV1U`4DTA~; z-w?XOM@!RLz-`#ZmQ%)^h@0eX?44W$VV z5+kTGu@3J~2qEdXDi$c2t;OW669)TgdW2a<41Z6*%0smB&E|1dGHF74Ze)^N#G>5I z7_w(&M4(0;lCNs{VkW=3qQ73feOb@j7W>exBSvHVz-=H>qrWpja?Jrc|Jqnq5ypw2 zOmpZEH()A3k~$R8Dah4+^oJE9C^hiFHd|(%L=1wpZ!@HahMeGj3{>2(GbF%9vYhGE z@BVCgDMN!k9bF*~AR5!0`0J#d1EtfSCjum(XTbEI2;MuIlEDneA|ML^L?0zKK0 zsTbTx|IjQFTk))OC;eF$Ta7vh=A)oT89lam0cNJYI;thqMfmes<>i_@%32;bR za{vGf6951U69E94oEQKA00(qQO+^Rf2M!Sd7zAxNM*si-*GWV{R9M69S=$bUFbErq z|NqPQW_Du0$~X>9`)DfHWVTLJRYaNrRc$u`Mys533GF}^5o-kgwycSO(GZ%SeWW?j zMm|ErYfGe!*qqk_`*2!{(ZJfA&I7b(YO}`M8&M2g30FcGC+cyIaV6!jaRe1Ge*e3# z`NHBPi#91+=N-@gYO|ipWR>4`ZA(mX2kjVGT&^8UH=c>67>~BzD(2d;CB}2I({Kw^ zTol0sMevJ7Fu@-x#MQxNsWDI*o;9Bp4UrtNq+qniIt|qJV- +#include +#include +#include +#include +#include +#include + +#include +#include + +//--- +// Date and time display +//--- + +extern bopti_image_t img_rtc_segments; + +#ifdef FX9860G +char const *days[7] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; +char const *months[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", + "Nov", "Dec" +}; + +/* Starting x,y and width of each segment image */ +static int x0=20, y0=8, dx=13; +/* Starting x and y of date, and alternative y when editing */ +static int yd=36, eyd=12; +#endif + +#ifdef FXCG50 +char const *days[7] = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", + "Saturday" +}; +char const *months[12] = { + "January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December" +}; + +static int x0=89, y0=58, dx=32; +static int yd=121, eyd=121; +#endif + +static void draw_time(rtc_time_t *time, int edit_field) +{ + /* Height of characters */ + int sh = img_rtc_segments.height; + /* Width of colon separator */ + int cw = img_rtc_segments.width - 10 * dx; + + int digits[6] = { + time->hours / 10, + time->hours % 10, + time->minutes / 10, + time->minutes % 10, + time->seconds / 10, + time->seconds % 10, + }; + + for(int i=0, x=x0; i < 6; i++) + { + dsubimage(x, y0, &img_rtc_segments, dx*digits[i], 0, dx, sh, + DIMAGE_NONE); + + x += dx; + + if(i != 1 && i != 3) continue; + dsubimage(x, y0, &img_rtc_segments, 10*dx,0,cw,sh, DIMAGE_NONE); + x += cw; + } + + if(edit_field >= 0) + { + int x = x0 + (2 * dx + cw) * edit_field - 1; + int y = y0 - 1; + + #ifdef FX9860G + drect(x, y, x + 2*dx - 1, y + sh+1, C_INVERT); + + row_print(6, 1, "EXE: Set time"); + row_print(7, 1, "EXIT: Cancel"); + #endif + + #ifdef FXCG50 + for(int a = y - 1; a <= y + sh + 2; a++) + for(int b = x - 1; b <= x + 2*dx - 2; b++) + { + gint_vram[396*a+b] ^= 0xffff; + } + + row_print(12, 1, "EXE: Set time"); + row_print(13, 1, "EXIT: Cancel"); + #endif + + extern bopti_image_t img_rtc_arrows; + int xa = x0 + (2 * dx + cw) * edit_field + dx - 4; + int ya1 = y - _(1,3) - img_rtc_arrows.height; + int ya2 = y0 + sh + _(2,4); + dsubimage(xa, ya1, &img_rtc_arrows, 0,0,7,4, DIMAGE_NONE); + dsubimage(xa, ya2, &img_rtc_arrows, 8,0,7,4, DIMAGE_NONE); + } +} + +static void draw_date(rtc_time_t *time, int edit_field) +{ + int w[4], h, space_width; + char month_day[16]; + char year[16]; + + sprintf(month_day, "%02d", time->month_day); + sprintf(year, "%4d", time->year); + + dsize(" ", NULL, &space_width, NULL); + dsize(days[time->week_day], NULL, &w[0], &h); + dsize(months[time->month], NULL, &w[1], &h); + dsize(month_day, NULL, &w[2], &h); + dsize(year, NULL, &w[3], &h); + + int y = (edit_field >= 0) ? eyd: yd; + int xd = (DWIDTH - (w[0]+w[1]+w[2]+w[3] + 3 * (space_width + 2))) / 2; + + dprint(xd, y, C_BLACK, "%s %s %s %s", days[time->week_day], + months[time->month], month_day, year); + + if(edit_field >= 0) + { + int x = 0; + for(int i = 0; i < edit_field; i++) + x += w[i] + space_width + 2; + + #ifdef FX9860G + drect(xd+x-1, y-1, xd+x+w[edit_field], y+h, C_INVERT); + + row_print(6, 1, "EXE: Set date"); + row_print(7, 1, "EXIT: Cancel"); + #endif + + #ifdef FXCG50 + for(int a = y-2; a <= y+h; a++) + for(int b = xd+x-2; b <= xd+x+w[edit_field]+1; b++) + { + gint_vram[396*a+b] ^= 0xffff; + } + + row_print(12, 1, "EXE: Set date"); + row_print(13, 1, "EXIT: Cancel"); + #endif + + extern bopti_image_t img_rtc_arrows; + int xa = xd + x - 3 + (w[edit_field] >> 1); + int ya1 = y - _(2,4) - img_rtc_arrows.height; + int ya2 = y + h + _(2,3); + dsubimage(xa, ya1, &img_rtc_arrows, 0,0,7,4, DIMAGE_NONE); + dsubimage(xa, ya2, &img_rtc_arrows, 8,0,7,4, DIMAGE_NONE); + } +} + +static void draw_rtc(rtc_time_t *time) +{ + dclear(C_WHITE); + draw_time(time, -1); + draw_date(time, -1); + + #ifdef FX9860G + extern bopti_image_t img_opt_gint_rtc; + dsubimage(0, 56, &img_opt_gint_rtc, 0, 0, 128, 8, DIMAGE_NONE); + #endif + + #ifdef FXCG50 + row_title("Real-Time Clock"); + fkey_menu(1, "RTC"); + fkey_menu(2, "TIMER"); + fkey_action(5, "DATE"); + fkey_action(6, "TIME"); + #endif + + dupdate(); +} + +//--- +// Speed comparison of RTC and timers +//--- + +static void draw_speed(rtc_time_t *time) +{ + dclear(C_WHITE); + + #ifdef FX9860G + extern bopti_image_t img_opt_gint_rtc; + row_print(1, 1, "Speed of RTC vs TMU"); + dsubimage(0, 56, &img_opt_gint_rtc, 0, 9, 128, 8, DIMAGE_NONE); + #endif + + #ifdef FXCG50 + row_title("Speed comparison of RTC and timers"); + fkey_menu(1, "RTC"); + fkey_menu(2, "TIMER"); + #endif + + dprint_opt(DWIDTH-2, DHEIGHT-1, C_BLACK, C_NONE, DTEXT_RIGHT, + DTEXT_BOTTOM, "%s %d, %02d:%02d", months[time->month], + time->month_day, time->hours, time->minutes); + dupdate(); +} + +//--- +// Edition facilities +//--- + +static int days_in_month(rtc_time_t *time) +{ + int base[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if(time->month != 1) return base[time->month]; + + int leap_year = 0; + if(time->year % 4 == 0) leap_year = 1; + if(time->year % 100 == 0) leap_year = 0; + if(time->year % 400 == 0) leap_year = 1; + return base[time->month] + leap_year; +} + +static void normalize(rtc_time_t *time) +{ + /* Check that month_day is still valid */ + int max = days_in_month(time); + if(time->month_day > max) time->month_day = max; +} + +static void move_field(rtc_time_t *time, int field, int diff) +{ + if(field == 0) time->hours = (time->hours + 24 + diff) % 24; + if(field == 1) time->minutes = (time->minutes + 60 + diff) % 60; + if(field == 2) time->seconds = (time->seconds + 60 + diff) % 60; + if(field == 3) time->week_day = (time->week_day + 7 + diff) % 7; + + if(field == 4) + { + time->month = (time->month + 12 + diff) % 12; + normalize(time); + } + if(field == 5) + { + int max = days_in_month(time); + time->month_day = ((time->month_day-1) + max + diff) % max + 1; + } + if(field == 6) + { + time->year += diff; + if(diff < 0 && -diff > time->year) time->year = 0; + if(time->year > 9999) time->year = 9999; + normalize(time); + } +} + +static void set_field(rtc_time_t *time, int field, int value) +{ + if(field == 0) time->hours = value; + if(field == 1) time->minutes = value; + if(field == 2) time->seconds = value; + if(field == 3) time->week_day = value; + if(field == 4) time->month = value; + if(field == 5) time->month_day = value; + if(field == 6) time->year = value; +} + +static int valid_field(rtc_time_t *time, int field, int value) +{ + if(field == 0) + return value >= 0 && value < 24; + if(field == 1 || field == 2) + return value >= 0 && value < 60; + if(field == 3) + return value >= 0 && value < 7; + if(field == 4) + return value >= 0 && value < 12; + if(field == 5) + return value >= 1 && value <= days_in_month(time); + if(field == 6) + return value >= 0 && value <= 9999; + return 1; +} + +static void edit_time(void) +{ + int key=0, edit_field=0; + rtc_time_t time; + rtc_get_time(&time); + + int key_input = 0; + int key_sequence = 0; + + while(key != KEY_EXE && key != KEY_EXIT) + { + dclear(C_WHITE); + draw_time(&time, edit_field); + #ifdef FXCG50 + draw_date(&time, -1); + row_title("Real-Time Clock"); + #endif + dupdate(); + + key = getkey().key; + + if(keycode_digit(key) >= 0) + { + /* Try to append the digit to the current value, if it + gives an invalid value restart the input sequence */ + key_input = key_input * 10 + keycode_digit(key); + key_sequence++; + + if(!valid_field(&time, edit_field, key_input)) + { + key_input = keycode_digit(key); + key_sequence = 1; + } + + set_field(&time, edit_field, key_input); + + /* If a field is fully set, switch to the next one */ + if(key_sequence == 2) + { + if(edit_field == 2) + { + key = KEY_EXE; + break; + } + else + { + edit_field++; + key_input = 0; + key_sequence = 0; + } + } + + continue; + } + + /* Any key other than a digit breaks an input sequence */ + key_input = 0; + key_sequence = 0; + + if(key == KEY_LEFT && edit_field > 0) edit_field--; + if(key == KEY_RIGHT && edit_field < 2) edit_field++; + + if(key == KEY_UP) move_field(&time, edit_field, +1); + if(key == KEY_DOWN) move_field(&time, edit_field, -1); + } + + if(key == KEY_EXE) rtc_set_time(&time); +} + +static void edit_date(void) +{ + int key=0, edit_field=0, option_tab=0; + rtc_time_t time; + rtc_get_time(&time); + + int key_input = 0; + int key_sequence = 0; + + while(key != KEY_EXE && key != KEY_EXIT) + { + dclear(C_WHITE); + #ifdef FXCG50 + draw_time(&time, -1); + row_title("Real-Time Clock"); + #endif + draw_date(&time, edit_field); + + #ifdef FX9860G + extern bopti_image_t img_opt_gint_rtc; + if(edit_field == 0) + dsubimage(0, 56, &img_opt_gint_rtc, 0, option_tab*9+18, + 128, 8, DIMAGE_NONE); + if(edit_field == 1) + dsubimage(0, 56, &img_opt_gint_rtc, 0, option_tab*9+36, + 128, 8, DIMAGE_NONE); + #endif + + #ifdef FXCG50 + char const *fkey_days[] = { + "SUN", "MON", "TUE", "WED", "THUR", "FRI", "SAT" + }; + if(edit_field == 0) for(int i = 0; i < 5; i++) + { + int id = 5 * option_tab + i; + if(id < 7) fkey_menu(i+1, fkey_days[id]); + } + + char const *fkey_months[] = { + "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", + "SEP", "OCT", "NOV", "DEC" + }; + if(edit_field == 1) for(int i = 0; i < 5; i++) + { + int id = 5 * option_tab + i; + if(id < 12) fkey_menu(i+1, fkey_months[id]); + } + + if(edit_field < 2) fkey_action(6, ">"); + #endif + + dupdate(); + key = getkey().key; + + if(keycode_digit(key) >= 0 && edit_field >= 2) + { + /* Try to append the digit to the current value, if it + gives an invalid value restart the input sequence */ + key_input = key_input * 10 + keycode_digit(key); + key_sequence++; + + if(!valid_field(&time, edit_field+3, key_input)) + { + key_input = keycode_digit(key); + key_sequence = 1; + } + + set_field(&time, edit_field+3, key_input); + + /* If a field is fully set, switch to the next one */ + if((edit_field == 2 && key_sequence == 2) + || (edit_field == 3 && key_sequence == 4)) + { + if(edit_field == 3) + { + key = KEY_EXE; + break; + } + else + { + edit_field++; + option_tab = 0; + key_input = 0; + key_sequence = 0; + } + } + + continue; + } + + /* Any key other than a digit breaks an input sequence */ + key_input = 0; + key_sequence = 0; + + if(key == KEY_LEFT && edit_field > 0) + { + edit_field--; + option_tab = 0; + } + if(key == KEY_RIGHT && edit_field < 3) + { + edit_field++; + option_tab = 0; + } + + int fk = keycode_function(key); + if(fk >= 1 && fk <= 5) + { + int value = option_tab * 5 + fk - 1; + if(valid_field(&time, edit_field+3, value)) + { + set_field(&time, edit_field+3, value); + + /* Go to next field */ + if(edit_field == 3) + { + key = KEY_EXE; + break; + } + else + { + edit_field++; + option_tab = 0; + } + } + } + if(key == KEY_F6) + { + int max = (edit_field == 0) ? 1 : 2; + option_tab++; + if(option_tab > max) option_tab = 0; + } + + if(key == KEY_UP) move_field(&time, edit_field+3, +1); + if(key == KEY_DOWN) move_field(&time, edit_field+3, -1); + } + + if(key == KEY_EXE) + { + /* Copy current time and set only the date */ + int wd = time.week_day; + int d = time.month_day; + int m = time.month; + int y = time.year; + + rtc_get_time(&time); + time.week_day = wd; + time.month_day = d; + time.month = m; + time.year = y; + rtc_set_time(&time); + } +} + +//--- +// Main screen with lazy update +//--- + +static volatile int frame_done = 0; + +static int rtc_timer_callback(void) +{ + frame_done = 0; + return TIMER_CONTINUE; +} + +/* gintctl_gint_rtc(): Configure RTC and check timer speed */ +void gintctl_gint_rtc(void) +{ + key_event_t ev; + rtc_time_t time; + + int run_loop = 1; + int tab = 1; + + rtc_start_timer(RTC_1Hz, rtc_timer_callback); + + while(run_loop) + { + if(!frame_done) rtc_get_time(&time); + + /* Redraw only when a second elapses */ + if(!frame_done && tab == 1) + { + draw_rtc(&time); + frame_done = 1; + } + else if(!frame_done && tab == 2) + { + draw_speed(&time); + frame_done = 1; + } + + /* Handle keyboard events */ + while((ev = pollevent()).type != KEYEV_NONE) + { + if(ev.type != KEYEV_DOWN) continue; + int action = 1; + + if(ev.key == KEY_EXIT) run_loop = 0; + else if(ev.key == KEY_MENU) gint_osmenu(); + else if(ev.key == KEY_F1) tab = 1; + else if(ev.key == KEY_F2) tab = 2; + else if(ev.key == KEY_F5 && tab == 1) edit_date(); + else if(ev.key == KEY_F6 && tab == 1) edit_time(); + else action = 0; + + if(action) frame_done = 0; + } + + /* Wait for either keyboard or RTC to produce an event, except + if we already have work to do */ + if(frame_done) sleep(); + } + + rtc_stop_timer(); +} diff --git a/src/gintctl.c b/src/gintctl.c index 41a5d32..cbaf6ce 100644 --- a/src/gintctl.c +++ b/src/gintctl.c @@ -46,7 +46,7 @@ struct menu menu_gint = { #ifdef FXCG50 { "DMA Control", gintctl_gint_dma }, #endif - { "Real-time clock", NULL }, + { "Real-time clock", gintctl_gint_rtc }, { "Image rendering", gintctl_gint_bopti }, { "Text rendering", gintctl_gint_topti }, #ifdef FX9860G