... | ... |
@@ -20,15 +20,42 @@ |
20 | 20 |
/*! The number of printable characters in the font tables */ |
21 | 21 |
#define PRINTABLE_CHARACTERS ( 94 ) |
22 | 22 |
|
23 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
24 |
+__attribute__((__far__)) |
|
25 |
+#endif |
|
23 | 26 |
const unsigned char MetaWatch5table[PRINTABLE_CHARACTERS][5]; |
27 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
28 |
+__attribute__((__far__)) |
|
29 |
+#endif |
|
24 | 30 |
const unsigned char MetaWatch7table[PRINTABLE_CHARACTERS][7]; |
31 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
32 |
+__attribute__((__far__)) |
|
33 |
+#endif |
|
25 | 34 |
const u16t MetaWatch16table[PRINTABLE_CHARACTERS][16]; |
35 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
36 |
+__attribute__((__far__)) |
|
37 |
+#endif |
|
26 | 38 |
const u16t MetaWatchTimeTable[TOTAL_TIME_CHARACTERS][19]; |
39 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
40 |
+__attribute__((__far__)) |
|
41 |
+#endif |
|
27 | 42 |
const unsigned char MetaWatchMonospaced10Table[PRINTABLE_CHARACTERS][10]; |
28 | 43 |
|
44 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
45 |
+__attribute__((__far__)) |
|
46 |
+#endif |
|
29 | 47 |
const unsigned char MetaWatch5width[PRINTABLE_CHARACTERS]; |
48 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
49 |
+__attribute__((__far__)) |
|
50 |
+#endif |
|
30 | 51 |
const unsigned char MetaWatch7width[PRINTABLE_CHARACTERS]; |
52 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
53 |
+__attribute__((__far__)) |
|
54 |
+#endif |
|
31 | 55 |
const unsigned char MetaWatch16width[PRINTABLE_CHARACTERS]; |
56 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
57 |
+__attribute__((__far__)) |
|
58 |
+#endif |
|
32 | 59 |
const unsigned char MetaWatchTimeWidth[TOTAL_TIME_CHARACTERS]; |
33 | 60 |
|
34 | 61 |
/*! Font Structure |
... | ... |
@@ -189,6 +216,9 @@ void GetCharacterBitmap(unsigned char Character, u16t *pBitmap) |
189 | 216 |
|
190 | 217 |
} |
191 | 218 |
|
219 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
220 |
+__attribute__((__far__)) |
|
221 |
+#endif |
|
192 | 222 |
const unsigned char MetaWatch5table[PRINTABLE_CHARACTERS][5] = |
193 | 223 |
{ |
194 | 224 |
/* character 0x20 (' '): (width = 2) */ |
... | ... |
@@ -474,6 +504,9 @@ const unsigned char MetaWatch5table[PRINTABLE_CHARACTERS][5] = |
474 | 504 |
0x00, 0x00, 0x00, 0x00, 0x00,}, |
475 | 505 |
}; |
476 | 506 |
|
507 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
508 |
+__attribute__((__far__)) |
|
509 |
+#endif |
|
477 | 510 |
const unsigned char MetaWatch5width[PRINTABLE_CHARACTERS] = |
478 | 511 |
{ |
479 | 512 |
/* width char hexcode */ |
... | ... |
@@ -574,6 +607,9 @@ const unsigned char MetaWatch5width[PRINTABLE_CHARACTERS] = |
574 | 607 |
3, /* } 7D */ |
575 | 608 |
}; |
576 | 609 |
|
610 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
611 |
+__attribute__((__far__)) |
|
612 |
+#endif |
|
577 | 613 |
const unsigned char MetaWatch7table[PRINTABLE_CHARACTERS][7] = |
578 | 614 |
{ |
579 | 615 |
|
... | ... |
@@ -860,6 +896,9 @@ const unsigned char MetaWatch7table[PRINTABLE_CHARACTERS][7] = |
860 | 896 |
|
861 | 897 |
}; |
862 | 898 |
|
899 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
900 |
+__attribute__((__far__)) |
|
901 |
+#endif |
|
863 | 902 |
const unsigned char MetaWatch7width[PRINTABLE_CHARACTERS] = { |
864 | 903 |
/* width char hexcode */ |
865 | 904 |
/* ===== ==== ======= */ |
... | ... |
@@ -960,6 +999,9 @@ const unsigned char MetaWatch7width[PRINTABLE_CHARACTERS] = { |
960 | 999 |
}; |
961 | 1000 |
|
962 | 1001 |
|
1002 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
1003 |
+__attribute__((__far__)) |
|
1004 |
+#endif |
|
963 | 1005 |
const u16t MetaWatch16table[PRINTABLE_CHARACTERS][16] = |
964 | 1006 |
{ |
965 | 1007 |
/* character 0x20 (' '): (width=4) */ |
... | ... |
@@ -1526,6 +1568,9 @@ const u16t MetaWatch16table[PRINTABLE_CHARACTERS][16] = |
1526 | 1568 |
0x0006, 0x0002, 0x0001, 0x0000}, |
1527 | 1569 |
}; |
1528 | 1570 |
|
1571 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
1572 |
+__attribute__((__far__)) |
|
1573 |
+#endif |
|
1529 | 1574 |
const unsigned char MetaWatch16width[PRINTABLE_CHARACTERS] = |
1530 | 1575 |
{ |
1531 | 1576 |
/* width char hexcode */ |
... | ... |
@@ -1627,6 +1672,9 @@ const unsigned char MetaWatch16width[PRINTABLE_CHARACTERS] = |
1627 | 1672 |
}; |
1628 | 1673 |
|
1629 | 1674 |
/******************************************************************************/ |
1675 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
1676 |
+__attribute__((__far__)) |
|
1677 |
+#endif |
|
1630 | 1678 |
const u16t MetaWatchTimeTable[TOTAL_TIME_CHARACTERS][19] = |
1631 | 1679 |
{ |
1632 | 1680 |
/* character 0x30 ('0'): (width=11, offset=0) */ |
... | ... |
@@ -1714,6 +1762,9 @@ const u16t MetaWatchTimeTable[TOTAL_TIME_CHARACTERS][19] = |
1714 | 1762 |
0x0000, 0x0000, 0x0000}, |
1715 | 1763 |
}; |
1716 | 1764 |
|
1765 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
1766 |
+__attribute__((__far__)) |
|
1767 |
+#endif |
|
1717 | 1768 |
const unsigned char MetaWatchTimeWidth[TOTAL_TIME_CHARACTERS] = |
1718 | 1769 |
{ |
1719 | 1770 |
/* width char hexcode */ |
... | ... |
@@ -1734,6 +1785,9 @@ const unsigned char MetaWatchTimeWidth[TOTAL_TIME_CHARACTERS] = |
1734 | 1785 |
|
1735 | 1786 |
/******************************************************************************/ |
1736 | 1787 |
|
1788 |
+#if defined(__GNUC__) && (__MSP430X__ > 0) |
|
1789 |
+__attribute__((__far__)) |
|
1790 |
+#endif |
|
1737 | 1791 |
const unsigned char MetaWatchMonospaced10Table[PRINTABLE_CHARACTERS][10] = |
1738 | 1792 |
{ |
1739 | 1793 |
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, |
... | ... |
@@ -1,4 +1,5 @@ |
1 |
-#include "oswald-ui.h" |
|
1 |
+#include "oswald.h" |
|
2 |
+#include "oswald_hal.h" |
|
2 | 3 |
#include "oswald_strings.h" |
3 | 4 |
#include "Fonts.h" |
4 | 5 |
|
... | ... |
@@ -32,7 +33,7 @@ void DrawLcdLineBresenham(u8t xstart, u8t ystart, u8t xend, u8t yend) |
32 | 33 |
x = xstart; |
33 | 34 |
y = ystart; |
34 | 35 |
err = el/2; |
35 |
- lcd_set_pixel(x, y, TRUE); |
|
36 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
36 | 37 |
|
37 | 38 |
for (t = 0; t < el; ++t) { |
38 | 39 |
err -= es; |
... | ... |
@@ -44,7 +45,7 @@ void DrawLcdLineBresenham(u8t xstart, u8t ystart, u8t xend, u8t yend) |
44 | 45 |
x += pdx; |
45 | 46 |
y += pdy; |
46 | 47 |
} |
47 |
- lcd_set_pixel(x, y, TRUE); |
|
48 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
48 | 49 |
} |
49 | 50 |
// lcd_update_display(); |
50 | 51 |
} |
... | ... |
@@ -77,12 +78,12 @@ void DrawLcdLineBresenhamWW(u8t xstart, u8t ystart, u8t xend, u8t yend, u8t thic |
77 | 78 |
x = xstart; |
78 | 79 |
y = ystart; |
79 | 80 |
err = el/2; |
80 |
- lcd_set_pixel(x, y, TRUE); |
|
81 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
81 | 82 |
for (i=1; i<thickness; i++) { |
82 |
- lcd_set_pixel(x-i, y, TRUE); |
|
83 |
- lcd_set_pixel(x+i, y, TRUE); |
|
84 |
- lcd_set_pixel(x, y-i, TRUE); |
|
85 |
- lcd_set_pixel(x, y+i, TRUE); |
|
83 |
+ hal_lcd_set_pixel(x-i, y, TRUE); |
|
84 |
+ hal_lcd_set_pixel(x+i, y, TRUE); |
|
85 |
+ hal_lcd_set_pixel(x, y-i, TRUE); |
|
86 |
+ hal_lcd_set_pixel(x, y+i, TRUE); |
|
86 | 87 |
} |
87 | 88 |
|
88 | 89 |
for (t = 0; t < el; ++t) { |
... | ... |
@@ -95,12 +96,12 @@ void DrawLcdLineBresenhamWW(u8t xstart, u8t ystart, u8t xend, u8t yend, u8t thic |
95 | 96 |
x += pdx; |
96 | 97 |
y += pdy; |
97 | 98 |
} |
98 |
- lcd_set_pixel(x, y, TRUE); |
|
99 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
99 | 100 |
for (i=1; i<thickness; i++) { |
100 |
- lcd_set_pixel(x-i, y, TRUE); |
|
101 |
- lcd_set_pixel(x+i, y, TRUE); |
|
102 |
- lcd_set_pixel(x, y-i, TRUE); |
|
103 |
- lcd_set_pixel(x, y+i, TRUE); |
|
101 |
+ hal_lcd_set_pixel(x-i, y, TRUE); |
|
102 |
+ hal_lcd_set_pixel(x+i, y, TRUE); |
|
103 |
+ hal_lcd_set_pixel(x, y-i, TRUE); |
|
104 |
+ hal_lcd_set_pixel(x, y+i, TRUE); |
|
104 | 105 |
} |
105 | 106 |
} |
106 | 107 |
// lcd_update_display(); |
... | ... |
@@ -119,10 +120,10 @@ u8t WriteLcdCharacter(u8t x, u8t y, u8t Character) |
119 | 120 |
for (ly=0; ly<CharacterHeight; ly++) { |
120 | 121 |
for (lx=0; lx<CharacterWidth; lx++) { |
121 | 122 |
if (bitmap[ly] & (1<<lx)) { |
122 |
- lcd_set_pixel(lx+x, ly+y, TRUE); |
|
123 |
+ hal_lcd_set_pixel(lx+x, ly+y, TRUE); |
|
123 | 124 |
// printf("."); |
124 | 125 |
} else { |
125 |
- lcd_set_pixel(lx+x, ly+y, FALSE); |
|
126 |
+ hal_lcd_set_pixel(lx+x, ly+y, FALSE); |
|
126 | 127 |
// printf(" "); |
127 | 128 |
} |
128 | 129 |
} |
... | ... |
@@ -132,18 +133,19 @@ u8t WriteLcdCharacter(u8t x, u8t y, u8t Character) |
132 | 133 |
return CharacterWidth + GetFontSpacing(); |
133 | 134 |
} |
134 | 135 |
|
135 |
-void WriteLcdString(u8t x, u8t y, char *str) |
|
136 |
+u8t WriteLcdString(u8t x, u8t y, char *str) |
|
136 | 137 |
{ |
137 | 138 |
int lx, i, strl; |
138 | 139 |
|
139 | 140 |
strl = oswald_strlen(str); |
140 | 141 |
if (strl == 0) |
141 |
- return; |
|
142 |
+ return 0; |
|
142 | 143 |
|
143 | 144 |
lx = x; |
144 | 145 |
for (i=0; i<strl; i++) { |
145 | 146 |
lx += WriteLcdCharacter(lx, y, str[i]); |
146 | 147 |
} |
148 |
+ return lx; |
|
147 | 149 |
} |
148 | 150 |
|
149 | 151 |
|
... | ... |
@@ -1,12 +1,12 @@ |
1 | 1 |
#ifndef _LcdDisplay_h |
2 | 2 |
#define _LcdDisplay_h |
3 | 3 |
|
4 |
-#include "oswald-ui.h" |
|
4 |
+// #include "oswald_hal.h" |
|
5 | 5 |
|
6 | 6 |
void DrawLcdLineBresenham(u8t xstart, u8t ystart, u8t xend, u8t yend); |
7 | 7 |
void DrawLcdLineBresenhamWW(u8t xstart, u8t ystart, u8t xend, u8t yend, u8t thickness); |
8 | 8 |
u8t WriteLcdCharacter(u8t x, u8t y, u8t Character); |
9 |
-void WriteLcdString(u8t x, u8t y, char *str); |
|
9 |
+u8t WriteLcdString(u8t x, u8t y, char *str); |
|
10 | 10 |
void WriteLcdNumber(u8t x, u8t y, s16t number); |
11 | 11 |
|
12 | 12 |
#endif |
... | ... |
@@ -3,7 +3,7 @@ ACLOCAL_AMFLAGS = -I m4 |
3 | 3 |
bin_PROGRAMS = oswald-gui |
4 | 4 |
|
5 | 5 |
oswald_gui_SOURCES = oswald-ui.c LcdDisplay.c Fonts.c oswald_main.c oswald_watch_faces.c oswald_strings.c oswald_screens.c \ |
6 |
-embedvm.c oswald_fonts.c oswald_graphics.c |
|
6 |
+embedvm.c oswald_fonts.c oswald_graphics.c calendar.c |
|
7 | 7 |
oswald_gui_CFLAGS = -g $(GTK_CFLAGS) |
8 | 8 |
oswald_gui_LDADD = $(GTK_LIBS) |
9 | 9 |
|
10 | 10 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,208 @@ |
1 |
+#include "oswald.h" |
|
2 |
+ |
|
3 |
+#include "calendar.h" |
|
4 |
+ |
|
5 |
+unsigned char is_leap(const unsigned int year) |
|
6 |
+{ |
|
7 |
+ // Die Regel lautet: Alles, was durch 4 teilbar ist, ist ein Schaltjahr. |
|
8 |
+ // Es sei denn, das Jahr ist durch 100 teilbar, dann ist es keins. |
|
9 |
+ // Aber wenn es durch 400 teilbar ist, ist es doch wieder eins. |
|
10 |
+ |
|
11 |
+ if ((year % 400) == 0) |
|
12 |
+ return 1; |
|
13 |
+ else if ((year % 100) == 0) |
|
14 |
+ return 0; |
|
15 |
+ else if ((year % 4) == 0) |
|
16 |
+ return 1; |
|
17 |
+ |
|
18 |
+ return 0; |
|
19 |
+} |
|
20 |
+ |
|
21 |
+unsigned short days_of_month(const unsigned int uMonat, const unsigned int uJahr) |
|
22 |
+{ |
|
23 |
+ // ungült,Jan,Feb,Mrz,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez |
|
24 |
+ int arrTageImMonat[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
|
25 |
+ |
|
26 |
+ if (uMonat == 2) { |
|
27 |
+ // Februar: Schaltjahr unterscheiden |
|
28 |
+ if (is_leap(uJahr)) |
|
29 |
+ return 29; |
|
30 |
+ else |
|
31 |
+ return 28; |
|
32 |
+ } |
|
33 |
+ |
|
34 |
+ if ((uMonat >= 1) && (uMonat <= 12)) |
|
35 |
+ return arrTageImMonat[uMonat]; |
|
36 |
+ else { |
|
37 |
+ return 0; |
|
38 |
+ } |
|
39 |
+} |
|
40 |
+ |
|
41 |
+short getAnzahlTageImJahr(const unsigned int uJahr) |
|
42 |
+{ |
|
43 |
+ return (is_leap(uJahr)) ? 366 : 365; |
|
44 |
+} |
|
45 |
+ |
|
46 |
+short getWochentag(const unsigned int uTag, const unsigned int uMonat, const unsigned int uJahr) |
|
47 |
+{ |
|
48 |
+ // ungült Jan Feb Mrz Apr Mai Jun Jul Aug Sep Okt Nov Dez |
|
49 |
+ unsigned char arrMonatsOffset[13] = { 0, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; |
|
50 |
+ short nErgebnis = 0; |
|
51 |
+ |
|
52 |
+ // Monat / Tag - Plausi prüfen: |
|
53 |
+ if ((uTag > 31) || (uMonat > 12) || (uMonat <= 0) |
|
54 |
+ || (uTag <= 0) || (uJahr <= 0)) { |
|
55 |
+ return -1; |
|
56 |
+ } |
|
57 |
+ |
|
58 |
+ unsigned char cbTagesziffer = (uTag % 7); |
|
59 |
+ unsigned char cbMonatsziffer = arrMonatsOffset[uMonat]; |
|
60 |
+ unsigned char cbJahresziffer = ((uJahr % 100) + ((uJahr % 100) / 4)) % 7; |
|
61 |
+ unsigned char cbJahrhundertziffer = (3 - ((uJahr / 100) % 4)) * 2; |
|
62 |
+ |
|
63 |
+ // Schaltjahreskorrektur: |
|
64 |
+ if ((uMonat <= 2) && (is_leap(uJahr))) |
|
65 |
+ cbTagesziffer = cbTagesziffer + 6; |
|
66 |
+ |
|
67 |
+ nErgebnis = (cbTagesziffer + cbMonatsziffer + cbJahresziffer + cbJahrhundertziffer) % 7; |
|
68 |
+ |
|
69 |
+ // Ergebnis: |
|
70 |
+ // 0 = Sonntag |
|
71 |
+ // 1 = Montag |
|
72 |
+ // 2 = Dienstag |
|
73 |
+ // 3 = Mittwoch |
|
74 |
+ // 4 = Donnerstag |
|
75 |
+ // 5 = Freitag |
|
76 |
+ // 6 = Samstag |
|
77 |
+ return nErgebnis; |
|
78 |
+} |
|
79 |
+ |
|
80 |
+short getTagDesJahres(const unsigned int uTag, const unsigned int uMonat, const unsigned int uJahr) |
|
81 |
+{ |
|
82 |
+ // Der wievielte Tag des Jahres ist dieser Tag |
|
83 |
+ if ((uMonat == 0) || (uMonat > 12)) { |
|
84 |
+ return -1; |
|
85 |
+ } |
|
86 |
+ |
|
87 |
+ unsigned int uLokalTag = uTag; |
|
88 |
+ unsigned int uLokalMonat = uMonat; |
|
89 |
+ |
|
90 |
+ while (uLokalMonat > 1) { |
|
91 |
+ uLokalMonat--; |
|
92 |
+ uLokalTag += days_of_month(uLokalMonat, uJahr); |
|
93 |
+ } |
|
94 |
+ |
|
95 |
+ return uLokalTag; |
|
96 |
+} |
|
97 |
+ |
|
98 |
+short getKalenderwoche(short uTag, short uMonat, short uJahr) |
|
99 |
+{ |
|
100 |
+ // Berechnung erfolgt analog DIN 1355, welche besagt: |
|
101 |
+ // Der erste Donnerstag im neuen Jahr liegt immer in der KW 1. |
|
102 |
+ // "Woche" ist dabei definiert als [Mo, ..., So]. |
|
103 |
+ short nTagDesJahres = getTagDesJahres(uTag, uMonat, uJahr); |
|
104 |
+ |
|
105 |
+ // Berechnen des Wochentags des 1. Januar: |
|
106 |
+ short nWochentag1Jan = getWochentag(1, 1, uJahr); |
|
107 |
+ |
|
108 |
+ // Sonderfälle Freitag und Samstag |
|
109 |
+ if (nWochentag1Jan >= 5) |
|
110 |
+ nWochentag1Jan = nWochentag1Jan - 7; |
|
111 |
+ |
|
112 |
+ // Sonderfälle "Jahresanfang mit KW - Nummer aus dem Vorjahr" |
|
113 |
+ if ( (nTagDesJahres + nWochentag1Jan) <= 1) { |
|
114 |
+ return getKalenderwoche(31, 12, uJahr - 1); |
|
115 |
+ } |
|
116 |
+ |
|
117 |
+ short nKalenderWoche = ((nTagDesJahres + nWochentag1Jan + 5) / 7); |
|
118 |
+ |
|
119 |
+ // 53 Kalenderwochen hat grundsätzlich nur ein Jahr, |
|
120 |
+ // welches mit einem Donnerstag anfängt ! |
|
121 |
+ // In Schaltjahren ist es auch mit einem Mittwoch möglich, z.B. 1992 |
|
122 |
+ // Andernfalls ist diese KW schon die KW1 des Folgejahres. |
|
123 |
+ if (nKalenderWoche == 53) { |
|
124 |
+ boolean bIstSchaltjahr = is_leap(uJahr); |
|
125 |
+ |
|
126 |
+ if ((nWochentag1Jan == 4) // Donnerstag |
|
127 |
+ || (nWochentag1Jan == -3) // auch Donnerstag |
|
128 |
+ || ((nWochentag1Jan == 3) && bIstSchaltjahr) |
|
129 |
+ || ((nWochentag1Jan == -4) && bIstSchaltjahr)) { |
|
130 |
+ ; // Das ist korrekt und erlaubt |
|
131 |
+ } else |
|
132 |
+ nKalenderWoche = 1; // Korrektur des Wertes |
|
133 |
+ } |
|
134 |
+ |
|
135 |
+ return nKalenderWoche; |
|
136 |
+} |
|
137 |
+ |
|
138 |
+void getOsterdatum(const unsigned int uJahr, unsigned int *uTag, unsigned int *uMonat) |
|
139 |
+{ |
|
140 |
+ // Berechnet für ein beliebiges Jahr das Osterdatum. |
|
141 |
+ |
|
142 |
+ // Quelle des Gauss - Algorithmus: Stefan Gerth, |
|
143 |
+ // "Die Gauß'sche Osterregel", Nürnberg, Februar 2003. |
|
144 |
+ // http://krapfen.org/content/paper/Schule/Facharbeit/Berechnung_des_Osterfestes.pdf |
|
145 |
+ |
|
146 |
+ unsigned int a = uJahr % 19; |
|
147 |
+ unsigned int b = uJahr % 4; |
|
148 |
+ unsigned int c = uJahr % 7; |
|
149 |
+ |
|
150 |
+ int k = uJahr / 100; |
|
151 |
+ int q = k / 4; |
|
152 |
+ int p = ((8 * k) + 13) / 25; |
|
153 |
+ unsigned int Egz = (38 - (k - q) + p) % 30; // Die Jahrhundertepakte |
|
154 |
+ unsigned int M = (53 - Egz) % 30; |
|
155 |
+ unsigned int N = (4 + k - q) % 7; |
|
156 |
+ |
|
157 |
+ unsigned int d = ((19 * a) + M) % 30; |
|
158 |
+ unsigned int e = ((2 * b) + (4 * c) + (6 * d) + N) % 7; |
|
159 |
+ |
|
160 |
+ // Ausrechnen des Ostertermins: |
|
161 |
+ if ((22 + d + e) <= 31) { |
|
162 |
+ *uTag = 22 + d + e; |
|
163 |
+ *uMonat = 3; |
|
164 |
+ } else { |
|
165 |
+ *uTag = d + e - 9; |
|
166 |
+ *uMonat = 4; |
|
167 |
+ |
|
168 |
+ // Zwei Ausnahmen berücksichtigen: |
|
169 |
+ if (*uTag == 26) |
|
170 |
+ *uTag = 19; |
|
171 |
+ else if ((*uTag == 25) && (d == 28) && (a > 10)) |
|
172 |
+ *uTag = 18; |
|
173 |
+ } |
|
174 |
+ |
|
175 |
+ // Offsets für andere Feiertage: |
|
176 |
+ |
|
177 |
+ // Schwerdonnerstag / Weiberfastnacht -52 |
|
178 |
+ // Rosenmontag -48 |
|
179 |
+ // Fastnachtsdienstag -47 |
|
180 |
+ // Aschermittwoch -46 |
|
181 |
+ // Gründonnerstag -3 |
|
182 |
+ // Karfreitag -2 |
|
183 |
+ // Ostersonntag 0 |
|
184 |
+ // Ostermontag +1 |
|
185 |
+ // Christi Himmelfahrt +39 |
|
186 |
+ // Pfingstsonntag +49 |
|
187 |
+ // Pfingstmontag +50 |
|
188 |
+ // Fronleichnam +60 |
|
189 |
+ |
|
190 |
+ // Mariä Himmelfahrt ist stets am 15. August (Danke an Michael Plugge!) |
|
191 |
+} |
|
192 |
+ |
|
193 |
+void getViertenAdvent(const unsigned int uJahr, unsigned int *uTag, unsigned int *uMonat) |
|
194 |
+{ |
|
195 |
+ // Berechnet für ein beliebiges Jahr das Datum des 4. Advents-Sonntags. |
|
196 |
+ // Der 4. Adventssonntag ist stets der Sonntag vor dem 1. Weihnachtsfeiertag, |
|
197 |
+ // muß also stets in der Periode [18. - 24.12.] liegen: |
|
198 |
+ |
|
199 |
+ *uMonat = 12; // Das steht jedes Jahr fest :-) |
|
200 |
+ |
|
201 |
+ short nWoTag = getWochentag(24, 12, uJahr); // Wochentag des 24.12. ermitteln |
|
202 |
+ |
|
203 |
+ *uTag = 24 - nWoTag; |
|
204 |
+ |
|
205 |
+ // Offsets: Der Buß- und Bettag liegt stets 32 Tage vor dem 4. Advent |
|
206 |
+} |
|
207 |
+ |
|
208 |
+ |
0 | 209 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,21 @@ |
1 |
+#ifndef _CALENDAR_H |
|
2 |
+#define _CALENDAR_H |
|
3 |
+ |
|
4 |
+unsigned char is_leap(const unsigned int year); |
|
5 |
+ |
|
6 |
+unsigned short days_of_month(const unsigned int uMonat, const unsigned int uJahr); |
|
7 |
+ |
|
8 |
+short getAnzahlTageImJahr(const unsigned int uJahr); |
|
9 |
+ |
|
10 |
+short getWochentag(const unsigned int uTag, const unsigned int uMonat, const unsigned int uJahr); |
|
11 |
+ |
|
12 |
+short getTagDesJahres(const unsigned int uTag, const unsigned int uMonat, const unsigned int uJahr); |
|
13 |
+ |
|
14 |
+short getKalenderwoche(short uTag, short uMonat, short uJahr); |
|
15 |
+ |
|
16 |
+void getOsterdatum(const unsigned int uJahr, unsigned int *uTag, unsigned int *uMonat); |
|
17 |
+ |
|
18 |
+void getViertenAdvent(const unsigned int uJahr, unsigned int *uTag, unsigned int *uMonat); |
|
19 |
+ |
|
20 |
+#endif |
|
21 |
+ |
... | ... |
@@ -23,7 +23,7 @@ |
23 | 23 |
|
24 | 24 |
static oswald_ui *ui_g; |
25 | 25 |
|
26 |
-void lcd_set_pixel(gint x, gint y, gboolean state) |
|
26 |
+void hal_lcd_set_pixel(gint x, gint y, gboolean state) |
|
27 | 27 |
{ |
28 | 28 |
gint ix, iy; |
29 | 29 |
|
... | ... |
@@ -39,12 +39,12 @@ void lcd_set_pixel(gint x, gint y, gboolean state) |
39 | 39 |
} |
40 | 40 |
|
41 | 41 |
/* updates the actual LCD so that drawing becomes visible */ |
42 |
-void lcd_update_display(void) |
|
42 |
+void hal_lcd_update_display(void) |
|
43 | 43 |
{ |
44 | 44 |
gtk_widget_queue_draw(ui_g->darea); |
45 | 45 |
} |
46 | 46 |
|
47 |
-void lcd_clear_display(void) |
|
47 |
+void hal_lcd_clear_display(void) |
|
48 | 48 |
{ |
49 | 49 |
gdk_draw_rectangle (ui_g->pixmap, |
50 | 50 |
ui_g->darea->style->white_gc, |
... | ... |
@@ -219,19 +219,19 @@ static void create_mainwin(oswald_ui *ui) |
219 | 219 |
vb = gtk_vbox_new(FALSE, 5); |
220 | 220 |
gtk_box_pack_start (GTK_BOX(hb), vb, FALSE, FALSE, 5); |
221 | 221 |
|
222 |
- btn = gtk_button_new_with_label(" D "); |
|
222 |
+ btn = gtk_button_new_with_label(" F "); |
|
223 | 223 |
gtk_box_pack_start (GTK_BOX(vb), btn, FALSE, FALSE, 10); |
224 |
- g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(button_D_clicked), ui); |
|
224 |
+ g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(button_F_clicked), ui); |
|
225 |
+ g_signal_connect(G_OBJECT(btn), "button-press-event", G_CALLBACK(button_F_pr), ui); |
|
226 |
+ g_signal_connect(G_OBJECT(btn), "button-release-event", G_CALLBACK(button_F_pr), ui); |
|
225 | 227 |
|
226 | 228 |
btn = gtk_button_new_with_label(" E "); |
227 | 229 |
gtk_box_pack_start (GTK_BOX(vb), btn, FALSE, FALSE, 10); |
228 | 230 |
g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(button_E_clicked), ui); |
229 | 231 |
|
230 |
- btn = gtk_button_new_with_label(" F "); |
|
232 |
+ btn = gtk_button_new_with_label(" D "); |
|
231 | 233 |
gtk_box_pack_start (GTK_BOX(vb), btn, FALSE, FALSE, 10); |
232 |
- g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(button_F_clicked), ui); |
|
233 |
- g_signal_connect(G_OBJECT(btn), "button-press-event", G_CALLBACK(button_F_pr), ui); |
|
234 |
- g_signal_connect(G_OBJECT(btn), "button-release-event", G_CALLBACK(button_F_pr), ui); |
|
234 |
+ g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(button_D_clicked), ui); |
|
235 | 235 |
|
236 | 236 |
ui->darea = gtk_drawing_area_new (); |
237 | 237 |
gtk_box_pack_start (GTK_BOX(hb), GTK_WIDGET(ui->darea), FALSE, FALSE, 5); |
... | ... |
@@ -323,13 +323,13 @@ static gboolean centisecond_tmo_handler (gpointer userdata) |
323 | 323 |
return TRUE; |
324 | 324 |
} |
325 | 325 |
|
326 |
-void enable_centisecond_timer(void) |
|
326 |
+void hal_enable_centisecond_timer(void) |
|
327 | 327 |
{ |
328 | 328 |
ui_g->centisecond_active = TRUE; |
329 | 329 |
g_timeout_add(10, centisecond_tmo_handler, ui_g); |
330 | 330 |
} |
331 | 331 |
|
332 |
-void disable_centisecond_timer(void) |
|
332 |
+void hal_disable_centisecond_timer(void) |
|
333 | 333 |
{ |
334 | 334 |
ui_g->centisecond_active = FALSE; |
335 | 335 |
} |
... | ... |
@@ -346,17 +346,67 @@ static gboolean halfsecond_tmo_handler (gpointer userdata) |
346 | 346 |
return TRUE; |
347 | 347 |
} |
348 | 348 |
|
349 |
-void enable_halfsecond_timer(void) |
|
349 |
+void hal_enable_halfsecond_timer(void) |
|
350 | 350 |
{ |
351 | 351 |
ui_g->halfsecond_active = TRUE; |
352 | 352 |
g_timeout_add(500, halfsecond_tmo_handler, ui_g); |
353 | 353 |
} |
354 | 354 |
|
355 |
-void disable_halfsecond_timer(void) |
|
355 |
+void hal_disable_halfsecond_timer(void) |
|
356 | 356 |
{ |
357 | 357 |
ui_g->halfsecond_active = FALSE; |
358 | 358 |
} |
359 | 359 |
|
360 |
+void hal_get_rtc(clock_state *rtc) |
|
361 |
+{ |
|
362 |
+ time_t mt; |
|
363 |
+ struct tm mtime; |
|
364 |
+ |
|
365 |
+ mt = time(NULL); |
|
366 |
+ localtime_r(&mt, &mtime); |
|
367 |
+ |
|
368 |
+ rtc->hour = mtime.tm_hour; |
|
369 |
+ rtc->minute = mtime.tm_min; |
|
370 |
+ rtc->second = mtime.tm_sec; |
|
371 |
+ rtc->day = mtime.tm_mday; |
|
372 |
+ rtc->month = (mtime.tm_mon + 1); |
|
373 |
+ rtc->year = (mtime.tm_year + 1900); |
|
374 |
+} |
|
375 |
+ |
|
376 |
+void hal_set_rtc(const clock_state *rtc, boolean set_set) |
|
377 |
+{ |
|
378 |
+} |
|
379 |
+ |
|
380 |
+void hal_get_power_state(power_state *pwr) |
|
381 |
+{ |
|
382 |
+} |
|
383 |
+ |
|
384 |
+static boolean BacklightState = FALSE; |
|
385 |
+ |
|
386 |
+/* sets the backlight on/off, on=TRUE, off=FALSE */ |
|
387 |
+void hal_lcd_set_backlight(boolean state) |
|
388 |
+{ |
|
389 |
+ g_print("turn LCD backlight %s\n", state ? "on" : "off"); |
|
390 |
+ BacklightState = state; |
|
391 |
+} |
|
392 |
+ |
|
393 |
+boolean hal_lcd_get_backlight(void) |
|
394 |
+{ |
|
395 |
+ return BacklightState; |
|
396 |
+} |
|
397 |
+ |
|
398 |
+ |
|
399 |
+/* sets the vibration motor on/off, on=TRUE, off=FALSE */ |
|
400 |
+void hal_vibration_set_state(boolean state) |
|
401 |
+{ |
|
402 |
+} |
|
403 |
+ |
|
404 |
+boolean hal_vibration_get_state(void) |
|
405 |
+{ |
|
406 |
+ return FALSE; |
|
407 |
+} |
|
408 |
+ |
|
409 |
+ |
|
360 | 410 |
int main(int argc , char ** argv) |
361 | 411 |
{ |
362 | 412 |
oswald_ui ui; |
... | ... |
@@ -1,5 +1,6 @@ |
1 | 1 |
#ifndef _OSWALD_H |
2 | 2 |
#define _OSWALD_H |
3 |
+#include <stdint.h> |
|
3 | 4 |
|
4 | 5 |
//#define DEBUG 1 |
5 | 6 |
#ifdef DEBUG |
... | ... |
@@ -30,20 +31,36 @@ typedef struct { |
30 | 31 |
u8t minute; |
31 | 32 |
u8t second; |
32 | 33 |
u8t day; |
34 |
+ u8t wday; // day in week, 0=sunday, 1=monday,... |
|
33 | 35 |
u8t month; |
34 | 36 |
u16t year; |
35 | 37 |
boolean clk24hr; |
36 | 38 |
boolean day_first; |
37 | 39 |
} clock_state; |
38 | 40 |
|
41 |
+#define WDAY_SUNDAY (1 << 0) |
|
42 |
+#define WDAY_MONDAY (1 << 1) |
|
43 |
+#define WDAY_TUESDAY (1 << 2) |
|
44 |
+#define WDAY_WEDNESDAY (1 << 3) |
|
45 |
+#define WDAY_THURSDAY (1 << 4) |
|
46 |
+#define WDAY_FRIDAY (1 << 5) |
|
47 |
+#define WDAY_SATURDAY (1 << 6) |
|
48 |
+typedef struct { |
|
49 |
+ u8t hour; |
|
50 |
+ u8t minute; |
|
51 |
+ u8t wday; // bitfield 0 to 6, 1=sunday, 2=monday, 4=tuesday... |
|
52 |
+} alarm_clk; |
|
53 |
+ |
|
39 | 54 |
typedef enum { |
40 | 55 |
IDLE_SCREEN = 0, |
56 |
+ ALARM_SETUP_SCREEN, |
|
57 |
+ STOP_WATCH_SCREEN, |
|
41 | 58 |
ACCEL_DISPLAY_SCREEN, |
42 | 59 |
MENU_TEST_SCREEN, |
43 |
- STOP_WATCH_SCREEN, |
|
44 | 60 |
// APPLICATION_SCREEN, |
45 | 61 |
LAST_SCREEN, // a marker for the last (not valid) screen) |
46 | 62 |
DATETIME_SETTING_SCREEN, |
63 |
+ ALARM_SCREEN, |
|
47 | 64 |
SCREENS_END, |
48 | 65 |
} screen_number; |
49 | 66 |
|
... | ... |
@@ -66,6 +83,8 @@ typedef enum { |
66 | 83 |
#define EVENT_AMBIENTLIGHT_UPDATE (1<<7) // ambient light sensor updates |
67 | 84 |
#define EVENT_POWER_CHANGE (1<<8) // power source status change |
68 | 85 |
#define EVENT_COMMS (1<<9) // communication, like Bluetooth I/O |
86 |
+#define EVENT_POWER_STATE (1<<10) // power source changed or similar |
|
87 |
+ |
|
69 | 88 |
|
70 | 89 |
typedef struct { |
71 | 90 |
u16t event_mask; // the event the screen wants to receive |
... | ... |
@@ -85,5 +104,26 @@ typedef struct { |
85 | 104 |
u8t z; |
86 | 105 |
} accel_data_t; |
87 | 106 |
|
88 |
-#endif |
|
107 |
+#define POWER_SOURCE_BATTERY 0 |
|
108 |
+#define POWER_SOURCE_EXTERNAL 1 |
|
109 |
+ |
|
110 |
+#define POWER_CHARGER_DONE 0 |
|
111 |
+#define POWER_CHARGER_PRECHARGE 1 |
|
112 |
+#define POWER_CHARGER_CHARGING 2 |
|
113 |
+#define POWER_CHARGER_UNK 3 |
|
114 |
+ |
|
115 |
+typedef struct { |
|
116 |
+ u8t source; |
|
117 |
+ u8t charge_state; |
|
118 |
+ u8t percent; |
|
119 |
+ u16t level; |
|
120 |
+} power_state; |
|
89 | 121 |
|
122 |
+typedef enum { |
|
123 |
+ BLUETOOTH_OFF = 0, |
|
124 |
+ BLUETOOTH_ON, |
|
125 |
+ BLUETOOTH_CONNECTED, |
|
126 |
+ BLUETOOTH_ILL |
|
127 |
+} bluetooth_state; |
|
128 |
+ |
|
129 |
+#endif |
... | ... |
@@ -5,7 +5,19 @@ |
5 | 5 |
#include "oswald_graphics.h" |
6 | 6 |
|
7 | 7 |
|
8 |
-void oswald_draw_Line(u8t xstart, u8t ystart, u8t xend, u8t yend) |
|
8 |
+void oswald_draw_bitmap(const uint8_t xstart, const uint8_t ystart, const uint8_t width, const uint8_t height, const void *bmp) |
|
9 |
+{ |
|
10 |
+ uint8_t x, y; |
|
11 |
+ |
|
12 |
+ // we only draw set pixel, unset pixel remain as they are |
|
13 |
+ for (y=0; y<height; y++) { |
|
14 |
+ for (x=0; x<width; x++) { |
|
15 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
16 |
+ } |
|
17 |
+ } |
|
18 |
+} |
|
19 |
+ |
|
20 |
+void oswald_draw_Line(uint8_t xstart, uint8_t ystart, uint8_t xend, uint8_t yend) |
|
9 | 21 |
{ |
10 | 22 |
int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; |
11 | 23 |
|
... | ... |
@@ -33,7 +45,7 @@ void oswald_draw_Line(u8t xstart, u8t ystart, u8t xend, u8t yend) |
33 | 45 |
x = xstart; |
34 | 46 |
y = ystart; |
35 | 47 |
err = el/2; |
36 |
- lcd_set_pixel(x, y, TRUE); |
|
48 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
37 | 49 |
|
38 | 50 |
for (t = 0; t < el; ++t) { |
39 | 51 |
err -= es; |
... | ... |
@@ -45,9 +57,9 @@ void oswald_draw_Line(u8t xstart, u8t ystart, u8t xend, u8t yend) |
45 | 57 |
x += pdx; |
46 | 58 |
y += pdy; |
47 | 59 |
} |
48 |
- lcd_set_pixel(x, y, TRUE); |
|
60 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
49 | 61 |
} |
50 |
- lcd_update_display(); |
|
62 |
+ hal_lcd_update_display(); |
|
51 | 63 |
} |
52 | 64 |
|
53 | 65 |
void oswald_draw_line_ww(u8t xstart, u8t ystart, u8t xend, u8t yend, u8t thickness) |
... | ... |
@@ -78,12 +90,12 @@ void oswald_draw_line_ww(u8t xstart, u8t ystart, u8t xend, u8t yend, u8t thickne |
78 | 90 |
x = xstart; |
79 | 91 |
y = ystart; |
80 | 92 |
err = el/2; |
81 |
- lcd_set_pixel(x, y, TRUE); |
|
93 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
82 | 94 |
for (i=1; i<thickness; i++) { |
83 |
- lcd_set_pixel(x-i, y, TRUE); |
|
84 |
- lcd_set_pixel(x+i, y, TRUE); |
|
85 |
- lcd_set_pixel(x, y-i, TRUE); |
|
86 |
- lcd_set_pixel(x, y+i, TRUE); |
|
95 |
+ hal_lcd_set_pixel(x-i, y, TRUE); |
|
96 |
+ hal_lcd_set_pixel(x+i, y, TRUE); |
|
97 |
+ hal_lcd_set_pixel(x, y-i, TRUE); |
|
98 |
+ hal_lcd_set_pixel(x, y+i, TRUE); |
|
87 | 99 |
} |
88 | 100 |
|
89 | 101 |
for (t = 0; t < el; ++t) { |
... | ... |
@@ -96,15 +108,15 @@ void oswald_draw_line_ww(u8t xstart, u8t ystart, u8t xend, u8t yend, u8t thickne |
96 | 108 |
x += pdx; |
97 | 109 |
y += pdy; |
98 | 110 |
} |
99 |
- lcd_set_pixel(x, y, TRUE); |
|
111 |
+ hal_lcd_set_pixel(x, y, TRUE); |
|
100 | 112 |
for (i=1; i<thickness; i++) { |
101 |
- lcd_set_pixel(x-i, y, TRUE); |
|
102 |
- lcd_set_pixel(x+i, y, TRUE); |
|
103 |
- lcd_set_pixel(x, y-i, TRUE); |
|
104 |
- lcd_set_pixel(x, y+i, TRUE); |
|
113 |
+ hal_lcd_set_pixel(x-i, y, TRUE); |
|
114 |
+ hal_lcd_set_pixel(x+i, y, TRUE); |
|
115 |
+ hal_lcd_set_pixel(x, y-i, TRUE); |
|
116 |
+ hal_lcd_set_pixel(x, y+i, TRUE); |
|
105 | 117 |
} |
106 | 118 |
} |
107 |
- lcd_update_display(); |
|
119 |
+ hal_lcd_update_display(); |
|
108 | 120 |
} |
109 | 121 |
|
110 | 122 |
u8t oswald_write_character(u8t x, u8t y, oswald_font_face face, u8t Character) |
... | ... |
@@ -121,10 +133,10 @@ u8t oswald_write_character(u8t x, u8t y, oswald_font_face face, u8t Character) |
121 | 133 |
for (ly=0; ly<CharacterHeight; ly++) { |
122 | 134 |
for (lx=0; lx<CharacterWidth; lx++) { |
123 | 135 |
if (bitmap[ly] & (1<<lx)) { |
124 |
- lcd_set_pixel(lx+x, ly+y, TRUE); |
|
136 |
+ hal_lcd_set_pixel(lx+x, ly+y, TRUE); |
|
125 | 137 |
// printf("."); |
126 | 138 |
} else { |
127 |
- lcd_set_pixel(lx+x, ly+y, FALSE); |
|
139 |
+ hal_lcd_set_pixel(lx+x, ly+y, FALSE); |
|
128 | 140 |
// printf(" "); |
129 | 141 |
} |
130 | 142 |
} |
... | ... |
@@ -8,7 +8,7 @@ |
8 | 8 |
#include "oswald_graphics.h" |
9 | 9 |
|
10 | 10 |
|
11 |
-void oswald_draw_Line(u8t xstart, u8t ystart, u8t xend, u8t yend); |
|
11 |
+void oswald_draw_Line(uint8_t xstart, uint8_t ystart, uint8_t xend, uint8_t yend); |
|
12 | 12 |
|
13 | 13 |
void oswald_draw_line_ww(u8t xstart, u8t ystart, u8t xend, u8t yend, u8t thickness); |
14 | 14 |
|
15 | 15 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,30 @@ |
1 |
+#ifndef _oswald_hal_h |
|
2 |
+#define _oswald_hal_h |
|
3 |
+ |
|
4 |
+/* |
|
5 |
+ * these functions must be implemented for a concrete hardware |
|
6 |
+ */ |
|
7 |
+ |
|
8 |
+void hal_lcd_set_pixel(unsigned int x, unsigned int y, unsigned char state); |
|
9 |
+void hal_lcd_clear_display(void); |
|
10 |
+void hal_lcd_update_display(void); |
|
11 |
+/* sets the backlight on/off, on=TRUE, off=FALSE */ |
|
12 |
+void hal_lcd_set_backlight(boolean state); |
|
13 |
+boolean hal_lcd_get_backlight(void); |
|
14 |
+ |
|
15 |
+void hal_enable_centisecond_timer(void); |
|
16 |
+void hal_disable_centisecond_timer(void); |
|
17 |
+ |
|
18 |
+void hal_enable_halfsecond_timer(void); |
|
19 |
+void hal_disable_halfsecond_timer(void); |
|
20 |
+ |
|
21 |
+void hal_get_rtc(clock_state *rtc); |
|
22 |
+void hal_set_rtc(clock_state *rtc, boolean set_set); |
|
23 |
+void hal_get_power_state(power_state *pwr); |
|
24 |
+ |
|
25 |
+/* sets the vibration motor on/off, on=TRUE, off=FALSE */ |
|
26 |
+void hal_vibration_set_state(boolean state); |
|
27 |
+boolean hal_vibration_get_state(void); |
|
28 |
+ |
|
29 |
+#endif |
|
30 |
+ |
... | ... |
@@ -1,6 +1,7 @@ |
1 | 1 |
#include "oswald.h" |
2 | 2 |
#include "oswald_watch_faces.h" |
3 | 3 |
#include "oswald_screens.h" |
4 |
+#include "oswald_hal.h" |
|
4 | 5 |
|
5 | 6 |
#include "embedvm.h" |
6 | 7 |
|
... | ... |
@@ -12,9 +13,11 @@ |
12 | 13 |
* through function calls thus saving stack space |
13 | 14 |
*/ |
14 | 15 |
clock_state OswaldClk; |
16 |
+alarm_clk OswaldAlarm; |
|
15 | 17 |
watch_state OswaldState; |
16 | 18 |
watch_screen OswaldScreens[SCREENS_END]; |
17 |
- |
|
19 |
+power_state OswaldPowerState; |
|
20 |
+u8t backlight_safety_off = 0; |
|
18 | 21 |
|
19 | 22 |
void oswald_change_to_screen(screen_number screen_id) |
20 | 23 |
{ |
... | ... |
@@ -45,29 +48,33 @@ void oswald_set_date(u8t day, u8t month, u16t year, boolean day_first) |
45 | 48 |
|
46 | 49 |
static void update_clock_state (void) |
47 | 50 |
{ |
48 |
- OswaldClk.second += 1; |
|
49 |
- if (OswaldClk.second > 59) { |
|
50 |
- OswaldClk.second = 0; |
|
51 |
- OswaldClk.minute += 1; |
|
52 |
- } else |
|
53 |
- return; |
|
54 |
- if (OswaldClk.minute > 59) { |
|
55 |
- OswaldClk.minute = 0; |
|
56 |
- OswaldClk.hour += 1; |
|
57 |
- } else |
|
58 |
- return; |
|
59 |
- if (OswaldClk.hour > 23) { |
|
60 |
- OswaldClk.hour = 0; |
|
61 |
- // day++ |
|
62 |
- } else |
|
63 |
- return; |
|
51 |
+ hal_get_rtc(&OswaldClk); |
|
52 |
+ |
|
53 |
+ /* check for pending alarm once per minute */ |
|
54 |
+ if (OswaldClk.second == 0) { |
|
55 |
+ if (OswaldClk.hour == OswaldAlarm.hour && |
|
56 |
+ OswaldClk.minute == OswaldAlarm.minute && |
|
57 |
+ ((1 << OswaldClk.wday) & OswaldAlarm.wday)) { |
|
58 |
+ OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL); |
|
59 |
+ OswaldState.screen_id = ALARM_SCREEN; |
|
60 |
+ OswaldState.screen = &OswaldScreens[OswaldState.screen_id]; |
|
61 |
+ OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL); |
|
62 |
+ } |
|
63 |
+ } |
|
64 | 64 |
} |
65 | 65 |
|
66 | 66 |
void oswald_one_second_tick(void) |
67 | 67 |
{ |
68 |
- /* update our 'RTC' */ |
|
68 |
+ /* update clock - should use RTC if available */ |
|
69 | 69 |
update_clock_state(); |
70 | 70 |
|
71 |
+ hal_get_power_state(&OswaldPowerState); |
|
72 |
+ if (backlight_safety_off) { |
|
73 |
+ backlight_safety_off--; |
|
74 |
+ if (!backlight_safety_off) |
|
75 |
+ hal_lcd_set_backlight(FALSE); |
|
76 |
+ } |
|
77 |
+ |
|
71 | 78 |
/* wake-up screen if interested in the one-second-event */ |
72 | 79 |
if (OswaldState.screen->event_func != NULL && |
73 | 80 |
(OswaldState.screen->event_mask & EVENT_ONE_SEC_TIMER)) |
... | ... |
@@ -91,10 +98,20 @@ void oswald_halfsecond_tick(void) |
91 | 98 |
void oswald_handle_button_press(watch_button button) |
92 | 99 |
{ |
93 | 100 |
switch (button) { |
101 |
+ case BUTTON_D: |
|
102 |
+ // backlight on/off |
|
103 |
+ if (hal_lcd_get_backlight()) { |
|
104 |
+ hal_lcd_set_backlight(FALSE); |
|
105 |
+ backlight_safety_off = 0; |
|
106 |
+ } else { |
|
107 |
+ hal_lcd_set_backlight(TRUE); |
|
108 |
+ backlight_safety_off = 2; |
|
109 |
+ } |
|
110 |
+ break; |
|
94 | 111 |
case BUTTON_A: |
95 | 112 |
case BUTTON_B: |
96 |
- case BUTTON_D: |
|
97 | 113 |
case BUTTON_E: |
114 |
+ case BUTTON_F: |
|
98 | 115 |
if (OswaldState.screen->event_func != NULL && |
99 | 116 |
(OswaldState.screen->event_mask & EVENT_USER_BUTTONS)) |
100 | 117 |
OswaldState.screen->event_func(EVENT_USER_BUTTONS, &button); |
... | ... |
@@ -109,9 +126,6 @@ void oswald_handle_button_press(watch_button button) |
109 | 126 |
OswaldState.screen = &OswaldScreens[OswaldState.screen_id]; |
110 | 127 |
OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL); |
111 | 128 |
break; |
112 |
- case BUTTON_F: |
|
113 |
- // backlight on/off |
|
114 |
- break; |
|
115 | 129 |
default: |
116 | 130 |
// should never get here |
117 | 131 |
break; |
... | ... |
@@ -149,16 +163,26 @@ void oswald_init(void) |
149 | 163 |
OswaldScreens[DATETIME_SETTING_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER; |
150 | 164 |
OswaldScreens[DATETIME_SETTING_SCREEN].event_func = datetime_setup_events; |
151 | 165 |
|
166 |
+ OswaldScreens[ALARM_SETUP_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER; |
|
167 |
+ OswaldScreens[ALARM_SETUP_SCREEN].event_func = alarm_setup_events; |
|
168 |
+ |
|
152 | 169 |
OswaldScreens[MENU_TEST_SCREEN].event_mask = EVENT_USER_BUTTONS; |
153 | 170 |
OswaldScreens[MENU_TEST_SCREEN].event_func = test_menu_handle_events; |
154 | 171 |
|
155 | 172 |
OswaldScreens[STOP_WATCH_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_CS_TIMER; |
156 | 173 |
OswaldScreens[STOP_WATCH_SCREEN].event_func = stop_watch_handle_events; |
157 | 174 |
|
175 |
+ OswaldScreens[ALARM_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_HALF_SEC_TIMER; |
|
176 |
+ OswaldScreens[ALARM_SCREEN].event_func = alarm_handle_events; |
|
177 |
+ |
|
158 | 178 |
OswaldState.screen_id = IDLE_SCREEN; |
159 | 179 |
OswaldState.screen = &OswaldScreens[OswaldState.screen_id]; |
160 | 180 |
|
161 | 181 |
if (OswaldState.screen->event_func != NULL) |
162 | 182 |
OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL); |
183 |
+ |
|
184 |
+ OswaldAlarm.hour = 12; |
|
185 |
+ OswaldAlarm.minute = 0; |
|
186 |
+ OswaldAlarm.wday = 0x00; |
|
163 | 187 |
} |
164 | 188 |
|
... | ... |
@@ -4,6 +4,8 @@ |
4 | 4 |
#include "oswald.h" |
5 | 5 |
|
6 | 6 |
extern clock_state OswaldClk; |
7 |
+extern alarm_clk OswaldAlarm; |
|
8 |
+extern power_state OswaldPowerState; |
|
7 | 9 |
extern watch_state OswaldState; |
8 | 10 |
extern watch_screen OswaldScreens[]; |
9 | 11 |
|
... | ... |
@@ -24,4 +26,3 @@ void oswald_centisecond_tick(void); |
24 | 26 |
void oswald_init(void); |
25 | 27 |
|
26 | 28 |
#endif |
27 |
- |
... | ... |
@@ -1,8 +1,11 @@ |
1 |
+#include <stdio.h> |
|
2 |
+ |
|
1 | 3 |
#include "oswald.h" |
2 | 4 |
#include "oswald_main.h" |
3 | 5 |
#include "oswald_watch_faces.h" |
4 | 6 |
#include "Fonts.h" |
5 | 7 |
#include "LcdDisplay.h" |
8 |
+#include "oswald_hal.h" |
|
6 | 9 |
|
7 | 10 |
#include "oswald_screens.h" |
8 | 11 |
|
... | ... |
@@ -14,7 +17,7 @@ typedef struct { |
14 | 17 |
} idle_data_t; |
15 | 18 |
static idle_data_t idle_screen = { |
16 | 19 |
DrawLcdDigitalClock, |
17 |
- FALSE, |
|
20 |
+ TRUE, |
|
18 | 21 |
FALSE, |
19 | 22 |
}; |
20 | 23 |
|
... | ... |
@@ -36,7 +39,7 @@ void idle_handle_user_buttons(watch_button button) |
36 | 39 |
idle_screen.screendraw_func = DrawLcdAnaClock; |
37 | 40 |
}; |
38 | 41 |
break; |
39 |
- case BUTTON_D: |
|
42 |
+ case BUTTON_F: |
|
40 | 43 |
OswaldState.screen_id = DATETIME_SETTING_SCREEN; |
41 | 44 |
OswaldState.screen = &OswaldScreens[OswaldState.screen_id]; |
42 | 45 |
OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL); |
... | ... |
@@ -74,7 +77,7 @@ static accelscreen_data_t accel_screen = { |
74 | 77 |
|
75 | 78 |
void draw_accel_screen(accel_data_t *accel_data) |
76 | 79 |
{ |
77 |
- lcd_clear_display(); |
|
80 |
+ hal_lcd_clear_display(); |
|
78 | 81 |
SetFont(MetaWatch16); |
79 | 82 |
WriteLcdString(2, 2, "X:"); |
80 | 83 |
WriteLcdNumber(20, 2, accel_data->x); |
... | ... |
@@ -82,7 +85,7 @@ void draw_accel_screen(accel_data_t *accel_data) |
82 | 85 |
WriteLcdNumber(20, 18, accel_data->y); |
83 | 86 |
WriteLcdString(2, 34, "Z:"); |
84 | 87 |
WriteLcdNumber(20, 34, accel_data->z); |
85 |
- lcd_update_display(); |
|
88 |
+ hal_lcd_update_display(); |
|
86 | 89 |
} |
87 | 90 |
|
88 | 91 |
void accel_handle_events(u16t event, void *data) |
... | ... |
@@ -119,7 +122,7 @@ static datetime_setup_data_t dt_setup_screen = { |
119 | 122 |
|
120 | 123 |
void draw_datetime_setup_screen(datetime_setup_data_t *sdata) |
121 | 124 |
{ |
122 |
- lcd_clear_display(); |
|
125 |
+ hal_lcd_clear_display(); |
|
123 | 126 |
SetFont(MetaWatch16); |
124 | 127 |
WriteLcdString(2, 2, "Set"); |
125 | 128 |
|
... | ... |
@@ -172,7 +175,7 @@ void draw_datetime_setup_screen(datetime_setup_data_t *sdata) |
172 | 175 |
} |
173 | 176 |
WriteLcdString(15, 79, "dd.mm. mm/dd"); |
174 | 177 |
|
175 |
- lcd_update_display(); |
|
178 |
+ hal_lcd_update_display(); |
|
176 | 179 |
} |
177 | 180 |
|
178 | 181 |
void datetime_handle_updown(u8t pos, s8t incr) |
... | ... |
@@ -235,6 +238,10 @@ void datetime_handle_updown(u8t pos, s8t incr) |
235 | 238 |
default: |
236 | 239 |
break; |
237 | 240 |
}; |
241 |
+ if (pos == 2) |
|
242 |
+ hal_set_rtc(&OswaldClk, TRUE); |
|
243 |
+ else |
|
244 |
+ hal_set_rtc(&OswaldClk, FALSE); |
|
238 | 245 |
} |
239 | 246 |
|
240 | 247 |
void handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata) |
... | ... |
@@ -246,7 +253,7 @@ void handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *s |
246 | 253 |
case BUTTON_B: |
247 | 254 |
datetime_handle_updown(sdata->pos, -1); |
248 | 255 |
break; |
249 |
- case BUTTON_D: |
|
256 |
+ case BUTTON_F: |
|
250 | 257 |
sdata->pos++; |
251 | 258 |
sdata->pos %= 8; |
252 | 259 |
break; |
... | ... |
@@ -260,11 +267,12 @@ void datetime_setup_events(u16t event, void *data) |
260 | 267 |
{ |
261 | 268 |
switch (event) { |
262 | 269 |
case EVENT_SCREEN_VISIBLE: |
270 |
+ dt_setup_screen.pos = 0; |
|
263 | 271 |
draw_datetime_setup_screen(&dt_setup_screen); |
264 |
- enable_halfsecond_timer(); |
|
272 |
+ hal_enable_halfsecond_timer(); |
|
265 | 273 |
break; |
266 | 274 |
case EVENT_SCREEN_DESTROY: |
267 |
- disable_halfsecond_timer(); |
|
275 |
+ hal_disable_halfsecond_timer(); |
|
268 | 276 |
break; |
269 | 277 |
case EVENT_USER_BUTTONS: |
270 | 278 |
dbg_out("button event %d\n", *(int *)data); |
... | ... |
@@ -282,6 +290,172 @@ void datetime_setup_events(u16t event, void *data) |
282 | 290 |
}; |
283 | 291 |
} |
284 | 292 |
|
293 |
+typedef struct { |
|
294 |
+ u8t pos; |
|
295 |
+ boolean on; |
|
296 |
+} alarm_setup_data_t; |
|
297 |
+static alarm_setup_data_t alarm_setup_screen = { |
|
298 |
+ 0, |
|
299 |
+ TRUE |
|
300 |
+}; |
|
301 |
+ |
|
302 |
+void draw_alarm_setup_screen(alarm_setup_data_t *sdata) |
|
303 |
+{ |
|
304 |
+ hal_lcd_clear_display(); |
|
305 |
+ |
|
306 |
+ SetFont(MetaWatch16); |
|
307 |
+ WriteLcdString(2, 2, "Alarm"); |
|
308 |
+ |
|
309 |
+ SetFont(MetaWatchTime); |
|
310 |
+ if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) { |
|
311 |
+ WriteLcdCharacter(2, 20, (OswaldAlarm.hour / 10)); |
|
312 |
+ WriteLcdCharacter(14, 20, (OswaldAlarm.hour % 10)); |
|
313 |
+ } |
|
314 |
+ WriteLcdCharacter(26, 20, TIME_CHARACTER_COLON_INDEX); |
|
315 |
+ |
|
316 |
+ if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) { |
|
317 |
+ WriteLcdCharacter(31, 20, (OswaldAlarm.minute / 10)); |
|
318 |
+ WriteLcdCharacter(43, 20, (OswaldAlarm.minute % 10)); |
|
319 |
+ } |
|
320 |
+ |
|
321 |
+ SetFont(MetaWatchMonospaced10); |
|
322 |
+ WriteLcdCharacter(3, 45, 'S'); |
|
323 |
+ WriteLcdCharacter(15, 45, 'M'); |
|
324 |
+ WriteLcdCharacter(27, 45, 'T'); |
|
325 |
+ WriteLcdCharacter(39, 45, 'W'); |
|
326 |
+ WriteLcdCharacter(51, 45, 'T'); |
|
327 |
+ WriteLcdCharacter(63, 45, 'F'); |
|
328 |
+ WriteLcdCharacter(75, 45, 'S'); |
|
329 |
+ |
|
330 |
+ if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) |
|
331 |
+ WriteLcdCharacter(3, 55, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_'); |
|
332 |
+ if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) |
|
333 |
+ WriteLcdCharacter(15, 55, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_'); |
|
334 |
+ if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) |
|
335 |
+ WriteLcdCharacter(27, 55, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_'); |
|
336 |
+ if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) |
|
337 |
+ WriteLcdCharacter(39, 55, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_'); |
|
338 |
+ if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) |
|
339 |
+ WriteLcdCharacter(51, 55, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_'); |
|
340 |
+ if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) |
|
341 |
+ WriteLcdCharacter(63, 55, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_'); |
|
342 |
+ if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8) |
|
343 |
+ WriteLcdCharacter(75, 55, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_'); |
|
344 |
+ |
|
345 |
+#if 0 |
|
346 |
+ SetFont(MetaWatch7); |
|
347 |
+ if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) { |
|
348 |
+ if (OswaldClk.clk24hr) |
|
349 |
+ WriteLcdString(2, 66, "x"); |
|
350 |
+ else |
|
351 |
+ WriteLcdString(2, 66, "_"); |
|
352 |
+ } |
|
353 |
+ WriteLcdString(15, 66, "24hr"); |
|
354 |
+ |
|
355 |
+ if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) { |
|
356 |
+ if (OswaldClk.day_first) |
|
357 |
+ WriteLcdString(2, 79, "x"); |
|
358 |
+ else |
|
359 |
+ WriteLcdString(2, 79, "_"); |
|
360 |
+ } |
|
361 |
+ WriteLcdString(15, 79, "dd.mm. mm/dd"); |
|
362 |
+#endif |
|
363 |
+ hal_lcd_update_display(); |
|
364 |
+} |
|
365 |
+ |
|
366 |
+void alarm_handle_updown(u8t pos, s8t incr) |
|
367 |
+{ |
|
368 |
+ switch (pos) { |
|
369 |
+ case 0: // hour |
|
370 |
+ if (OswaldAlarm.hour == 0 && incr == -1) { |
|
371 |
+ OswaldAlarm.hour = 23; |
|
372 |
+ break; |
|
373 |
+ }; |
|
374 |
+ OswaldAlarm.hour += incr; |
|
375 |
+ if (OswaldAlarm.hour > 23) |
|
376 |
+ OswaldAlarm.hour = 0; |
|
377 |
+ break; |
|
378 |
+ case 1: // minute |
|
379 |
+ if (OswaldAlarm.minute == 0 && incr == -1) { |
|
380 |
+ OswaldAlarm.minute = 59; |
|
381 |
+ break; |
|
382 |
+ }; |
|
383 |
+ OswaldAlarm.minute += incr; |
|
384 |
+ if (OswaldAlarm.minute > 59) |
|
385 |
+ OswaldAlarm.minute = 0; |
|
386 |
+ break; |
|
387 |
+ case 2: // sunday |
|
388 |
+ OswaldAlarm.wday ^= WDAY_SUNDAY; |
|
389 |
+ break; |
|
390 |
+ case 3: // monday |
|
391 |
+ OswaldAlarm.wday ^= WDAY_MONDAY; |
|
392 |
+ break; |
|
393 |
+ case 4: // tuesday |
|
394 |
+ OswaldAlarm.wday ^= WDAY_TUESDAY; |
|
395 |
+ break; |
|
396 |
+ case 5: // wednesday |
|
397 |
+ OswaldAlarm.wday ^= WDAY_WEDNESDAY; |
|
398 |
+ break; |
|
399 |
+ case 6: // thursday |
|
400 |
+ OswaldAlarm.wday ^= WDAY_THURSDAY; |
|
401 |
+ break; |
|
402 |
+ case 7: // friday |
|
403 |
+ OswaldAlarm.wday ^= WDAY_FRIDAY; |
|
404 |
+ break; |
|
405 |
+ case 8: // saturday |
|
406 |
+ OswaldAlarm.wday ^= WDAY_SATURDAY; |
|
407 |
+ break; |
|
408 |
+ default: |
|
409 |
+ break; |
|
410 |
+ }; |
|
411 |
+} |
|
412 |
+ |
|
413 |
+void handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata) |
|
414 |
+{ |
|
415 |
+ switch (button) { |
|
416 |
+ case BUTTON_A: |
|
417 |
+ alarm_handle_updown(sdata->pos, 1); |
|
418 |
+ break; |
|
419 |
+ case BUTTON_B: |
|
420 |
+ alarm_handle_updown(sdata->pos, -1); |
|
421 |
+ break; |
|
422 |
+ case BUTTON_F: |
|
423 |
+ sdata->pos++; |
|
424 |
+ sdata->pos %= 9; |
|
425 |
+ break; |
|
426 |
+ default: |
|
427 |
+ break; |
|
428 |
+ } |
|
429 |
+ draw_alarm_setup_screen(sdata); |
|
430 |
+} |
|
431 |
+ |
|
432 |
+void alarm_setup_events(u16t event, void *data) |
|
433 |
+{ |
|
434 |
+ switch (event) { |
|
435 |
+ case EVENT_SCREEN_VISIBLE: |
|
436 |
+ alarm_setup_screen.pos = 0; |
|
437 |
+ draw_alarm_setup_screen(&alarm_setup_screen); |
|
438 |
+ hal_enable_halfsecond_timer(); |
|
439 |
+ break; |
|
440 |
+ case EVENT_SCREEN_DESTROY: |
|
441 |
+ hal_disable_halfsecond_timer(); |
|
442 |
+ break; |
|
443 |
+ case EVENT_USER_BUTTONS: |
|
444 |
+ dbg_out("button event %d\n", *(int *)data); |
|
445 |
+ handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen); |
|
446 |
+ break; |
|
447 |
+ case EVENT_HALF_SEC_TIMER: |
|
448 |
+ if (alarm_setup_screen.on) |
|
449 |
+ alarm_setup_screen.on = FALSE; |
|
450 |
+ else |
|
451 |
+ alarm_setup_screen.on = TRUE; |
|
452 |
+ draw_alarm_setup_screen(&alarm_setup_screen); |
|
453 |
+ break; |
|
454 |
+ default: |
|
455 |
+ break; |
|
456 |
+ }; |
|
457 |
+} |
|
458 |
+ |
|
285 | 459 |
|
286 | 460 |
typedef struct { |
287 | 461 |
u8t menu_pos; |
... | ... |
@@ -290,7 +464,7 @@ static test_menu_t test_menu = { 0 }; |
290 | 464 |
|
291 | 465 |
void draw_menu_test_screen(void) |
292 | 466 |
{ |
293 |
- lcd_clear_display(); |
|
467 |
+ hal_lcd_clear_display(); |
|
294 | 468 |
SetFont(MetaWatch16); |
295 | 469 |
WriteLcdString(2, 2, "Menu"); |
296 | 470 |
SetFont(MetaWatch7); |
... | ... |
@@ -301,7 +475,7 @@ void draw_menu_test_screen(void) |
301 | 475 |
WriteLcdString(2, 56, "Item 5"); |
302 | 476 |
|
303 | 477 |
WriteLcdString(50, 20+(9*test_menu.menu_pos), "*"); |
304 |
- lcd_update_display(); |
|
478 |
+ hal_lcd_update_display(); |
|
305 | 479 |
} |
306 | 480 |
|
307 | 481 |
static void handle_menu_user_buttons(watch_button button) |
... | ... |
@@ -354,8 +528,10 @@ static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE }; |
354 | 528 |
|
355 | 529 |
static void update_stop_watch_screen(stopwatch_data_t *sdata) |
356 | 530 |
{ |
531 |
+ char tstr[16]; |
|
357 | 532 |
SetFont(MetaWatchMonospaced10); |
358 | 533 |
|
534 |
+#if 0 |
|
359 | 535 |
WriteLcdNumber(0, 30, sdata->hr); |
360 | 536 |
WriteLcdCharacter(14, 30, ':'); |
361 | 537 |
WriteLcdNumber(19, 30, sdata->min); |
... | ... |
@@ -371,8 +547,14 @@ static void update_stop_watch_screen(stopwatch_data_t *sdata) |
371 | 547 |
WriteLcdNumber(38, 50, sdata->lapse_sec); |
372 | 548 |
WriteLcdCharacter(52, 50, '.'); |
373 | 549 |
WriteLcdNumber(57, 50, sdata->lapse_csec / 10); |
374 |
- |
|
375 |
- lcd_update_display(); |
|
550 |
+#else |
|
551 |
+ snprintf(tstr, 16, "%02d:%02d:%02d.%1d", sdata->hr, sdata->min, sdata->sec, sdata->csec / 10); |
|
552 |
+ WriteLcdString(0, 30, tstr); |
|
553 |
+ snprintf(tstr, 16, "%02d:%02d:%02d.%02d", sdata->lapse_hr, sdata->lapse_min, sdata->lapse_sec, sdata->lapse_csec); |
|
554 |
+ WriteLcdString(0, 50, tstr); |
|
555 |
+#endif |
|
556 |
+ |
|
557 |
+ hal_lcd_update_display(); |
|
376 | 558 |
} |
377 | 559 |
|
378 | 560 |
static void draw_stop_watch_screen(stopwatch_data_t *sdata) |
... | ... |
@@ -388,10 +570,10 @@ static void handle_stop_watch_buttons(watch_button button) |
388 | 570 |
switch (button) { |
389 | 571 |
case BUTTON_A: // start/stop |
390 | 572 |
if (stopwatch_screen.running) { |
391 |
- disable_centisecond_timer(); |
|
573 |
+ hal_disable_centisecond_timer(); |
|
392 | 574 |
stopwatch_screen.running = FALSE; |
393 | 575 |
} else { |
394 |
- enable_centisecond_timer(); |
|
576 |
+ hal_enable_centisecond_timer(); |
|
395 | 577 |
stopwatch_screen.running = TRUE; |
396 | 578 |
} |
397 | 579 |
break; |
... | ... |
@@ -401,7 +583,7 @@ static void handle_stop_watch_buttons(watch_button button) |
401 | 583 |
stopwatch_screen.lapse_sec = stopwatch_screen.sec; |
402 | 584 |
stopwatch_screen.lapse_csec = stopwatch_screen.csec; |
403 | 585 |
break; |
404 |
- case BUTTON_D: // reset |
|
586 |
+ case BUTTON_F: // reset |
|
405 | 587 |
stopwatch_screen.hr = 0; |
406 | 588 |
stopwatch_screen.min = 0; |
407 | 589 |
stopwatch_screen.sec = 0; |
... | ... |
@@ -425,11 +607,11 @@ void stop_watch_handle_events(u16t event, void *data) |
425 | 607 |
update_stop_watch_screen(&stopwatch_screen); |
426 | 608 |
break; |
427 | 609 |
case EVENT_SCREEN_VISIBLE: |
428 |
- lcd_clear_display(); |
|
610 |
+ hal_lcd_clear_display(); |
|
429 | 611 |
draw_stop_watch_screen(&stopwatch_screen); |
430 | 612 |
break; |
431 | 613 |
case EVENT_SCREEN_DESTROY: |
432 |
- disable_centisecond_timer(); |
|
614 |
+ hal_disable_centisecond_timer(); |
|
433 | 615 |
stopwatch_screen.running = FALSE; |
434 | 616 |
break; |
435 | 617 |
case EVENT_CS_TIMER: |
... | ... |
@@ -456,3 +638,42 @@ void stop_watch_handle_events(u16t event, void *data) |
456 | 638 |
break; |
457 | 639 |
}; |
458 | 640 |
} |
641 |
+ |
|
642 |
+ |
|
643 |
+void draw_alarm_screen(void) |
|
644 |
+{ |
|
645 |
+ hal_lcd_clear_display(); |
|
646 |
+ |
|
647 |
+ SetFont(MetaWatch16); |
|
648 |
+ WriteLcdString(2, 2, "ALARM !"); |
|
649 |
+ |
|
650 |
+ hal_lcd_update_display(); |
|
651 |
+} |
|
652 |
+ |
|
653 |
+void alarm_handle_events(u16t event, void *data) |
|
654 |
+{ |
|
655 |
+ switch (event) { |
|
656 |
+ case EVENT_SCREEN_VISIBLE: |
|
657 |
+ draw_alarm_screen(); |
|
658 |
+ hal_enable_halfsecond_timer(); |
|
659 |
+ hal_vibration_set_state(TRUE); |
|
660 |
+ break; |
|
661 |
+ case EVENT_SCREEN_DESTROY: |
|
662 |
+ hal_disable_halfsecond_timer(); |
|
663 |
+ hal_lcd_set_backlight(FALSE); |
|
664 |
+ hal_vibration_set_state(FALSE); |
|
665 |
+ break; |
|
666 |
+ case EVENT_USER_BUTTONS: |
|
667 |
+ dbg_out("button event %d\n", *(int *)data); |
|
668 |
+ // hal_lcd_set_backlight(FALSE); |
|
669 |
+ break; |
|
670 |
+ case EVENT_HALF_SEC_TIMER: |
|
671 |
+ hal_lcd_set_backlight(!hal_lcd_get_backlight()); |
|
672 |
+ hal_vibration_set_state(!hal_vibration_get_state()); |
|
673 |
+ dbg_out("timer\n"); |
|
674 |
+ break; |
|
675 |
+ default: |
|
676 |
+ break; |
|
677 |
+ }; |
|
678 |
+} |
|
679 |
+ |
... | ... |
@@ -8,9 +8,13 @@ void accel_handle_events(u16t event, void *data); |
8 | 8 |
|
9 | 9 |
void datetime_setup_events(u16t event, void *data); |
10 | 10 |
|
11 |
+void alarm_setup_events(u16t event, void *data); |
|
12 |
+ |
|
11 | 13 |
void test_menu_handle_events(u16t event, void *data); |
12 | 14 |
|
13 | 15 |
void stop_watch_handle_events(u16t event, void *data); |
14 | 16 |
|
17 |
+void alarm_handle_events(u16t event, void *data); |
|
18 |
+ |
|
15 | 19 |
#endif |
16 | 20 |
|
... | ... |
@@ -1,89 +1,203 @@ |
1 |
-#include <math.h> |
|
1 |
+#include <stdio.h> |
|
2 |
+#include <stdint.h> |
|
2 | 3 |
|
3 | 4 |
#include "oswald.h" |
4 | 5 |
#include "oswald_main.h" |
5 |
-#include "oswald-ui.h" |
|
6 | 6 |
#include "Fonts.h" |
7 | 7 |
#include "LcdDisplay.h" |
8 |
+#include "oswald_hal.h" |
|
8 | 9 |
|
9 | 10 |
#include "oswald_watch_faces.h" |
10 | 11 |
|
12 |
+int16_t sintab[]={ |
|
13 |
+ 0, 2, 3, 5, 7, 9, 10, 12, 14, 16, |
|
14 |
+ 17, 19, 21, 22, 24, 26, 28, 29, 31, 33, |
|
15 |
+ 34, 36, 37, 39, 41, 42, 44, 45, 47, 48, |
|
16 |
+ 50, 52, 53, 54, 56, 57, 59, 60, 62, 63, |
|
17 |
+ 64, 66, 67, 68, 69, 71, 72, 73, 74, 75, |
|
18 |
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, |
|
19 |
+ 87, 87, 88, 89, 90, 91, 91, 92, 93, 93, |
|
20 |
+ 94, 95, 95, 96, 96, 97, 97, 97, 98, 98, |
|
21 |
+ 98, 99, 99, 99, 99, 100, 100, 100, 100, 100, |
|
22 |
+ 100, 100, 100, 100, 100, 100, 99, 99, 99, 99, |
|
23 |
+ 98, 98, 98, 97, 97, 97, 96, 96, 95, 95, |
|
24 |
+ 94, 93, 93, 92, 91, 91, 90, 89, 88, 87, |
|
25 |
+ 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, |
|
26 |
+ 77, 75, 74, 73, 72, 71, 69, 68, 67, 66, |
|
27 |
+ 64, 63, 62, 60, 59, 57, 56, 54, 53, 52, |
|
28 |
+ 50, 48, 47, 45, 44, 42, 41, 39, 37, 36, |
|
29 |
+ 34, 33, 31, 29, 28, 26, 24, 22, 21, 19, |
|
30 |
+ 17, 16, 14, 12, 10, 9, 7, 5, 3, 2, |
|
31 |
+ 0, -2, -3, -5, -7, -9, -10, -12, -14, -16, |
|
32 |
+ -17, -19, -21, -22, -24, -26, -28, -29, -31, -33, |
|
33 |
+ -34, -36, -37, -39, -41, -42, -44, -45, -47, -48, |
|
34 |
+ -50, -52, -53, -54, -56, -57, -59, -60, -62, -63, |
|
35 |
+ -64, -66, -67, -68, -69, -71, -72, -73, -74, -75, |
|
36 |
+ -77, -78, -79, -80, -81, -82, -83, -84, -85, -86, |
|
37 |
+ -87, -87, -88, -89, -90, -91, -91, -92, -93, -93, |
|
38 |
+ -94, -95, -95, -96, -96, -97, -97, -97, -98, -98, |
|
39 |
+ -98, -99, -99, -99, -99,-100,-100,-100,-100,-100, |
|
40 |
+ -100,-100,-100,-100,-100,-100, -99, -99, -99, -99, |
|
41 |
+ -98, -98, -98, -97, -97, -97, -96, -96, -95, -95, |
|
42 |
+ -94, -93, -93, -92, -91, -91, -90, -89, -88, -87, |
|
43 |
+ -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, |
|
44 |
+ -77, -75, -74, -73, -72, -71, -69, -68, -67, -66, |
|
45 |
+ -64, -63, -62, -60, -59, -57, -56, -54, -53, -52, |
|
46 |
+ -50, -48, -47, -45, -44, -42, -41, -39, -37, -36, |
|
47 |
+ -34, -33, -31, -29, -28, -26, -24, -22, -21, -19, |
|
48 |
+ -17, -16, -14, -12, -10, -9, -7, -5, -3, -2 |
|
49 |
+}; |
|
50 |
+ |
|
51 |
+int16_t f_sin(int16_t v) |
|
52 |
+{ |
|
53 |
+ v %= 360; |
|
54 |
+ return sintab[v]; |
|
55 |
+} |
|
56 |
+ |
|
57 |
+int16_t f_cos(int16_t v) |
|
58 |
+{ |
|
59 |
+ v += 90; |
|
60 |
+ v %= 360; |
|
61 |
+ return sintab[v]; |
|
62 |
+} |
|
63 |
+ |
|
11 | 64 |
void DrawLcdAnaClock(boolean show_seconds) |
12 | 65 |
{ |
13 |
- //unsigned char *bbuf; |
|
14 |
- //char daystr[5]; |
|
15 |
- //int len; |
|
16 |
- int i, x, y, x2, y2; |
|
17 |
- double tmp, mf; |
|
18 |
- s8t hour, minute, seconds; |
|
66 |
+ int16_t i, x, y, x2, y2; |
|
67 |
+ int16_t tmp; |
|
68 |
+ int8_t hour, minute, seconds; |
|
69 |
+ char tstr[16]; |
|
19 | 70 |
|
20 | 71 |
hour = OswaldClk.hour; |
21 | 72 |
minute = OswaldClk.minute; |
22 | 73 |
seconds = OswaldClk.second; |
23 | 74 |
|
24 | 75 |
hour -= 3; |
25 |
- mf = (1. / 59.) * (double)minute; |
|
76 |
+ if (hour < 0) |
|
77 |
+ hour += 12; |
|
78 |
+ // mf = (1. / 59.) * (double)minute; |
|
26 | 79 |
minute -= 15; |
80 |
+ if (minute < 0) |
|
81 |
+ minute += 60; |
|
27 | 82 |
seconds -= 15; |
83 |
+ if (seconds < 0) |
|
84 |
+ seconds += 60; |
|
28 | 85 |
|
29 |
- lcd_clear_display(); |
|
86 |
+ hal_lcd_clear_display(); |
|
87 |
+ |
|
88 |
+ SetFont(MetaWatch16); |
|
89 |
+ snprintf(tstr, 16, "%02d", OswaldClk.day); |
|
90 |
+ WriteLcdString(70, 40, tstr); |
|
30 | 91 |
|
31 | 92 |
// plot(R*cos(360° * i/N), R*sin(360° * i/N)) |
32 | 93 |
for (i=0; i<12; i++) { |
33 |
- tmp = 48. + (43. * cos(((2. * M_PI) / 12.) * (double)i)); |
|
94 |
+ tmp = 48 + ((43 * f_cos((360 / 12) * i)) / 100); |
|
34 | 95 |
x = tmp; |
35 |
- tmp = 48 + (43. * sin(((2. * M_PI) / 12.) * (double)i)); |
|
96 |
+ tmp = 48 + ((43 * f_sin((360 / 12) * i)) / 100); |
|
36 | 97 |
y = tmp; |
37 |
- tmp = 48. + (48. * cos(((2. * M_PI) / 12.) * (double)i)); |
|
98 |
+ tmp = 48 + ((48 * f_cos((360 / 12) * i)) / 100); |
|
38 | 99 |
x2 = tmp; |
39 |
- tmp = 48 + (48. * sin(((2. * M_PI) / 12.) * (double)i)); |
|
100 |
+ tmp = 48 + ((48 * f_sin((360 / 12) * i)) / 100); |
|
40 | 101 |
y2 = tmp; |
41 | 102 |
DrawLcdLineBresenhamWW(x, y, x2, y2, 2); |
42 | 103 |
}; |
104 |
+ |
|
43 | 105 |
// Hour |
44 |
- tmp = 48. + (30. * cos(((2. * M_PI) / 12.) * ((double)hour + mf))); |
|
106 |
+ tmp = 48 + (30 * f_cos(((360 / 12) * hour) + ((OswaldClk.minute * 360) /12 / 60)) / 100); |
|
45 | 107 |
x = tmp; |
46 |
- tmp = 48 + (30. * sin(((2. * M_PI) / 12.) * ((double)hour + mf))); |
|
108 |
+ tmp = 48 + (30 * f_sin(((360 / 12) * hour) + ((OswaldClk.minute * 360) /12 / 60)) / 100); |
|
47 | 109 |
y = tmp; |
48 | 110 |
DrawLcdLineBresenhamWW(48, 48, x, y, 2); |
49 | 111 |
// Minute |
50 |
- tmp = 48. + (40. * cos(((2. * M_PI) / 60.) * (double)minute)); |
|
112 |
+ tmp = 48 + ((40 * f_cos((360 / 60) * minute)) / 100); |
|
51 | 113 |
x = tmp; |
52 |
- tmp = 48 + (40. * sin(((2. * M_PI) / 60.) * (double)minute)); |
|
114 |
+ tmp = 48 + ((40 * f_sin((360 / 60) * minute)) / 100); |
|
53 | 115 |
y = tmp; |
54 | 116 |
DrawLcdLineBresenhamWW(48, 48, x, y, 2); |
55 | 117 |
if (show_seconds) { |
56 | 118 |
// Seconds |
57 |
- tmp = 48. + (40. * cos(((2. * M_PI) / 60.) * (double)seconds)); |
|
119 |
+ tmp = 48 + ((40 * f_cos((360 / 60) * seconds)) / 100); |
|
58 | 120 |
x = tmp; |
59 |
- tmp = 48 + (40. * sin(((2. * M_PI) / 60.) * (double)seconds)); |
|
121 |
+ tmp = 48 + ((40 * f_sin((360 / 60) * seconds)) / 100); |
|
60 | 122 |
y = tmp; |
61 | 123 |
DrawLcdLineBresenham(48, 48, x, y); |
62 | 124 |
}; |
63 | 125 |
|
64 |
- //snprintf(daystr, 5, "%d", day); |
|
65 |
- // mw_buf_print(mwbuf, 74, 45, daystr, 0, MW_WHITE, MW_BLACK); |
|
66 |
- lcd_update_display(); |
|
126 |
+ hal_lcd_update_display(); |
|
67 | 127 |
} |
68 | 128 |
|
69 | 129 |
void DrawLcdDigitalClock(boolean show_seconds) |
70 | 130 |
{ |
71 | 131 |
int gRow = 3; |
72 |
- int gColumn = 4; |
|
132 |
+ int gColumn = 3; |
|
133 |
+ char tstr[16]; |
|
73 | 134 |
|
74 | 135 |
SetFont(MetaWatchTime); |
75 | 136 |
|
76 |
- lcd_clear_display(); |
|
137 |
+ hal_lcd_clear_display(); |
|
77 | 138 |
//gRow += WriteLcdCharacter(ui, gRow, gColumn, TIME_CHARACTER_SPACE_INDEX); |
78 |
- gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.hour / 10)); |
|
79 |
- gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.hour % 10)); |
|
139 |
+ if (OswaldClk.clk24hr) { |
|
140 |
+ gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.hour / 10)); |
|
141 |
+ gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.hour % 10)); |
|
142 |
+ } else { |
|
143 |
+ unsigned char val = OswaldClk.hour; |
|
144 |
+ if (val > 12) |
|
145 |
+ val -= 12; |
|
146 |
+ gRow += WriteLcdCharacter(gRow, gColumn, (val / 10)); |
|
147 |
+ gRow += WriteLcdCharacter(gRow, gColumn, (val % 10)); |
|
148 |
+ } |
|
80 | 149 |
gRow += WriteLcdCharacter(gRow, gColumn, TIME_CHARACTER_COLON_INDEX); |
81 | 150 |
gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.minute / 10)); |
82 | 151 |
gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.minute % 10)); |
152 |
+ |
|
153 |
+ gRow += 3; |
|
83 | 154 |
if (show_seconds) { |
84 |
- gRow += WriteLcdCharacter(gRow, gColumn, TIME_CHARACTER_COLON_INDEX); |
|
85 |
- gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.second / 10)); |
|
86 |
- gRow += WriteLcdCharacter(gRow, gColumn, (OswaldClk.second % 10)); |
|
155 |
+ SetFont(MetaWatch16); |
|
156 |
+ snprintf(tstr, 16, "%02d", OswaldClk.second); |
|
157 |
+ WriteLcdString(gRow, 9, tstr); |
|
87 | 158 |
}; |
88 |
- lcd_update_display(); |
|
159 |
+ |
|
160 |
+ SetFont(MetaWatch7); |
|
161 |
+ |
|
162 |
+ if (!OswaldClk.clk24hr) { |
|
163 |
+ if (OswaldClk.hour > 12) { |
|
164 |
+ WriteLcdString(gRow, 3, "PM"); |
|
165 |
+ } else { |
|
166 |
+ WriteLcdString(gRow, 3, "AM"); |
|
167 |
+ } |
|
168 |
+ } |
|
169 |
+ |
|
170 |
+ SetFont(MetaWatch16); |
|
171 |
+ |
|
172 |
+ if (OswaldClk.day_first) |
|
173 |
+ snprintf(tstr, 16, "%d.%d.%d", OswaldClk.day, OswaldClk.month, OswaldClk.year); |
|
174 |
+ else |
|
175 |
+ snprintf(tstr, 16, "%d/%d %d", OswaldClk.month, OswaldClk.day, OswaldClk.year); |
|
176 |
+ WriteLcdString(3, 25, tstr); |
|
177 |
+ |
|
178 |
+ snprintf(tstr, 16, "%d%% (%dmV)", OswaldPowerState.percent, OswaldPowerState.level); |
|
179 |
+ WriteLcdString(2, 48, tstr); |
|
180 |
+ WriteLcdString(2, 64, OswaldPowerState.source ? "ext" : "bat"); |
|
181 |
+ |
|
182 |
+ /* this makes only sense when the charger is active */ |
|
183 |
+ if (OswaldPowerState.source) { |
|
184 |
+ switch (OswaldPowerState.charge_state) { |
|
185 |
+ case POWER_CHARGER_DONE: |
|
186 |
+ WriteLcdString(2, 80, "charge done"); |
|
187 |
+ break; |
|
188 |
+ case POWER_CHARGER_PRECHARGE: |
|
189 |
+ WriteLcdString(2, 80, "precharging"); |
|
190 |
+ break; |
|
191 |
+ case POWER_CHARGER_CHARGING: |
|
192 |
+ WriteLcdString(2, 80, "charging"); |
|
193 |
+ break; |
|
194 |
+ case POWER_CHARGER_UNK: |
|
195 |
+ WriteLcdString(2, 80, "charge unkn."); |
|
196 |
+ break; |
|
197 |
+ default: |
|
198 |
+ break; |
|
199 |
+ }; |
|
200 |
+ }; |
|
201 |
+ hal_lcd_update_display(); |
|
89 | 202 |
} |
203 |
+ |