diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-08-13 17:16:09 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-08-13 17:16:09 +0000 |
commit | cd7691de2261e84d3ee72ec3d585ab66680d04e2 (patch) | |
tree | b9aea6c27b4f68342a9ec87d77fddb682bff5385 /apps/settings.c | |
parent | 9872b66cd100dce18e2e6f4f77ee2beaa50b8075 (diff) | |
download | rockbox-cd7691de2261e84d3ee72ec3d585ab66680d04e2.tar.gz rockbox-cd7691de2261e84d3ee72ec3d585ab66680d04e2.zip |
Enabled saving settings to disk on player
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1717 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/settings.c')
-rw-r--r-- | apps/settings.c | 181 |
1 files changed, 75 insertions, 106 deletions
diff --git a/apps/settings.c b/apps/settings.c index e285d266d5..7ca5715674 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -30,12 +30,18 @@ | |||
30 | #include "mpeg.h" | 30 | #include "mpeg.h" |
31 | #include "string.h" | 31 | #include "string.h" |
32 | #include "ata.h" | 32 | #include "ata.h" |
33 | #include "fat.h" | ||
33 | #include "power.h" | 34 | #include "power.h" |
34 | #include "backlight.h" | 35 | #include "backlight.h" |
35 | #include "powermgmt.h" | 36 | #include "powermgmt.h" |
36 | 37 | ||
37 | struct user_settings global_settings; | 38 | struct user_settings global_settings; |
38 | 39 | ||
40 | static unsigned short last_checksum = 0; | ||
41 | |||
42 | #define CONFIG_BLOCK_VERSION 0 | ||
43 | #define CONFIG_BLOCK_SIZE 44 | ||
44 | |||
39 | /******************************************** | 45 | /******************************************** |
40 | 46 | ||
41 | Config block as saved on the battery-packed RTC user RAM memory block | 47 | Config block as saved on the battery-packed RTC user RAM memory block |
@@ -78,25 +84,24 @@ modified unless the header & checksum test fails. | |||
78 | *************************************/ | 84 | *************************************/ |
79 | 85 | ||
80 | #include "rtc.h" | 86 | #include "rtc.h" |
81 | static unsigned char rtc_config_block[44]; | 87 | static unsigned char rtc_config_block[CONFIG_BLOCK_SIZE]; |
82 | 88 | ||
83 | /* | 89 | /* |
84 | * Calculates the checksum for the config block and places it in the given 2-byte buffer | 90 | * Calculates the checksum for the config block and places it in the given 2-byte buffer |
85 | */ | 91 | */ |
86 | 92 | ||
87 | static void calculate_config_checksum(unsigned char *cksum) | 93 | static unsigned short calculate_config_checksum(void) |
88 | { | 94 | { |
89 | unsigned char *p; | 95 | unsigned int i; |
96 | unsigned char cksum[2]; | ||
90 | cksum[0] = cksum[1] = 0; | 97 | cksum[0] = cksum[1] = 0; |
91 | 98 | ||
92 | for (p = rtc_config_block; | 99 | for (i=0; i < CONFIG_BLOCK_SIZE - 2; i+=2 ) { |
93 | p < rtc_config_block + sizeof(rtc_config_block) - 2; | 100 | cksum[0] ^= rtc_config_block[i]; |
94 | p++) | 101 | cksum[1] ^= rtc_config_block[i+1]; |
95 | { | ||
96 | cksum[0] = cksum[0] ^ *p; | ||
97 | p++; | ||
98 | cksum[1] = cksum[1] ^ *p; | ||
99 | } | 102 | } |
103 | |||
104 | return (cksum[0] << 8) | cksum[1]; | ||
100 | } | 105 | } |
101 | 106 | ||
102 | /* | 107 | /* |
@@ -107,141 +112,107 @@ static void init_config_buffer( void ) | |||
107 | DEBUGF( "init_config_buffer()\n" ); | 112 | DEBUGF( "init_config_buffer()\n" ); |
108 | 113 | ||
109 | /* reset to 0xff - all unused */ | 114 | /* reset to 0xff - all unused */ |
110 | memset(rtc_config_block, 0xff, sizeof(rtc_config_block)); | 115 | memset(rtc_config_block, 0xff, CONFIG_BLOCK_SIZE); |
111 | /* insert header */ | 116 | /* insert header */ |
112 | rtc_config_block[0] = 'R'; | 117 | rtc_config_block[0] = 'R'; |
113 | rtc_config_block[1] = 'o'; | 118 | rtc_config_block[1] = 'o'; |
114 | rtc_config_block[2] = 'c'; | 119 | rtc_config_block[2] = 'c'; |
115 | rtc_config_block[3] = 0x1; /* config block version number */ | 120 | rtc_config_block[3] = CONFIG_BLOCK_VERSION; |
116 | } | 121 | } |
117 | 122 | ||
118 | #ifdef HAVE_RTC | ||
119 | /* | 123 | /* |
120 | * save the config block buffer on the RTC RAM | 124 | * save the config block buffer to disk or RTC RAM |
121 | */ | 125 | */ |
122 | static int save_config_buffer( void ) | 126 | static int save_config_buffer( void ) |
123 | { | 127 | { |
124 | unsigned char addr = 0x14; | 128 | unsigned short chksum; |
125 | int r; | 129 | |
126 | unsigned char *p; | 130 | #ifdef HAVE_RTC |
127 | 131 | unsigned int i; | |
132 | int addr=0x14; | ||
133 | #endif | ||
134 | |||
128 | DEBUGF( "save_config_buffer()\n" ); | 135 | DEBUGF( "save_config_buffer()\n" ); |
129 | 136 | ||
130 | /* update the checksum in the end of the block before saving */ | 137 | /* update the checksum in the end of the block before saving */ |
131 | calculate_config_checksum(rtc_config_block + sizeof(rtc_config_block) - 2); | 138 | chksum = calculate_config_checksum(); |
132 | 139 | rtc_config_block[ CONFIG_BLOCK_SIZE - 2 ] = chksum >> 8; | |
140 | rtc_config_block[ CONFIG_BLOCK_SIZE - 1 ] = chksum & 0xff; | ||
141 | |||
142 | /* don't save if no changes were made */ | ||
143 | if ( chksum == last_checksum ) | ||
144 | return 0; | ||
145 | |||
146 | #ifdef HAVE_RTC | ||
133 | /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so | 147 | /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so |
134 | that it would write a number of bytes at a time since the RTC chip | 148 | that it would write a number of bytes at a time since the RTC chip |
135 | supports that, but this will have to do for now 8-) */ | 149 | supports that, but this will have to do for now 8-) */ |
136 | for (p = rtc_config_block; | 150 | for (i=0; i < CONFIG_BLOCK_SIZE; i++ ) { |
137 | p < rtc_config_block + sizeof(rtc_config_block); | 151 | int r = rtc_write(14, rtc_config_block[i]); |
138 | p++) | ||
139 | { | ||
140 | r = rtc_write(addr, *p); | ||
141 | if (r) { | 152 | if (r) { |
142 | DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", addr, r ); | 153 | DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", 14, r ); |
143 | return r; | 154 | return r; |
144 | } | 155 | } |
145 | addr++; | 156 | addr++; |
146 | } | 157 | } |
147 | 158 | ||
159 | #else | ||
160 | |||
161 | if(battery_level_safe() && (fat_startsector()!=0)) | ||
162 | return !ata_write_sectors( 61, 1, rtc_config_block); | ||
163 | else | ||
164 | return -1; | ||
165 | |||
166 | #endif | ||
167 | |||
148 | return 0; | 168 | return 0; |
149 | } | 169 | } |
150 | 170 | ||
151 | /* | 171 | /* |
152 | * load the config block buffer from the RTC RAM | 172 | * load the config block buffer from disk or RTC RAM |
153 | */ | 173 | */ |
154 | static int load_config_buffer( void ) | 174 | static int load_config_buffer( void ) |
155 | { | 175 | { |
176 | unsigned short chksum; | ||
177 | |||
178 | #ifdef HAVE_RTC | ||
156 | unsigned char addr = 0x14; | 179 | unsigned char addr = 0x14; |
157 | unsigned char cksum[2]; | 180 | unsigned int i; |
158 | unsigned char *p; | 181 | #endif |
159 | 182 | ||
160 | DEBUGF( "load_config_buffer()\n" ); | 183 | DEBUGF( "load_config_buffer()\n" ); |
161 | 184 | ||
185 | #ifdef HAVE_RTC | ||
162 | /* FIXME: the same comment applies here as for rtc_write */ | 186 | /* FIXME: the same comment applies here as for rtc_write */ |
163 | for (p = rtc_config_block; | 187 | for (i=0; i < CONFIG_BLOCK_SIZE; i++ ) { |
164 | p < rtc_config_block + sizeof(rtc_config_block); | 188 | rtc_config_block[i] = rtc_read(addr); |
165 | p++) | ||
166 | { | ||
167 | *p = rtc_read(addr); | ||
168 | addr++; | 189 | addr++; |
169 | } | 190 | } |
170 | |||
171 | /* calculate the checksum, check it and the header */ | ||
172 | calculate_config_checksum(cksum); | ||
173 | |||
174 | if (rtc_config_block[0x0] == 'R' | ||
175 | && rtc_config_block[0x1] == 'o' | ||
176 | && rtc_config_block[0x2] == 'c' | ||
177 | && rtc_config_block[0x3] == 0x0 | ||
178 | && cksum[0] == rtc_config_block[0x2a] | ||
179 | && cksum[1] == rtc_config_block[0x2b]) { | ||
180 | DEBUGF( "load_config_buffer: header & checksum test ok\n" ); | ||
181 | return 0; /* header and checksum is valid */ | ||
182 | } | ||
183 | |||
184 | /* if checksum is not valid, initialize the config buffer to all-unused */ | ||
185 | DEBUGF( "load_config_buffer: header & checksum test failed\n" ); | ||
186 | init_config_buffer(); | ||
187 | return 1; | ||
188 | } | ||
189 | |||
190 | #else /* HAVE_RTC */ | ||
191 | /* | ||
192 | * save the config block buffer on the 61 Sector | ||
193 | */ | ||
194 | static int save_config_buffer( void ) | ||
195 | { | ||
196 | DEBUGF( "save_config_buffer()\n" ); | ||
197 | |||
198 | /* update the checksum in the end of the block before saving */ | ||
199 | calculate_config_checksum(rtc_config_block + sizeof(rtc_config_block) - 2); | ||
200 | #ifdef SAVE_TO_DISK | ||
201 | if(battery_level_safe() && (fat_firstsector()!=0)) | ||
202 | return !ata_write_sectors( 61, 1, rtc_config_block); | ||
203 | else | ||
204 | return -1; | ||
205 | #else | 191 | #else |
206 | return 0; | 192 | ata_read_sectors( 61, 1, rtc_config_block); |
207 | #endif | 193 | #endif |
208 | } | ||
209 | |||
210 | /* | ||
211 | * load the config block buffer from disk | ||
212 | */ | ||
213 | static int load_config_buffer( void ) | ||
214 | { | ||
215 | #ifdef SAVE_TO_DISK | ||
216 | unsigned char cksum[2]; | ||
217 | |||
218 | DEBUGF( "load_config_buffer()\n" ); | ||
219 | 194 | ||
220 | ata_read_sectors( 61, 1, rtc_config_block); | ||
221 | |||
222 | /* calculate the checksum, check it and the header */ | 195 | /* calculate the checksum, check it and the header */ |
223 | calculate_config_checksum(cksum); | 196 | chksum = calculate_config_checksum(); |
197 | |||
198 | if (rtc_config_block[0] == 'R' && | ||
199 | rtc_config_block[1] == 'o' && | ||
200 | rtc_config_block[2] == 'c' && | ||
201 | rtc_config_block[3] == CONFIG_BLOCK_VERSION && | ||
202 | (chksum >> 8) == rtc_config_block[CONFIG_BLOCK_SIZE - 2] && | ||
203 | (chksum & 0xff) == rtc_config_block[CONFIG_BLOCK_SIZE - 1]) | ||
204 | { | ||
205 | DEBUGF( "load_config_buffer: header & checksum test ok\n" ); | ||
206 | last_checksum = chksum; | ||
207 | return 0; /* header and checksum is valid */ | ||
208 | } | ||
224 | 209 | ||
225 | if (rtc_config_block[0x0] == 'R' | ||
226 | && rtc_config_block[0x1] == 'o' | ||
227 | && rtc_config_block[0x2] == 'c' | ||
228 | && rtc_config_block[0x3] == 0x0 | ||
229 | && cksum[0] == rtc_config_block[0x2a] | ||
230 | && cksum[1] == rtc_config_block[0x2b]) { | ||
231 | DEBUGF( "load_config_buffer: header & checksum test ok\n" ); | ||
232 | return 0; /* header and checksum is valid */ | ||
233 | } | ||
234 | #endif | ||
235 | /* if checksum is not valid, initialize the config buffer to all-unused */ | 210 | /* if checksum is not valid, initialize the config buffer to all-unused */ |
236 | DEBUGF( "load_config_buffer: header & checksum test failed\n" ); | 211 | DEBUGF( "load_config_buffer: header & checksum test failed\n" ); |
237 | init_config_buffer(); | 212 | init_config_buffer(); |
238 | return 1; | 213 | return 1; |
239 | } | 214 | } |
240 | 215 | ||
241 | |||
242 | #endif /* HAVE_RTC */ | ||
243 | |||
244 | |||
245 | /* | 216 | /* |
246 | * persist all runtime user settings to disk or RTC RAM | 217 | * persist all runtime user settings to disk or RTC RAM |
247 | */ | 218 | */ |
@@ -276,8 +247,6 @@ int settings_save( void ) | |||
276 | 247 | ||
277 | rtc_config_block[0x11] = (unsigned char)global_settings.avc; | 248 | rtc_config_block[0x11] = (unsigned char)global_settings.avc; |
278 | 249 | ||
279 | rtc_config_block[0x12] = (unsigned char)global_settings.contrast; | ||
280 | |||
281 | memcpy(&rtc_config_block[0x24], &global_settings.total_uptime, 4); | 250 | memcpy(&rtc_config_block[0x24], &global_settings.total_uptime, 4); |
282 | 251 | ||
283 | if(save_config_buffer()) | 252 | if(save_config_buffer()) |
@@ -325,8 +294,11 @@ void settings_load(void) | |||
325 | if (rtc_config_block[0x9] != 0xFF) | 294 | if (rtc_config_block[0x9] != 0xFF) |
326 | global_settings.bass_boost = rtc_config_block[0x9]; | 295 | global_settings.bass_boost = rtc_config_block[0x9]; |
327 | 296 | ||
328 | if (rtc_config_block[0xa] != 0xFF) | 297 | if (rtc_config_block[0xa] != 0xFF) { |
329 | global_settings.contrast = rtc_config_block[0xa]; | 298 | global_settings.contrast = rtc_config_block[0xa]; |
299 | if ( global_settings.contrast < MIN_CONTRAST_SETTING ) | ||
300 | global_settings.contrast < DEFAULT_CONTRAST_SETTING; | ||
301 | } | ||
330 | if (rtc_config_block[0xb] != 0xFF) | 302 | if (rtc_config_block[0xb] != 0xFF) |
331 | global_settings.backlight = rtc_config_block[0xb]; | 303 | global_settings.backlight = rtc_config_block[0xb]; |
332 | if (rtc_config_block[0xc] != 0xFF) | 304 | if (rtc_config_block[0xc] != 0xFF) |
@@ -352,9 +324,6 @@ void settings_load(void) | |||
352 | if (rtc_config_block[0x11] != 0xFF) | 324 | if (rtc_config_block[0x11] != 0xFF) |
353 | global_settings.avc = rtc_config_block[0x11]; | 325 | global_settings.avc = rtc_config_block[0x11]; |
354 | 326 | ||
355 | if (rtc_config_block[0x12] != 0xff) | ||
356 | global_settings.contrast = rtc_config_block[0x12]; | ||
357 | |||
358 | if (rtc_config_block[0x24] != 0xFF) | 327 | if (rtc_config_block[0x24] != 0xFF) |
359 | memcpy(&global_settings.total_uptime, &rtc_config_block[0x24], 4); | 328 | memcpy(&global_settings.total_uptime, &rtc_config_block[0x24], 4); |
360 | } | 329 | } |