summaryrefslogtreecommitdiff
path: root/apps/settings.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/settings.c')
-rw-r--r--apps/settings.c302
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
30struct user_settings global_settings; 32struct user_settings global_settings;
31 33
34#ifdef HAVE_RTC
35
36/********************************************
37
38Config block as saved on the battery-packed RTC user RAM memory block
39of 44 bytes, starting at offset 0x14 of the RTC memory space.
40
41offset abs
420x00 0x14 "Roc" header signature: 0x52 0x6f 0x63
430x03 0x17 <version byte: 0x0>
440x04 0x18 <volume byte>
450x05 0x19 <balance byte>
460x06 0x1a <bass byte>
470x07 0x1b <treble byte>
480x08 0x1c <loudness byte>
490x09 0x1d <bass boost byte>
500x0a 0x1e <contrast byte>
510x0b 0x1f <backlight byte>
520x0c 0x20 <poweroff timer byte>
530x0d 0x21 <resume settings byte>
540x0e 0x22 <shuffle mode & directory filter byte>
550x0f 0x23 <scroll speed & WPS display byte>
560x10 0x24 <playlist options byte>
57
58 <all unused space filled with 0xff>
59
60 the geeky but useless statistics part:
610x24 <total uptime in seconds: 32 bits uint, actually unused for now>
620x28 <boots: 16 bits uint>
63
640x2a <checksum 2 bytes: xor of 0x0-0x29>
65
66Config memory is reset to 0xff and initialized with 'factory defaults' if
67a valid header & checksum is not found. Config version number is only
68increased when information is _relocated_ or space is _reused_ so that old
69versions can read and modify configuration changed by new versions. New
70versions should check for the value of '0xff' in each config memory
71location used, and reset the setting in question with a factory default if
72needed. Memory locations not used by a given version should not be
73modified unless the header & checksum test fails.
74
75*************************************/
76
77#include "rtc.h"
78static 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
84static 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 */
102static 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 */
118static 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 */
35int persist_all_settings( void ) 150static 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 */
43int persist_all_playlist_info( void ) 191int 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 */
51void reload_all_settings( struct user_settings *settings ) 230void 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 */
65void reset_settings( struct user_settings *settings ) { 291void 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 */
87void display_current_settings( struct user_settings *settings ) 316void 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