diff options
Diffstat (limited to 'apps/settings.c')
-rw-r--r-- | apps/settings.c | 302 |
1 files changed, 264 insertions, 38 deletions
diff --git a/apps/settings.c b/apps/settings.c index 5d33ad8f50..58633396bf 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2002 by wavey@wavey.org | 10 | * Copyright (C) 2002 by wavey@wavey.org |
11 | * RTC config saving code (C) 2002 by hessu@hes.iki.fi | ||
11 | * | 12 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 13 | * All files in this archive are subject to the GNU General Public License. |
13 | * See the file COPYING in the source tree root for full license agreement. | 14 | * See the file COPYING in the source tree root for full license agreement. |
@@ -26,84 +27,309 @@ | |||
26 | #include "button.h" | 27 | #include "button.h" |
27 | #include "lcd.h" | 28 | #include "lcd.h" |
28 | #include "mpeg.h" | 29 | #include "mpeg.h" |
30 | #include "string.h" | ||
29 | 31 | ||
30 | struct user_settings global_settings; | 32 | struct user_settings global_settings; |
31 | 33 | ||
34 | #ifdef HAVE_RTC | ||
35 | |||
36 | /******************************************** | ||
37 | |||
38 | Config block as saved on the battery-packed RTC user RAM memory block | ||
39 | of 44 bytes, starting at offset 0x14 of the RTC memory space. | ||
40 | |||
41 | offset abs | ||
42 | 0x00 0x14 "Roc" header signature: 0x52 0x6f 0x63 | ||
43 | 0x03 0x17 <version byte: 0x0> | ||
44 | 0x04 0x18 <volume byte> | ||
45 | 0x05 0x19 <balance byte> | ||
46 | 0x06 0x1a <bass byte> | ||
47 | 0x07 0x1b <treble byte> | ||
48 | 0x08 0x1c <loudness byte> | ||
49 | 0x09 0x1d <bass boost byte> | ||
50 | 0x0a 0x1e <contrast byte> | ||
51 | 0x0b 0x1f <backlight byte> | ||
52 | 0x0c 0x20 <poweroff timer byte> | ||
53 | 0x0d 0x21 <resume settings byte> | ||
54 | 0x0e 0x22 <shuffle mode & directory filter byte> | ||
55 | 0x0f 0x23 <scroll speed & WPS display byte> | ||
56 | 0x10 0x24 <playlist options byte> | ||
57 | |||
58 | <all unused space filled with 0xff> | ||
59 | |||
60 | the geeky but useless statistics part: | ||
61 | 0x24 <total uptime in seconds: 32 bits uint, actually unused for now> | ||
62 | 0x28 <boots: 16 bits uint> | ||
63 | |||
64 | 0x2a <checksum 2 bytes: xor of 0x0-0x29> | ||
65 | |||
66 | Config memory is reset to 0xff and initialized with 'factory defaults' if | ||
67 | a valid header & checksum is not found. Config version number is only | ||
68 | increased when information is _relocated_ or space is _reused_ so that old | ||
69 | versions can read and modify configuration changed by new versions. New | ||
70 | versions should check for the value of '0xff' in each config memory | ||
71 | location used, and reset the setting in question with a factory default if | ||
72 | needed. Memory locations not used by a given version should not be | ||
73 | modified unless the header & checksum test fails. | ||
74 | |||
75 | *************************************/ | ||
76 | |||
77 | #include "rtc.h" | ||
78 | static unsigned char rtc_config_block[44]; | ||
79 | |||
80 | /* | ||
81 | * Calculates the checksum for the config block and places it in the given 2-byte buffer | ||
82 | */ | ||
83 | |||
84 | static void calculate_config_checksum(unsigned char *cksum) | ||
85 | { | ||
86 | unsigned char *p; | ||
87 | cksum[0] = cksum[1] = 0; | ||
88 | |||
89 | for (p = rtc_config_block; | ||
90 | p < rtc_config_block + sizeof(rtc_config_block) - 2; | ||
91 | p++) | ||
92 | { | ||
93 | cksum[0] = cksum[0] ^ *p; | ||
94 | p++; | ||
95 | cksum[1] = cksum[1] ^ *p; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * initialize the config block buffer | ||
101 | */ | ||
102 | static void init_config_buffer( void ) | ||
103 | { | ||
104 | DEBUGF( "init_config_buffer()\n" ); | ||
105 | |||
106 | /* reset to 0xff - all unused */ | ||
107 | memset(rtc_config_block, 0xff, sizeof(rtc_config_block)); | ||
108 | /* insert header */ | ||
109 | rtc_config_block[0] = 'R'; | ||
110 | rtc_config_block[1] = 'o'; | ||
111 | rtc_config_block[2] = 'c'; | ||
112 | rtc_config_block[3] = 0x0; /* config block version number */ | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * save the config block buffer on the RTC RAM | ||
117 | */ | ||
118 | static int save_config_buffer( void ) | ||
119 | { | ||
120 | unsigned char addr = 0x14; | ||
121 | int r; | ||
122 | unsigned char *p; | ||
123 | |||
124 | DEBUGF( "save_config_buffer()\n" ); | ||
125 | |||
126 | /* update the checksum in the end of the block before saving */ | ||
127 | calculate_config_checksum(rtc_config_block + sizeof(rtc_config_block) - 2); | ||
128 | |||
129 | /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so | ||
130 | that it would write a number of bytes at a time since the RTC chip | ||
131 | supports that, but this will have to do for now 8-) */ | ||
132 | for (p = rtc_config_block; | ||
133 | p < rtc_config_block + sizeof(rtc_config_block); | ||
134 | p++) | ||
135 | { | ||
136 | r = rtc_write(addr, *p); | ||
137 | if (r) { | ||
138 | DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", addr, r ); | ||
139 | return r; | ||
140 | } | ||
141 | addr++; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
32 | /* | 147 | /* |
33 | * persist all runtime user settings to disk | 148 | * load the config block buffer from the RTC RAM |
34 | */ | 149 | */ |
35 | int persist_all_settings( void ) | 150 | static int load_config_buffer( void ) |
36 | { | 151 | { |
152 | unsigned char addr = 0x14; | ||
153 | unsigned char cksum[2]; | ||
154 | unsigned char *p; | ||
155 | |||
156 | DEBUGF( "load_config_buffer()\n" ); | ||
157 | |||
158 | /* FIXME: the same comment applies here as for rtc_write */ | ||
159 | for (p = rtc_config_block; | ||
160 | p < rtc_config_block + sizeof(rtc_config_block); | ||
161 | p++) | ||
162 | { | ||
163 | *p = rtc_read(addr); | ||
164 | addr++; | ||
165 | } | ||
166 | |||
167 | /* calculate the checksum, check it and the header */ | ||
168 | calculate_config_checksum(cksum); | ||
169 | |||
170 | if (rtc_config_block[0x0] == 'R' | ||
171 | && rtc_config_block[0x1] == 'o' | ||
172 | && rtc_config_block[0x2] == 'c' | ||
173 | && rtc_config_block[0x3] == 0x0 | ||
174 | && cksum[0] == rtc_config_block[0x2a] | ||
175 | && cksum[1] == rtc_config_block[0x2b]) { | ||
176 | DEBUGF( "load_config_buffer: header & checksum test ok" ); | ||
177 | return 0; /* header and checksum is valid */ | ||
178 | } | ||
179 | |||
180 | /* if checksum is not valid, initialize the config buffer to all-unused */ | ||
181 | DEBUGF( "load_config_buffer: header & checksum test failed" ); | ||
182 | init_config_buffer(); | ||
37 | return 1; | 183 | return 1; |
38 | } | 184 | } |
39 | 185 | ||
186 | #endif /* HAVE_RTC */ | ||
187 | |||
40 | /* | 188 | /* |
41 | * persist all the playlist information to disk | 189 | * persist all runtime user settings to disk or RTC RAM |
42 | */ | 190 | */ |
43 | int persist_all_playlist_info( void ) | 191 | int settings_save( void ) |
44 | { | 192 | { |
193 | DEBUGF( "settings_save()\n" ); | ||
194 | |||
195 | #ifdef HAVE_RTC | ||
196 | /* update the config block buffer with current | ||
197 | settings and save the block in the RTC */ | ||
198 | rtc_config_block[0x4] = (unsigned char)global_settings.volume; | ||
199 | rtc_config_block[0x5] = (unsigned char)global_settings.balance; | ||
200 | rtc_config_block[0x6] = (unsigned char)global_settings.bass; | ||
201 | rtc_config_block[0x7] = (unsigned char)global_settings.treble; | ||
202 | rtc_config_block[0x8] = (unsigned char)global_settings.loudness; | ||
203 | rtc_config_block[0x9] = (unsigned char)global_settings.bass_boost; | ||
204 | |||
205 | rtc_config_block[0xa] = (unsigned char)global_settings.contrast; | ||
206 | rtc_config_block[0xb] = (unsigned char)global_settings.backlight; | ||
207 | rtc_config_block[0xc] = (unsigned char)global_settings.poweroff; | ||
208 | rtc_config_block[0xd] = (unsigned char)global_settings.resume; | ||
209 | |||
210 | rtc_config_block[0xe] = (unsigned char) | ||
211 | ((global_settings.playlist_shuffle & 1) | | ||
212 | ((global_settings.mp3filter & 1) << 1)); | ||
213 | |||
214 | rtc_config_block[0xf] = (unsigned char) | ||
215 | ((global_settings.scroll_speed << 3) | | ||
216 | (global_settings.wps_display & 7)); | ||
217 | |||
218 | memcpy(&rtc_config_block[0x24], &global_settings.total_uptime, 4); | ||
219 | memcpy(&rtc_config_block[0x28], &global_settings.total_boots, 2); | ||
220 | |||
221 | save_config_buffer(); | ||
222 | #endif /* HAVE_RTC */ | ||
223 | |||
45 | return 1; | 224 | return 1; |
46 | } | 225 | } |
47 | 226 | ||
48 | /* | 227 | /* |
49 | * load settings from disk | 228 | * load settings from disk or RTC RAM |
50 | */ | 229 | */ |
51 | void reload_all_settings( struct user_settings *settings ) | 230 | void settings_load(void) |
52 | { | 231 | { |
232 | #ifdef HAVE_RTC | ||
233 | unsigned char c; | ||
234 | #endif | ||
235 | |||
53 | DEBUGF( "reload_all_settings()\n" ); | 236 | DEBUGF( "reload_all_settings()\n" ); |
54 | 237 | ||
55 | /* this is a TEMP stub version */ | ||
56 | |||
57 | /* populate settings with default values */ | 238 | /* populate settings with default values */ |
239 | settings_reset(); | ||
58 | 240 | ||
59 | reset_settings( settings ); | 241 | #ifdef HAVE_RTC |
242 | /* load the buffer from the RTC (resets it to all-unused if the block | ||
243 | is invalid) and decode the settings which are set in the block */ | ||
244 | if (!load_config_buffer()) { | ||
245 | if (rtc_config_block[0x4] != 0xFF) | ||
246 | global_settings.volume = rtc_config_block[0x4]; | ||
247 | if (rtc_config_block[0x5] != 0xFF) | ||
248 | global_settings.balance = rtc_config_block[0x5]; | ||
249 | if (rtc_config_block[0x6] != 0xFF) | ||
250 | global_settings.bass = rtc_config_block[0x6]; | ||
251 | if (rtc_config_block[0x7] != 0xFF) | ||
252 | global_settings.treble = rtc_config_block[0x7]; | ||
253 | if (rtc_config_block[0x8] != 0xFF) | ||
254 | global_settings.loudness = rtc_config_block[0x8]; | ||
255 | if (rtc_config_block[0x9] != 0xFF) | ||
256 | global_settings.bass_boost = rtc_config_block[0x9]; | ||
257 | |||
258 | if (rtc_config_block[0xa] != 0xFF) | ||
259 | global_settings.contrast = rtc_config_block[0xa]; | ||
260 | if (rtc_config_block[0xb] != 0xFF) | ||
261 | global_settings.backlight = rtc_config_block[0xb]; | ||
262 | if (rtc_config_block[0xc] != 0xFF) | ||
263 | global_settings.poweroff = rtc_config_block[0xc]; | ||
264 | if (rtc_config_block[0xd] != 0xFF) | ||
265 | global_settings.resume = rtc_config_block[0xd]; | ||
266 | if (rtc_config_block[0xe] != 0xFF) { | ||
267 | global_settings.playlist_shuffle = rtc_config_block[0xe] & 1; | ||
268 | global_settings.mp3filter = (rtc_config_block[0xe] >> 1) & 1; | ||
269 | } | ||
270 | |||
271 | c = rtc_config_block[0xf] >> 3; | ||
272 | if (c != 31) | ||
273 | global_settings.scroll_speed = c; | ||
274 | |||
275 | c = rtc_config_block[0xf] & 7; | ||
276 | if (c != 7) | ||
277 | global_settings.wps_display = c; | ||
278 | |||
279 | if (rtc_config_block[0x24] != 0xFF) | ||
280 | memcpy(&global_settings.total_uptime, &rtc_config_block[0x24], 4); | ||
281 | if (rtc_config_block[0x28] != 0xFF) | ||
282 | memcpy(&global_settings.total_boots, &rtc_config_block[0x28], 2); | ||
283 | } | ||
284 | |||
285 | #endif /* HAVE_RTC */ | ||
60 | } | 286 | } |
61 | 287 | ||
62 | /* | 288 | /* |
63 | * reset all settings to their default value | 289 | * reset all settings to their default value |
64 | */ | 290 | */ |
65 | void reset_settings( struct user_settings *settings ) { | 291 | void settings_reset(void) { |
66 | 292 | ||
67 | DEBUGF( "reset_settings()\n" ); | 293 | DEBUGF( "settings_reset()\n" ); |
68 | 294 | ||
69 | settings->volume = mpeg_sound_default(SOUND_VOLUME); | 295 | global_settings.volume = mpeg_sound_default(SOUND_VOLUME); |
70 | settings->balance = DEFAULT_BALANCE_SETTING; | 296 | global_settings.balance = DEFAULT_BALANCE_SETTING; |
71 | settings->bass = mpeg_sound_default(SOUND_BASS); | 297 | global_settings.bass = mpeg_sound_default(SOUND_BASS); |
72 | settings->treble = mpeg_sound_default(SOUND_TREBLE); | 298 | global_settings.treble = mpeg_sound_default(SOUND_TREBLE); |
73 | settings->loudness = DEFAULT_LOUDNESS_SETTING; | 299 | global_settings.loudness = DEFAULT_LOUDNESS_SETTING; |
74 | settings->bass_boost = DEFAULT_BASS_BOOST_SETTING; | 300 | global_settings.bass_boost = DEFAULT_BASS_BOOST_SETTING; |
75 | settings->contrast = DEFAULT_CONTRAST_SETTING; | 301 | global_settings.contrast = DEFAULT_CONTRAST_SETTING; |
76 | settings->poweroff = DEFAULT_POWEROFF_SETTING; | 302 | global_settings.poweroff = DEFAULT_POWEROFF_SETTING; |
77 | settings->backlight = DEFAULT_BACKLIGHT_SETTING; | 303 | global_settings.backlight = DEFAULT_BACKLIGHT_SETTING; |
78 | settings->wps_display = DEFAULT_WPS_DISPLAY; | 304 | global_settings.wps_display = DEFAULT_WPS_DISPLAY; |
79 | settings->mp3filter = true; | 305 | global_settings.mp3filter = true; |
80 | settings->playlist_shuffle = false; | 306 | global_settings.playlist_shuffle = false; |
307 | global_settings.total_boots = 0; | ||
308 | global_settings.total_uptime = 0; | ||
309 | global_settings.scroll_speed = 8; | ||
81 | } | 310 | } |
82 | 311 | ||
83 | 312 | ||
84 | /* | 313 | /* |
85 | * dump the list of current settings | 314 | * dump the list of current settings |
86 | */ | 315 | */ |
87 | void display_current_settings( struct user_settings *settings ) | 316 | void settings_display(void) |
88 | { | 317 | { |
89 | #ifdef DEBUG | 318 | #ifdef DEBUG |
90 | DEBUGF( "\ndisplay_current_settings()\n" ); | 319 | DEBUGF( "\nsettings_display()\n" ); |
91 | 320 | ||
92 | DEBUGF( "\nvolume:\t\t%d\nbalance:\t%d\nbass:\t\t%d\ntreble:\t\t%d\nloudness:\t%d\nbass boost:\t%d\n", | 321 | DEBUGF( "\nvolume:\t\t%d\nbalance:\t%d\nbass:\t\t%d\ntreble:\t\t%d\nloudness:\t%d\nbass boost:\t%d\n", |
93 | settings->volume, | 322 | global_settings.volume, |
94 | settings->balance, | 323 | global_settings.balance, |
95 | settings->bass, | 324 | global_settings.bass, |
96 | settings->treble, | 325 | global_settings.treble, |
97 | settings->loudness, | 326 | global_settings.loudness, |
98 | settings->bass_boost ); | 327 | global_settings.bass_boost ); |
99 | 328 | ||
100 | DEBUGF( "contrast:\t%d\npoweroff:\t%d\nbacklight:\t%d\n", | 329 | DEBUGF( "contrast:\t%d\npoweroff:\t%d\nbacklight:\t%d\n", |
101 | settings->contrast, | 330 | global_settings.contrast, |
102 | settings->poweroff, | 331 | global_settings.poweroff, |
103 | settings->backlight ); | 332 | global_settings.backlight ); |
104 | #else | ||
105 | /* Get rid of warning */ | ||
106 | settings = settings; | ||
107 | #endif | 333 | #endif |
108 | } | 334 | } |
109 | 335 | ||