From c5dacdcc771d89cd079cd9d61052be3ba9d23f0b Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Sun, 4 May 2003 02:23:18 +0000 Subject: FM preset handling on F2 and F3 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3648 a1c6a512-1295-4272-9138-f99709370657 --- apps/recorder/radio.c | 296 +++++++++++++++++++++++++++++++++++++++++++++++++- apps/recorder/radio.h | 7 ++ 2 files changed, 300 insertions(+), 3 deletions(-) (limited to 'apps') diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 839fafe303..6fcc982946 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c @@ -20,6 +20,7 @@ #include "config.h" #include #include +#include "sprintf.h" #include "lcd.h" #include "mas.h" #include "settings.h" @@ -28,6 +29,17 @@ #include "status.h" #include "kernel.h" #include "mpeg.h" +#include "ctype.h" +#include "file.h" +#include "errno.h" +#include "atoi.h" +#include "string.h" +#include "system.h" +#include "radio.h" +#include "menu.h" +#include "misc.h" +#include "keyboard.h" +#include "screens.h" #ifdef HAVE_FMRADIO @@ -36,9 +48,18 @@ #define PLL_FREQ_STEP 10000 #define FREQ_STEP 100000 +static int curr_preset = -1; static int curr_freq = 99400000; static int pll_cnt; +#define MAX_PRESETS 32 +static bool presets_loaded = false; +static struct fmstation presets[MAX_PRESETS]; + +void fm_load_presets(void); +bool fm_preset_select(void); +bool fm_f3_menu(void); + void fm_set_frequency(int freq) { /* We add the standard Intermediate Frequency 10.7MHz before calculating @@ -55,6 +76,21 @@ void fm_set_frequency(int freq) fmradio_set(1, 0x100002 | pll_cnt << 3); } +static int find_preset(int freq) +{ + int i; + if(presets_loaded) + { + for(i = 0;i < MAX_PRESETS;i++) + { + if(freq == presets[i].frequency) + return i; + } + } + + return -1; +} + bool radio_screen(void) { char buf[128]; @@ -71,6 +107,8 @@ bool radio_screen(void) lcd_setmargins(0, 8); status_draw(false); fmradio_set_status(FMRADIO_PLAYING); + + fm_load_presets(); /* Enable the Left and right A/D Converter */ mas_codec_writereg(0x0, 0xccc7); @@ -79,6 +117,7 @@ bool radio_screen(void) fmradio_set(2, 0x140884); /* 5kHz, 7.2MHz crystal */ fm_set_frequency(curr_freq); + curr_preset = find_preset(curr_freq); while(!done) { @@ -108,18 +147,26 @@ bool radio_screen(void) /* Stop searching if the IF frequency is close to 10.7MHz */ if(i_freq > 1065 && i_freq < 1075) + { search_dir = 0; + curr_preset = find_preset(curr_freq); + } } freq = curr_freq / 100000; snprintf(buf, 128, "Freq: %d.%dMHz", freq / 10, freq % 10); - lcd_puts(0, 1, buf); + lcd_puts(0, 2, buf); val = fmradio_read(3); stereo = (val & 0x100000)?true:false; lock = (val & 0x80000)?true:false; snprintf(buf, 128, "Mode: %s", stereo?"Stereo":"Mono"); - lcd_puts(0, 2, buf); + lcd_puts(0, 3, buf); + + if(curr_preset >= 0) + { + lcd_puts_scroll(0, 1, presets[curr_preset].name); + } lcd_update(); @@ -129,7 +176,7 @@ bool radio_screen(void) button = button_get_w_tmo(HZ/2); switch(button) { - case BUTTON_OFF | BUTTON_REL: + case BUTTON_OFF: done = true; break; @@ -139,6 +186,7 @@ bool radio_screen(void) curr_freq = MIN_FREQ; fm_set_frequency(curr_freq); + curr_preset = find_preset(curr_freq); search_dir = 0; break; @@ -148,6 +196,7 @@ bool radio_screen(void) curr_freq = MAX_FREQ; fm_set_frequency(curr_freq); + curr_preset = find_preset(curr_freq); search_dir = 0; break; @@ -179,13 +228,254 @@ bool radio_screen(void) settings_save(); break; + case BUTTON_F2: + fm_preset_select(); + curr_preset = find_preset(curr_freq); + lcd_clear_display(); + lcd_setmargins(0, 8); + status_draw(false); + break; + + case BUTTON_F3: + fm_f3_menu(); + curr_preset = find_preset(curr_freq); + lcd_clear_display(); + lcd_setmargins(0, 8); + status_draw(false); + break; + case BUTTON_NONE: status_draw(true); break; + + case SYS_USB_CONNECTED: + usb_screen(); + fmradio_set_status(0); + return true; } } fmradio_set_status(0); return false; } + +static bool parseline(char* line, char** freq, char** name) +{ + char* ptr; + + while ( isspace(*line) ) + line++; + + if ( *line == '#' ) + return false; + + ptr = strchr(line, ':'); + if ( !ptr ) + return false; + + *freq = line; + *ptr = 0; + ptr++; + while (isspace(*ptr)) + ptr++; + *name = ptr; + return true; +} + +void fm_save_presets(void) +{ + int fd; + int i; + + fd = open("/.rockbox/fm_presets.txt", O_WRONLY); + if(fd >= 0) + { + for(i = 0;i < MAX_PRESETS;i++) + { + fprintf(fd, "%d:%s\n", presets[i].frequency, presets[i].name); + } + close(fd); + } + else + { + splash(HZ*2, 0, true, "Preset save failed"); + } +} + +void fm_load_presets(void) +{ + int fd; + int rc; + char buf[128]; + char *freq; + char *name; + int num_presets = 0; + bool done = false; + int i; + + if(!presets_loaded) + { + memset(presets, 0, sizeof(presets)); + + fd = open("/.rockbox/fm_presets.txt", O_RDONLY); + if(fd >= 0) + { + i = 0; + while(!done) + { + rc = read_line(fd, buf, 128); + if(rc > 0) + { + if(parseline(buf, &freq, &name)) + { + presets[i].frequency = atoi(freq); + strncpy(presets[i].name, name, 27); + presets[i].name[27] = 0; + i++; + presets_loaded = true; + if(num_presets == MAX_PRESETS) + done = true; + } + } + else + done = true; + } + close(fd); + } + } +} + +bool fm_preset_select(void) +{ + struct menu_items menu[MAX_PRESETS]; + int m, result; + int i; + bool reload_dir = false; + int num_presets; + + if(presets_loaded) + { + num_presets = 0; + + for(i = 0;i < MAX_PRESETS;i++) + { + if(presets[i].frequency) + { + menu[num_presets].desc = presets[i].name; + /* We use the function pointer entry for the preset + entry index */ + menu[num_presets++].function = (void *)i; + } + } + + if(num_presets) + { + /* DIY menu handling, since we want to exit after selection */ + m = menu_init( menu, num_presets ); + result = menu_show(m); + menu_exit(m); + if (result == MENU_SELECTED_EXIT) + return false; + else if (result == MENU_ATTACHED_USB) + reload_dir = true; + + if (result >= 0) + { + i = (int)menu[result].function; + curr_freq = presets[i].frequency; + fm_set_frequency(curr_freq); + } + } + else + { + splash(HZ*2, 0, true, "No presets"); + } + } + + return reload_dir; +} + +static bool fm_add_preset(void) +{ + char buf[27]; + int i = find_preset(0); + + if(i >= 0) + { + memset(buf, 0, 27); + + if (!kbd_input(buf, 27)) + { + buf[27] = 0; + strcpy(presets[i].name, buf); + presets[i].frequency = curr_freq; + fm_save_presets(); + } + } + else + { + splash(HZ*2, 0, true, "No free preset entries"); + } + return true; +} + +bool fm_delete_preset(void) +{ + struct menu_items menu[MAX_PRESETS]; + int m, result; + int i; + bool reload_dir = false; + int num_presets; + + if(presets_loaded) + { + num_presets = 0; + + for(i = 0;i < MAX_PRESETS;i++) + { + if(presets[i].frequency) + { + menu[num_presets].desc = presets[i].name; + /* We use the function pointer entry for the preset + entry index */ + menu[num_presets++].function = (void *)i; + } + } + + /* DIY menu handling, since we want to exit after selection */ + m = menu_init( menu, num_presets ); + result = menu_show(m); + menu_exit(m); + if (result == MENU_SELECTED_EXIT) + return false; + else if (result == MENU_ATTACHED_USB) + reload_dir = true; + + if (result >= 0) + { + i = (int)menu[result].function; + presets[i].frequency = 0; + fm_save_presets(); + } + } + + return reload_dir; +} + +static struct menu_items f3_items[] = { + { "Add preset...", fm_add_preset }, + { "Delete preset...", fm_delete_preset } +}; + +bool fm_f3_menu(void) +{ + int m; + bool result; + + m = menu_init( f3_items, sizeof f3_items / sizeof(struct menu_items) ); + result = menu_run(m); + menu_exit(m); + return result; +} + #endif diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h index dafa46d90d..f6d7686ea9 100644 --- a/apps/recorder/radio.h +++ b/apps/recorder/radio.h @@ -21,6 +21,13 @@ #ifdef HAVE_FMRADIO bool radio_screen(void); + +struct fmstation +{ + int frequency; /* In Hz */ + char name[28]; +}; + #endif #endif -- cgit v1.2.3