summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/radio.c296
-rw-r--r--apps/recorder/radio.h7
2 files changed, 300 insertions, 3 deletions
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 @@
20#include "config.h" 20#include "config.h"
21#include <stdio.h> 21#include <stdio.h>
22#include <stdbool.h> 22#include <stdbool.h>
23#include "sprintf.h"
23#include "lcd.h" 24#include "lcd.h"
24#include "mas.h" 25#include "mas.h"
25#include "settings.h" 26#include "settings.h"
@@ -28,6 +29,17 @@
28#include "status.h" 29#include "status.h"
29#include "kernel.h" 30#include "kernel.h"
30#include "mpeg.h" 31#include "mpeg.h"
32#include "ctype.h"
33#include "file.h"
34#include "errno.h"
35#include "atoi.h"
36#include "string.h"
37#include "system.h"
38#include "radio.h"
39#include "menu.h"
40#include "misc.h"
41#include "keyboard.h"
42#include "screens.h"
31 43
32#ifdef HAVE_FMRADIO 44#ifdef HAVE_FMRADIO
33 45
@@ -36,9 +48,18 @@
36#define PLL_FREQ_STEP 10000 48#define PLL_FREQ_STEP 10000
37#define FREQ_STEP 100000 49#define FREQ_STEP 100000
38 50
51static int curr_preset = -1;
39static int curr_freq = 99400000; 52static int curr_freq = 99400000;
40static int pll_cnt; 53static int pll_cnt;
41 54
55#define MAX_PRESETS 32
56static bool presets_loaded = false;
57static struct fmstation presets[MAX_PRESETS];
58
59void fm_load_presets(void);
60bool fm_preset_select(void);
61bool fm_f3_menu(void);
62
42void fm_set_frequency(int freq) 63void fm_set_frequency(int freq)
43{ 64{
44 /* We add the standard Intermediate Frequency 10.7MHz before calculating 65 /* We add the standard Intermediate Frequency 10.7MHz before calculating
@@ -55,6 +76,21 @@ void fm_set_frequency(int freq)
55 fmradio_set(1, 0x100002 | pll_cnt << 3); 76 fmradio_set(1, 0x100002 | pll_cnt << 3);
56} 77}
57 78
79static int find_preset(int freq)
80{
81 int i;
82 if(presets_loaded)
83 {
84 for(i = 0;i < MAX_PRESETS;i++)
85 {
86 if(freq == presets[i].frequency)
87 return i;
88 }
89 }
90
91 return -1;
92}
93
58bool radio_screen(void) 94bool radio_screen(void)
59{ 95{
60 char buf[128]; 96 char buf[128];
@@ -71,6 +107,8 @@ bool radio_screen(void)
71 lcd_setmargins(0, 8); 107 lcd_setmargins(0, 8);
72 status_draw(false); 108 status_draw(false);
73 fmradio_set_status(FMRADIO_PLAYING); 109 fmradio_set_status(FMRADIO_PLAYING);
110
111 fm_load_presets();
74 112
75 /* Enable the Left and right A/D Converter */ 113 /* Enable the Left and right A/D Converter */
76 mas_codec_writereg(0x0, 0xccc7); 114 mas_codec_writereg(0x0, 0xccc7);
@@ -79,6 +117,7 @@ bool radio_screen(void)
79 117
80 fmradio_set(2, 0x140884); /* 5kHz, 7.2MHz crystal */ 118 fmradio_set(2, 0x140884); /* 5kHz, 7.2MHz crystal */
81 fm_set_frequency(curr_freq); 119 fm_set_frequency(curr_freq);
120 curr_preset = find_preset(curr_freq);
82 121
83 while(!done) 122 while(!done)
84 { 123 {
@@ -108,18 +147,26 @@ bool radio_screen(void)
108 147
109 /* Stop searching if the IF frequency is close to 10.7MHz */ 148 /* Stop searching if the IF frequency is close to 10.7MHz */
110 if(i_freq > 1065 && i_freq < 1075) 149 if(i_freq > 1065 && i_freq < 1075)
150 {
111 search_dir = 0; 151 search_dir = 0;
152 curr_preset = find_preset(curr_freq);
153 }
112 } 154 }
113 155
114 freq = curr_freq / 100000; 156 freq = curr_freq / 100000;
115 snprintf(buf, 128, "Freq: %d.%dMHz", freq / 10, freq % 10); 157 snprintf(buf, 128, "Freq: %d.%dMHz", freq / 10, freq % 10);
116 lcd_puts(0, 1, buf); 158 lcd_puts(0, 2, buf);
117 159
118 val = fmradio_read(3); 160 val = fmradio_read(3);
119 stereo = (val & 0x100000)?true:false; 161 stereo = (val & 0x100000)?true:false;
120 lock = (val & 0x80000)?true:false; 162 lock = (val & 0x80000)?true:false;
121 snprintf(buf, 128, "Mode: %s", stereo?"Stereo":"Mono"); 163 snprintf(buf, 128, "Mode: %s", stereo?"Stereo":"Mono");
122 lcd_puts(0, 2, buf); 164 lcd_puts(0, 3, buf);
165
166 if(curr_preset >= 0)
167 {
168 lcd_puts_scroll(0, 1, presets[curr_preset].name);
169 }
123 170
124 lcd_update(); 171 lcd_update();
125 172
@@ -129,7 +176,7 @@ bool radio_screen(void)
129 button = button_get_w_tmo(HZ/2); 176 button = button_get_w_tmo(HZ/2);
130 switch(button) 177 switch(button)
131 { 178 {
132 case BUTTON_OFF | BUTTON_REL: 179 case BUTTON_OFF:
133 done = true; 180 done = true;
134 break; 181 break;
135 182
@@ -139,6 +186,7 @@ bool radio_screen(void)
139 curr_freq = MIN_FREQ; 186 curr_freq = MIN_FREQ;
140 187
141 fm_set_frequency(curr_freq); 188 fm_set_frequency(curr_freq);
189 curr_preset = find_preset(curr_freq);
142 search_dir = 0; 190 search_dir = 0;
143 break; 191 break;
144 192
@@ -148,6 +196,7 @@ bool radio_screen(void)
148 curr_freq = MAX_FREQ; 196 curr_freq = MAX_FREQ;
149 197
150 fm_set_frequency(curr_freq); 198 fm_set_frequency(curr_freq);
199 curr_preset = find_preset(curr_freq);
151 search_dir = 0; 200 search_dir = 0;
152 break; 201 break;
153 202
@@ -179,13 +228,254 @@ bool radio_screen(void)
179 settings_save(); 228 settings_save();
180 break; 229 break;
181 230
231 case BUTTON_F2:
232 fm_preset_select();
233 curr_preset = find_preset(curr_freq);
234 lcd_clear_display();
235 lcd_setmargins(0, 8);
236 status_draw(false);
237 break;
238
239 case BUTTON_F3:
240 fm_f3_menu();
241 curr_preset = find_preset(curr_freq);
242 lcd_clear_display();
243 lcd_setmargins(0, 8);
244 status_draw(false);
245 break;
246
182 case BUTTON_NONE: 247 case BUTTON_NONE:
183 status_draw(true); 248 status_draw(true);
184 break; 249 break;
250
251 case SYS_USB_CONNECTED:
252 usb_screen();
253 fmradio_set_status(0);
254 return true;
185 } 255 }
186 } 256 }
187 257
188 fmradio_set_status(0); 258 fmradio_set_status(0);
189 return false; 259 return false;
190} 260}
261
262static bool parseline(char* line, char** freq, char** name)
263{
264 char* ptr;
265
266 while ( isspace(*line) )
267 line++;
268
269 if ( *line == '#' )
270 return false;
271
272 ptr = strchr(line, ':');
273 if ( !ptr )
274 return false;
275
276 *freq = line;
277 *ptr = 0;
278 ptr++;
279 while (isspace(*ptr))
280 ptr++;
281 *name = ptr;
282 return true;
283}
284
285void fm_save_presets(void)
286{
287 int fd;
288 int i;
289
290 fd = open("/.rockbox/fm_presets.txt", O_WRONLY);
291 if(fd >= 0)
292 {
293 for(i = 0;i < MAX_PRESETS;i++)
294 {
295 fprintf(fd, "%d:%s\n", presets[i].frequency, presets[i].name);
296 }
297 close(fd);
298 }
299 else
300 {
301 splash(HZ*2, 0, true, "Preset save failed");
302 }
303}
304
305void fm_load_presets(void)
306{
307 int fd;
308 int rc;
309 char buf[128];
310 char *freq;
311 char *name;
312 int num_presets = 0;
313 bool done = false;
314 int i;
315
316 if(!presets_loaded)
317 {
318 memset(presets, 0, sizeof(presets));
319
320 fd = open("/.rockbox/fm_presets.txt", O_RDONLY);
321 if(fd >= 0)
322 {
323 i = 0;
324 while(!done)
325 {
326 rc = read_line(fd, buf, 128);
327 if(rc > 0)
328 {
329 if(parseline(buf, &freq, &name))
330 {
331 presets[i].frequency = atoi(freq);
332 strncpy(presets[i].name, name, 27);
333 presets[i].name[27] = 0;
334 i++;
335 presets_loaded = true;
336 if(num_presets == MAX_PRESETS)
337 done = true;
338 }
339 }
340 else
341 done = true;
342 }
343 close(fd);
344 }
345 }
346}
347
348bool fm_preset_select(void)
349{
350 struct menu_items menu[MAX_PRESETS];
351 int m, result;
352 int i;
353 bool reload_dir = false;
354 int num_presets;
355
356 if(presets_loaded)
357 {
358 num_presets = 0;
359
360 for(i = 0;i < MAX_PRESETS;i++)
361 {
362 if(presets[i].frequency)
363 {
364 menu[num_presets].desc = presets[i].name;
365 /* We use the function pointer entry for the preset
366 entry index */
367 menu[num_presets++].function = (void *)i;
368 }
369 }
370
371 if(num_presets)
372 {
373 /* DIY menu handling, since we want to exit after selection */
374 m = menu_init( menu, num_presets );
375 result = menu_show(m);
376 menu_exit(m);
377 if (result == MENU_SELECTED_EXIT)
378 return false;
379 else if (result == MENU_ATTACHED_USB)
380 reload_dir = true;
381
382 if (result >= 0)
383 {
384 i = (int)menu[result].function;
385 curr_freq = presets[i].frequency;
386 fm_set_frequency(curr_freq);
387 }
388 }
389 else
390 {
391 splash(HZ*2, 0, true, "No presets");
392 }
393 }
394
395 return reload_dir;
396}
397
398static bool fm_add_preset(void)
399{
400 char buf[27];
401 int i = find_preset(0);
402
403 if(i >= 0)
404 {
405 memset(buf, 0, 27);
406
407 if (!kbd_input(buf, 27))
408 {
409 buf[27] = 0;
410 strcpy(presets[i].name, buf);
411 presets[i].frequency = curr_freq;
412 fm_save_presets();
413 }
414 }
415 else
416 {
417 splash(HZ*2, 0, true, "No free preset entries");
418 }
419 return true;
420}
421
422bool fm_delete_preset(void)
423{
424 struct menu_items menu[MAX_PRESETS];
425 int m, result;
426 int i;
427 bool reload_dir = false;
428 int num_presets;
429
430 if(presets_loaded)
431 {
432 num_presets = 0;
433
434 for(i = 0;i < MAX_PRESETS;i++)
435 {
436 if(presets[i].frequency)
437 {
438 menu[num_presets].desc = presets[i].name;
439 /* We use the function pointer entry for the preset
440 entry index */
441 menu[num_presets++].function = (void *)i;
442 }
443 }
444
445 /* DIY menu handling, since we want to exit after selection */
446 m = menu_init( menu, num_presets );
447 result = menu_show(m);
448 menu_exit(m);
449 if (result == MENU_SELECTED_EXIT)
450 return false;
451 else if (result == MENU_ATTACHED_USB)
452 reload_dir = true;
453
454 if (result >= 0)
455 {
456 i = (int)menu[result].function;
457 presets[i].frequency = 0;
458 fm_save_presets();
459 }
460 }
461
462 return reload_dir;
463}
464
465static struct menu_items f3_items[] = {
466 { "Add preset...", fm_add_preset },
467 { "Delete preset...", fm_delete_preset }
468};
469
470bool fm_f3_menu(void)
471{
472 int m;
473 bool result;
474
475 m = menu_init( f3_items, sizeof f3_items / sizeof(struct menu_items) );
476 result = menu_run(m);
477 menu_exit(m);
478 return result;
479}
480
191#endif 481#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 @@
21 21
22#ifdef HAVE_FMRADIO 22#ifdef HAVE_FMRADIO
23bool radio_screen(void); 23bool radio_screen(void);
24
25struct fmstation
26{
27 int frequency; /* In Hz */
28 char name[28];
29};
30
24#endif 31#endif
25 32
26#endif 33#endif