summaryrefslogtreecommitdiff
path: root/apps/settings.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/settings.c')
-rw-r--r--apps/settings.c247
1 files changed, 149 insertions, 98 deletions
diff --git a/apps/settings.c b/apps/settings.c
index f8b6870863..41d04c2819 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -37,10 +37,9 @@
37 37
38struct user_settings global_settings; 38struct user_settings global_settings;
39 39
40static unsigned short last_checksum = 0;
41
42#define CONFIG_BLOCK_VERSION 1 40#define CONFIG_BLOCK_VERSION 1
43#define CONFIG_BLOCK_SIZE 44 41#define CONFIG_BLOCK_SIZE 512
42#define RTC_BLOCK_SIZE 44
44 43
45/******************************************** 44/********************************************
46 45
@@ -64,6 +63,8 @@ offset abs
640x0f 0x23 <scroll speed & WPS display byte> 630x0f 0x23 <scroll speed & WPS display byte>
650x10 0x24 <playlist options byte> 640x10 0x24 <playlist options byte>
660x11 0x25 <AVC byte> 650x11 0x25 <AVC byte>
660x12 0x26 <(int) Resume playlist index, or -1 if no playlist resume>
670x16 0x2b <(int) Byte offset into resume file>
67 68
68 <all unused space filled with 0xff> 69 <all unused space filled with 0xff>
69 70
@@ -81,24 +82,30 @@ location used, and reset the setting in question with a factory default if
81needed. Memory locations not used by a given version should not be 82needed. Memory locations not used by a given version should not be
82modified unless the header & checksum test fails. 83modified unless the header & checksum test fails.
83 84
85
86Rest of config block, only saved to disk:
87
880xF8 (int) Playlist shuffle seed
890xFC (char[260]) Resume playlist (path/to/dir or path/to/playlist.m3u)
90
84*************************************/ 91*************************************/
85 92
86#include "rtc.h" 93#include "rtc.h"
87static unsigned char rtc_config_block[CONFIG_BLOCK_SIZE]; 94static unsigned char config_block[CONFIG_BLOCK_SIZE];
88 95
89/* 96/*
90 * Calculates the checksum for the config block and places it in the given 2-byte buffer 97 * Calculates the checksum for the config block and returns it
91 */ 98 */
92 99
93static unsigned short calculate_config_checksum(void) 100static unsigned short calculate_config_checksum(unsigned char* buf)
94{ 101{
95 unsigned int i; 102 unsigned int i;
96 unsigned char cksum[2]; 103 unsigned char cksum[2];
97 cksum[0] = cksum[1] = 0; 104 cksum[0] = cksum[1] = 0;
98 105
99 for (i=0; i < CONFIG_BLOCK_SIZE - 2; i+=2 ) { 106 for (i=0; i < RTC_BLOCK_SIZE - 2; i+=2 ) {
100 cksum[0] ^= rtc_config_block[i]; 107 cksum[0] ^= buf[i];
101 cksum[1] ^= rtc_config_block[i+1]; 108 cksum[1] ^= buf[i+1];
102 } 109 }
103 110
104 return (cksum[0] << 8) | cksum[1]; 111 return (cksum[0] << 8) | cksum[1];
@@ -112,12 +119,12 @@ static void init_config_buffer( void )
112 DEBUGF( "init_config_buffer()\n" ); 119 DEBUGF( "init_config_buffer()\n" );
113 120
114 /* reset to 0xff - all unused */ 121 /* reset to 0xff - all unused */
115 memset(rtc_config_block, 0xff, CONFIG_BLOCK_SIZE); 122 memset(config_block, 0xff, CONFIG_BLOCK_SIZE);
116 /* insert header */ 123 /* insert header */
117 rtc_config_block[0] = 'R'; 124 config_block[0] = 'R';
118 rtc_config_block[1] = 'o'; 125 config_block[1] = 'o';
119 rtc_config_block[2] = 'c'; 126 config_block[2] = 'c';
120 rtc_config_block[3] = CONFIG_BLOCK_VERSION; 127 config_block[3] = CONFIG_BLOCK_VERSION;
121} 128}
122 129
123/* 130/*
@@ -126,7 +133,6 @@ static void init_config_buffer( void )
126static int save_config_buffer( void ) 133static int save_config_buffer( void )
127{ 134{
128 unsigned short chksum; 135 unsigned short chksum;
129
130#ifdef HAVE_RTC 136#ifdef HAVE_RTC
131 unsigned int i; 137 unsigned int i;
132#endif 138#endif
@@ -134,36 +140,29 @@ static int save_config_buffer( void )
134 DEBUGF( "save_config_buffer()\n" ); 140 DEBUGF( "save_config_buffer()\n" );
135 141
136 /* update the checksum in the end of the block before saving */ 142 /* update the checksum in the end of the block before saving */
137 chksum = calculate_config_checksum(); 143 chksum = calculate_config_checksum(config_block);
138 rtc_config_block[ CONFIG_BLOCK_SIZE - 2 ] = chksum >> 8; 144 config_block[ RTC_BLOCK_SIZE - 2 ] = chksum >> 8;
139 rtc_config_block[ CONFIG_BLOCK_SIZE - 1 ] = chksum & 0xff; 145 config_block[ RTC_BLOCK_SIZE - 1 ] = chksum & 0xff;
140
141 /* don't save if no changes were made */
142 if ( chksum == last_checksum )
143 return 0;
144 last_checksum = chksum;
145 146
146#ifdef HAVE_RTC 147#ifdef HAVE_RTC
147 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so 148 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
148 that it would write a number of bytes at a time since the RTC chip 149 that it would write a number of bytes at a time since the RTC chip
149 supports that, but this will have to do for now 8-) */ 150 supports that, but this will have to do for now 8-) */
150 for (i=0; i < CONFIG_BLOCK_SIZE; i++ ) { 151 for (i=0; i < RTC_BLOCK_SIZE; i++ ) {
151 int r = rtc_write(0x14+i, rtc_config_block[i]); 152 int r = rtc_write(0x14+i, config_block[i]);
152 if (r) { 153 if (r) {
153 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", 14+i, r ); 154 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", 14+i, r );
154 return r; 155 return r;
155 } 156 }
156 } 157 }
157 158
158#else 159#endif
159 160
160 if(battery_level_safe() && (fat_startsector()!=0)) 161 if (fat_startsector() != 0)
161 ata_delayed_write( 61, rtc_config_block); 162 ata_delayed_write( 61, config_block);
162 else 163 else
163 return -1; 164 return -1;
164 165
165#endif
166
167 return 0; 166 return 0;
168} 167}
169 168
@@ -173,40 +172,61 @@ static int save_config_buffer( void )
173static int load_config_buffer( void ) 172static int load_config_buffer( void )
174{ 173{
175 unsigned short chksum; 174 unsigned short chksum;
175 bool correct = false;
176 176
177#ifdef HAVE_RTC 177#ifdef HAVE_RTC
178 unsigned int i; 178 unsigned int i;
179 unsigned char rtc_block[RTC_BLOCK_SIZE];
179#endif 180#endif
180 181
181 DEBUGF( "load_config_buffer()\n" ); 182 DEBUGF( "load_config_buffer()\n" );
182 183
184 if (fat_startsector() != 0) {
185 ata_read_sectors( 61, 1, config_block);
186
187 /* calculate the checksum, check it and the header */
188 chksum = calculate_config_checksum(config_block);
189
190 if (config_block[0] == 'R' &&
191 config_block[1] == 'o' &&
192 config_block[2] == 'c' &&
193 config_block[3] == CONFIG_BLOCK_VERSION &&
194 (chksum >> 8) == config_block[RTC_BLOCK_SIZE - 2] &&
195 (chksum & 0xff) == config_block[RTC_BLOCK_SIZE - 1])
196 {
197 DEBUGF( "load_config_buffer: header & checksum test ok\n" );
198 correct = true;
199 }
200 }
201
183#ifdef HAVE_RTC 202#ifdef HAVE_RTC
184 /* FIXME: the same comment applies here as for rtc_write */ 203 /* read rtc block */
185 for (i=0; i < CONFIG_BLOCK_SIZE; i++ ) 204 for (i=0; i < RTC_BLOCK_SIZE; i++ )
186 rtc_config_block[i] = rtc_read(0x14+i); 205 rtc_block[i] = rtc_read(0x14+i);
187#else 206
188 ata_read_sectors( 61, 1, rtc_config_block); 207 chksum = calculate_config_checksum(rtc_block);
189#endif
190
191 /* calculate the checksum, check it and the header */
192 chksum = calculate_config_checksum();
193 208
194 if (rtc_config_block[0] == 'R' && 209 /* if rtc block is ok, use that */
195 rtc_config_block[1] == 'o' && 210 if (rtc_block[0] == 'R' &&
196 rtc_config_block[2] == 'c' && 211 rtc_block[1] == 'o' &&
197 rtc_config_block[3] == CONFIG_BLOCK_VERSION && 212 rtc_block[2] == 'c' &&
198 (chksum >> 8) == rtc_config_block[CONFIG_BLOCK_SIZE - 2] && 213 rtc_block[3] == CONFIG_BLOCK_VERSION &&
199 (chksum & 0xff) == rtc_config_block[CONFIG_BLOCK_SIZE - 1]) 214 (chksum >> 8) == rtc_block[RTC_BLOCK_SIZE - 2] &&
215 (chksum & 0xff) == rtc_block[RTC_BLOCK_SIZE - 1])
200 { 216 {
201 DEBUGF( "load_config_buffer: header & checksum test ok\n" ); 217 memcpy(config_block, rtc_block, RTC_BLOCK_SIZE);
202 last_checksum = chksum; 218 correct = true;
203 return 0; /* header and checksum is valid */
204 } 219 }
220#endif
205 221
206 /* if checksum is not valid, initialize the config buffer to all-unused */ 222 if ( !correct ) {
207 DEBUGF( "load_config_buffer: header & checksum test failed\n" ); 223 /* if checksum is not valid, clear the config buffer */
208 init_config_buffer(); 224 DEBUGF( "load_config_buffer: header & checksum test failed\n" );
209 return 1; 225 init_config_buffer();
226 return -1;
227 }
228
229 return 0;
210} 230}
211 231
212/* 232/*
@@ -218,33 +238,47 @@ int settings_save( void )
218 238
219 /* update the config block buffer with current 239 /* update the config block buffer with current
220 settings and save the block in the RTC */ 240 settings and save the block in the RTC */
221 rtc_config_block[0x4] = (unsigned char)global_settings.volume; 241 config_block[0x4] = (unsigned char)global_settings.volume;
222 rtc_config_block[0x5] = (unsigned char)global_settings.balance; 242 config_block[0x5] = (unsigned char)global_settings.balance;
223 rtc_config_block[0x6] = (unsigned char)global_settings.bass; 243 config_block[0x6] = (unsigned char)global_settings.bass;
224 rtc_config_block[0x7] = (unsigned char)global_settings.treble; 244 config_block[0x7] = (unsigned char)global_settings.treble;
225 rtc_config_block[0x8] = (unsigned char)global_settings.loudness; 245 config_block[0x8] = (unsigned char)global_settings.loudness;
226 rtc_config_block[0x9] = (unsigned char)global_settings.bass_boost; 246 config_block[0x9] = (unsigned char)global_settings.bass_boost;
227 247
228 rtc_config_block[0xa] = (unsigned char)global_settings.contrast; 248 config_block[0xa] = (unsigned char)global_settings.contrast;
229 rtc_config_block[0xb] = (unsigned char)global_settings.backlight; 249 config_block[0xb] = (unsigned char)global_settings.backlight;
230 rtc_config_block[0xc] = (unsigned char)global_settings.poweroff; 250 config_block[0xc] = (unsigned char)global_settings.poweroff;
231 rtc_config_block[0xd] = (unsigned char)global_settings.resume; 251 config_block[0xd] = (unsigned char)global_settings.resume;
232 252
233 rtc_config_block[0xe] = (unsigned char) 253 config_block[0xe] = (unsigned char)
234 ((global_settings.playlist_shuffle & 1) | 254 ((global_settings.playlist_shuffle & 1) |
235 ((global_settings.mp3filter & 1) << 1) | 255 ((global_settings.mp3filter & 1) << 1) |
236 ((global_settings.sort_case & 1) << 2) | 256 ((global_settings.sort_case & 1) << 2) |
237 ((global_settings.discharge & 1) << 3) | 257 ((global_settings.discharge & 1) << 3) |
238 ((global_settings.statusbar & 1) << 4)); 258 ((global_settings.statusbar & 1) << 4));
239 259
240 rtc_config_block[0xf] = (unsigned char) 260 config_block[0xf] = (unsigned char)
241 ((global_settings.scroll_speed << 3) | 261 ((global_settings.scroll_speed << 3) |
242 (global_settings.wps_display & 7)); 262 (global_settings.wps_display & 7));
243 263
244 rtc_config_block[0x11] = (unsigned char)global_settings.avc; 264 config_block[0x10] = (unsigned char)global_settings.ff_rewind;
265 config_block[0x11] = (unsigned char)global_settings.avc;
245 266
246 memcpy(&rtc_config_block[0x24], &global_settings.total_uptime, 4); 267 memcpy(&config_block[0x12], &global_settings.resume_index, 4);
268 memcpy(&config_block[0x16], &global_settings.resume_offset, 4);
269 memcpy(&config_block[0xF8], &global_settings.resume_seed, 4);
270
271 memcpy(&config_block[0x24], &global_settings.total_uptime, 4);
272 strncpy(&config_block[0xFC], global_settings.resume_file, MAX_PATH);
247 273
274 DEBUGF("+Resume file %s\n",global_settings.resume_file);
275 DEBUGF("+Resume index %X offset %X\n",
276 global_settings.resume_index,
277 global_settings.resume_offset);
278 DEBUGF("+Resume shuffle %s seed %X\n",
279 global_settings.playlist_shuffle?"on":"off",
280 global_settings.resume_seed);
281
248 if(save_config_buffer()) 282 if(save_config_buffer())
249 { 283 {
250 lcd_clear_display(); 284 lcd_clear_display();
@@ -277,51 +311,65 @@ void settings_load(void)
277 /* load the buffer from the RTC (resets it to all-unused if the block 311 /* load the buffer from the RTC (resets it to all-unused if the block
278 is invalid) and decode the settings which are set in the block */ 312 is invalid) and decode the settings which are set in the block */
279 if (!load_config_buffer()) { 313 if (!load_config_buffer()) {
280 if (rtc_config_block[0x4] != 0xFF) 314 if (config_block[0x4] != 0xFF)
281 global_settings.volume = rtc_config_block[0x4]; 315 global_settings.volume = config_block[0x4];
282 if (rtc_config_block[0x5] != 0xFF) 316 if (config_block[0x5] != 0xFF)
283 global_settings.balance = rtc_config_block[0x5]; 317 global_settings.balance = config_block[0x5];
284 if (rtc_config_block[0x6] != 0xFF) 318 if (config_block[0x6] != 0xFF)
285 global_settings.bass = rtc_config_block[0x6]; 319 global_settings.bass = config_block[0x6];
286 if (rtc_config_block[0x7] != 0xFF) 320 if (config_block[0x7] != 0xFF)
287 global_settings.treble = rtc_config_block[0x7]; 321 global_settings.treble = config_block[0x7];
288 if (rtc_config_block[0x8] != 0xFF) 322 if (config_block[0x8] != 0xFF)
289 global_settings.loudness = rtc_config_block[0x8]; 323 global_settings.loudness = config_block[0x8];
290 if (rtc_config_block[0x9] != 0xFF) 324 if (config_block[0x9] != 0xFF)
291 global_settings.bass_boost = rtc_config_block[0x9]; 325 global_settings.bass_boost = config_block[0x9];
292 326
293 if (rtc_config_block[0xa] != 0xFF) { 327 if (config_block[0xa] != 0xFF) {
294 global_settings.contrast = rtc_config_block[0xa]; 328 global_settings.contrast = config_block[0xa];
295 if ( global_settings.contrast < MIN_CONTRAST_SETTING ) 329 if ( global_settings.contrast < MIN_CONTRAST_SETTING )
296 global_settings.contrast = DEFAULT_CONTRAST_SETTING; 330 global_settings.contrast = DEFAULT_CONTRAST_SETTING;
297 } 331 }
298 if (rtc_config_block[0xb] != 0xFF) 332 if (config_block[0xb] != 0xFF)
299 global_settings.backlight = rtc_config_block[0xb]; 333 global_settings.backlight = config_block[0xb];
300 if (rtc_config_block[0xc] != 0xFF) 334 if (config_block[0xc] != 0xFF)
301 global_settings.poweroff = rtc_config_block[0xc]; 335 global_settings.poweroff = config_block[0xc];
302 if (rtc_config_block[0xd] != 0xFF) 336 if (config_block[0xd] != 0xFF)
303 global_settings.resume = rtc_config_block[0xd]; 337 global_settings.resume = config_block[0xd];
304 if (rtc_config_block[0xe] != 0xFF) { 338 if (config_block[0xe] != 0xFF) {
305 global_settings.playlist_shuffle = rtc_config_block[0xe] & 1; 339 global_settings.playlist_shuffle = config_block[0xe] & 1;
306 global_settings.mp3filter = (rtc_config_block[0xe] >> 1) & 1; 340 global_settings.mp3filter = (config_block[0xe] >> 1) & 1;
307 global_settings.sort_case = (rtc_config_block[0xe] >> 2) & 1; 341 global_settings.sort_case = (config_block[0xe] >> 2) & 1;
308 global_settings.discharge = (rtc_config_block[0xe] >> 3) & 1; 342 global_settings.discharge = (config_block[0xe] >> 3) & 1;
309 global_settings.statusbar = (rtc_config_block[0xe] >> 4) & 1; 343 global_settings.statusbar = (config_block[0xe] >> 4) & 1;
310 } 344 }
311 345
312 c = rtc_config_block[0xf] >> 3; 346 c = config_block[0xf] >> 3;
313 if (c != 31) 347 if (c != 31)
314 global_settings.scroll_speed = c; 348 global_settings.scroll_speed = c;
315 349
316 c = rtc_config_block[0xf] & 7; 350 c = config_block[0xf] & 7;
317 if (c != 7) 351 if (c != 7)
318 global_settings.wps_display = c; 352 global_settings.wps_display = c;
319 353
320 if (rtc_config_block[0x11] != 0xFF) 354 if (config_block[0x10] != 0xFF)
321 global_settings.avc = rtc_config_block[0x11]; 355 global_settings.ff_rewind = config_block[0x10];
356
357 if (config_block[0x11] != 0xFF)
358 global_settings.avc = config_block[0x11];
359
360 if (config_block[0x12] != 0xFF)
361 memcpy(&global_settings.resume_index, &config_block[0x12], 4);
362
363 if (config_block[0x16] != 0xFF)
364 memcpy(&global_settings.resume_offset, &config_block[0x16], 4);
365
366 memcpy(&global_settings.resume_seed, &config_block[0xF8], 4);
367
368 if (config_block[0x24] != 0xFF)
369 memcpy(&global_settings.total_uptime, &config_block[0x24], 4);
322 370
323 if (rtc_config_block[0x24] != 0xFF) 371 strncpy(global_settings.resume_file, &config_block[0xFC], MAX_PATH);
324 memcpy(&global_settings.total_uptime, &rtc_config_block[0x24], 4); 372 global_settings.resume_file[MAX_PATH]=0;
325 } 373 }
326 lcd_set_contrast(global_settings.contrast); 374 lcd_set_contrast(global_settings.contrast);
327 lcd_scroll_speed(global_settings.scroll_speed); 375 lcd_scroll_speed(global_settings.scroll_speed);
@@ -345,6 +393,7 @@ void settings_reset(void) {
345 global_settings.loudness = mpeg_sound_default(SOUND_LOUDNESS); 393 global_settings.loudness = mpeg_sound_default(SOUND_LOUDNESS);
346 global_settings.bass_boost = mpeg_sound_default(SOUND_SUPERBASS); 394 global_settings.bass_boost = mpeg_sound_default(SOUND_SUPERBASS);
347 global_settings.avc = mpeg_sound_default(SOUND_AVC); 395 global_settings.avc = mpeg_sound_default(SOUND_AVC);
396 global_settings.resume = true;
348 global_settings.contrast = DEFAULT_CONTRAST_SETTING; 397 global_settings.contrast = DEFAULT_CONTRAST_SETTING;
349 global_settings.poweroff = DEFAULT_POWEROFF_SETTING; 398 global_settings.poweroff = DEFAULT_POWEROFF_SETTING;
350 global_settings.backlight = DEFAULT_BACKLIGHT_SETTING; 399 global_settings.backlight = DEFAULT_BACKLIGHT_SETTING;
@@ -358,6 +407,8 @@ void settings_reset(void) {
358 global_settings.total_uptime = 0; 407 global_settings.total_uptime = 0;
359 global_settings.scroll_speed = 8; 408 global_settings.scroll_speed = 8;
360 global_settings.ff_rewind = DEFAULT_FF_REWIND_SETTING; 409 global_settings.ff_rewind = DEFAULT_FF_REWIND_SETTING;
410 global_settings.resume_index = -1;
411 global_settings.resume_offset = -1;
361} 412}
362 413
363 414