diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 1c6c0a3a3e..f93ce0a0ac 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -7408,10 +7408,10 @@ desc: in radio screen user: - *: "Station: %d.%dMHz" + *: "Station: %d.%02d MHz" - *: "Station: %d.%dMHz" + *: "Station: %d.%02d MHz" *: "" @@ -7646,10 +7646,10 @@ desc: during auto scan user: - *: "Scanning %d.%01dMHz" + *: "Scanning %d.%02d MHz" - *: "Scanning %d.%01dMHz" + *: "Scanning %d.%02d MHz" *: "" @@ -7660,10 +7660,10 @@ desc: default preset name for auto scan mode user: - *: "%d.%01dMHz" + *: "%d.%02d MHz" - *: "%d.%01dMHz" + *: "%d.%02d MHz" *: "" @@ -9862,3 +9862,68 @@ *: "Disable auto-resume if phones not present" + + id: LANG_FM_REGION + desc: fm tuner region setting + + *: "Region" + + + *: "Region" + + + *: "Region" + + + + id: LANG_FM_EUROPE + desc: fm tuner region europe + + *: "Europe" + + + *: "Europe" + + + *: "Europe" + + + + id: LANG_FM_US + desc: fm region us / canada + + *: "US / Canada" + + + *: "US / Canada" + + + *: "US / Canada" + + + + id: LANG_FM_JAPAN + desc: fm region japan + + *: "Japan" + + + *: "Japan" + + + *: "Japan" + + + + id: LANG_FM_KOREA + desc: fm region korea + + *: "Korea" + + + *: "Korea" + + + *: "Korea" + + diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 4afe0b2204..e7a5912235 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 @@ void radio_start(void) 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 @@ static int find_closest_preset(int freq) { 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 int find_closest_preset(int freq) 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 @@ bool radio_screen(void) { 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 @@ bool radio_screen(void) 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 @@ bool radio_screen(void) 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 @@ bool radio_screen(void) 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 @@ static bool toggle_mono_mode(void) 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 @@ static bool scan_presets(void) 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 @@ static bool scan_presets(void) /* 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 @@ bool radio_menu(void) #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 @@ bool radio_menu(void) }; 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 fdf446dc0a..439061e579 100644 --- a/apps/recorder/radio.h +++ b/apps/recorder/radio.h @@ -42,6 +42,18 @@ struct fmstation 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 d419d4ae8b..ebe0d1e4cd 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -661,6 +661,9 @@ static const struct bit_entry hd_bits[] = {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 09834ec183..b29a219733 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -491,6 +491,10 @@ struct user_settings 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 a6a7e8ee0e..48d9bc97d1 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 2958e9e829..89c7dd11c7 100644 --- a/firmware/tuner_philips.c +++ b/firmware/tuner_philips.c @@ -73,6 +73,14 @@ void philips_set(int setting, int value) 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; }