? SOURCES.diff.txt ? allbuilds ? builds ? cvsadd ? cvsexport ? makepatch ? patchup ? test_fps.patch.txt ? uisim-sdl-calls.txt ? unpatch ? x5asm ? apps/playback (working).c ? apps/plugins/div_test.c ? apps/plugins/flanger-old.c ? apps/plugins/flanger.c ? apps/plugins/lawbreaker.c ? apps/plugins/ringmod.c ? firmware/Document4.txt ? firmware/target/coldfire/iaudio/x5/ds2411-x5.c ? tools/codepages ? tools/configure_ ? tools/ipod_fw ? tools/mkboot ? tools/rdf2binary ? tools/uclpack Index: apps/plugins/SOURCES =================================================================== RCS file: /cvsroot/rockbox/apps/plugins/SOURCES,v retrieving revision 1.144 diff -u -r1.144 SOURCES --- apps/plugins/SOURCES 30 Nov 2006 22:29:48 -0000 1.144 +++ apps/plugins/SOURCES 12 Dec 2006 04:12:05 -0000 @@ -21,6 +21,10 @@ vbrfix.c viewer.c +ringmod.c +flanger.c +flanger-old.c + /* plugins built for all targets, but not for the simulator */ #if !defined(SIMULATOR) metronome.c Index: apps/recorder/radio.c =================================================================== RCS file: /cvsroot/rockbox/apps/recorder/radio.c,v retrieving revision 1.114 diff -u -r1.114 radio.c --- apps/recorder/radio.c 6 Nov 2006 18:07:27 -0000 1.114 +++ apps/recorder/radio.c 12 Dec 2006 04:12:06 -0000 @@ -221,8 +221,10 @@ if(radio_status == FMRADIO_OFF) { +#if CONFIG_TUNER != TEA5767 radio_set(RADIO_IF_MEASUREMENT, 0); radio_set(RADIO_SENSITIVITY, 0); +#endif radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono); #if (CONFIG_TUNER & TEA5767) radio_set(RADIO_SET_DEEMPHASIS, @@ -292,6 +294,12 @@ #endif } +static void mute_if_playing(bool mute) +{ + if (radio_status == FMRADIO_PLAYING) + radio_set(RADIO_MUTE, mute?1:0); +} + static int find_preset(int freq) { int i; @@ -358,39 +366,75 @@ curr_preset--; curr_freq = presets[curr_preset].frequency; + mute_if_playing(true); radio_set(RADIO_FREQUENCY, curr_freq); + mute_if_playing(false); remember_frequency(); } +static int step_freq(int f, int direction) +{ + f += direction*fm_region[global_settings.fm_region].freq_step; + + if (direction > 0) + { + if (f > fm_region[global_settings.fm_region].freq_max) + f = fm_region[global_settings.fm_region].freq_min; + } + else if (direction < 0) + { + if (f < fm_region[global_settings.fm_region].freq_min) + f = fm_region[global_settings.fm_region].freq_max; + } + + return f; +} + +static void next_station(int direction) +{ + if (direction != 0 && radio_mode != RADIO_SCAN_MODE) + { + next_preset(direction); + return; + } + + curr_freq = step_freq(curr_freq, direction); + mute_if_playing(true); + radio_set(RADIO_FREQUENCY, curr_freq); + mute_if_playing(false); + curr_preset = find_preset(curr_freq); + remember_frequency(); +} bool radio_screen(void) { char buf[MAX_PATH]; bool done = false; - int button, lastbutton = BUTTON_NONE; -#ifdef FM_RECORD_DBLPRE - unsigned long rec_lastclick = 0; -#endif - int freq, i; - bool tuned; - bool stereo = false; + int button; + int i; int search_dir = 0; + bool stereo = false, last_stereo = false; int fh; - bool last_stereo_status = false; int top_of_screen = 0; bool update_screen = true; - int timeout = current_tick + HZ/10; bool screen_freeze = false; + bool keep_playing = false; + bool statusbar = global_settings.statusbar; +#ifdef FM_RECORD_DBLPRE + int lastbutton = BUTTON_NONE; + unsigned long rec_lastclick = 0; +#endif +#if CONFIG_CODEC != SWCODEC bool have_recorded = false; + int timeout = current_tick + HZ/10; unsigned int seconds = 0; unsigned int last_seconds = 0; -#if CONFIG_CODEC != SWCODEC int hours, minutes; struct audio_recording_options rec_options; -#endif - bool keep_playing = false; - bool statusbar = global_settings.statusbar; +#endif /* CONFIG_CODEC != SWCODEC */ +#ifndef IAUDIO_X5 int button_timeout = current_tick + (2*HZ); +#endif #ifdef HAS_BUTTONBAR struct gui_buttonbar buttonbar; gui_buttonbar_init(&buttonbar); @@ -456,7 +500,6 @@ radio_start(); #endif - /* I hate this thing with vehement passion (jhMikeS): */ if(num_presets == 0 && yesno_pop(str(LANG_FM_FIRST_AUTOSCAN))) scan_presets(); @@ -469,50 +512,49 @@ str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD)); #endif +#ifndef IAUDIO_X5 + /* this makes _alot_ of noise on x5 */ cpu_idle_mode(true); +#endif + + void end_search(void) + { + if (search_dir != 0 && radio_status == FMRADIO_PLAYING) + radio_set(RADIO_MUTE, 0); + search_dir = 0; + } while(!done) { - if(search_dir) + if(search_dir != 0) { - 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); - sleep(1); - - /* Start IF measurement */ - radio_set(RADIO_IF_MEASUREMENT, 1); - sleep(1); - - /* Now check how close to the IF frequency we are */ - tuned = radio_get(RADIO_TUNED); - - /* Stop searching if the tuning is close */ - if(tuned) + curr_freq = step_freq(curr_freq, search_dir); + if(radio_set(RADIO_SCAN_FREQUENCY, curr_freq)) { - search_dir = 0; curr_preset = find_preset(curr_freq); remember_frequency(); + end_search(); } - + update_screen = true; } - if(search_dir) - button = button_get(false); - else - button = get_action(CONTEXT_FM, HZ / PEAK_METER_FPS); +#if CONFIG_CODEC != SWCODEC + button = get_action(CONTEXT_FM, + update_screen ? TIMEOUT_NOBLOCK : HZ / PEAK_METER_FPS); +#else + button = get_action(CONTEXT_FM, + update_screen ? TIMEOUT_NOBLOCK : HZ); +#endif + +#ifndef IAUDIO_X5 if (button != ACTION_NONE) { cpu_idle_mode(false); button_timeout = current_tick + (2*HZ); } +#endif + switch(button) { case ACTION_FM_STOP: @@ -554,7 +596,7 @@ rec_lastclick = current_tick; break; } -#endif +#endif /* FM_RECORD_DBLPRE */ #ifndef SIMULATOR if(audio_status() == AUDIO_STATUS_RECORD) { @@ -567,7 +609,7 @@ rec_record(); update_screen = true; } -#endif +#endif /* SIMULATOR */ last_seconds = 0; break; #endif /* #ifdef FM_RECORD */ @@ -597,63 +639,27 @@ break; case ACTION_STD_PREV: - if(radio_mode == RADIO_SCAN_MODE) - { - 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(); - } - else - next_preset(-1); - search_dir = 0; - update_screen = true; - break; - case ACTION_STD_NEXT: - if(radio_mode == RADIO_SCAN_MODE) - { - 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(); - } - else - next_preset(1); - search_dir = 0; + next_station(button == ACTION_STD_PREV ? -1 : 1); + end_search(); update_screen = true; break; case ACTION_STD_PREVREPEAT: - if(radio_mode == RADIO_SCAN_MODE) - search_dir = -1; - else - { - next_preset(-1); - update_screen = true; - } - - break; - case ACTION_STD_NEXTREPEAT: - if(radio_mode == RADIO_SCAN_MODE) - search_dir = 1; - else + { + int dir = search_dir; + search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1; + if (radio_mode != RADIO_SCAN_MODE) { - next_preset(1); - update_screen = true; + next_preset(search_dir); + end_search(); } - + else if (dir == 0) + radio_set(RADIO_MUTE, 1); + update_screen = true; break; - + } case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INCREPEAT: @@ -729,7 +735,7 @@ #endif update_screen = true; break; -#endif +#endif /* FM_PRESET */ #ifdef FM_FREEZE case ACTION_FM_FREEZE: @@ -744,10 +750,13 @@ screen_freeze = false; } break; -#endif +#endif /* FM_FREEZE */ + case SYS_USB_CONNECTED: +#if CONFIG_CODEC != SWCODEC /* Only accept USB connection when not recording */ if(audio_status() != AUDIO_STATUS_RECORD) +#endif { default_event_handler(SYS_USB_CONNECTED); screen_freeze = true; /* Cosmetic: makes sure the @@ -768,18 +777,20 @@ radio_mode = RADIO_SCAN_MODE; update_screen = true; break; -#endif +#endif /* FM_MODE */ + #ifdef FM_NEXT_PRESET case ACTION_FM_NEXT_PRESET: next_preset(1); - search_dir = 0; + end_search(); update_screen = true; break; #endif + #ifdef FM_PREV_PRESET case ACTION_FM_PREV_PRESET: next_preset(-1); - search_dir = 0; + end_search(); update_screen = true; break; #endif @@ -789,8 +800,10 @@ break; } /*switch(button)*/ +#ifdef FM_RECORD_DBLPRE if (button != ACTION_NONE) lastbutton = button; +#endif #if CONFIG_CODEC != SWCODEC peak_meter_peek(); @@ -799,10 +812,9 @@ if(!screen_freeze) { /* Only display the peak meter when not recording */ +#if CONFIG_CODEC != SWCODEC if(!audio_status()) { - -#if CONFIG_CODEC != SWCODEC FOR_NB_SCREENS(i) { peak_meter_screen(&screens[i],0, @@ -810,35 +822,39 @@ screens[i].update_rect(0, STATUSBAR_HEIGHT + fh*(top_of_screen + 4), screens[i].width, fh); } -#endif - } if(TIME_AFTER(current_tick, timeout)) { timeout = current_tick + HZ; +#else /* SWCODEC */ + { +#endif /* CONFIG_CODEC == SWCODEC */ /* keep "mono" from always being displayed when paused */ if (radio_status != FMRADIO_PAUSED) { stereo = radio_get(RADIO_STEREO) && !global_settings.fm_force_mono; - if(stereo != last_stereo_status) + + if(stereo != last_stereo) { update_screen = true; - last_stereo_status = stereo; + last_stereo = stereo; } } } - -#ifndef SIMULATOR -#if CONFIG_CODEC != SWCODEC + +#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) seconds = audio_recorded_time() / HZ; -#endif -#endif - if(update_screen || seconds > last_seconds) + if (update_screen || seconds > last_seconds) { last_seconds = seconds; +#else + if (update_screen) + { +#endif + int freq; FOR_NB_SCREENS(i) screens[i].setfont(FONT_UI); @@ -866,6 +882,7 @@ str(LANG_RADIO_SCAN_MODE)); FOR_NB_SCREENS(i) screens[i].puts_scroll(0, top_of_screen + 3, buf); + #if CONFIG_CODEC != SWCODEC if(audio_status() == AUDIO_STATUS_RECORD) { @@ -887,7 +904,7 @@ screens[i].puts_scroll(0, top_of_screen + 4, buf); } } -#endif +#endif /* CONFIG_CODEC != SWCODEC */ #ifdef HAS_BUTTONBAR gui_buttonbar_draw(&buttonbar); @@ -897,21 +914,27 @@ } /* Only force the redraw if update_screen is true */ gui_syncstatusbar_draw(&statusbars,true); - - update_screen = false; } + update_screen = false; + +#if CONFIG_CODEC != SWCODEC if(audio_status() & AUDIO_STATUS_ERROR) { done = true; } +#endif + +#ifndef IAUDIO_X5 if (TIME_AFTER(current_tick, button_timeout)) { cpu_idle_mode(true); } +#endif } /*while(!done)*/ #ifndef SIMULATOR +#if CONFIG_CODEC != SWCODEC if(audio_status() & AUDIO_STATUS_ERROR) { gui_syncsplash(0, true, str(LANG_DISK_FULL)); @@ -928,16 +951,15 @@ } } -#if CONFIG_CODEC != SWCODEC audio_init_playback(); -#endif +#endif /* CONFIG_CODEC != SWCODEC */ sound_settings_apply(); #endif /* SIMULATOR */ if(keep_playing) { -/* Catch FMRADIO_PLAYING status for the sim. */ +/* Catch FMRADIO_PLAYING status for the sim. */ #ifndef SIMULATOR #if CONFIG_CODEC != SWCODEC /* Enable the Left and right A/D Converter */ @@ -946,7 +968,8 @@ AUDIO_GAIN_LINEIN); mas_codec_writereg(6, 0x4000); #endif -#endif + end_search(); +#endif /* SIMULATOR */ } else { @@ -963,8 +986,11 @@ global_settings.statusbar = statusbar; in_screen = false; - +#if CONFIG_CODEC != SWCODEC return have_recorded; +#else + return false; +#endif } /* radio_screen */ void radio_save_presets(void) @@ -1320,7 +1346,7 @@ { curr_preset = menu_cursor(preset_menu); curr_freq = presets[curr_preset].frequency; - radio_set(RADIO_FREQUENCY, curr_freq); + next_station(0); remember_frequency(); } } @@ -1373,8 +1399,8 @@ 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); + next_station(0); remember_frequency(); create_region_menu(); return false; @@ -1401,7 +1427,7 @@ static bool scan_presets(void) { - bool tuned = false, do_scan = true; + bool do_scan = true; char buf[MAX_FMPRESET_LEN]; int freq, i; @@ -1413,6 +1439,7 @@ curr_freq = fm_region[global_settings.fm_region].freq_min; num_presets = 0; memset(presets, 0, sizeof(presets)); + radio_set(RADIO_MUTE, 1); while(curr_freq <= fm_region[global_settings.fm_region].freq_max) { if (num_presets >= MAX_PRESETS) @@ -1423,19 +1450,9 @@ freq/100, freq % 100); gui_syncsplash(0, true, buf); - /* Tune in and delay */ - radio_set(RADIO_FREQUENCY, curr_freq); - sleep(1); - - /* Start IF measurement */ - radio_set(RADIO_IF_MEASUREMENT, 1); - sleep(1); - /* Now check how close to the IF frequency we are */ - tuned = radio_get(RADIO_TUNED); - /* add preset */ - if(tuned){ + if (radio_set(RADIO_SCAN_FREQUENCY, curr_freq)) { snprintf(buf, MAX_FMPRESET_LEN, str(LANG_FM_DEFAULT_PRESET_NAME),freq/100, freq % 100); strcpy(presets[num_presets].name,buf); @@ -1444,9 +1461,11 @@ } curr_freq += fm_region[global_settings.fm_region].freq_step; - } + if (radio_status == FMRADIO_PLAYING) + radio_set(RADIO_MUTE, 0); + presets_changed = true; FOR_NB_SCREENS(i) @@ -1459,7 +1478,7 @@ if(num_presets > 0 ) { curr_freq = presets[0].frequency; - radio_set(RADIO_FREQUENCY, curr_freq); + next_station(0); remember_frequency(); radio_mode = RADIO_PRESET_MODE; presets_loaded = true; Index: firmware/tuner_philips.c =================================================================== RCS file: /cvsroot/rockbox/firmware/tuner_philips.c,v retrieving revision 1.11 diff -u -r1.11 tuner_philips.c --- firmware/tuner_philips.c 23 Oct 2006 19:48:42 -0000 1.11 +++ firmware/tuner_philips.c 12 Dec 2006 04:12:07 -0000 @@ -24,12 +24,119 @@ #include "kernel.h" #include "tuner.h" /* tuner abstraction interface */ #include "fmradio_i2c.h" /* physical interface driver */ +#include "logf.h" -#define I2C_ADR 0xC0 +#define I2C_ADR 0xC0 static unsigned char write_bytes[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; +#define MIN_ADC_LEVEL 4 +#define MAX_LEVEL_DIFF 2 +#define MIN_IFC 0x32 +#define MAX_IFC 0x3d + +struct station_info +{ + int level; + int ifc; + int tuned; +}; + +static void set_pll_write(int value) +{ + value += (write_bytes[2] & 0x10) ? 225000 : -225000; + +#if CONFIG_TUNER_XTAL == 32768 + value = (value + 4096) >> 13; +#else + value = (value + 6250) / 12500; +#endif + + write_bytes[0] = (write_bytes[0] & 0xC0) | ((value >> 8) & 0x3F); + write_bytes[1] = value; +} + +static void write_regs(void) +{ + fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes)); +} + +static void read_regs(unsigned char read_bytes[5]) +{ + fmradio_i2c_read(I2C_ADR, read_bytes, sizeof(read_bytes)); +} + +static int tune_frequency(int value, struct station_info *si_p) +{ + struct station_info si[2]; + unsigned char read_bytes[5]; + int i; + + write_bytes[2] |= 0x10; + + for (i = 0; i < 2; i++) + { + set_pll_write(value); + write_regs(); + sleep(HZ/30); + + read_regs(read_bytes); + si[i].level = (unsigned)read_bytes[3] >> 4; + si[i].ifc = (unsigned)read_bytes[2] & 0x7f; + si[i].tuned = read_bytes[0] & 0x80; + + write_bytes[2] ^= 0x10; + } + + i = 0; + if (si[0].level <= si[1].level) + { + write_bytes[2] ^= 0x10; + i = 1; + } + + if (si_p) + memcpy(si_p, si, sizeof(si)); + + set_pll_write(value); + + return i; +} + +static int scan_frequency(int value) +{ + struct station_info si[2]; + + int i = tune_frequency(value, si); + + i = si[i].tuned && + si[0].level >= MIN_ADC_LEVEL && + si[1].level >= MIN_ADC_LEVEL && + abs(si[0].level - si[1].level) <= MAX_LEVEL_DIFF && + si[0].ifc >= MIN_IFC && si[0].ifc <= MAX_IFC && + si[1].ifc >= MIN_IFC && si[1].ifc <= MAX_IFC; + + if (si[i].tuned) + { + logf("%03d.%d: %02d %02d %02X %02X %s", + value / 1000000, + value / 100000 % 10, + si[0].level, + si[1].level, + si[0].ifc, + si[1].ifc, + i ? "*" : ""); + } + + if (i) + { + write_regs(); + sleep(HZ/30); + } + + return i; +} /* tuner abstraction layer: set something to the tuner */ -void philips_set(int setting, int value) +int philips_set(int setting, int value) { switch(setting) { @@ -48,18 +155,12 @@ break; case RADIO_FREQUENCY: - { - int n; -#if CONFIG_TUNER_XTAL == 32768 - n = (4 * (value - 225000) + 16384) / 32768; -#else - n = (4 * (value - 225000)) / 50000; -#endif - write_bytes[0] = (write_bytes[0] & 0xC0) | (n >> 8); - write_bytes[1] = n & 0xFF; - } + tune_frequency(value, NULL); break; + case RADIO_SCAN_FREQUENCY: + return scan_frequency(value); + case RADIO_MUTE: write_bytes[0] = (write_bytes[0] & 0x7F) | (value ? 0x80 : 0); break; @@ -75,9 +176,11 @@ case RADIO_SET_BAND: write_bytes[3] = (write_bytes[3] & ~(1<<5)) | (value ? (1<<5) : 0); default: - return; + return -1; } - fmradio_i2c_write(I2C_ADR, write_bytes, sizeof(write_bytes)); + + write_regs(); + return 1; } /* tuner abstraction layer: read something from the tuner */ @@ -86,7 +189,7 @@ unsigned char read_bytes[5]; int val = -1; /* default for unsupported query */ - fmradio_i2c_read(I2C_ADR, read_bytes, sizeof(read_bytes)); + read_regs(read_bytes); switch(setting) { @@ -95,12 +198,8 @@ break; case RADIO_TUNED: - val = 0; - if (read_bytes[0] & 0x80) /* ready */ - { - val = read_bytes[2] & 0x7F; /* IF counter */ - val = (abs(val - 0x36) < 2); /* close match */ - } + val = (read_bytes[0] & 0x80) && + (read_bytes[3] >> 4) >= MIN_ADC_LEVEL; break; case RADIO_STEREO: Index: firmware/tuner_samsung.c =================================================================== RCS file: /cvsroot/rockbox/firmware/tuner_samsung.c,v retrieving revision 1.6 diff -u -r1.6 tuner_samsung.c --- firmware/tuner_samsung.c 29 Aug 2005 21:15:20 -0000 1.6 +++ firmware/tuner_samsung.c 12 Dec 2006 04:12:07 -0000 @@ -34,8 +34,10 @@ static int fm_in2; /* tuner abstraction layer: set something to the tuner */ -void samsung_set(int setting, int value) +int samsung_set(int setting, int value) { + int val = 1; + switch(setting) { case RADIO_SLEEP: @@ -90,6 +92,16 @@ break; } + case RADIO_SCAN_FREQUENCY: + /* Tune in and delay */ + samsung_set(RADIO_FREQUENCY, value); + sleep(1); + /* Start IF measurement */ + samsung_set(RADIO_IF_MEASUREMENT, 1); + sleep(1); + val = samsung_get(RADIO_TUNED); + break; + case RADIO_MUTE: fm_in1 = (fm_in1 & 0xfffffffe) | (value?1:0); fmradio_set(1, fm_in1); @@ -109,7 +121,11 @@ fm_in2 = (fm_in2 & 0xfffffffb) | (value?0:4); fmradio_set(2, fm_in2); break; + default: + val = -1; } + + return val; } /* tuner abstraction layer: read something from the tuner */ Index: firmware/export/tuner.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/tuner.h,v retrieving revision 1.4 diff -u -r1.4 tuner.h --- firmware/export/tuner.h 5 Oct 2006 12:40:13 -0000 1.4 +++ firmware/export/tuner.h 12 Dec 2006 04:12:07 -0000 @@ -31,6 +31,7 @@ #define RADIO_SET_DEEMPHASIS 6 #define RADIO_SET_BAND 7 #endif +#define RADIO_SCAN_FREQUENCY 8 /* readback from the tuner layer */ #define RADIO_PRESENT 0 #define RADIO_TUNED 1 @@ -40,12 +41,12 @@ #ifdef CONFIG_TUNER #if (CONFIG_TUNER & S1A0903X01) -void samsung_set(int setting, int value); +int samsung_set(int setting, int value); int samsung_get(int setting); #endif #if (CONFIG_TUNER & TEA5767) -void philips_set(int setting, int value); +int philips_set(int setting, int value); int philips_get(int setting); #endif