From 6b25f79af039b8b367b4fff8c3aadac1cca0ab7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Stenberg?= Date: Mon, 15 Jul 2002 11:02:12 +0000 Subject: [PATCH] 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 | 312 +++++++++++++++++++++++++++++++++++++------ apps/settings.h | 17 ++- apps/settings_menu.c | 1 + apps/sound_menu.c | 1 + firmware/debug.c | 179 ------------------------- firmware/debug.h | 3 - firmware/panic.c | 2 +- firmware/usb.c | 3 + 10 files changed, 312 insertions(+), 240 deletions(-) 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]; + /* - * persist all runtime user settings to disk + * Calculates the checksum for the config block and places it in the given 2-byte buffer */ -int persist_all_settings( void ) + +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; +} + +/* + * load the config block buffer from the RTC RAM + */ +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 runtime user settings to disk or RTC RAM + */ +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; } /* - * persist all the playlist information to disk + * load settings from disk or RTC RAM */ -int persist_all_playlist_info( void ) -{ - return 1; -} - -/* - * load settings from disk - */ -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" ); + DEBUGF( "settings_reset()\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; + 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(); } diff --git a/firmware/debug.c b/firmware/debug.c index a7923ac237..83eb149706 100644 --- a/firmware/debug.c +++ b/firmware/debug.c @@ -29,12 +29,7 @@ static char debugbuf[200]; #ifndef SIMULATOR /* allow non archos platforms to display output */ #include "kernel.h" -#include "button.h" #include "system.h" -#include "lcd.h" -#include "adc.h" -#include "mas.h" -#include "power.h" void debug_init(void) { @@ -214,180 +209,6 @@ void debugf(char *fmt, ...) #endif } -/*---------------------------------------------------*/ -/* SPECIAL DEBUG STUFF */ -/*---------------------------------------------------*/ -extern int ata_device; -extern int ata_io_address; - -#ifdef ARCHOS_RECORDER -/* Test code!!! */ -void dbg_ports(void) -{ - unsigned short porta; - unsigned short portb; - unsigned char portc; - char buf[32]; - int button; - int battery_voltage; - int batt_int, batt_frac; - bool charge_status = false; - bool ide_status = true; - - lcd_clear_display(); - - while(1) - { - porta = PADR; - portb = PBDR; - portc = PCDR; - - snprintf(buf, 32, "PADR: %04x", porta); - lcd_puts(0, 0, buf); - snprintf(buf, 32, "PBDR: %04x", portb); - lcd_puts(0, 1, buf); - - snprintf(buf, 32, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4)); - lcd_puts(0, 2, buf); - snprintf(buf, 32, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5)); - lcd_puts(0, 3, buf); - snprintf(buf, 32, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6)); - lcd_puts(0, 4, buf); - snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7)); - lcd_puts(0, 5, buf); - - battery_voltage = (adc_read(6) * BATTERY_SCALE_FACTOR) / 10000; - batt_int = battery_voltage / 100; - batt_frac = battery_voltage % 100; - - snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac, - battery_level()); - lcd_puts(0, 6, buf); - - snprintf(buf, 32, "ATA: %s, 0x%x", - ata_device?"slave":"master", ata_io_address); - lcd_puts(0, 7, buf); - - lcd_update(); - sleep(HZ/10); - - button = button_get(false); - - switch(button) - { - case BUTTON_ON: - charge_status = charge_status?false:true; - charger_enable(charge_status); - break; - - case BUTTON_UP: - ide_status = ide_status?false:true; - ide_power_enable(ide_status); - break; - - case BUTTON_OFF: - charger_enable(false); - ide_power_enable(true); - return; - } - } -} -#else -void dbg_ports(void) -{ - unsigned short porta; - unsigned short portb; - unsigned char portc; - char buf[32]; - unsigned long crc_count; - int button; - int battery_voltage; - int batt_int, batt_frac; - int currval = 0; - - lcd_clear_display(); - - while(1) - { - porta = PADR; - portb = PBDR; - portc = PCDR; - - switch(currval) - { - case 0: - snprintf(buf, 32, "PADR: %04x ", porta); - break; - case 1: - snprintf(buf, 32, "PBDR: %04x ", portb); - break; - case 2: - snprintf(buf, 32, "AN0: %03x ", adc_read(0)); - break; - case 3: - snprintf(buf, 32, "AN1: %03x ", adc_read(1)); - break; - case 4: - snprintf(buf, 32, "AN2: %03x ", adc_read(2)); - break; - case 5: - snprintf(buf, 32, "AN3: %03x ", adc_read(3)); - break; - case 6: - snprintf(buf, 32, "AN4: %03x ", adc_read(4)); - break; - case 7: - snprintf(buf, 32, "AN5: %03x ", adc_read(5)); - break; - case 8: - snprintf(buf, 32, "AN6: %03x ", adc_read(6)); - break; - case 9: - snprintf(buf, 32, "AN7: %03x ", adc_read(7)); - break; - case 10: - snprintf(buf, 32, "%s, 0x%x ", - ata_device?"slv":"mst", ata_io_address); - break; - case 11: - mas_readmem(MAS_BANK_D0, 0x303, &crc_count, 1); - - snprintf(buf, 32, "CRC: %d ", crc_count); - break; - } - lcd_puts(0, 0, buf); - - battery_voltage = (adc_read(6) * BATTERY_SCALE_FACTOR) / 10000; - batt_int = battery_voltage / 100; - batt_frac = battery_voltage % 100; - - snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac); - lcd_puts(0, 1, buf); - - sleep(HZ/5); - - button = button_get(false); - - switch(button) - { - case BUTTON_STOP: - return; - - case BUTTON_LEFT: - currval--; - if(currval < 0) - currval = 11; - break; - - case BUTTON_RIGHT: - currval++; - if(currval > 11) - currval = 0; - break; - } - } -} -#endif #else /* SIMULATOR code coming up */ diff --git a/firmware/debug.h b/firmware/debug.h index 2f984ee55e..876b8511a6 100644 --- a/firmware/debug.h +++ b/firmware/debug.h @@ -21,9 +21,6 @@ extern void debug_init(void); extern void debugf(char* fmt,...); -#ifndef SIMULATOR -extern void dbg_ports(void); -#endif #ifdef __GNUC__ diff --git a/firmware/panic.c b/firmware/panic.c index f34ac07f4f..95519ce621 100644 --- a/firmware/panic.c +++ b/firmware/panic.c @@ -23,7 +23,7 @@ #include "lcd.h" #include "debug.h" -char panic_buf[128]; +static char panic_buf[128]; /* * "Dude. This is pretty fucked-up, right here." diff --git a/firmware/usb.c b/firmware/usb.c index 1e45cd34b8..3732d83df6 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -32,6 +32,9 @@ #include "button.h" #include "sprintf.h" +#ifdef ARCHOS_RECORDER +extern void dbg_ports(void); +#endif #define USB_REALLY_BRAVE