Settings are now stored in /.rockbox/config.cfg instead of the hidden sector. (FS #6557)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12093 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/SOURCES b/apps/SOURCES
index 2070732..2304ee7 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -20,6 +20,7 @@
plugin.c
screens.c
settings.c
+settings_list.c
settings_menu.c
sound_menu.c
status.c
diff --git a/apps/filetree.c b/apps/filetree.c
index f10c02b..cd020d0 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -486,7 +486,7 @@
case TREE_ATTR_CFG:
gui_syncsplash(0, true, str(LANG_WAIT));
- if (!settings_load_config(buf))
+ if (!settings_load_config(buf,true))
break;
gui_syncsplash(HZ, true, str(LANG_SETTINGS_LOADED));
break;
diff --git a/apps/main.c b/apps/main.c
index 1361b81..5137ff9 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -247,7 +247,6 @@
screen_access_init();
gui_syncstatusbar_init(&statusbars);
settings_reset();
- settings_calc_config_sector();
settings_load(SETTINGS_ALL);
gui_sync_wps_init();
settings_apply();
@@ -447,8 +446,6 @@
}
}
- settings_calc_config_sector();
-
#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
(CONFIG_KEYPAD == IRIVER_H10_PAD) || (CONFIG_KEYPAD == GIGABEAT_PAD)
#ifdef SETTINGS_RESET
diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h
index 439061e..a4f9f1a 100644
--- a/apps/recorder/radio.h
+++ b/apps/recorder/radio.h
@@ -18,7 +18,6 @@
****************************************************************************/
#ifndef RADIO_H
#define RADIO_H
-#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
#ifndef FMRADIO_H
#include "fmradio.h"
diff --git a/apps/settings.c b/apps/settings.c
index 4ef2f14..01ede41 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -25,6 +25,7 @@
#include "kernel.h"
#include "thread.h"
#include "action.h"
+#include "crc32.h"
#include "settings.h"
#include "disk.h"
#include "panic.h"
@@ -72,6 +73,7 @@
#include "statusbar.h"
#include "splash.h"
#include "list.h"
+#include "settings_list.h"
#if LCD_DEPTH > 1
#include "backdrop.h"
#endif
@@ -100,9 +102,7 @@
#include "eq_menu.h"
#endif
-#define CONFIG_BLOCK_VERSION 59
-#define CONFIG_BLOCK_SIZE 512
-#define RTC_BLOCK_SIZE 44
+#define NVRAM_BLOCK_SIZE 44
#ifdef HAVE_LCD_BITMAP
#define MAX_LINES 10
@@ -115,644 +115,115 @@
#endif
long lasttime = 0;
-static long config_sector = 0; /* mark uninitialized */
-static unsigned char config_block[CONFIG_BLOCK_SIZE];
-
-/* descriptor for a configuration value */
-/* (watch the struct packing and member sizes to keep this small) */
-struct bit_entry
-{
- /* how many bits within the bitfield (1-32), MSB set if value is signed */
- unsigned char bit_size; /* min 6+1 bit */
- /* how many bytes in the global_settings struct (1,2,4) */
- unsigned char byte_size; /* min 3 bits */
- /* store position in global_settings struct */
- short settings_offset; /* min 9 bit, better 10 */
- /* default value */
- int default_val; /* min 15 bit */
- /* variable name in a .cfg file, NULL if not to be saved */
- const char* cfg_name;
- /* set of values, "rgb" for a color, or NULL for a numerical value */
- const char* cfg_val;
-};
-
-/********************************************
-
-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 <version byte: 0x0>
-0x04 0x18 start of bit-table
-...
-0x28,0x29 unused, not reachable by set_bits() without disturbing the next 2
-0x2A,0x2B <checksum 2 bytes: xor of 0x00-0x29>
-
-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.
-Memory locations not used by a given version should not be
-modified unless the header & checksum test fails.
-
-Rest of config block, only saved to disk:
-0x2C start of 2nd bit-table
-...
-0xA4 (char[20]) FMR Preset file
-0xB8 (char[20]) WPS file
-0xCC (char[20]) Lang file
-0xE0 (char[20]) Font file
-... (char[20]) RWPS file (on targets supporting a Remote WPS)
-... (char[20]) Main backdrop file (on color LCD targets)
-
-... to 0x200 <unused>
-
-*************************************/
-
-/* The persistence of the global_settings members is now controlled by
- the two tables below, rtc_bits and hd_bits.
- New values can just be added to the end, it will be backwards
- compatible. If you however change order, bitsize, etc. of existing
- entries, you need to bump CONFIG_BLOCK_VERSION to break compatibility.
+/* NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin */
+/* NVRAM is set out as
+[0] 'R'
+[1] 'b'
+[2] version
+[3] stored variable count
+[4-7] crc32 checksum
+[8-NVRAM_BLOCK_SIZE] data
*/
+#define NVRAM_DATA_START 8
+#define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
+static char nvram_buffer[NVRAM_BLOCK_SIZE];
-
-/* convenience macro for both size and offset of global_settings member */
-#define S_O(val) sizeof(global_settings.val), offsetof(struct user_settings, val)
-#define SIGNED 0x80 /* for bitsize value with signed attribute */
-
-/* some sets of values which are used more than once, to save memory */
-static const char off_on[] = "off,on";
-static const char off_on_ask[] = "off,on,ask";
-static const char off_number_spell_hover[] = "off,number,spell,hover";
-#ifdef HAVE_LCD_BITMAP
-static const char graphic_numeric[] = "graphic,numeric";
-#endif
-
-#ifdef HAVE_RECORDING
-/* keep synchronous to trig_durations and
- trigger_times in settings_apply_trigger */
-static const char trig_durations_conf [] =
- "0s,1s,2s,5s,10s,15s,20s,25s,30s,1min,2min,5min,10min";
-#endif
-
-#if defined(CONFIG_BACKLIGHT)
-static const char backlight_times_conf [] =
- "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90";
-#endif
-
-/* the part of the settings which ends up in the RTC RAM, where available
- (those we either need early, save frequently, or without spinup) */
-static const struct bit_entry rtc_bits[] =
+static bool read_nvram_data(char* buf, int max_len)
{
- /* placeholder, containing the size information */
- {9, 0, 0, 0, NULL, NULL }, /* 9 bit to tell how far this is populated */
-
- /* # of bits, offset+size, default, .cfg name, .cfg values */
- /* sound */
-#if CONFIG_CODEC == MAS3507D
- {8 | SIGNED, S_O(volume), -18, "volume", NULL }, /* -78...+18 */
+ unsigned crc32 = 0xffffffff;
+ int var_count = 0, i = 0, buf_pos = 0;
+#ifndef HAVE_RTC_RAM
+ int fd = open(NVRAM_FILE,O_RDONLY);
+ if (fd < 0)
+ return false;
+ memset(buf,0,max_len);
+ if (read(fd,buf,max_len) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
+ return false;
+ close(fd);
#else
- {8 | SIGNED, S_O(volume), -25, "volume", NULL }, /* -100...+12 / -84...0 */
+ memset(buf,0,max_len);
+ /* read rtc block */
+ for (i=0; i < max_len; i++ )
+ buf[i] = rtc_read(0x14+i);
#endif
- {8 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -100...100 */
-#if CONFIG_CODEC != SWCODEC /* any MAS */
- {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -15..+15 / -12..+12 */
- {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -15..+15 / -12..+12 */
-#elif defined HAVE_UDA1380
- {5, S_O(bass), 0, "bass", NULL }, /* 0..+24 */
- {3, S_O(treble), 0, "treble", NULL }, /* 0..+6 */
-#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
- || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
- || defined(HAVE_WM8751)
- {5 | SIGNED, S_O(bass), 0, "bass", NULL }, /* -6..+9 */
- {5 | SIGNED, S_O(treble), 0, "treble", NULL }, /* -6..+9 */
-#endif
-#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
- {5, S_O(loudness), 0, "loudness", NULL }, /* 0...17 */
- {3, S_O(avc), 0, "auto volume", "off,20ms,2,4,8" },
- {1, S_O(superbass), false, "superbass", off_on },
-#endif
- {3, S_O(channel_config), 0, "channels",
- "stereo,mono,custom,mono left,mono right,karaoke" },
- {8, S_O(stereo_width), 100, "stereo width", NULL},
- /* playback */
- {1, S_O(resume), false, "resume", off_on },
- {1, S_O(playlist_shuffle), false, "shuffle", off_on },
- {16 | SIGNED, S_O(resume_index), -1, NULL, NULL },
- {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL },
- {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL },
- {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL },
- {3, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one,shuffle,ab" },
- /* LCD */
-#ifdef HAVE_LCD_CONTRAST
- {6, S_O(contrast), DEFAULT_CONTRAST_SETTING, "contrast", NULL },
-#endif
-#ifdef CONFIG_BACKLIGHT
- {5, S_O(backlight_timeout), 6, "backlight timeout", backlight_times_conf },
-#ifdef CONFIG_CHARGING
- {5, S_O(backlight_timeout_plugged), 11, "backlight timeout plugged",
- backlight_times_conf },
-#endif
-#endif /* CONFIG_BACKLIGHT */
-#ifdef HAVE_LCD_BITMAP
- {1, S_O(invert), false, "invert", off_on },
- {1, S_O(flip_display), false, "flip display", off_on },
- /* display */
- {1, S_O(invert_cursor), true, "invert cursor", off_on },
- {1, S_O(statusbar), true, "statusbar", off_on },
- {1, S_O(scrollbar), true, "scrollbar", off_on },
-#if CONFIG_KEYPAD == RECORDER_PAD
- {1, S_O(buttonbar), true, "buttonbar", off_on },
-#endif
- {1, S_O(volume_type), 0, "volume display", graphic_numeric },
- {1, S_O(battery_display), 0, "battery display", graphic_numeric },
- {1, S_O(timeformat), 0, "time format", "24hour,12hour" },
-#endif /* HAVE_LCD_BITMAP */
- {1, S_O(show_icons), true, "show icons", off_on },
- /* system */
- {4, S_O(poweroff), 10,
- "idle poweroff", "off,1,2,3,4,5,6,7,8,9,10,15,30,45,60" },
- {18, S_O(runtime), 0, NULL, NULL },
- {18, S_O(topruntime), 0, NULL, NULL },
-#if MEM > 1
- {15, S_O(max_files_in_playlist), 10000,
- "max files in playlist", NULL }, /* 1000...20000 */
- {14, S_O(max_files_in_dir), 400,
- "max files in dir", NULL }, /* 50...10000 */
-#else
- {15, S_O(max_files_in_playlist), 1000,
- "max files in playlist", NULL }, /* 1000...20000 */
- {14, S_O(max_files_in_dir), 200,
- "max files in dir", NULL }, /* 50...10000 */
-#endif
- /* battery */
- {12, S_O(battery_capacity), BATTERY_CAPACITY_DEFAULT, "battery capacity",
- NULL }, /* 1500...3200 for NiMH, 2200...3200 for LiIon,
- 500...1500 for Alkaline */
-#ifdef CONFIG_CHARGING
- {1, S_O(car_adapter_mode), false, "car adapter mode", off_on },
-#endif
- /* tuner */
-#ifdef CONFIG_TUNER
- {1, S_O(fm_force_mono), false, "force fm mono", off_on },
- {9, S_O(last_frequency), 0, NULL, NULL }, /* Default: MIN_FREQ */
-#endif
-
-#if BATTERY_TYPES_COUNT > 1
- {1, S_O(battery_type), 0, "battery type", "alkaline,nimh" },
-#endif
-
-#ifdef HAVE_REMOTE_LCD
- /* remote lcd */
- {6, S_O(remote_contrast), DEFAULT_REMOTE_CONTRAST_SETTING,
- "remote contrast", NULL },
- {1, S_O(remote_invert), false, "remote invert", off_on },
- {1, S_O(remote_flip_display), false, "remote flip display", off_on },
- {5, S_O(remote_backlight_timeout), 6, "remote backlight timeout",
- backlight_times_conf },
-#ifdef CONFIG_CHARGING
- {5, S_O(remote_backlight_timeout_plugged), 11,
- "remote backlight timeout plugged", backlight_times_conf },
-#endif
-#ifdef HAVE_REMOTE_LCD_TICKING
- {1, S_O(remote_reduce_ticking), false, "remote reduce ticking", off_on },
-#endif
-#endif
-
-#ifdef CONFIG_BACKLIGHT
- {1, S_O(bl_filter_first_keypress), false,
- "backlight filters first keypress", off_on },
-#ifdef HAVE_REMOTE_LCD
- {1, S_O(remote_bl_filter_first_keypress), false,
- "backlight filters first remote keypress", off_on },
-#endif
-#endif /* CONFIG_BACKLIGHT */
-
- /* new stuff to be added here */
- /* If values are just added to the end, no need to bump the version. */
-
- /* Current sum of bits: 277 (worst case, but w/o remote lcd) */
- /* Sum of all bit sizes must not grow beyond 288! */
-};
-
-
-/* the part of the settings which ends up in HD sector only */
-static const struct bit_entry hd_bits[] =
-{
- /* This table starts after the 44 RTC bytes = 352 bits. */
- /* Here we need 11 bits to tell how far this is populated. */
-
- /* placeholder, containing the size information */
- {11, 0, 0, 0, NULL, NULL }, /* 11 bit to tell how far this is populated */
-
- /* # of bits, offset+size, default, .cfg name, .cfg values */
- /* more display */
-#ifdef CONFIG_BACKLIGHT
- {1, S_O(caption_backlight), false, "caption backlight", off_on },
-#endif
-#ifdef HAVE_REMOTE_LCD
- {1, S_O(remote_caption_backlight), false,
- "remote caption backlight", off_on },
-#endif
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
- {6, S_O(brightness), DEFAULT_BRIGHTNESS_SETTING, "brightness", NULL },
-#endif
-#ifdef HAVE_BACKLIGHT_PWM_FADING
- /* backlight fading */
- {2, S_O(backlight_fade_in), 1, "backlight fade in", "off,500ms,1s,2s"},
- {3, S_O(backlight_fade_out), 3, "backlight fade out",
- "off,500ms,1s,2s,3s,4s,5s,10s"},
-#endif
-
- {4, S_O(scroll_speed), 9, "scroll speed", NULL }, /* 0...15 */
- {8, S_O(scroll_delay), 100, "scroll delay", NULL }, /* 0...250 */
- {8, S_O(bidir_limit), 50, "bidir limit", NULL }, /* 0...200 */
-
-#ifdef HAVE_REMOTE_LCD
- {4, S_O(remote_scroll_speed), 9, "remote scroll speed", NULL }, /* 0...15 */
- {8, S_O(remote_scroll_step), 6, "remote scroll step", NULL }, /* 1...160 */
- {8, S_O(remote_scroll_delay), 100, "remote scroll delay", NULL }, /* 0...250 */
- {8, S_O(remote_bidir_limit), 50, "remote bidir limit", NULL }, /* 0...200 */
-#endif
-
-#ifdef HAVE_LCD_BITMAP
- {1, S_O(offset_out_of_view), false, "Screen Scrolls Out Of View", off_on },
-#if LCD_WIDTH > 255
- {9, S_O(scroll_step), 6, "scroll step", NULL },
- {9, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
-#elif LCD_WIDTH > 127
- {8, S_O(scroll_step), 6, "scroll step", NULL },
- {8, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
-#else
- {7, S_O(scroll_step), 6, "scroll step", NULL },
- {7, S_O(screen_scroll_step), 16, "screen scroll step", NULL },
-#endif
-#endif /* HAVE_LCD_BITMAP */
-#ifdef HAVE_LCD_CHARCELLS
- {3, S_O(jump_scroll), 0, "jump scroll", NULL }, /* 0...5 */
- {8, S_O(jump_scroll_delay), 50, "jump scroll delay", NULL }, /* 0...250 */
-#endif
- {1, S_O(scroll_paginated), false, "scroll paginated", off_on },
-
-#ifdef HAVE_LCD_COLOR
- {LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"},
- {LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"},
-#endif
-
- /* more playback */
- {1, S_O(play_selected), true, "play selected", off_on },
- {1, S_O(fade_on_stop), true, "volume fade", off_on },
- {4, S_O(ff_rewind_min_step), FF_REWIND_1000,
- "scan min step", "1,2,3,4,5,6,8,10,15,20,25,30,45,60" },
- {4, S_O(ff_rewind_accel), 3, "scan accel", NULL },
-#if CONFIG_CODEC == SWCODEC
- {3, S_O(buffer_margin), 0, "antiskip",
- "5s,15s,30s,1min,2min,3min,5min,10min" },
-#else
- {3, S_O(buffer_margin), 0, "antiskip", NULL },
-#endif
- /* disk */
-#ifndef HAVE_MMC
-#ifdef HAVE_ATA_POWER_OFF
- {1, S_O(disk_poweroff), false, "disk poweroff", off_on },
-#endif
- {8, S_O(disk_spindown), 5, "disk spindown", NULL },
-#endif /* HAVE_MMC */
-
- /* browser */
- {3, S_O(dirfilter), SHOW_SUPPORTED,
- "show files", "all,supported,music,playlists"
-#ifdef HAVE_TAGCACHE
- ",id3 database"
-#endif
- },
- {1, S_O(sort_case), false, "sort case", off_on },
- {1, S_O(browse_current), false, "follow playlist", off_on },
- /* playlist */
- {1, S_O(playlist_viewer_icons), true, "playlist viewer icons", off_on },
- {1, S_O(playlist_viewer_indices), true,
- "playlist viewer indices", off_on },
- {1, S_O(playlist_viewer_track_display), 0,
- "playlist viewer track display", "track name,full path" },
- {2, S_O(recursive_dir_insert), RECURSE_OFF,
- "recursive directory insert", off_on_ask },
- /* bookmarks */
- {3, S_O(autocreatebookmark), BOOKMARK_NO, "autocreate bookmarks",
- "off,on,ask,recent only - on,recent only - ask" },
- {2, S_O(autoloadbookmark), BOOKMARK_NO,
- "autoload bookmarks", off_on_ask },
- {2, S_O(usemrb), BOOKMARK_NO,
- "use most-recent-bookmarks", "off,on,unique only" },
-#ifdef HAVE_LCD_BITMAP
- /* peak meter */
- {5, S_O(peak_meter_clip_hold), 16, "peak meter clip hold", /* 0...25 */
- "on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min,3min,5min,10min,20min,45min,90min" },
- {5, S_O(peak_meter_hold), 3, "peak meter hold",
- "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min" },
- {7, S_O(peak_meter_release), 8, "peak meter release", NULL }, /* 0...126 */
- {1, S_O(peak_meter_dbfs), true, "peak meter dbfs", off_on },
- {7, S_O(peak_meter_min), 60, "peak meter min", NULL }, /* 0...100 */
- {7, S_O(peak_meter_max), 0, "peak meter max", NULL }, /* 0...100 */
-#endif
-#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
- {7, S_O(mdb_strength), 0, "mdb strength", NULL},
- {7, S_O(mdb_harmonics), 0, "mdb harmonics", NULL},
- {9, S_O(mdb_center), 0, "mdb center", NULL},
- {9, S_O(mdb_shape), 0, "mdb shape", NULL},
- {1, S_O(mdb_enable), 0, "mdb enable", off_on},
-#endif
-#if CONFIG_CODEC == MAS3507D
- {1, S_O(line_in), false, "line in", off_on },
-#endif
- /* voice */
- {2, S_O(talk_dir), 0, "talk dir", off_number_spell_hover },
- {2, S_O(talk_file), 0, "talk file", off_number_spell_hover },
- {1, S_O(talk_menu), true, "talk menu", off_on },
-
- {2, S_O(sort_file), 0, "sort files", "alpha,oldest,newest,type" },
- {2, S_O(sort_dir), 0, "sort dirs", "alpha,oldest,newest" },
- {1, S_O(id3_v1_first), 0, "id3 tag priority", "v2-v1,v1-v2"},
-
-#ifdef HAVE_RECORDING
- /* recording */
- {1, S_O(recscreen_on), false, "recscreen on", off_on },
- {1, S_O(rec_startup), false, "rec screen on startup", off_on },
- {4, S_O(rec_timesplit), 0, "rec timesplit", /* 0...15 */
- "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00,04:00,06:00,08:00,10:00,12:00,18:00,24:00" },
- {4, S_O(rec_sizesplit), 0, "rec sizesplit", /* 0...15 */
- "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB,256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB" },
- {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" },
- {1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" },
- {1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" },
-
+ /* check magic, version */
+ if ((buf[0] != 'R') || (buf[1] != 'b')
+ || (buf[2] != NVRAM_CONFIG_VERSION))
+ return false;
+ /* check crc32 */
+ crc32 = crc_32(&buf[NVRAM_DATA_START],
+ max_len-NVRAM_DATA_START-1,0xffffffff);
+ if (memcmp(&crc32,&buf[4],4))
+ return false;
+ /* all good, so read in the settings */
+ var_count = buf[3];
+ buf_pos = NVRAM_DATA_START;
+ for(i=0; (i<nb_settings) && (var_count>0) && (buf_pos<max_len); i++)
{
-#if defined(HAVE_SPDIF_IN) || defined(HAVE_FMRADIO_IN)
- 2,
-#else
- 1,
-#endif
- S_O(rec_source), 0 /* 0=mic */, "rec source",
- "mic,line"
-#ifdef HAVE_SPDIF_IN
- ",spdif"
-#endif
-#ifdef HAVE_FMRADIO_IN
- ",fmradio"
-#endif
- },
- {5, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */
- {1, S_O(rec_directory), 0, /* rec_base_directory */
- "rec directory", REC_BASE_DIR ",current" },
-#ifdef CONFIG_BACKLIGHT
- {2, S_O(cliplight), 0, "cliplight", "off,main,both,remote" },
-#endif
-#if CONFIG_CODEC == MAS3587F
- {4, S_O(rec_mic_gain), 8, "rec mic gain", NULL },
- {4, S_O(rec_left_gain), 2 /* 0dB */, "rec left gain", NULL }, /* 0...15 */
- {4, S_O(rec_right_gain), 2 /* 0dB */, "rec right gain", NULL }, /* 0...15 */
- {3, S_O(rec_frequency), 0, /* 0=44.1kHz */
- "rec frequency", "44,48,32,22,24,16" },
- {3, S_O(rec_quality), 5 /* 192 kBit/s max */, "rec quality", NULL },
- {1, S_O(rec_editable), false, "editable recordings", off_on },
-#endif /* CONFIG_CODEC == MAS3587F */
-
-#if CONFIG_CODEC == SWCODEC
-#ifdef HAVE_UDA1380
- {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
- {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
- {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
-#elif defined(HAVE_TLV320)
- /* TLV320 only has no mic boost or 20db mic boost */
- {1, S_O(rec_mic_gain), 0 /* 0 dB */, "rec mic gain", NULL }, /* 0db or 20db */
- {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
- {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
-#elif defined(HAVE_WM8975)
- {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
- {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
- {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
-#elif defined(HAVE_WM8758)
- {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
- {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
- {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
-#elif defined(HAVE_WM8731)
- {8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
- {8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
- {8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
-#endif
- {REC_FREQ_CFG_NUM_BITS, S_O(rec_frequency), REC_FREQ_DEFAULT,
- "rec frequency", REC_FREQ_CFG_VAL_LIST },
- {REC_FORMAT_CFG_NUM_BITS ,S_O(rec_format), REC_FORMAT_DEFAULT,
- "rec format", REC_FORMAT_CFG_VAL_LIST },
- /** Encoder settings start - keep these together **/
- /* aiff_enc */
- /* (no settings yet) */
- /* mp3_enc */
- {5,S_O(mp3_enc_config.bitrate), MP3_ENC_BITRATE_CFG_DEFAULT,
- "mp3_enc bitrate", MP3_ENC_BITRATE_CFG_VALUE_LIST },
- /* wav_enc */
- /* (no settings yet) */
- /* wavpack_enc */
- /* (no settings yet) */
- /** Encoder settings end **/
-#endif /* CONFIG_CODEC == SWCODEC */
-
- /* values for the trigger */
- {8 | SIGNED, S_O(rec_start_thres), -35, "trigger start threshold", NULL},
- {8 | SIGNED, S_O(rec_stop_thres), -45, "trigger stop threshold", NULL},
- {4, S_O(rec_start_duration), 0, "trigger start duration", trig_durations_conf},
- {4, S_O(rec_stop_postrec), 2, "trigger stop postrec", trig_durations_conf},
- {4, S_O(rec_stop_gap), 1, "trigger min gap", trig_durations_conf},
- {4, S_O(rec_trigger_mode ), 0, "trigger mode", "off,once,repeat"},
-#endif /* HAVE_RECORDING */
-
-#ifdef HAVE_SPDIF_POWER
- {1, S_O(spdif_enable), false, "spdif enable", off_on},
-#endif
-
- {2, S_O(next_folder), false, "folder navigation", "off,on,random" },
- {1, S_O(runtimedb), false, "gather runtime data", off_on },
-
-#if CONFIG_CODEC == SWCODEC
- {1, S_O(replaygain), false, "replaygain", off_on },
- {2, S_O(replaygain_type), REPLAYGAIN_ALBUM, "replaygain type",
- "track,album,track shuffle" },
- {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on },
- {8 | SIGNED, S_O(replaygain_preamp), 0, "replaygain preamp", NULL },
- {2, S_O(beep), 0, "beep", "off,weak,moderate,strong" },
- {3, S_O(crossfade), 0, "crossfade", "off,shuffle,track skip,shuffle and track skip,always"},
- {3, S_O(crossfade_fade_in_delay), 0, "crossfade fade in delay", NULL},
- {3, S_O(crossfade_fade_out_delay), 0, "crossfade fade out delay", NULL},
- {4, S_O(crossfade_fade_in_duration), 0, "crossfade fade in duration", NULL},
- {4, S_O(crossfade_fade_out_duration), 0, "crossfade fade out duration", NULL},
- {1, S_O(crossfade_fade_out_mixmode), 0, "crossfade fade out mode", "crossfade,mix"},
- {1, S_O(crossfeed), false, "crossfeed", off_on },
- {6, S_O(crossfeed_direct_gain), 15, "crossfeed direct gain", NULL },
- {7, S_O(crossfeed_cross_gain), 60, "crossfeed cross gain", NULL },
- {8, S_O(crossfeed_hf_attenuation), 160, "crossfeed hf attenuation", NULL },
- {11, S_O(crossfeed_hf_cutoff), 700, "crossfeed hf cutoff", NULL },
-
- /* equalizer */
- {1, S_O(eq_enabled), false, "eq enabled", off_on },
- {8, S_O(eq_precut), 0, "eq precut", NULL },
- /* 0..32768 Hz */
- {15, S_O(eq_band0_cutoff), 60, "eq band 0 cutoff", NULL },
- {15, S_O(eq_band1_cutoff), 200, "eq band 1 cutoff", NULL },
- {15, S_O(eq_band2_cutoff), 800, "eq band 2 cutoff", NULL },
- {15, S_O(eq_band3_cutoff), 4000, "eq band 3 cutoff", NULL },
- {15, S_O(eq_band4_cutoff), 12000, "eq band 4 cutoff", NULL },
- /* 0..64 (or 0.0 to 6.4) */
- {6, S_O(eq_band0_q), 7, "eq band 0 q", NULL },
- {6, S_O(eq_band1_q), 10, "eq band 1 q", NULL },
- {6, S_O(eq_band2_q), 10, "eq band 2 q", NULL },
- {6, S_O(eq_band3_q), 10, "eq band 3 q", NULL },
- {6, S_O(eq_band4_q), 7, "eq band 4 q", NULL },
- /* -240..240 (or -24db to +24db) */
- {9|SIGNED, S_O(eq_band0_gain), 0, "eq band 0 gain", NULL },
- {9|SIGNED, S_O(eq_band1_gain), 0, "eq band 1 gain", NULL },
- {9|SIGNED, S_O(eq_band2_gain), 0, "eq band 2 gain", NULL },
- {9|SIGNED, S_O(eq_band3_gain), 0, "eq band 3 gain", NULL },
- {9|SIGNED, S_O(eq_band4_gain), 0, "eq band 4 gain", NULL },
-
- /* dithering */
- {1, S_O(dithering_enabled), false, "dithering enabled", off_on },
-#endif
-
-#ifdef HAVE_DIRCACHE
- {1, S_O(dircache), false, "dircache", off_on },
- {22, S_O(dircache_size), 0, NULL, NULL },
-#endif
-
-#ifdef HAVE_TAGCACHE
-#ifdef HAVE_TC_RAMCACHE
- {1, S_O(tagcache_ram), 0, "tagcache_ram", off_on },
-#endif
- {1, S_O(tagcache_autoupdate), 0, "tagcache_autoupdate", off_on },
-#endif
-
- {4, S_O(default_codepage), 0, "default codepage",
- "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" },
-
- {1, S_O(warnon_erase_dynplaylist), false,
- "warn when erasing dynamic playlist", off_on },
-
-#ifdef CONFIG_BACKLIGHT
-#ifdef HAS_BUTTON_HOLD
- {2, S_O(backlight_on_button_hold), 0, "backlight on button hold",
- "normal,off,on" },
-#endif
-
-#ifdef HAVE_LCD_SLEEP
- {4, S_O(lcd_sleep_after_backlight_off), 3,
- "lcd sleep after backlight off",
- "always,never,5,10,15,20,30,45,60,90" },
-#endif
-#endif /* CONFIG_BACKLIGHT */
-
-#ifdef HAVE_WM8758
- {1, S_O(eq_hw_enabled), false, "eq hardware enabled", off_on },
-
- {2, S_O(eq_hw_band0_cutoff), 1, "eq hardware band 0 cutoff", "80Hz,105Hz,135Hz,175Hz" },
- {5|SIGNED, S_O(eq_hw_band0_gain), 0, "eq hardware band 0 gain", NULL },
-
- {2, S_O(eq_hw_band1_center), 1, "eq hardware band 1 center", "230Hz,300Hz,385Hz,500Hz" },
- {1, S_O(eq_hw_band1_bandwidth), 0, "eq hardware band 1 bandwidth", "narrow,wide" },
- {5|SIGNED, S_O(eq_hw_band1_gain), 0, "eq hardware band 1 gain", NULL },
-
- {2, S_O(eq_hw_band2_center), 1, "eq hardware band 2 center", "650Hz,850Hz,1.1kHz,1.4kHz" },
- {1, S_O(eq_hw_band2_bandwidth), 0, "eq hardware band 2 bandwidth", "narrow,wide" },
- {5|SIGNED, S_O(eq_hw_band2_gain), 0, "eq hardware band 2 gain", NULL },
-
- {2, S_O(eq_hw_band3_center), 1, "eq hardware band 3 center", "1.8kHz,2.4kHz,3.2kHz,4.1kHz" },
- {1, S_O(eq_hw_band3_bandwidth), 0, "eq hardware band 3 bandwidth", "narrow,wide" },
- {5|SIGNED, S_O(eq_hw_band3_gain), 0, "eq hardware band 3 gain", NULL },
-
- {2, S_O(eq_hw_band4_cutoff), 1, "eq hardware band 4 cutoff", "5.3kHz,6.9kHz,9kHz,11.7kHz" },
- {5|SIGNED, S_O(eq_hw_band4_gain), 0, "eq hardware band 4 gain", NULL },
-#endif
- {1, S_O(hold_lr_for_scroll_in_list), true, "hold_lr_for_scroll_in_list", off_on },
-
- {2, S_O(show_path_in_browser), 0, "show path in browser", "off,current directory,full path" },
-#ifdef HAVE_AGC
- {4, S_O(rec_agc_preset_mic), 1, "agc mic preset", NULL}, /* 0...5 */
- {4, S_O(rec_agc_preset_line), 1, "agc line preset", NULL}, /* 0...5 */
- {8|SIGNED, S_O(rec_agc_maxgain_mic), 104, "agc maximum mic gain", NULL},
- {8|SIGNED, S_O(rec_agc_maxgain_line), 96, "agc maximum line gain", NULL},
- {3, S_O(rec_agc_cliptime), 1, "agc cliptime", "0.2s,0.4s,0.6s,0.8,1s"},
-#endif
-
-#ifdef HAVE_REMOTE_LCD
-#ifdef HAS_REMOTE_BUTTON_HOLD
- {2, S_O(remote_backlight_on_button_hold), 0, "remote backlight on button hold",
- "normal,off,on" },
-#endif
-#endif
-
-#ifdef HAVE_HEADPHONE_DETECTION
- {2, S_O(unplug_mode), 0, "pause on headphone unplug", NULL},
- {4, S_O(unplug_rw), 0, "rewind duration on pause", NULL},
- {1, S_O(unplug_autoresume), 0, "disable autoresume if phones not present", off_on },
-#endif
-#ifdef CONFIG_TUNER
- {2, S_O(fm_region), 0, "fm_region", "eu,us,jp,kr" },
-#endif
-
- {1, S_O(audioscrobbler), false, "Last.fm Logging", off_on},
-
- /* If values are just added to the end, no need to bump the version. */
- /* new stuff to be added at the end */
-#ifdef HAVE_RECORDING
- {2, S_O(rec_trigger_type), 0, "trigger type", "stop,pause,nf stp"},
-#endif
-
- /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */
-};
-
-/* helper function to extract n (<=32) bits from an arbitrary position
- * counting from LSB to MSB */
-static uint32_t get_bits(
- const uint32_t *p, /* the start of the bitfield array */
- unsigned int from, /* bit no. to start reading from */
- unsigned int size) /* how many bits to read */
-{
- unsigned int long_index = from / 32;
- unsigned int bit_index = from % 32;
- uint32_t result;
-
- result = p[long_index] >> bit_index;
-
- if (bit_index + size > 32) /* crossing longword boundary */
- result |= p[long_index+1] << (32 - bit_index);
-
- result &= 0xFFFFFFFF >> (32 - size);
-
- return result;
+ int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
+ >>F_NVRAM_MASK_SHIFT;
+ if (nvram_bytes)
+ {
+ memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes);
+ buf_pos += nvram_bytes;
+ var_count--;
+ }
+ }
+ return true;
}
-
-/* helper function to set n (<=32) bits to an arbitrary position,
- * counting from LSB to MSB */
-static void set_bits(
- uint32_t *p, /* the start of the bitfield array */
- unsigned int from, /* bit no. to start writing into */
- unsigned int size, /* how many bits to change */
- uint32_t value) /* content (LSBs will be taken) */
+static bool write_nvram_data(char* buf, int max_len)
{
- unsigned int long_index = from / 32;
- unsigned int bit_index = from % 32;
- uint32_t mask;
-
- mask = 0xFFFFFFFF >> (32 - size);
- value &= mask;
- mask <<= bit_index;
-
- if (bit_index + size > 32)
- p[long_index+1] =
- (p[long_index+1] & (0xFFFFFFFF << (bit_index + size - 32)))
- | (value >> (32 - bit_index));
-
- p[long_index] = (p[long_index] & ~mask) | (value << bit_index);
+ unsigned crc32 = 0xffffffff;
+ int i = 0, buf_pos = 0;
+ char var_count = 0;
+#ifndef HAVE_RTC_RAM
+ int fd;
+#endif
+ memset(buf,0,max_len);
+ /* magic, version */
+ buf[0] = 'R'; buf[1] = 'b';
+ buf[2] = NVRAM_CONFIG_VERSION;
+ buf_pos = NVRAM_DATA_START;
+ for(i=0; (i<nb_settings) && (buf_pos<max_len); i++)
+ {
+ int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
+ >>F_NVRAM_MASK_SHIFT;
+ if (nvram_bytes)
+ {
+ memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes);
+ buf_pos += nvram_bytes;
+ var_count++;
+ }
+ }
+ /* count and crc32 */
+ buf[3] = var_count;
+ crc32 = crc_32(&buf[NVRAM_DATA_START],
+ max_len-NVRAM_DATA_START-1,0xffffffff);
+ memcpy(&buf[4],&crc32,4);
+#ifndef HAVE_RTC_RAM
+ fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY);
+ if (fd >= 0)
+ {
+ int len = write(fd,buf,max_len);
+ close(fd);
+ if (len < 8)
+ return false;
+ }
+#else
+ /* 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 (i=0; i < NVRAM_BLOCK_SIZE; i++ ) {
+ int r = rtc_write(0x14+i, buf[i]);
+ if (r) {
+ DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
+ 14+i, r );
+ return false;
+ }
+ }
+#endif
+ return true;
}
#ifdef HAVE_LCD_COLOR
@@ -787,223 +258,89 @@
return 0;
}
#endif
-
-/*
- * Calculates the checksum for the config block and returns it
- */
-
-static unsigned short calculate_config_checksum(const unsigned char* buf)
+bool settings_write_config(char* filename)
{
- unsigned int i;
- unsigned char cksum[2];
- cksum[0] = cksum[1] = 0;
-
- for (i=0; i < RTC_BLOCK_SIZE - 2; i+=2 ) {
- cksum[0] ^= buf[i];
- cksum[1] ^= buf[i+1];
- }
-
- return (cksum[0] << 8) | cksum[1];
-}
-
-/*
- * initialize the config block buffer
- */
-static void init_config_buffer( void )
-{
- DEBUGF( "init_config_buffer()\n" );
-
- /* reset to 0 - all unused */
- memset(config_block, 0, CONFIG_BLOCK_SIZE);
- /* insert header */
- config_block[0] = 'R';
- config_block[1] = 'o';
- config_block[2] = 'c';
- config_block[3] = CONFIG_BLOCK_VERSION;
-}
-
-static bool flush_config_block_callback(void)
-{
- ata_write_sectors(IF_MV2(0,) config_sector, 1, config_block);
+ int i;
+ int fd;
+ char value[MAX_PATH];
+ fd = open(filename,O_CREAT|O_TRUNC|O_WRONLY);
+ if (fd < 0)
+ return false;
+ fdprintf(fd, "# .cfg file created by rockbox %s - "
+ "http://www.rockbox.org\r\n\r\n", appsversion);
+ for(i=0; i<nb_settings; i++)
+ {
+ if (settings[i].cfg_name == NULL)
+ continue;
+ switch (settings[i].flags&F_T_MASK)
+ {
+ case F_T_INT:
+ case F_T_UINT:
+#ifdef HAVE_LCD_COLOR
+ if (settings[i].flags&F_RGB)
+ {
+ int colour = *(int*)settings[i].setting;
+ snprintf(value,MAX_PATH,"%02x%02x%02x",
+ (int)RGB_UNPACK_RED(colour),
+ (int)RGB_UNPACK_GREEN(colour),
+ (int)RGB_UNPACK_BLUE(colour));
+ }
+ else
+#endif
+ if (settings[i].cfg_vals == NULL)
+ {
+ snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
+ }
+ else
+ {
+ char *s,*end;
+ char vals[MAX_PATH];
+ int val = 0;
+ strncpy(vals,settings[i].cfg_vals,MAX_PATH);
+ s = strtok_r(vals,",",&end);
+ while (s)
+ {
+ if (val == *(int*)settings[i].setting)
+ {
+ strncpy(value,s,MAX_PATH);
+ break;
+ }
+ val++;
+ s = strtok_r(NULL,",",&end);
+ }
+ }
+ break;
+ case F_T_BOOL:
+ strcpy(value,*(bool*)settings[i].setting == true?"on":"off");
+ break;
+ case F_T_CHARPTR:
+ case F_T_UCHARPTR:
+ if (((char*)settings[i].setting)[0] == '\0')
+ break;
+ if (settings[i].filename_setting->prefix)
+ {
+ snprintf(value,MAX_PATH,"%s%s%s",
+ settings[i].filename_setting->prefix,
+ (char*)settings[i].setting,
+ settings[i].filename_setting->suffix);
+ }
+ else strncpy(value,(char*)settings[i].setting,
+ settings[i].filename_setting->max_len);
+ break;
+ } /* switch () */
+ if (value[0])
+ fdprintf(fd,"%s: %s\r\n",settings[i].cfg_name,value);
+ value[0] = '\0';
+ } /* for(...) */
+ close(fd);
return true;
}
-/*
- * save the config block buffer to disk or RTC RAM
- */
-static int save_config_buffer( void )
+static bool flush_config_block_callback(void)
{
- unsigned short chksum;
-#ifdef HAVE_RTC_RAM
- unsigned int i;
-#endif
-
- /* update the checksum in the end of the block before saving */
- chksum = calculate_config_checksum(config_block);
- config_block[ RTC_BLOCK_SIZE - 2 ] = chksum >> 8;
- config_block[ RTC_BLOCK_SIZE - 1 ] = chksum & 0xff;
-
-#ifdef HAVE_RTC_RAM
- /* 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 (i=0; i < RTC_BLOCK_SIZE; i++ ) {
- int r = rtc_write(0x14+i, config_block[i]);
- if (r) {
- DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
- 14+i, r );
- return r;
- }
- }
-
-#endif
-
- if (config_sector != 0)
- register_ata_idle_func(flush_config_block_callback);
- else
- return -1;
-
- return 0;
-}
-
-/*
- * load the config block buffer from disk or RTC RAM
- */
-static int load_config_buffer(int which)
-{
- unsigned short chksum;
- bool correct = false;
-
-
- DEBUGF( "load_config_buffer()\n" );
-
- if (which & SETTINGS_HD)
- {
- if (config_sector != 0) {
- ata_read_sectors(IF_MV2(0,) config_sector, 1, config_block);
- /* calculate the checksum, check it and the header */
- chksum = calculate_config_checksum(config_block);
-
- if (config_block[0] == 'R' &&
- config_block[1] == 'o' &&
- config_block[2] == 'c' &&
- config_block[3] == CONFIG_BLOCK_VERSION &&
- (chksum >> 8) == config_block[RTC_BLOCK_SIZE - 2] &&
- (chksum & 0xff) == config_block[RTC_BLOCK_SIZE - 1])
- {
- DEBUGF( "load_config_buffer: header & checksum test ok\n" );
- correct = true;
- }
- }
- }
-
-#ifdef HAVE_RTC_RAM
- if(!correct)
- {
- /* If the disk sector was incorrect, reinit the buffer */
- memset(config_block, 0, CONFIG_BLOCK_SIZE);
- }
-
- if (which & SETTINGS_RTC)
- {
- unsigned int i;
- unsigned char rtc_block[RTC_BLOCK_SIZE];
-
- /* read rtc block */
- for (i=0; i < RTC_BLOCK_SIZE; i++ )
- rtc_block[i] = rtc_read(0x14+i);
-
- chksum = calculate_config_checksum(rtc_block);
-
- /* if rtc block is ok, use that */
- if (rtc_block[0] == 'R' &&
- rtc_block[1] == 'o' &&
- rtc_block[2] == 'c' &&
- rtc_block[3] == CONFIG_BLOCK_VERSION &&
- (chksum >> 8) == rtc_block[RTC_BLOCK_SIZE - 2] &&
- (chksum & 0xff) == rtc_block[RTC_BLOCK_SIZE - 1])
- {
- memcpy(config_block, rtc_block, RTC_BLOCK_SIZE);
- correct = true;
- }
- }
-#endif
-
- if ( !correct ) {
- /* if checksum is not valid, clear the config buffer */
- DEBUGF( "load_config_buffer: header & checksum test failed\n" );
- init_config_buffer();
- return -1;
- }
-
- return 0;
-}
-
-
-/* helper to save content of global_settings into a bitfield,
- as described per table */
-static void save_bit_table(const struct bit_entry* p_table, int count, int bitstart)
-{
- uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */
- uint32_t value; /* 32 bit content */
- int i;
- const struct bit_entry* p_run = p_table; /* start after the size info */
- int curr_bit = bitstart + p_table->bit_size;
- count--; /* first is excluded from loop */
-
- for (i=0; i<count; i++)
- {
- p_run++;
- /* could do a memcpy, but that would be endian-dependent */
- switch(p_run->byte_size)
- {
- case 1:
- value = ((uint8_t *)&global_settings)[p_run->settings_offset];
- break;
- case 2:
- value = ((uint16_t *)&global_settings)[p_run->settings_offset/2];
- break;
- case 4:
- value = ((uint32_t *)&global_settings)[p_run->settings_offset/4];
- break;
- default:
- DEBUGF( "save_bit_table: illegal size!\n" );
- continue;
- }
- set_bits(p_bitfield, curr_bit, p_run->bit_size & 0x3F, value);
- curr_bit += p_run->bit_size & 0x3F;
- }
- set_bits(p_bitfield, bitstart, p_table->bit_size, /* write size */
- curr_bit); /* = position after last element */
-}
-
-/*
- * figure out the config sector from the partition table and the
- * mounted file system
- */
-void settings_calc_config_sector(void)
-{
-#ifdef SIMULATOR
- config_sector = 61;
-#else
- int i;
- long partition_start;
- long sector = 0;
-
- if (fat_startsector(IF_MV(0)) != 0) /* There is a partition table */
- {
- sector = 61;
- for (i = 0; i < 4; i++)
- {
- partition_start = disk_partinfo(i)->start;
- if (partition_start != 0 && (partition_start - 2) < sector)
- sector = partition_start - 2;
- }
- if (sector < 0)
- sector = 0;
- }
-
- config_sector = sector;
-#endif
+ bool r1, r2;
+ r1 = write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
+ r2 = settings_write_config(CONFIGFILE);
+ return r1 || r2;
}
/*
@@ -1011,75 +348,34 @@
*/
int settings_save( void )
{
- int i;
+ int elapsed_secs;
+ elapsed_secs = (current_tick - lasttime) / HZ;
+ global_settings.runtime += elapsed_secs;
+ lasttime += (elapsed_secs * HZ);
+
+ if ( global_settings.runtime > global_settings.topruntime )
+ global_settings.topruntime = global_settings.runtime;
+#ifdef HAVE_RTC_RAM
+ /* this will be done in the ata_callback if
+ target doesnt have rtc ram */
+ write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
+#endif
+ if(!register_ata_idle_func(flush_config_block_callback))
{
- int elapsed_secs;
-
- elapsed_secs = (current_tick - lasttime) / HZ;
- global_settings.runtime += elapsed_secs;
- lasttime += (elapsed_secs * HZ);
-
- if ( global_settings.runtime > global_settings.topruntime )
- global_settings.topruntime = global_settings.runtime;
- }
-
- /* serialize scalar values into RTC and HD sector, specified via table */
- save_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8);
- save_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), RTC_BLOCK_SIZE*8);
-
- i = 0xb8;
- strncpy((char *)&config_block[i], (char *)global_settings.wps_file,
- MAX_FILENAME);
- i+= MAX_FILENAME;
- strncpy((char *)&config_block[i], (char *)global_settings.lang_file,
- MAX_FILENAME);
- i+= MAX_FILENAME;
- strncpy((char *)&config_block[i], (char *)global_settings.font_file,
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#ifdef HAVE_REMOTE_LCD
- strncpy((char *)&config_block[i], (char *)global_settings.rwps_file,
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
-
-#ifdef CONFIG_TUNER
- strncpy((char *)&config_block[i], (char *)global_settings.fmr_file,
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
-
-#if LCD_DEPTH > 1
- strncpy((char *)&config_block[i], (char *)global_settings.backdrop_file,
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
-#ifdef HAVE_LCD_BITMAP
- strncpy((char *)&config_block[i], (char *)global_settings.kbd_file,
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
-
- if(save_config_buffer())
- {
- lcd_clear_display();
-#ifdef HAVE_REMOTE_LCD
- lcd_remote_clear_display();
-#endif
+ int i;
+ FOR_NB_SCREENS(i)
+ {
+ screens[i].clear_display();
#ifdef HAVE_LCD_CHARCELLS
- lcd_puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER));
- lcd_puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER));
+ screens[i].puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER));
+ screens[i].puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER));
#else
- lcd_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
- lcd_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
- lcd_update();
-#ifdef HAVE_REMOTE_LCD
- lcd_remote_puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
- lcd_remote_puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
- lcd_remote_update();
+ screens[i].puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER));
+ screens[i].puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER));
+ screens[i].update();
#endif
-#endif
+ }
sleep(HZ*2);
return -1;
}
@@ -1147,6 +443,7 @@
int i;
#endif
+ DEBUGF( "settings_apply()\n" );
sound_settings_apply();
audio_set_buffer_margin(global_settings.buffer_margin);
@@ -1207,8 +504,7 @@
lcd_set_invert_display(global_settings.invert);
lcd_set_flip(global_settings.flip_display);
button_set_flip(global_settings.flip_display);
- if(global_settings.invert || global_settings.flip_display)
- lcd_update(); /* refresh after flipping the screen */
+ lcd_update(); /* refresh after flipping the screen */
settings_apply_pm_range();
peak_meter_init_times(
global_settings.peak_meter_release, global_settings.peak_meter_hold,
@@ -1239,7 +535,6 @@
unload_main_backdrop();
}
show_main_backdrop();
-
#endif
#ifdef HAVE_LCD_COLOR
@@ -1344,131 +639,16 @@
#endif
}
-
-/* helper to load global_settings from a bitfield, as described per table */
-static void load_bit_table(const struct bit_entry* p_table, int count, int bitstart)
-{
- uint32_t *p_bitfield = (uint32_t *)config_block; /* 32 bit addr. */
- uint32_t value; /* 32 bit content */
- int i;
- int maxbit; /* how many bits are valid in the saved part */
- const struct bit_entry* p_run = p_table; /* start after the size info */
- count--; /* first is excluded from loop */
- maxbit = get_bits(p_bitfield, bitstart, p_table->bit_size);
- bitstart += p_table->bit_size;
-
- for (i=0; i<count; i++)
- {
- int size;
- p_run++;
-
- size = p_run->bit_size & 0x3F; /* mask off abused bits */
- if (bitstart + size > maxbit)
- break; /* exit if this is not valid any more in bitfield */
-
- value = get_bits(p_bitfield, bitstart, size);
- bitstart += size;
- if (p_run->bit_size & SIGNED)
- { // sign extend the read value
- unsigned long mask = 0xFFFFFFFF << (size - 1);
- if (value & mask) /* true if MSB of value is set */
- value |= mask;
- }
-
- /* could do a memcpy, but that would be endian-dependent */
- switch(p_run->byte_size)
- {
- case 1:
- ((uint8_t *)&global_settings)[p_run->settings_offset] =
- (unsigned char)value;
- break;
- case 2:
- ((uint16_t *)&global_settings)[p_run->settings_offset/2] =
- (unsigned short)value;
- break;
- case 4:
- ((uint32_t *)&global_settings)[p_run->settings_offset/4] =
- (unsigned int)value;
- break;
- default:
- DEBUGF( "load_bit_table: illegal size!\n" );
- continue;
- }
- }
-}
-
-
/*
* load settings from disk or RTC RAM
*/
void settings_load(int which)
{
- int i;
DEBUGF( "reload_all_settings()\n" );
-
- /* 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(which))
- {
- /* load scalar values from RTC and HD sector, specified via table */
- if (which & SETTINGS_RTC)
- {
- load_bit_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), 4*8);
- }
- if (which & SETTINGS_HD)
- {
- load_bit_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]),
- RTC_BLOCK_SIZE*8);
- }
-
-#ifdef HAVE_RECORDING
- global_settings.recscreen_on = false;
-#endif
-
-#ifdef HAVE_LCD_CONTRAST
- if ( global_settings.contrast < MIN_CONTRAST_SETTING ||
- global_settings.contrast > MAX_CONTRAST_SETTING )
- global_settings.contrast = lcd_default_contrast();
-#endif
-
-#ifdef HAVE_LCD_REMOTE
- if (global_settings.remote_contrast < MIN_REMOTE_CONTRAST_SETTING ||
- global_settings.remote_contrast > MAX_REMOTE_CONTRAST_SETTING )
- global_settings.remote_contrast = lcd_remote_default_contrast();
-#endif
- i = 0xb8;
- strncpy((char *)global_settings.wps_file, (char *)&config_block[i],
- MAX_FILENAME);
- i+= MAX_FILENAME;
- strncpy((char *)global_settings.lang_file, (char *)&config_block[i],
- MAX_FILENAME);
- i+= MAX_FILENAME;
- strncpy((char *)global_settings.font_file, (char *)&config_block[i],
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#ifdef HAVE_REMOTE_LCD
- strncpy((char *)global_settings.rwps_file, (char *)&config_block[i],
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
-
-#ifdef CONFIG_TUNER
- strncpy((char *)global_settings.fmr_file, (char *)&config_block[i],
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
-
-#if LCD_DEPTH > 1
- strncpy((char *)global_settings.backdrop_file, (char *)&config_block[i],
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
-#ifdef HAVE_LCD_BITMAP
- strncpy((char *)global_settings.kbd_file, (char *)&config_block[i],
- MAX_FILENAME);
- i+= MAX_FILENAME;
-#endif
- }
+ if (which&SETTINGS_RTC)
+ read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
+ if (which&SETTINGS_HD)
+ settings_load_config(CONFIGFILE,false);
}
void set_file(char* filename, char* setting, int maxlen)
@@ -1502,94 +682,13 @@
settings_save();
}
-/* helper to sort a .cfg file entry into a global_settings member,
- as described per table. Returns the position if found, else 0. */
-static int load_cfg_table(
- const struct bit_entry* p_table, /* the table which describes the entries */
- int count, /* number of entries in the table, including the first */
- const char* name, /* the item to be searched */
- const char* value, /* the value which got loaded for that item */
- int hint) /* position to start looking */
-{
- int i = hint;
-
- do
- {
- if (p_table[i].cfg_name != NULL && !strcasecmp(name, p_table[i].cfg_name))
- { /* found */
- int val = 0;
- if (p_table[i].cfg_val == NULL)
- { /* numerical value, just convert the string */
- val = atoi(value);
- }
-#if HAVE_LCD_COLOR
- else if (!strncasecmp(p_table[i].cfg_val,"rgb",4))
- {
- val = hex_to_rgb(value);
- }
-#endif
- else
- { /* set of string values, find the index */
- const char* item;
- const char* run;
- int len = strlen(value);
-
- item = run = p_table[i].cfg_val;
-
- while(1)
- {
- /* count the length of the field */
- while (*run != ',' && *run != '\0')
- run++;
-
- if (!strncasecmp(value, item, MAX(run-item, len)))
- break; /* match, exit the search */
-
- if (*run == '\0') /* reached the end of the choices */
- return i; /* return the position, but don't update */
-
- val++; /* count the item up */
- run++; /* behind the ',' */
- item = run;
- }
- }
-
- /* could do a memcpy, but that would be endian-dependent */
- switch(p_table[i].byte_size)
- {
- case 1:
- ((unsigned char*)&global_settings)[p_table[i].settings_offset] =
- (unsigned char)val;
- break;
- case 2:
- ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] =
- (unsigned short)val;
- break;
- case 4:
- ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] =
- (unsigned int)val;
- break;
- default:
- DEBUGF( "illegal size!" );
- continue;
- }
-
- return i; /* return the position */
- }
-
- i++;
- if (i==count)
- i=1; /* wraparound */
- } while (i != hint); /* back where we started, all searched */
-
- return 0; /* indicate not found */
-}
-
-
-bool settings_load_config(const char* file)
+bool settings_load_config(const char* file, bool apply)
{
int fd;
char line[128];
+ char* name;
+ char* value;
+ int i;
fd = open(file, O_RDONLY);
if (fd < 0)
@@ -1597,180 +696,91 @@
while (read_line(fd, line, sizeof line) > 0)
{
- char* name;
- char* value;
- const struct bit_entry* table[2] = { rtc_bits, hd_bits };
- const int ta_size[2] = {
- sizeof(rtc_bits)/sizeof(rtc_bits[0]),
- sizeof(hd_bits)/sizeof(hd_bits[0])
- };
- int last_table = 0; /* which table was used last round */
- int last_pos = 1; /* at which position did we succeed */
- int pos; /* currently returned position */
-
if (!settings_parseline(line, &name, &value))
continue;
- /* check for the string values */
- if (!strcasecmp(name, "wps")) {
-#if LCD_DEPTH > 1
- unload_wps_backdrop();
-#endif
- int fd2;
- if ((fd2 = open(value, O_RDONLY)) >= 0) {
- close(fd2);
- set_file(value, (char *)global_settings.wps_file, MAX_FILENAME);
- }
- }
-#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
- else if (!strcasecmp(name, "rwps")) {
- int fd2;
- if ((fd2 = open(value, O_RDONLY)) >= 0) {
- close(fd2);
- set_file(value, (char *)global_settings.rwps_file, MAX_FILENAME);
- }
- }
-#endif
- else if (!strcasecmp(name, "lang")) {
- if (!lang_load(value))
+ for(i=0; i<nb_settings; i++)
+ {
+ if (settings[i].cfg_name == NULL)
+ continue;
+ if (!strcasecmp(name,settings[i].cfg_name))
{
- set_file(value, (char *)global_settings.lang_file, MAX_FILENAME);
- talk_init(); /* use voice of same language */
- }
- }
-#ifdef CONFIG_TUNER
- else if (!strcasecmp(name, "fmr")) {
- set_file(value, global_settings.fmr_file, MAX_FILENAME);
- }
-#endif
-#ifdef HAVE_LCD_BITMAP
- else if (!strcasecmp(name, "font")) {
- if (font_load(value))
- set_file(value, (char *)global_settings.font_file, MAX_FILENAME);
- }
-#endif
-#if LCD_DEPTH > 1
- else if (!strcasecmp(name, "backdrop")) {
- if (load_main_backdrop(value)) {
- set_file(value, (char *)global_settings.backdrop_file, MAX_FILENAME);
- show_main_backdrop();
- }
- }
-#endif
-#ifdef HAVE_LCD_BITMAP
- else if (!strcasecmp(name, "keyboard")) {
- if (!load_kbd(value))
- set_file(value, (char *)global_settings.kbd_file, MAX_FILENAME);
- }
-#endif
-
-
- /* check for scalar values, using the two tables */
- pos = load_cfg_table(table[last_table], ta_size[last_table],
- name, value, last_pos);
- if (pos) /* success */
- {
- last_pos = pos; /* remember as a position hint for next round */
- continue;
- }
-
- last_table = 1-last_table; /* try other table */
- last_pos = 1; /* search from start */
- pos = load_cfg_table(table[last_table], ta_size[last_table],
- name, value, last_pos);
- if (pos) /* success */
- {
- last_pos = pos; /* remember as a position hint for next round */
- continue;
- }
- }
+ switch (settings[i].flags&F_T_MASK)
+ {
+ case F_T_INT:
+ case F_T_UINT:
+#ifdef HAVE_LCD_COLOR
+ if (settings[i].flags&F_RGB)
+ *(int*)settings[i].setting = hex_to_rgb(value);
+ else
+#endif
+ if (settings[i].cfg_vals == NULL)
+ {
+ *(int*)settings[i].setting = atoi(value);
+ }
+ else
+ {
+ char *s,*end;
+ char vals[MAX_PATH];
+ int val = 0;
+ strncpy(vals,settings[i].cfg_vals,MAX_PATH);
+ s = strtok_r(vals,",",&end);
+ while (s)
+ {
+ if (!strcmp(value,s))
+ {
+ *(int*)settings[i].setting = val;
+ break;
+ }
+ val++;
+ s = strtok_r(NULL,",",&end);
+ }
+ }
+ break;
+ case F_T_BOOL:
+ *(bool*)settings[i].setting =
+ !strncmp(value,"off",3)?false:true;
+ break;
+ case F_T_CHARPTR:
+ case F_T_UCHARPTR:
+ {
+ char storage[MAX_PATH];
+ if (settings[i].filename_setting->prefix)
+ {
+ int len = strlen(settings[i].filename_setting->prefix);
+ if (!strncmp(value,settings[i].filename_setting->prefix,len))
+ {
+ strncpy(storage,&value[len],MAX_PATH);
+ }
+ else strncpy(storage,value,MAX_PATH);
+ }
+ else strncpy(storage,value,MAX_PATH);
+ if (settings[i].filename_setting->suffix)
+ {
+ char *s = strcasestr(storage,settings[i].filename_setting->suffix);
+ if (s) *s = '\0';
+ }
+ strncpy((char*)settings[i].setting,storage,
+ settings[i].filename_setting->max_len);
+ ((char*)settings[i].setting)
+ [settings[i].filename_setting->max_len-1] = '\0';
+ break;
+ }
+ }
+ break;
+ } /* if (!strcmp(name,settings[i].cfg_name)) */
+ } /* for(...) */
+ } /* while(...) */
close(fd);
- settings_apply();
settings_save();
+ if (apply)
+ settings_apply();
return true;
}
-
-/* helper to save content of global_settings into a file,
- as described per table */
-static void save_cfg_table(const struct bit_entry* p_table, int count, int fd)
-{
- long value; /* 32 bit content */
- int i;
- const struct bit_entry* p_run = p_table; /* start after the size info */
- count--; /* first is excluded from loop */
-
- for (i=0; i<count; i++)
- {
- p_run++;
-
- if (p_run->cfg_name == NULL)
- continue; /* this value is not to be saved */
-
- /* could do a memcpy, but that would be endian-dependent */
- switch(p_run->byte_size)
- {
- case 1:
- if (p_run->bit_size & SIGNED) /* signed? */
- value = ((char*)&global_settings)[p_run->settings_offset];
- else
- value = ((unsigned char*)&global_settings)[p_run->settings_offset];
- break;
- case 2:
- if (p_run->bit_size & SIGNED) /* signed? */
- value = ((short*)&global_settings)[p_run->settings_offset/2];
- else
- value = ((unsigned short*)&global_settings)[p_run->settings_offset/2];
- break;
- case 4:
- value = ((unsigned int*)&global_settings)[p_run->settings_offset/4];
- break;
- default:
- DEBUGF( "illegal size!" );
- continue;
- }
-
- if (p_run->cfg_val == NULL) /* write as number */
- {
- fdprintf(fd, "%s: %ld\r\n", p_run->cfg_name, value);
- }
-#ifdef HAVE_LCD_COLOR
- else if (!strcasecmp(p_run->cfg_val, "rgb"))
- {
- fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name,
- (int)RGB_UNPACK_RED(value),
- (int)RGB_UNPACK_GREEN(value),
- (int)RGB_UNPACK_BLUE(value));
- }
-#endif
- else /* write as item */
- {
- const char* p = p_run->cfg_val;
-
- fdprintf(fd, "%s: ", p_run->cfg_name);
-
- while(value >= 0)
- {
- char c = *p++; /* currently processed char */
- if (c == ',') /* separator */
- value--;
- else if (c == '\0') /* end of string */
- break; /* not found */
- else if (value == 0) /* the right place */
- write(fd, &c, 1); /* char by char, this is lame, OK */
- }
-
- fdprintf(fd, "\r\n");
- if (p_run->cfg_val != off_on) /* explaination for non-bool */
- fdprintf(fd, "# (possible values: %s)\r\n", p_run->cfg_val);
- }
- }
-}
-
bool settings_save_config(void)
{
- int fd;
char filename[MAX_PATH];
create_numbered_filename(filename, ROCKBOX_DIR, "config", ".cfg", 2
@@ -1779,11 +789,7 @@
/* allow user to modify filename */
while (true) {
if (!kbd_input(filename, sizeof filename)) {
- fd = creat(filename, O_WRONLY);
- if (fd < 0)
- gui_syncsplash(HZ, true, str(LANG_FAILED));
- else
- break;
+ break;
}
else {
gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL));
@@ -1791,145 +797,43 @@
}
}
- fdprintf(fd, "# .cfg file created by rockbox %s - "
- "http://www.rockbox.org\r\n#\r\n#\r\n# wps / rwps / language"
- " / font / fmpreset / backdrop \r\n#\r\n", appsversion);
-
- if (global_settings.wps_file[0] != 0)
- fdprintf(fd, "wps: %s/%s.wps\r\n", WPS_DIR,
- global_settings.wps_file);
-
-#ifdef HAVE_REMOTE_LCD
- if (global_settings.rwps_file[0] != 0)
- fdprintf(fd, "rwps: %s/%s.rwps\r\n", WPS_DIR,
- global_settings.rwps_file);
-#endif
-
- if (global_settings.lang_file[0] != 0)
- fdprintf(fd, "lang: %s/%s.lng\r\n", LANG_DIR,
- global_settings.lang_file);
-
-#ifdef HAVE_LCD_BITMAP
- if (global_settings.font_file[0] != 0)
- fdprintf(fd, "font: %s/%s.fnt\r\n", FONT_DIR,
- global_settings.font_file);
-#endif
-
-#if LCD_DEPTH > 1
- if (global_settings.backdrop_file[0] != 0)
- fdprintf(fd, "backdrop: %s/%s.bmp\r\n", BACKDROP_DIR,
- global_settings.backdrop_file);
-#endif
-
-#ifdef CONFIG_TUNER
- if (global_settings.fmr_file[0] != 0)
- fdprintf(fd, "fmr: %s/%s.fmr\r\n", FMPRESET_PATH,
- global_settings.fmr_file);
-#endif
-
-#ifdef HAVE_LCD_BITMAP
- if (global_settings.kbd_file[0] != 0)
- fdprintf(fd, "keyboard: %s/%s.kbd\r\n", ROCKBOX_DIR,
- global_settings.kbd_file);
-#endif
-
- /* here's the action: write values to file, specified via table */
- save_cfg_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]), fd);
- save_cfg_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]), fd);
-
- close(fd);
-
- gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED));
+ if (settings_write_config(filename))
+ gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED));
+ else gui_syncsplash(HZ, true, str(LANG_FAILED));
return true;
}
-/* helper to load defaults from table into global_settings members */
-static void default_table(const struct bit_entry* p_table, int count)
-{
- int i;
-
- for (i=1; i<count; i++) /* exclude the first, the size placeholder */
- {
- /* could do a memcpy, but that would be endian-dependent */
- switch(p_table[i].byte_size)
- {
- case 1:
- ((unsigned char*)&global_settings)[p_table[i].settings_offset] =
- (unsigned char)p_table[i].default_val;
- break;
- case 2:
- ((unsigned short*)&global_settings)[p_table[i].settings_offset/2] =
- (unsigned short)p_table[i].default_val;
- break;
- case 4:
- ((unsigned int*)&global_settings)[p_table[i].settings_offset/4] =
- (unsigned int)p_table[i].default_val;
- break;
- default:
- DEBUGF( "illegal size!" );
- continue;
- }
- }
-}
-
/*
* reset all settings to their default value
*/
void settings_reset(void) {
+ int i;
DEBUGF( "settings_reset()\n" );
- /* read defaults from table(s) into global_settings */
- default_table(rtc_bits, sizeof(rtc_bits)/sizeof(rtc_bits[0]));
- default_table(hd_bits, sizeof(hd_bits)/sizeof(hd_bits[0]));
-
- /* do some special cases not covered by table */
- global_settings.volume = sound_default(SOUND_VOLUME);
- global_settings.balance = sound_default(SOUND_BALANCE);
- global_settings.bass = sound_default(SOUND_BASS);
- global_settings.treble = sound_default(SOUND_TREBLE);
- global_settings.channel_config = sound_default(SOUND_CHANNELS);
- global_settings.stereo_width = sound_default(SOUND_STEREO_WIDTH);
-#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
- global_settings.loudness = sound_default(SOUND_LOUDNESS);
- global_settings.avc = sound_default(SOUND_AVC);
- global_settings.mdb_strength = sound_default(SOUND_MDB_STRENGTH);
- global_settings.mdb_harmonics = sound_default(SOUND_MDB_HARMONICS);
- global_settings.mdb_center = sound_default(SOUND_MDB_CENTER);
- global_settings.mdb_shape = sound_default(SOUND_MDB_SHAPE);
- global_settings.mdb_enable = sound_default(SOUND_MDB_ENABLE);
- global_settings.superbass = sound_default(SOUND_SUPERBASS);
-#endif
-#ifdef HAVE_LCD_CONTRAST
- global_settings.contrast = lcd_default_contrast();
-#endif
-#ifdef HAVE_LCD_REMOTE
- global_settings.remote_contrast = lcd_remote_default_contrast();
-#endif
-
-#ifdef CONFIG_TUNER
- global_settings.fmr_file[0] = '\0';
-#endif
- global_settings.wps_file[0] = '\0';
-#ifdef HAVE_REMOTE_LCD
- global_settings.rwps_file[0] = '\0';
-#endif
- global_settings.font_file[0] = '\0';
- global_settings.lang_file[0] = '\0';
-#if LCD_DEPTH > 1
- global_settings.backdrop_file[0] = '\0';
-#endif
-#ifdef HAVE_LCD_COLOR
- global_settings.fg_color = LCD_DEFAULT_FG;
- global_settings.bg_color = LCD_DEFAULT_BG;
-#endif
-#ifdef HAVE_LCD_BITMAP
- global_settings.kbd_file[0] = '\0';
-#endif
- global_settings.hold_lr_for_scroll_in_list = true;
-
+ for(i=0; i<nb_settings; i++)
+ {
+ switch (settings[i].flags&F_T_MASK)
+ {
+ case F_T_INT:
+ case F_T_UINT:
+ if (settings[i].flags&F_T_SOUND)
+ *(int*)settings[i].setting =
+ sound_default(settings[i].sound_setting->setting);
+ else *(int*)settings[i].setting = settings[i].default_val.int_;
+ break;
+ case F_T_BOOL:
+ *(bool*)settings[i].setting = settings[i].default_val.bool_;
+ break;
+ case F_T_CHARPTR:
+ case F_T_UCHARPTR:
+ strncpy((char*)settings[i].setting,
+ settings[i].default_val.charptr,MAX_FILENAME);
+ break;
+ }
+ } /* for(...) */
#if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
enc_global_settings_reset();
#endif
diff --git a/apps/settings.h b/apps/settings.h
index b5c673f..eee24f1 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -54,6 +54,9 @@
#define REC_BASE_DIR "/recordings"
#define EQS_DIR ROCKBOX_DIR "/eqs"
#define CODECS_DIR ROCKBOX_DIR"/codecs"
+#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
+
+#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
#define MAX_FILENAME 20
@@ -547,7 +550,6 @@
/* prototypes */
-void settings_calc_config_sector(void);
int settings_save(void);
void settings_load(int which);
void settings_reset(void);
@@ -556,7 +558,7 @@
void settings_apply_pm_range(void);
void settings_display(void);
-bool settings_load_config(const char* file);
+bool settings_load_config(const char* file, bool apply);
bool settings_save_config(void);
bool set_bool_options(const char* string, bool* variable,
const char* yes_str, int yes_voice,
diff --git a/apps/settings_list.c b/apps/settings_list.c
new file mode 100644
index 0000000..313524b
--- /dev/null
+++ b/apps/settings_list.c
@@ -0,0 +1,608 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: $
+ *
+ * Copyright (C) 2007 Jonathan Gordon
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include <stdbool.h>
+
+#include "lang.h"
+#include "lcd.h"
+#include "settings.h"
+#include "settings_list.h"
+#include "sound.h"
+
+/* some sets of values which are used more than once, to save memory */
+static const char off_on[] = "off,on";
+static const char off_on_ask[] = "off,on,ask";
+static const char off_number_spell_hover[] = "off,number,spell,hover";
+#ifdef HAVE_LCD_BITMAP
+static const char graphic_numeric[] = "graphic,numeric";
+#endif
+
+#ifdef HAVE_RECORDING
+/* keep synchronous to trig_durations and
+ trigger_times in settings_apply_trigger */
+static const char trig_durations_conf [] =
+ "0s,1s,2s,5s,10s,15s,20s,25s,30s,1min,2min,5min,10min";
+/* these should be in the config.h files */
+#if CONFIG_CODEC == MAS3587F
+# define DEFAULT_REC_MIC_GAIN 8
+# define DEFAULT_REC_LEFT_GAIN 2
+# define DEFAULT_REC_RIGHT_GAIN 2
+#elif CONFIG_CODEC == SWCODEC
+# ifdef HAVE_UDA1380
+# define DEFAULT_REC_MIC_GAIN 16
+# define DEFAULT_REC_LEFT_GAIN 0
+# define DEFAULT_REC_RIGHT_GAIN 0
+# elif defined(HAVE_TLV320)
+# define DEFAULT_REC_MIC_GAIN 0
+# define DEFAULT_REC_LEFT_GAIN 0
+# define DEFAULT_REC_RIGHT_GAIN 0
+# elif defined(HAVE_WM8975)
+# define DEFAULT_REC_MIC_GAIN 16
+# define DEFAULT_REC_LEFT_GAIN 0
+# define DEFAULT_REC_RIGHT_GAIN 0
+# elif defined(HAVE_WM8758)
+# define DEFAULT_REC_MIC_GAIN 16
+# define DEFAULT_REC_LEFT_GAIN 0
+# define DEFAULT_REC_RIGHT_GAIN 0
+# elif defined(HAVE_WM8731)
+# define DEFAULT_REC_MIC_GAIN 16
+# define DEFAULT_REC_LEFT_GAIN 0
+# define DEFAULT_REC_RIGHT_GAIN 0
+# endif
+#endif
+
+#endif /* HAVE_RECORDING */
+
+#if defined(CONFIG_BACKLIGHT)
+static const char backlight_times_conf [] =
+ "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90";
+#endif
+
+
+#define GS(a) &global_settings.a
+
+#define NVRAM(bytes) (bytes<<F_NVRAM_MASK_SHIFT)
+/** NOTE: NVRAM_CONFIG_VERSION is in settings_list.h
+ and you may need to update it if you edit this file */
+
+#define UNUSED {.RESERVED=NULL}
+#define INT(a) {.int_ = a}
+#define UINT(a) {.uint_ = a}
+#define BOOL(a) {.bool_ = a}
+#define CHARPTR(a) {.charptr = a}
+#define UCHARPTR(a) {.ucharptr = a}
+#define NODEFAULT INT(0)
+
+#define SOUND_SETTING(flags,var,setting) \
+ {flags|F_T_INT|F_T_SOUND, GS(var), NODEFAULT,#var,NULL,\
+ {.sound_setting=(struct sound_setting[]){{setting}}} }
+
+#define BOOL_SETTING(flags,var,default,name,cfgvals,yes,no,opt_cb) \
+ {flags|F_T_BOOL, GS(var), BOOL(default),name,cfgvals, \
+ {.bool_setting=(struct bool_setting[]){{opt_cb,yes,no}}} }
+
+#define OFFON_SETTING(flags,var,default,name,cb) \
+ {flags|F_T_BOOL, GS(var), BOOL(default),name,off_on, \
+ {.bool_setting=(struct bool_setting[]) \
+ {{cb,LANG_SET_BOOL_YES,LANG_SET_BOOL_NO}}} }
+
+#define SYSTEM_SETTING(flags,var,default) \
+ {flags|F_T_INT, GS(var), INT(default), NULL, NULL, UNUSED}
+
+#define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \
+ {flags|F_T_UCHARPTR, GS(var), CHARPTR(default),name,NULL,\
+ {.filename_setting=(struct filename_setting[]){{prefix,suffix,len}}} }
+const struct settings_list settings[] = {
+ /* sound settings */
+ SOUND_SETTING(0,volume,SOUND_VOLUME),
+ SOUND_SETTING(0,balance,SOUND_BALANCE),
+ SOUND_SETTING(0,bass,SOUND_BASS),
+ SOUND_SETTING(0,treble,SOUND_TREBLE),
+#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
+ { F_T_INT, GS(loudness), INT(0), "loudness", NULL, UNUSED },
+ { F_T_INT, GS(avc), INT(0), "auto volume", "off,20ms,2,4,8", UNUSED },
+ OFFON_SETTING(0,superbass,false,"superbass",NULL),
+#endif
+ { F_T_INT, GS(channel_config), INT(0), "channels",
+ "stereo,mono,custom,mono left,mono right,karaoke", UNUSED },
+ { F_T_INT, GS(stereo_width), INT(100), "stereo width", NULL, UNUSED },
+ /* playback */
+ OFFON_SETTING(0,resume,false,"resume", NULL),
+ OFFON_SETTING(0,playlist_shuffle,false,"shuffle", NULL),
+ SYSTEM_SETTING(NVRAM(4),resume_index,-1),
+ SYSTEM_SETTING(NVRAM(4),resume_first_index,0),
+ SYSTEM_SETTING(NVRAM(4),resume_offset,-1),
+ SYSTEM_SETTING(NVRAM(4),resume_seed,-1),
+ {F_T_INT, GS(repeat_mode), INT(REPEAT_ALL), "repeat",
+ "off,all,one,shuffle,ab" , UNUSED},
+ /* LCD */
+#ifdef HAVE_LCD_CONTRAST
+ {F_T_INT, GS(contrast), INT(DEFAULT_CONTRAST_SETTING),
+ "contrast", NULL , UNUSED},
+#endif
+#ifdef CONFIG_BACKLIGHT
+ {F_T_INT, GS(backlight_timeout), INT(6),
+ "backlight timeout",backlight_times_conf , UNUSED},
+#ifdef CONFIG_CHARGING
+ {F_T_INT, GS(backlight_timeout_plugged), INT(11),
+ "backlight timeout plugged",backlight_times_conf , UNUSED},
+#endif
+#endif /* CONFIG_BACKLIGHT */
+#ifdef HAVE_LCD_BITMAP
+ OFFON_SETTING(0,invert,false,"invert", NULL),
+ OFFON_SETTING(0,flip_display,false,"flip display", NULL),
+ /* display */
+ OFFON_SETTING(0,invert_cursor,true,"invert cursor", NULL),
+ OFFON_SETTING(0,statusbar,true,"statusbar", NULL),
+ OFFON_SETTING(0,scrollbar,true,"scrollbar", NULL),
+#if CONFIG_KEYPAD == RECORDER_PAD
+ OFFON_SETTING(0,buttonbar,true,"buttonbar", NULL),
+#endif
+ {F_T_INT,GS(volume_type),INT(0),"volume display",graphic_numeric,UNUSED},
+ {F_T_INT,GS(battery_display),INT(0),"battery display",graphic_numeric,UNUSED},
+ {F_T_INT,GS(timeformat),INT(0),"time format","24hour,12hour",UNUSED},
+#endif /* HAVE_LCD_BITMAP */
+ OFFON_SETTING(0,show_icons,true,"show icons", NULL),
+ /* system */
+ {F_T_INT,GS(poweroff),INT(10),"idle poweroff",
+ "off,1,2,3,4,5,6,7,8,9,10,15,30,45,60",UNUSED},
+ SYSTEM_SETTING(NVRAM(4),runtime,0),
+ SYSTEM_SETTING(NVRAM(4),topruntime,0),
+#if MEM > 1
+ {F_T_INT,GS(max_files_in_playlist),INT(10000),
+ "max files in playlist",NULL,UNUSED},
+ {F_T_INT,GS(max_files_in_dir),INT(400),
+ "max files in dir",NULL,UNUSED},
+#else
+ {F_T_INT,GS(max_files_in_playlist),INT(1000),
+ "max files in playlist",NULL,UNUSED},
+ {F_T_INT,GS(max_files_in_dir),INT(200),
+ "max files in dir",NULL,UNUSED},
+#endif
+ {F_T_INT,GS(battery_capacity),INT(BATTERY_CAPACITY_DEFAULT),
+ "battery capacity",NULL,UNUSED},
+#ifdef CONFIG_CHARGING
+ OFFON_SETTING(0,car_adapter_mode,false,"car adapter mode", NULL),
+#endif
+ /* tuner */
+#ifdef CONFIG_TUNER
+ OFFON_SETTING(0,fm_force_mono,false,"force fm mono", NULL),
+ SYSTEM_SETTING(NVRAM(4),last_frequency,0),
+#endif
+
+#if BATTERY_TYPES_COUNT > 1
+ {F_T_INT,GS(battery_type),INT(0),
+ "battery type","alkaline,nimh",UNUSED},
+#endif
+#ifdef HAVE_REMOTE_LCD
+ /* remote lcd */
+ {F_T_INT,GS(remote_contrast),INT(DEFAULT_REMOTE_CONTRAST_SETTING),
+ "remote contrast",NULL,UNUSED},
+ OFFON_SETTING(0,remote_invert,false,"remote invert", NULL),
+ OFFON_SETTING(0,remote_flip_display,false,"remote flip display", NULL),
+ {F_T_INT,GS(remote_backlight_timeout),INT(6),
+ "remote backlight timeout",backlight_times_conf,UNUSED},
+#ifdef CONFIG_CHARGING
+ {F_T_INT,GS(remote_backlight_timeout_plugged),INT(11),
+ "remote backlight timeout plugged",backlight_times_conf,UNUSED},
+#endif
+#ifdef HAVE_REMOTE_LCD_TICKING
+ OFFON_SETTING(0,remote_reduce_ticking,false,"remote reduce ticking", NULL),
+#endif
+#endif
+
+#ifdef CONFIG_BACKLIGHT
+ OFFON_SETTING(0,bl_filter_first_keypress,false,
+ "backlight filters first keypress", NULL),
+#ifdef HAVE_REMOTE_LCD
+ OFFON_SETTING(0,remote_bl_filter_first_keypress,false,
+ "backlight filters first remote keypress", NULL),
+#endif
+#endif /* CONFIG_BACKLIGHT */
+
+/** End of old RTC config block **/
+
+#ifdef CONFIG_BACKLIGHT
+ OFFON_SETTING(0,caption_backlight,false,"caption backlight",NULL),
+#ifdef HAVE_REMOTE_LCD
+ OFFON_SETTING(0,remote_caption_backlight,false,"remote caption backlight",NULL),
+#endif
+#endif /* CONFIG_BACKLIGHT */
+#ifdef HAVE_BACKLIGHT_BRIGHTNESS
+ {F_T_INT,GS(brightness), INT(DEFAULT_BRIGHTNESS_SETTING), "brightness", NULL ,UNUSED},
+#endif
+#ifdef HAVE_BACKLIGHT_PWM_FADING
+ /* backlight fading */
+ {F_T_INT,GS(backlight_fade_in),INT(1),
+ "backlight fade in","off,500ms,1s,2s",UNUSED},
+ {F_T_INT,GS(backlight_fade_out),INT(1),
+ "backlight fade out","off,500ms,1s,2s,3s,4s,5s,10s",UNUSED},
+#endif
+ {F_T_INT,GS(scroll_speed),INT(9),"scroll speed",NULL,UNUSED},
+ {F_T_INT,GS(scroll_delay),INT(100),"scroll delay",NULL,UNUSED},
+ {F_T_INT,GS(bidir_limit),INT(50),"bidir limit",NULL,UNUSED},
+#ifdef HAVE_REMOTE_LCD
+ {F_T_INT,GS(remote_scroll_speed),INT(9),"remote scroll speed",NULL,UNUSED},
+ {F_T_INT,GS(remote_scroll_step),INT(6),"remote scroll step",NULL,UNUSED},
+ {F_T_INT,GS(remote_scroll_delay),INT(100),"remote scroll delay",NULL,UNUSED},
+ {F_T_INT,GS(remote_bidir_limit),INT(50),"remote bidir limit",NULL,UNUSED},
+#endif
+#ifdef HAVE_LCD_BITMAP
+ OFFON_SETTING(0,offset_out_of_view,false,"Screen Scrolls Out Of View",NULL),
+ {F_T_INT,GS(scroll_step),INT(6),"scroll step",NULL,UNUSED},
+ {F_T_INT,GS(screen_scroll_step),INT(16),"screen scroll step",NULL,UNUSED},
+#endif /* HAVE_LCD_BITMAP */
+ OFFON_SETTING(0,scroll_paginated,false,"scroll paginated",NULL),
+#ifdef HAVE_LCD_COLOR
+ {F_T_INT|F_RGB,GS(fg_color),INT(LCD_DEFAULT_FG),"foreground color",NULL,UNUSED},
+ {F_T_INT|F_RGB,GS(bg_color),INT(LCD_DEFAULT_BG),"background color",NULL,UNUSED},
+#endif
+ /* more playback */
+ OFFON_SETTING(0,play_selected,true,"play selected",NULL),
+ OFFON_SETTING(0,fade_on_stop,true,"volume fade",NULL),
+ {F_T_INT,GS(ff_rewind_min_step),INT(FF_REWIND_1000),
+ "scan min step","1,2,3,4,5,6,8,10,15,20,25,30,45,60",UNUSED},
+ {F_T_INT,GS(ff_rewind_accel),INT(3),"scan accel",NULL,UNUSED},
+#if CONFIG_CODEC == SWCODEC
+ {F_T_INT,GS(buffer_margin),INT(0),"antiskip",
+ "5s,15s,30s,1min,2min,3min,5min,10min",UNUSED},
+#else
+ {F_T_INT,GS(buffer_margin),INT(0),"antiskip",NULL,UNUSED},
+#endif
+ /* disk */
+#ifndef HAVE_MMC
+#ifdef HAVE_ATA_POWER_OFF
+ OFFON_SETTING(0,disk_poweroff,false,"disk poweroff",NULL),
+#endif
+ {F_T_INT,GS(disk_spindown),INT(5),"disk spindown",NULL,UNUSED},
+#endif /* HAVE_MMC */
+ /* browser */
+ {F_T_INT,GS(dirfilter),INT(SHOW_SUPPORTED),"show files",
+ "all,supported,music,playlists"
+#ifdef HAVE_TAGCACHE
+ ",id3 database"
+#endif
+ ,UNUSED},
+ OFFON_SETTING(0,sort_case,false,"sort case",NULL),
+ OFFON_SETTING(0,browse_current,false,"follow playlist",NULL),
+ OFFON_SETTING(0,playlist_viewer_icons,true,
+ "playlist viewer icons",NULL),
+ OFFON_SETTING(0,playlist_viewer_indices,true,
+ "playlist viewer indices",NULL),
+ {F_T_INT,GS(recursive_dir_insert),INT(RECURSE_OFF),
+ "recursive directory insert",off_on_ask,UNUSED},
+ /* bookmarks */
+ {F_T_INT,GS(autocreatebookmark),INT(BOOKMARK_NO),"autocreate bookmarks",
+ "off,on,ask,recent only - on,recent only - ask",UNUSED},
+ {F_T_INT,GS(autoloadbookmark),INT(BOOKMARK_NO),
+ "autoload bookmarks",off_on_ask,UNUSED},
+ {F_T_INT,GS(usemrb),INT(BOOKMARK_NO),
+ "use most-recent-bookmarks","off,on,unique only",UNUSED},
+#ifdef HAVE_LCD_BITMAP
+ /* peak meter */
+ {F_T_INT,GS(peak_meter_clip_hold),INT(16),"peak meter clip hold",
+ "on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,2min"
+ ",3min,5min,10min,20min,45min,90min",UNUSED},
+ {F_T_INT,GS(peak_meter_hold),INT(3),"peak meter hold",
+ "off,200ms,300ms,500ms,1,2,3,4,5,6,7,8,9,10,15,20,30,1min",UNUSED},
+ {F_T_INT,GS(peak_meter_release),INT(8),"peak meter release",NULL,UNUSED},
+ OFFON_SETTING(0,peak_meter_dbfs,true,"peak meter dbfs",NULL),
+ {F_T_INT,GS(peak_meter_min),INT(60),"peak meter min",NULL,UNUSED},
+ {F_T_INT,GS(peak_meter_max),INT(0),"peak meter max",NULL,UNUSED},
+#endif
+#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
+ {F_T_INT,GS(mdb_strength),INT(0),"mdb strength",NULL,UNUSED},
+ {F_T_INT,GS(mdb_harmonics),INT(0),"mdb harmonics",NULL,UNUSED},
+ {F_T_INT,GS(mdb_center),INT(0),"mdb center",NULL,UNUSED},
+ {F_T_INT,GS(mdb_shape),INT(0),"mdb shape",NULL,UNUSED},
+ OFFON_SETTING(0,mdb_enable,false,"mdb enable",NULL),
+#endif
+#if CONFIG_CODEC == MAS3507D
+ OFFON_SETTING(0,line_in,false,"line in",NULL),
+#endif
+ /* voice */
+ {F_T_INT,GS(talk_dir),INT(0),"talk dir",off_number_spell_hover,UNUSED},
+ {F_T_INT,GS(talk_file),INT(0),"talk file",off_number_spell_hover,UNUSED},
+ OFFON_SETTING(0,talk_menu,true,"talk menu",NULL),
+
+ {F_T_INT,GS(sort_file),INT(0),"sort files","alpha,oldest,newest,type",UNUSED},
+ {F_T_INT,GS(sort_dir),INT(0),"sort dirs","alpha,oldest,newest",UNUSED},
+ BOOL_SETTING(0,id3_v1_first,false,"id3 tag priority","v2-v1,v1-v2",
+ LANG_ID3_V2_FIRST,LANG_ID3_V1_FIRST,NULL),
+
+#ifdef HAVE_RECORDING
+ /* recording */
+ OFFON_SETTING(0,recscreen_on,false,"recscreen on",NULL),
+ OFFON_SETTING(0,rec_startup,false,"rec screen on startup",NULL),
+ {F_T_INT,GS(rec_timesplit),INT(0),"rec timesplit",
+ "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00,"
+ "04:00,06:00,08:00,10:00,12:00,18:00,24:00",UNUSED},
+ {F_T_INT,GS(rec_sizesplit),INT(0),"rec sizesplit",
+ "off,5MB,10MB,15MB,32MB,64MB,75MB,100MB,128MB,"
+ "256MB,512MB,650MB,700MB,1GB,1.5GB,1.75GB",UNUSED},
+ {F_T_INT,GS(rec_channels),INT(0),"rec channels","stereo,mono",UNUSED},
+ {F_T_INT,GS(rec_split_type),INT(0),"rec split type","Split, Stop",UNUSED},
+ {F_T_INT,GS(rec_split_method),INT(0),"rec split method","Time,Filesize",UNUSED},
+ {F_T_INT,GS(rec_source),INT(0),"rec source","mic,line"
+#ifdef HAVE_SPDIF_IN
+ ",spdif"
+#endif
+#ifdef HAVE_FMRADIO_IN
+ ",fmradio"
+#endif
+ ,UNUSED},
+ {F_T_INT,GS(rec_prerecord_time),INT(0),"prerecording time",NULL,UNUSED},
+ {F_T_INT,GS(rec_directory),INT(0),"rec directory",REC_BASE_DIR ",current",UNUSED},
+#ifdef CONFIG_BACKLIGHT
+ {F_T_INT,GS(cliplight),INT(0),"cliplight","off,main,both,remote",UNUSED},
+#endif
+ {F_T_INT,GS(rec_mic_gain),INT(DEFAULT_REC_MIC_GAIN),
+ "rec mic gain",NULL,UNUSED},
+ {F_T_INT,GS(rec_left_gain),INT(DEFAULT_REC_LEFT_GAIN),
+ "rec left gain",NULL,UNUSED},
+ {F_T_INT,GS(rec_right_gain),INT(DEFAULT_REC_RIGHT_GAIN),
+ "rec right gain",NULL,UNUSED},
+#if CONFIG_CODEC == MAS3587F
+ {F_T_INT,GS(rec_frequency),INT(0),"rec frequency","44,48,32,22,24,16",UNUSED},
+ {F_T_INT,GS(rec_quality),INT(5),"rec quality",NULL,UNUSED},
+ OFFON_SETTING(0,rec_editable,false,"editable recordings",NULL),
+#endif /* CONFIG_CODEC == MAS3587F */
+#if CONFIG_CODEC == SWCODEC
+ {F_T_INT,GS(rec_frequency),INT(REC_FREQ_DEFAULT),
+ "rec frequency",REC_FREQ_CFG_VAL_LIST,UNUSED},
+ {F_T_INT,GS(rec_format),INT(REC_FORMAT_DEFAULT),
+ "rec format",REC_FORMAT_CFG_VAL_LIST,UNUSED},
+ /** Encoder settings start - keep these together **/
+ /* aiff_enc */
+ /* (no settings yet) */
+ /* mp3_enc */
+ {F_T_INT,GS(mp3_enc_config.bitrate),INT(MP3_ENC_BITRATE_CFG_DEFAULT),
+ "mp3_enc bitrate",MP3_ENC_BITRATE_CFG_VALUE_LIST,UNUSED},
+ /* wav_enc */
+ /* (no settings yet) */
+ /* wavpack_enc */
+ /* (no settings yet) */
+ /** Encoder settings end **/
+#endif /* CONFIG_CODEC == SWCODEC */
+ /* values for the trigger */
+ {F_T_INT,GS(rec_start_thres),INT(-35),
+ "trigger start threshold",NULL,UNUSED},
+ {F_T_INT,GS(rec_stop_thres),INT(-45),
+ "trigger stop threshold",NULL,UNUSED},
+ {F_T_INT,GS(rec_start_duration),INT(0),
+ "trigger start duration",trig_durations_conf,UNUSED},
+ {F_T_INT,GS(rec_stop_postrec),INT(2),
+ "trigger stop postrec",trig_durations_conf,UNUSED},
+ {F_T_INT,GS(rec_stop_gap),INT(1),
+ "trigger min gap",trig_durations_conf,UNUSED},
+ {F_T_INT,GS(rec_trigger_mode),INT(0),
+ "trigger mode","off,once,repeat",UNUSED},
+#endif /* HAVE_RECORDING */
+
+#ifdef HAVE_SPDIF_POWER
+ OFFON_SETTING(0,spdif_enable,false,"spdif enable",NULL),
+#endif
+ {F_T_INT,GS(next_folder),INT(FOLDER_ADVANCE_OFF),
+ "folder navigation","off,on,random",UNUSED},
+ OFFON_SETTING(0,runtimedb,false,"gather runtime data",NULL),
+
+#if CONFIG_CODEC == SWCODEC
+ OFFON_SETTING(0,replaygain,false,"replaygain",NULL),
+ {F_T_INT,GS(replaygain_type),INT(REPLAYGAIN_ALBUM),
+ "replaygain type","track,album,track shuffle",UNUSED},
+ OFFON_SETTING(0,replaygain_noclip,false,"replaygain noclip",NULL),
+ {F_T_INT,GS(replaygain_preamp),INT(0),"replaygain preamp",NULL,UNUSED},
+ {F_T_INT,GS(beep),INT(0),"beep","off,weak,moderate,strong",UNUSED},
+ {F_T_INT,GS(crossfade),INT(0),"crossfade",
+ "off,shuffle,track skip,shuffle and track skip,always",UNUSED},
+ {F_T_INT,GS(crossfade_fade_in_delay),INT(0),
+ "crossfade fade in delay",NULL,UNUSED},
+ {F_T_INT,GS(crossfade_fade_out_delay),INT(0),
+ "crossfade fade out delay",NULL,UNUSED},
+ {F_T_INT,GS(crossfade_fade_in_duration),INT(0),
+ "crossfade fade in duration",NULL,UNUSED},
+ {F_T_INT,GS(crossfade_fade_out_duration),INT(0),
+ "crossfade fade out duration",NULL,UNUSED},
+ {F_T_INT,GS(crossfade_fade_out_mixmode),INT(0),
+ "crossfade fade out mode","crossfade,mix",UNUSED},
+ {F_T_INT,GS(crossfade),INT(0),"crossfade",
+ "off,shuffle,track skip,shuffle and track skip,always",UNUSED},
+ OFFON_SETTING(0,crossfeed,false,"crossfeed",NULL),
+ {F_T_INT,GS(crossfeed_direct_gain),INT(15),
+ "crossfeed direct gain",NULL,UNUSED},
+ {F_T_INT,GS(crossfeed_cross_gain),INT(60),
+ "crossfeed cross gain",NULL,UNUSED},
+ {F_T_INT,GS(crossfeed_hf_attenuation),INT(160),
+ "crossfeed hf attenuation",NULL,UNUSED},
+ {F_T_INT,GS(crossfeed_hf_cutoff),INT(700),
+ "crossfeed hf cutoff",NULL,UNUSED},
+
+ /* equalizer */
+ OFFON_SETTING(0,eq_enabled,false,"eq enabled",NULL),
+ {F_T_INT,GS(eq_precut),INT(0),
+ "eq precut",NULL,UNUSED},
+ /* 0..32768 Hz */
+ {F_T_INT,GS(eq_band0_cutoff),INT(0),
+ "eq band 0 cutoff",NULL,UNUSED},
+ {F_T_INT,GS(eq_band1_cutoff),INT(200),
+ "eq band 1 cutoff",NULL,UNUSED},
+ {F_T_INT,GS(eq_band2_cutoff),INT(800),
+ "eq band 2 cutoff",NULL,UNUSED},
+ {F_T_INT,GS(eq_band3_cutoff),INT(4000),
+ "eq band 3 cutoff",NULL,UNUSED},
+ {F_T_INT,GS(eq_band4_cutoff),INT(12000),
+ "eq band 4 cutoff",NULL,UNUSED},
+ /* 0..64 (or 0.0 to 6.4) */
+ {F_T_INT,GS(eq_band0_q),INT(7),
+ "eq band 0 q",NULL,UNUSED},
+ {F_T_INT,GS(eq_band1_q),INT(10),
+ "eq band 1 q",NULL,UNUSED},
+ {F_T_INT,GS(eq_band2_q),INT(10),
+ "eq band 2 q",NULL,UNUSED},
+ {F_T_INT,GS(eq_band3_q),INT(10),
+ "eq band 3 q",NULL,UNUSED},
+ {F_T_INT,GS(eq_band4_q),INT(7),
+ "eq band 4 q",NULL,UNUSED},
+ /* -240..240 (or -24db to +24db) */
+ {F_T_INT,GS(eq_band0_gain),INT(0),
+ "eq band 0 gain",NULL,UNUSED},
+ {F_T_INT,GS(eq_band1_gain),INT(0),
+ "eq band 1 gain",NULL,UNUSED},
+ {F_T_INT,GS(eq_band2_gain),INT(0),
+ "eq band 2 gain",NULL,UNUSED},
+ {F_T_INT,GS(eq_band3_gain),INT(0),
+ "eq band 3 gain",NULL,UNUSED},
+ {F_T_INT,GS(eq_band4_gain),INT(0),
+ "eq band 4 gain",NULL,UNUSED},
+
+ /* dithering */
+ OFFON_SETTING(0,dithering_enabled,false,"dithering enabled",NULL),
+#endif
+#ifdef HAVE_DIRCACHE
+ OFFON_SETTING(0,dircache,false,"dircache",NULL),
+ SYSTEM_SETTING(NVRAM(4),dircache_size,0),
+#endif
+
+#ifdef HAVE_TAGCACHE
+#ifdef HAVE_TC_RAMCACHE
+ OFFON_SETTING(0,tagcache_ram,false,"tagcache_ram",NULL),
+#endif
+ OFFON_SETTING(0,tagcache_autoupdate,false,"tagcache_autoupdate",NULL),
+#endif
+
+ {F_T_INT,GS(default_codepage),INT(0),"default codepage",
+ "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,"
+ "iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256",UNUSED},
+
+ OFFON_SETTING(0,warnon_erase_dynplaylist,false,
+ "warn when erasing dynamic playlist",NULL),
+
+#ifdef CONFIG_BACKLIGHT
+#ifdef HAS_BUTTON_HOLD
+ {F_T_INT,GS(backlight_on_button_hold),INT(0),
+ "backlight on button hold","normal,off,on",UNUSED},
+#endif
+
+#ifdef HAVE_LCD_SLEEP
+ {F_T_INT,GS(lcd_sleep_after_backlight_off),INT(3),
+ "lcd sleep after backlight off",
+ "always,never,5,10,15,20,30,45,60,90",UNUSED},
+#endif
+#endif /* CONFIG_BACKLIGHT */
+
+#ifdef HAVE_WM8758
+ OFFON_SETTING(0,eq_hw_enabled,false,
+ "eq hardware enabled",NULL),
+
+ {F_T_INT,GS(eq_hw_band0_cutoff),INT(1),
+ "eq hardware band 0 cutoff",
+ "80Hz,105Hz,135Hz,175Hz",UNUSED},
+ {F_T_INT,GS(eq_hw_band0_gain),INT(0),
+ "eq hardware band 0 gain",NULL,UNUSED},
+
+ {F_T_INT,GS(eq_hw_band1_center),INT(1),
+ "eq hardware band 1 center",
+ "230Hz,300Hz,385Hz,500Hz",UNUSED},
+ {F_T_INT,GS(eq_hw_band1_bandwidth),INT(0),
+ "eq hardware band 1 bandwidth","narrow,wide",UNUSED},
+ {F_T_INT,GS(eq_hw_band1_gain),INT(0),
+ "eq hardware band 1 gain",NULL,UNUSED},
+
+ {F_T_INT,GS(eq_hw_band2_center),INT(1),
+ "eq hardware band 2 center",
+ "650Hz,850Hz,1.1kHz,1.4kHz",UNUSED},
+ {F_T_INT,GS(eq_hw_band2_bandwidth),INT(0),
+ "eq hardware band 2 bandwidth","narrow,wide",UNUSED},
+ {F_T_INT,GS(eq_hw_band2_gain),INT(0),
+ "eq hardware band 1 gain",NULL,UNUSED},
+
+ {F_T_INT,GS(eq_hw_band3_center),INT(1),
+ "eq hardware band 3 center",
+ "1.8kHz,2.4kHz,3.2kHz,4.1kHz",UNUSED},
+ {F_T_INT,GS(eq_hw_band3_bandwidth),INT(0),
+ "eq hardware band 3 bandwidth","narrow,wide",UNUSED},
+ {F_T_INT,GS(eq_hw_band3_gain),INT(0),
+ "eq hardware band 3 gain",NULL,UNUSED},
+
+ {F_T_INT,GS(eq_hw_band4_cutoff),INT(1),
+ "eq hardware band 4 cutoff",
+ "5.3kHz,6.9kHz,9kHz,11.7kHz",UNUSED},
+ {F_T_INT,GS(eq_hw_band4_gain),INT(0),
+ "eq hardware band 0 gain",NULL,UNUSED},
+#endif
+
+ OFFON_SETTING(0,hold_lr_for_scroll_in_list,true,
+ "hold_lr_for_scroll_in_list",NULL),
+ {F_T_INT,GS(show_path_in_browser),INT(SHOW_PATH_OFF),
+ "show path in browser","off,current directory,full path",UNUSED},
+
+#ifdef HAVE_AGC
+ {F_T_INT,GS(rec_agc_preset_mic),INT(1),"agc mic preset",NULL,UNUSED},
+ {F_T_INT,GS(rec_agc_preset_line),INT(1),"agc line preset",NULL,UNUSED},
+ {F_T_INT,GS(rec_agc_maxgain_mic),INT(104),
+ "agc maximum mic gain",NULL,UNUSED},
+ {F_T_INT,GS(rec_agc_maxgain_line),INT(96),
+ "agc maximum line gain",NULL,UNUSED},
+ {F_T_INT,GS(rec_agc_cliptime),INT(1),
+ "agc cliptime","0.2s,0.4s,0.6s,0.8,1s",UNUSED},
+#endif
+
+#ifdef HAVE_REMOTE_LCD
+#ifdef HAS_REMOTE_BUTTON_HOLD
+ {F_T_INT,GS(remote_backlight_on_button_hold),INT(0),
+ "remote backlight on button hold","normal,off,on",UNUSED},
+#endif
+#endif
+#ifdef HAVE_HEADPHONE_DETECTION
+ {F_T_INT,GS(unplug_mode),INT(0),"pause on headphone unplug",NULL,UNUSED},
+ {F_T_INT,GS(unplug_rw),INT(0),"rewind duration on pause",NULL,UNUSED},
+ OFFON_SETTING(0,unplug_autoresume,false,
+ "disable autoresume if phones not present",NULL),
+#endif
+#ifdef CONFIG_TUNER
+ {F_T_INT,GS(fm_region),INT(0),"fm_region","eu,us,jp,kr",UNUSED},
+#endif
+
+ OFFON_SETTING(0,audioscrobbler,false,"Last.fm Logging",NULL),
+
+#ifdef HAVE_RECORDING
+ {F_T_INT,GS(rec_trigger_type),INT(0),"trigger type","stop,pause,nf stp",UNUSED},
+#endif
+
+ /** settings not in the old config blocks **/
+#ifdef CONFIG_TUNER
+ FILENAME_SETTING(0,fmr_file,"fmr","",FMPRESET_PATH "/",".fmr",MAX_FILENAME+1),
+#endif
+ FILENAME_SETTING(0,font_file,"font","",FONT_DIR "/",".fnt",MAX_FILENAME+1),
+ FILENAME_SETTING(0,wps_file, "wps","",WPS_DIR "/",".wps",MAX_FILENAME+1),
+ FILENAME_SETTING(0,lang_file,"lang","",LANG_DIR "/",".lng",MAX_FILENAME+1),
+#ifdef HAVE_REMOTE_LCD
+ FILENAME_SETTING(0,rwps_file,"rwps","",WPS_DIR "/",".rwps",MAX_FILENAME+1),
+#endif
+#if LCD_DEPTH > 1
+ FILENAME_SETTING(0,backdrop_file,"backdrop","",BACKDROP_DIR "/",".bmp",MAX_FILENAME+1),
+#endif
+#ifdef HAVE_LCD_BITMAP
+ FILENAME_SETTING(0,lang_file,"kbd","",ROCKBOX_DIR "/",".kbd",MAX_FILENAME+1),
+#endif
+
+};
+
+const int nb_settings = sizeof(settings)/sizeof(*settings);
diff --git a/apps/settings_list.h b/apps/settings_list.h
new file mode 100644
index 0000000..01e8cea
--- /dev/null
+++ b/apps/settings_list.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: $
+ *
+ * Copyright (C) 2007 Jonathan Gordon
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __SETTINGSLIST_H
+#define __SETTINGSLIST_H
+#include <stdio.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <limits.h>
+#include "inttypes.h"
+
+union storage_type {
+ int int_;
+ unsigned int uint_;
+ bool bool_;
+ char *charptr;
+ unsigned char *ucharptr;
+};
+/* the variable type for the setting */
+#define F_T_INT 1
+#define F_T_UINT 2
+#define F_T_BOOL 3
+#define F_T_CHARPTR 4
+#define F_T_UCHARPTR 5
+#define F_T_MASK 0x7
+
+struct sound_setting {
+ int setting; /* from the enum in firmware/sound.h */
+};
+#define F_T_SOUND 0x8 /* this variable uses the set_sound stuff, \
+ | with one of the above types (usually F_T_INT) \
+ These settings get the default from sound_default(setting); */
+struct bool_setting {
+ void (*option_callback)(bool);
+ int lang_yes;
+ int lang_no;
+};
+#define F_BOOL_SETTING F_T_BOOL|0x10
+#define F_RGB 0x20
+
+struct int_setting {
+ void (*option_callback)(int);
+ int min;
+ int max;
+ int step;
+};
+#define F_NVRAM_BYTES_MASK 0xE00 /*0-4 bytes can be stored */
+#define F_NVRAM_MASK_SHIFT 9
+#define NVRAM_CONFIG_VERSION 1
+/* Above define should be bumped if
+- a new NVRAM setting is added between 2 other NVRAM settings
+- number of bytes for a NVRAM setting is changed
+- a NVRAM setting is removed
+*/
+
+struct filename_setting {
+ const char* prefix;
+ const char* suffix;
+ int max_len;
+};
+#define F_FILENAME 0x40
+struct settings_list {
+ uint32_t flags; /* ____ ____ ____ ____ ____ NNN_ _FRB STTT */
+ void *setting;
+ union storage_type default_val;
+ const char *cfg_name; /* this settings name in the cfg file */
+ const char *cfg_vals; /*comma seperated legal values, or NULL */
+ /* used with F_T_UCHARPTR this is the folder prefix */
+ union {
+ void *RESERVED; /* to stop compile errors, will be removed */
+ struct sound_setting *sound_setting; /* use F_T_SOUND for this */
+ struct bool_setting *bool_setting; /* F_BOOL_SETTING */
+ struct filename_setting *filename_setting; /* use F_FILENAME */
+ };
+};
+
+#ifndef PLUGIN
+/* not needed for plugins and just causes compile error,
+ possibly fix proberly later */
+extern const struct settings_list settings[];
+extern const int nb_settings;
+
+#endif
+
+#endif
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index fef7592..04fd64b 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -1844,6 +1844,7 @@
case YESNO_YES:
settings_reset();
settings_apply();
+ settings_save();
break;
case YESNO_NO:
break;
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 4e41ef2..4dd0fdc 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -81,7 +81,7 @@
#ifdef HAVE_LBA48
static bool lba48 = false; /* set for 48 bit addressing */
#endif
-static long ata_stack[DEFAULT_STACK_SIZE/sizeof(long)];
+static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)];
static const char ata_thread_name[] = "ata";
static struct event_queue ata_queue;
static bool initialized = false;
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
index 7382788..a549624 100644
--- a/firmware/drivers/ata_mmc.c
+++ b/firmware/drivers/ata_mmc.c
@@ -92,9 +92,9 @@
#ifdef HAVE_HOTSWAP
static bool mmc_monitor_enabled = true;
-static long mmc_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
+static long mmc_stack[((DEFAULT_STACK_SIZE*2) + 0x800)/sizeof(long)];
#else
-static long mmc_stack[DEFAULT_STACK_SIZE/sizeof(long)];
+static long mmc_stack[(DEFAULT_STACK_SIZE*2)/sizeof(long)];
#endif
static const char mmc_thread_name[] = "mmc";
static struct event_queue mmc_queue;