From 6b25f79af039b8b367b4fff8c3aadac1cca0ab7d Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Mon, 15 Jul 2002 11:02:12 +0000 Subject: Settings are now saved in RTC RAM on Recorder (Heikki Hannikainen). Introduced debug menu (Heikki Hannikainen). Cleaned up settings API. Added scroll_speed init. Moved dbg_ports() and dbg_rtc() from firmware/debug.c to apps/debug_menu.c Made panic buffer static. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1347 a1c6a512-1295-4272-9138-f99709370657 --- apps/main.c | 13 ++- apps/main_menu.c | 21 +++- apps/settings.c | 302 ++++++++++++++++++++++++++++++++++++++++++++------- apps/settings.h | 17 +-- apps/settings_menu.c | 1 + apps/sound_menu.c | 1 + 6 files changed, 303 insertions(+), 52 deletions(-) (limited to 'apps') diff --git a/apps/main.c b/apps/main.c index 816df5c10f..2062efa347 100644 --- a/apps/main.c +++ b/apps/main.c @@ -41,6 +41,7 @@ #include "thread.h" #include "settings.h" #include "backlight.h" +#include "debug_menu.h" #include "version.h" @@ -63,7 +64,7 @@ void init(void) init_threads(); lcd_init(); show_logo(); - reset_settings(&global_settings); + settings_reset(); sleep(HZ/2); } @@ -81,7 +82,7 @@ void init(void) system_init(); kernel_init(); - reset_settings(&global_settings); + settings_reset(); dmalloc_initialize(); bmalloc_add_pool(poolstart, poolend-poolstart); @@ -114,12 +115,12 @@ void init(void) lcd_puts(0, 1, str); lcd_puts(0, 3, "Press ON to debug"); lcd_update(); - while(button_get(true) != BUTTON_ON) {}; + while(button_get(true) != BUTTON_ON); dbg_ports(); #endif panicf("ata: %d", rc); } - + pinfo = disk_init(); if (!pinfo) panicf("disk: NULL"); @@ -128,6 +129,10 @@ void init(void) if(rc) panicf("mount: %d",rc); + settings_load(); + global_settings.total_boots++; + settings_save(); + mpeg_init( global_settings.volume, global_settings.bass, global_settings.treble ); diff --git a/apps/main_menu.c b/apps/main_menu.c index e231a22033..de09897baa 100644 --- a/apps/main_menu.c +++ b/apps/main_menu.c @@ -25,7 +25,7 @@ #include "kernel.h" #include "main_menu.h" #include "version.h" -#include "debug.h" +#include "debug_menu.h" #include "sprintf.h" #include #include "playlist.h" @@ -116,11 +116,25 @@ void show_credits(void) sleep((HZ*2)/10); if (button_get(false)) - return; + return; } roll_credits(); } +void show_info(void) +{ + char s[32]; + + lcd_clear_display(); + lcd_puts(0, 0, "Rockbox info:"); + /* TODO: add disk size/usage info, battery charge etc here? */ + snprintf(s, sizeof(s), "Booted: %d times", global_settings.total_boots); + lcd_puts(0, 2, s); + lcd_update(); + + button_get(true); +} + void main_menu(void) { int m; @@ -133,9 +147,10 @@ void main_menu(void) { "Games", games_menu }, { "Screensavers", screensavers_menu }, #endif + { "Info", show_info }, { "Version", show_credits }, #ifndef SIMULATOR - { "Debug (keep out!)", dbg_ports }, + { "Debug (keep out!)", debug_menu }, #endif }; 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 @@ * $Id$ * * Copyright (C) 2002 by wavey@wavey.org + * RTC config saving code (C) 2002 by hessu@hes.iki.fi * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -26,84 +27,309 @@ #include "button.h" #include "lcd.h" #include "mpeg.h" +#include "string.h" struct user_settings global_settings; +#ifdef HAVE_RTC + +/******************************************** + +Config block as saved on the battery-packed RTC user RAM memory block +of 44 bytes, starting at offset 0x14 of the RTC memory space. + +offset abs +0x00 0x14 "Roc" header signature: 0x52 0x6f 0x63 +0x03 0x17 +0x04 0x18 +0x05 0x19 +0x06 0x1a +0x07 0x1b +0x08 0x1c +0x09 0x1d +0x0a 0x1e +0x0b 0x1f +0x0c 0x20 +0x0d 0x21 +0x0e 0x22 +0x0f 0x23 +0x10 0x24 + + + + the geeky but useless statistics part: +0x24 +0x28 + +0x2a + +Config memory is reset to 0xff and initialized with 'factory defaults' if +a valid header & checksum is not found. Config version number is only +increased when information is _relocated_ or space is _reused_ so that old +versions can read and modify configuration changed by new versions. New +versions should check for the value of '0xff' in each config memory +location used, and reset the setting in question with a factory default if +needed. Memory locations not used by a given version should not be +modified unless the header & checksum test fails. + +*************************************/ + +#include "rtc.h" +static unsigned char rtc_config_block[44]; + +/* + * Calculates the checksum for the config block and places it in the given 2-byte buffer + */ + +static void calculate_config_checksum(unsigned char *cksum) +{ + unsigned char *p; + cksum[0] = cksum[1] = 0; + + for (p = rtc_config_block; + p < rtc_config_block + sizeof(rtc_config_block) - 2; + p++) + { + cksum[0] = cksum[0] ^ *p; + p++; + cksum[1] = cksum[1] ^ *p; + } +} + +/* + * initialize the config block buffer + */ +static void init_config_buffer( void ) +{ + DEBUGF( "init_config_buffer()\n" ); + + /* reset to 0xff - all unused */ + memset(rtc_config_block, 0xff, sizeof(rtc_config_block)); + /* insert header */ + rtc_config_block[0] = 'R'; + rtc_config_block[1] = 'o'; + rtc_config_block[2] = 'c'; + rtc_config_block[3] = 0x0; /* config block version number */ +} + +/* + * save the config block buffer on the RTC RAM + */ +static int save_config_buffer( void ) +{ + unsigned char addr = 0x14; + int r; + unsigned char *p; + + DEBUGF( "save_config_buffer()\n" ); + + /* update the checksum in the end of the block before saving */ + calculate_config_checksum(rtc_config_block + sizeof(rtc_config_block) - 2); + + /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so + that it would write a number of bytes at a time since the RTC chip + supports that, but this will have to do for now 8-) */ + for (p = rtc_config_block; + p < rtc_config_block + sizeof(rtc_config_block); + p++) + { + r = rtc_write(addr, *p); + if (r) { + DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n", addr, r ); + return r; + } + addr++; + } + + return 0; +} + /* - * persist all runtime user settings to disk + * load the config block buffer from the RTC RAM */ -int persist_all_settings( void ) +static int load_config_buffer( void ) { + unsigned char addr = 0x14; + unsigned char cksum[2]; + unsigned char *p; + + DEBUGF( "load_config_buffer()\n" ); + + /* FIXME: the same comment applies here as for rtc_write */ + for (p = rtc_config_block; + p < rtc_config_block + sizeof(rtc_config_block); + p++) + { + *p = rtc_read(addr); + addr++; + } + + /* calculate the checksum, check it and the header */ + calculate_config_checksum(cksum); + + if (rtc_config_block[0x0] == 'R' + && rtc_config_block[0x1] == 'o' + && rtc_config_block[0x2] == 'c' + && rtc_config_block[0x3] == 0x0 + && cksum[0] == rtc_config_block[0x2a] + && cksum[1] == rtc_config_block[0x2b]) { + DEBUGF( "load_config_buffer: header & checksum test ok" ); + return 0; /* header and checksum is valid */ + } + + /* if checksum is not valid, initialize the config buffer to all-unused */ + DEBUGF( "load_config_buffer: header & checksum test failed" ); + init_config_buffer(); return 1; } +#endif /* HAVE_RTC */ + /* - * persist all the playlist information to disk + * persist all runtime user settings to disk or RTC RAM */ -int persist_all_playlist_info( void ) +int settings_save( void ) { + DEBUGF( "settings_save()\n" ); + +#ifdef HAVE_RTC + /* update the config block buffer with current + settings and save the block in the RTC */ + rtc_config_block[0x4] = (unsigned char)global_settings.volume; + rtc_config_block[0x5] = (unsigned char)global_settings.balance; + rtc_config_block[0x6] = (unsigned char)global_settings.bass; + rtc_config_block[0x7] = (unsigned char)global_settings.treble; + rtc_config_block[0x8] = (unsigned char)global_settings.loudness; + rtc_config_block[0x9] = (unsigned char)global_settings.bass_boost; + + rtc_config_block[0xa] = (unsigned char)global_settings.contrast; + rtc_config_block[0xb] = (unsigned char)global_settings.backlight; + rtc_config_block[0xc] = (unsigned char)global_settings.poweroff; + rtc_config_block[0xd] = (unsigned char)global_settings.resume; + + rtc_config_block[0xe] = (unsigned char) + ((global_settings.playlist_shuffle & 1) | + ((global_settings.mp3filter & 1) << 1)); + + rtc_config_block[0xf] = (unsigned char) + ((global_settings.scroll_speed << 3) | + (global_settings.wps_display & 7)); + + memcpy(&rtc_config_block[0x24], &global_settings.total_uptime, 4); + memcpy(&rtc_config_block[0x28], &global_settings.total_boots, 2); + + save_config_buffer(); +#endif /* HAVE_RTC */ + return 1; } /* - * load settings from disk + * load settings from disk or RTC RAM */ -void reload_all_settings( struct user_settings *settings ) +void settings_load(void) { +#ifdef HAVE_RTC + unsigned char c; +#endif + DEBUGF( "reload_all_settings()\n" ); - /* this is a TEMP stub version */ - /* populate settings with default values */ + settings_reset(); - reset_settings( settings ); +#ifdef HAVE_RTC + /* load the buffer from the RTC (resets it to all-unused if the block + is invalid) and decode the settings which are set in the block */ + if (!load_config_buffer()) { + if (rtc_config_block[0x4] != 0xFF) + global_settings.volume = rtc_config_block[0x4]; + if (rtc_config_block[0x5] != 0xFF) + global_settings.balance = rtc_config_block[0x5]; + if (rtc_config_block[0x6] != 0xFF) + global_settings.bass = rtc_config_block[0x6]; + if (rtc_config_block[0x7] != 0xFF) + global_settings.treble = rtc_config_block[0x7]; + if (rtc_config_block[0x8] != 0xFF) + global_settings.loudness = rtc_config_block[0x8]; + if (rtc_config_block[0x9] != 0xFF) + global_settings.bass_boost = rtc_config_block[0x9]; + + if (rtc_config_block[0xa] != 0xFF) + global_settings.contrast = rtc_config_block[0xa]; + if (rtc_config_block[0xb] != 0xFF) + global_settings.backlight = rtc_config_block[0xb]; + if (rtc_config_block[0xc] != 0xFF) + global_settings.poweroff = rtc_config_block[0xc]; + if (rtc_config_block[0xd] != 0xFF) + global_settings.resume = rtc_config_block[0xd]; + if (rtc_config_block[0xe] != 0xFF) { + global_settings.playlist_shuffle = rtc_config_block[0xe] & 1; + global_settings.mp3filter = (rtc_config_block[0xe] >> 1) & 1; + } + + c = rtc_config_block[0xf] >> 3; + if (c != 31) + global_settings.scroll_speed = c; + + c = rtc_config_block[0xf] & 7; + if (c != 7) + global_settings.wps_display = c; + + if (rtc_config_block[0x24] != 0xFF) + memcpy(&global_settings.total_uptime, &rtc_config_block[0x24], 4); + if (rtc_config_block[0x28] != 0xFF) + memcpy(&global_settings.total_boots, &rtc_config_block[0x28], 2); + } + +#endif /* HAVE_RTC */ } /* * reset all settings to their default value */ -void reset_settings( struct user_settings *settings ) { +void settings_reset(void) { - DEBUGF( "reset_settings()\n" ); - - settings->volume = mpeg_sound_default(SOUND_VOLUME); - settings->balance = DEFAULT_BALANCE_SETTING; - settings->bass = mpeg_sound_default(SOUND_BASS); - settings->treble = mpeg_sound_default(SOUND_TREBLE); - settings->loudness = DEFAULT_LOUDNESS_SETTING; - settings->bass_boost = DEFAULT_BASS_BOOST_SETTING; - settings->contrast = DEFAULT_CONTRAST_SETTING; - settings->poweroff = DEFAULT_POWEROFF_SETTING; - settings->backlight = DEFAULT_BACKLIGHT_SETTING; - settings->wps_display = DEFAULT_WPS_DISPLAY; - settings->mp3filter = true; - settings->playlist_shuffle = false; + DEBUGF( "settings_reset()\n" ); + + global_settings.volume = mpeg_sound_default(SOUND_VOLUME); + global_settings.balance = DEFAULT_BALANCE_SETTING; + global_settings.bass = mpeg_sound_default(SOUND_BASS); + global_settings.treble = mpeg_sound_default(SOUND_TREBLE); + global_settings.loudness = DEFAULT_LOUDNESS_SETTING; + global_settings.bass_boost = DEFAULT_BASS_BOOST_SETTING; + global_settings.contrast = DEFAULT_CONTRAST_SETTING; + global_settings.poweroff = DEFAULT_POWEROFF_SETTING; + global_settings.backlight = DEFAULT_BACKLIGHT_SETTING; + global_settings.wps_display = DEFAULT_WPS_DISPLAY; + global_settings.mp3filter = true; + global_settings.playlist_shuffle = false; + global_settings.total_boots = 0; + global_settings.total_uptime = 0; + global_settings.scroll_speed = 8; } /* * dump the list of current settings */ -void display_current_settings( struct user_settings *settings ) +void settings_display(void) { #ifdef DEBUG - DEBUGF( "\ndisplay_current_settings()\n" ); + DEBUGF( "\nsettings_display()\n" ); DEBUGF( "\nvolume:\t\t%d\nbalance:\t%d\nbass:\t\t%d\ntreble:\t\t%d\nloudness:\t%d\nbass boost:\t%d\n", - settings->volume, - settings->balance, - settings->bass, - settings->treble, - settings->loudness, - settings->bass_boost ); + global_settings.volume, + global_settings.balance, + global_settings.bass, + global_settings.treble, + global_settings.loudness, + global_settings.bass_boost ); DEBUGF( "contrast:\t%d\npoweroff:\t%d\nbacklight:\t%d\n", - settings->contrast, - settings->poweroff, - settings->backlight ); -#else - /* Get rid of warning */ - settings = settings; + global_settings.contrast, + global_settings.poweroff, + global_settings.backlight ); #endif } diff --git a/apps/settings.h b/apps/settings.h index 5f67b3b1bc..d47c9b8a83 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -54,20 +54,23 @@ struct user_settings int loop_playlist; /* do we return to top of playlist at end? */ bool mp3filter; - int scroll_speed; + int scroll_speed; /* long texts scrolling speed: 1-20 */ bool playlist_shuffle; /* while playing screen settings */ - int wps_display; - + int wps_display; /* 0=id3, 1=file, 2=parse */ + + /* geeky persistent statistics */ + unsigned short total_boots; /* how many times the device has been booted */ + unsigned int total_uptime; /* total uptime since rockbox was first booted */ }; /* prototypes */ -int persist_all_settings( void ); -void reload_all_settings( struct user_settings *settings ); -void reset_settings( struct user_settings *settings ); -void display_current_settings( struct user_settings *settings ); +int settings_save(void); +void settings_load(void); +void settings_reset(void); +void settings_display(void); void set_bool(char* string, bool* variable ); void set_option(char* string, int* variable, char* options[], int numoptions ); diff --git a/apps/settings_menu.c b/apps/settings_menu.c index a27f4feac1..f910d52c1f 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -76,4 +76,5 @@ void settings_menu(void) m=menu_init( items, sizeof items / sizeof(struct menu_items) ); menu_run(m); menu_exit(m); + settings_save(); } diff --git a/apps/sound_menu.c b/apps/sound_menu.c index cbfc7a714e..a9111bbaed 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c @@ -130,4 +130,5 @@ void sound_menu(void) m=menu_init( items, sizeof items / sizeof(struct menu_items) ); menu_run(m); menu_exit(m); + settings_save(); } -- cgit v1.2.3