Implement region setting for the fm tuner. The region setting affects deemphasis, band limits and step size. Fixes FS#5929, FS#5928.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11133 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 1c6c0a3..f93ce0a 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -7408,10 +7408,10 @@
desc: in radio screen
user:
<source>
- *: "Station: %d.%dMHz"
+ *: "Station: %d.%02d MHz"
</source>
<dest>
- *: "Station: %d.%dMHz"
+ *: "Station: %d.%02d MHz"
</dest>
<voice>
*: ""
@@ -7646,10 +7646,10 @@
desc: during auto scan
user:
<source>
- *: "Scanning %d.%01dMHz"
+ *: "Scanning %d.%02d MHz"
</source>
<dest>
- *: "Scanning %d.%01dMHz"
+ *: "Scanning %d.%02d MHz"
</dest>
<voice>
*: ""
@@ -7660,10 +7660,10 @@
desc: default preset name for auto scan mode
user:
<source>
- *: "%d.%01dMHz"
+ *: "%d.%02d MHz"
</source>
<dest>
- *: "%d.%01dMHz"
+ *: "%d.%02d MHz"
</dest>
<voice>
*: ""
@@ -9862,3 +9862,68 @@
*: "Disable auto-resume if phones not present"
</voice>
</phrase>
+<phrase>
+ id: LANG_FM_REGION
+ desc: fm tuner region setting
+ <source>
+ *: "Region"
+ </source>
+ <dest>
+ *: "Region"
+ </dest>
+ <voice>
+ *: "Region"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_FM_EUROPE
+ desc: fm tuner region europe
+ <source>
+ *: "Europe"
+ </source>
+ <dest>
+ *: "Europe"
+ </dest>
+ <voice>
+ *: "Europe"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_FM_US
+ desc: fm region us / canada
+ <source>
+ *: "US / Canada"
+ </source>
+ <dest>
+ *: "US / Canada"
+ </dest>
+ <voice>
+ *: "US / Canada"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_FM_JAPAN
+ desc: fm region japan
+ <source>
+ *: "Japan"
+ </source>
+ <dest>
+ *: "Japan"
+ </dest>
+ <voice>
+ *: "Japan"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_FM_KOREA
+ desc: fm region korea
+ <source>
+ *: "Korea"
+ </source>
+ <dest>
+ *: "Korea"
+ </dest>
+ <voice>
+ *: "Korea"
+ </voice>
+</phrase>
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index 4afe0b2..e7a5912 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -85,13 +85,31 @@
#define FM_RECORD
#endif
-#define MAX_FREQ (108000000)
-#define MIN_FREQ (87500000)
-#define FREQ_STEP 100000
-
#define RADIO_SCAN_MODE 0
#define RADIO_PRESET_MODE 1
+#if (CONFIG_TUNER & TEA5767)
+#define DEEMPH_50 0,
+#define DEEMPH_75 1,
+#define BAND_LIM_EU 0
+#define BAND_LIM_JP 1
+#else
+#define DEEMPH_50
+#define DEEMPH_75
+#define BAND_LIM_EU
+#define BAND_LIM_JP
+#endif
+static struct fm_region_setting fm_region[] = {
+ /* Europe */
+ { LANG_FM_EUROPE, 87500000, 108000000, 50000, DEEMPH_50 BAND_LIM_EU },
+ /* US / Canada */
+ { LANG_FM_US, 87900000, 107900000, 200000, DEEMPH_75 BAND_LIM_EU },
+ /* Japan */
+ { LANG_FM_JAPAN, 76000000, 90000000, 100000, DEEMPH_50 BAND_LIM_JP },
+ /* Korea */
+ { LANG_FM_KOREA, 87500000, 108000000, 100000, DEEMPH_50 BAND_LIM_EU },
+ };
+
static int curr_preset = -1;
static int curr_freq;
static int radio_mode = RADIO_SCAN_MODE;
@@ -194,7 +212,9 @@
if(radio_status == FMRADIO_OFF)
radio_power(true);
- curr_freq = global_settings.last_frequency * FREQ_STEP + MIN_FREQ;
+ curr_freq = global_settings.last_frequency
+ * fm_region[global_settings.fm_region].freq_step
+ + fm_region[global_settings.fm_region].freq_min;
radio_set(RADIO_SLEEP, 0); /* wake up the tuner */
radio_set(RADIO_FREQUENCY, curr_freq);
@@ -285,7 +305,7 @@
{
int i;
int diff;
- int min_diff = MAX_FREQ;
+ int min_diff = fm_region[global_settings.fm_region].freq_min;
int preset = -1;
for(i = 0;i < MAX_PRESETS;i++)
@@ -307,7 +327,9 @@
static void remember_frequency(void)
{
- global_settings.last_frequency = (curr_freq - MIN_FREQ) / FREQ_STEP;
+ global_settings.last_frequency = (curr_freq
+ - fm_region[global_settings.fm_region].freq_min)
+ / fm_region[global_settings.fm_region].freq_step;
settings_save();
}
@@ -450,11 +472,12 @@
{
if(search_dir)
{
- curr_freq += search_dir * FREQ_STEP;
- if(curr_freq < MIN_FREQ)
- curr_freq = MAX_FREQ;
- if(curr_freq > MAX_FREQ)
- curr_freq = MIN_FREQ;
+ curr_freq += search_dir
+ * fm_region[global_settings.fm_region].freq_step;
+ if(curr_freq < fm_region[global_settings.fm_region].freq_min)
+ curr_freq = fm_region[global_settings.fm_region].freq_max;
+ if(curr_freq > fm_region[global_settings.fm_region].freq_max)
+ curr_freq = fm_region[global_settings.fm_region].freq_min;
/* Tune in and delay */
radio_set(RADIO_FREQUENCY, curr_freq);
@@ -573,9 +596,11 @@
case ACTION_STD_PREV:
if(radio_mode == RADIO_SCAN_MODE)
{
- curr_freq -= FREQ_STEP;
- if(curr_freq < MIN_FREQ)
- curr_freq = MAX_FREQ;
+ curr_freq
+ -= fm_region[global_settings.fm_region].freq_step;
+ if(curr_freq < fm_region[global_settings.fm_region].freq_min)
+ curr_freq
+ = fm_region[global_settings.fm_region].freq_max;
radio_set(RADIO_FREQUENCY, curr_freq);
curr_preset = find_preset(curr_freq);
remember_frequency();
@@ -589,9 +614,11 @@
case ACTION_STD_NEXT:
if(radio_mode == RADIO_SCAN_MODE)
{
- curr_freq += FREQ_STEP;
- if(curr_freq > MAX_FREQ)
- curr_freq = MIN_FREQ;
+ curr_freq
+ += fm_region[global_settings.fm_region].freq_step;
+ if(curr_freq > fm_region[global_settings.fm_region].freq_max)
+ curr_freq
+ = fm_region[global_settings.fm_region].freq_min;
radio_set(RADIO_FREQUENCY, curr_freq);
curr_preset = find_preset(curr_freq);
remember_frequency();
@@ -821,8 +848,8 @@
FOR_NB_SCREENS(i)
screens[i].puts_scroll(0, top_of_screen, buf);
- freq = curr_freq / 100000;
- snprintf(buf, 128, str(LANG_FM_STATION), freq / 10, freq % 10);
+ freq = curr_freq / 10000;
+ snprintf(buf, 128, str(LANG_FM_STATION), freq / 100, freq % 100);
FOR_NB_SCREENS(i)
screens[i].puts_scroll(0, top_of_screen + 1, buf);
@@ -1316,6 +1343,39 @@
return false;
}
+char region_menu_string[32];
+static void create_region_menu(void)
+{
+ snprintf(region_menu_string, sizeof(region_menu_string),
+ "%s: %s", str(LANG_FM_REGION),
+ str(fm_region[global_settings.fm_region].lang));
+}
+
+static bool toggle_region_mode(void)
+{
+ global_settings.fm_region++;
+ if(global_settings.fm_region >=
+ (int)(sizeof(fm_region) / sizeof(struct fm_region_setting)))
+ global_settings.fm_region = 0;
+#if (CONFIG_TUNER & TEA5767)
+ radio_set(RADIO_SET_DEEMPHASIS,
+ fm_region[global_settings.fm_region].deemphasis);
+ radio_set(RADIO_SET_BAND, fm_region[global_settings.fm_region].band);
+#endif
+ /* make sure the current frequency is in the region range */
+ curr_freq -= (curr_freq - fm_region[global_settings.fm_region].freq_min)
+ % fm_region[global_settings.fm_region].freq_step;
+ if(curr_freq < fm_region[global_settings.fm_region].freq_min)
+ curr_freq = fm_region[global_settings.fm_region].freq_min;
+ if(curr_freq > fm_region[global_settings.fm_region].freq_max)
+ curr_freq = fm_region[global_settings.fm_region].freq_max;
+ radio_set(RADIO_FREQUENCY, curr_freq);
+
+ settings_save();
+ create_region_menu();
+ return false;
+}
+
#ifndef FM_MODE
char radiomode_menu_string[32];
@@ -1346,17 +1406,17 @@
if(do_scan)
{
- curr_freq = MIN_FREQ;
+ curr_freq = fm_region[global_settings.fm_region].freq_min;
num_presets = 0;
memset(presets, 0, sizeof(presets));
- while(curr_freq <= MAX_FREQ)
+ while(curr_freq <= fm_region[global_settings.fm_region].freq_max)
{
if (num_presets >= MAX_PRESETS)
break;
- freq = curr_freq /100000;
+ freq = curr_freq / 10000;
snprintf(buf, MAX_FMPRESET_LEN, str(LANG_FM_SCANNING),
- freq/10, freq % 10);
+ freq/100, freq % 100);
gui_syncsplash(0, true, buf);
/* Tune in and delay */
@@ -1373,13 +1433,13 @@
/* add preset */
if(tuned){
snprintf(buf, MAX_FMPRESET_LEN,
- str(LANG_FM_DEFAULT_PRESET_NAME),freq/10, freq % 10);
+ str(LANG_FM_DEFAULT_PRESET_NAME),freq/100, freq % 100);
strcpy(presets[num_presets].name,buf);
presets[num_presets].frequency = curr_freq;
num_presets++;
}
- curr_freq += FREQ_STEP;
+ curr_freq += fm_region[global_settings.fm_region].freq_step;
}
@@ -1504,6 +1564,7 @@
#ifndef FM_MODE
{ radiomode_menu_string , toggle_radio_mode },
#endif
+ { region_menu_string , toggle_region_mode },
{ ID2P(LANG_SOUND_SETTINGS) , sound_menu },
#ifndef SIMULATOR
#if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC
@@ -1515,6 +1576,7 @@
};
create_monomode_menu();
+ create_region_menu();
#ifndef FM_MODE
create_radiomode_menu();
#endif
diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h
index fdf446d..439061e 100644
--- a/apps/recorder/radio.h
+++ b/apps/recorder/radio.h
@@ -42,6 +42,18 @@
char name[MAX_FMPRESET_LEN+1];
};
+struct fm_region_setting
+{
+ int lang;
+ int freq_min;
+ int freq_max;
+ int freq_step;
+#if (CONFIG_TUNER & TEA5767)
+ int deemphasis; /* 0: 50us, 1: 75us */
+ int band; /* 0: europe, 1: japan (BL in TEA spec)*/
+#endif
+};
+
#endif
#endif
diff --git a/apps/settings.c b/apps/settings.c
index d419d4a..ebe0d1e 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -661,6 +661,9 @@
{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
/* If values are just added to the end, no need to bump the version. */
/* new stuff to be added at the end */
diff --git a/apps/settings.h b/apps/settings.h
index 09834ec..b29a219 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -491,6 +491,10 @@
int unplug_rw; /* time in s to rewind when pausing */
bool unplug_autoresume; /* disable auto-resume if no phones */
#endif
+#ifdef CONFIG_TUNER
+ int fm_region;
+#endif
+
};
enum optiontype { INT, BOOL };
diff --git a/firmware/export/tuner.h b/firmware/export/tuner.h
index a6a7e8e..48d9bc9 100644
--- a/firmware/export/tuner.h
+++ b/firmware/export/tuner.h
@@ -27,6 +27,10 @@
#define RADIO_IF_MEASUREMENT 3
#define RADIO_SENSITIVITY 4
#define RADIO_FORCE_MONO 5
+#if (CONFIG_TUNER & TEA5767)
+#define RADIO_SET_DEEMPHASIS 6
+#define RADIO_SET_BAND 7
+#endif
/* readback from the tuner layer */
#define RADIO_PRESENT 0
#define RADIO_TUNED 1
diff --git a/firmware/tuner_philips.c b/firmware/tuner_philips.c
index 2958e9e..89c7dd1 100644
--- a/firmware/tuner_philips.c
+++ b/firmware/tuner_philips.c
@@ -73,6 +73,14 @@
fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes));
break;
+ case RADIO_SET_DEEMPHASIS:
+ write_bytes[4] = (write_bytes[4] & ~(1<<6)) | (value ? (1<<6) : 0);
+ fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes));
+ break;
+
+ case RADIO_SET_BAND:
+ write_bytes[3] = (write_bytes[3] & ~(1<<5)) | (value ? (1<<5) : 0);
+ fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes));
default:
return;
}