summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2003-05-03 02:40:09 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2003-05-03 02:40:09 +0000
commit331c7d9255e7873d3583aceea6bd00c7360f2366 (patch)
treed0dfb9e1eb62e8e96ef14e01b013179118c6c6f1
parent86704740792ae81add713f4f4b619c57fee79e47 (diff)
downloadrockbox-331c7d9255e7873d3583aceea6bd00c7360f2366.tar.gz
rockbox-331c7d9255e7873d3583aceea6bd00c7360f2366.zip
Finally, FM radio support on the FM Recorder
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3640 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/main_menu.c6
-rw-r--r--apps/recorder/radio.c189
-rw-r--r--apps/recorder/radio.h26
-rw-r--r--firmware/drivers/fmradio.c133
-rw-r--r--firmware/export/config-fmrecorder.h4
-rw-r--r--firmware/export/fmradio.h25
6 files changed, 383 insertions, 0 deletions
diff --git a/apps/main_menu.c b/apps/main_menu.c
index 9f4aa8f812..b455e074a2 100644
--- a/apps/main_menu.c
+++ b/apps/main_menu.c
@@ -41,6 +41,9 @@
41#include "fat.h" 41#include "fat.h"
42#include "sleeptimer.h" 42#include "sleeptimer.h"
43#include "wps.h" 43#include "wps.h"
44#ifdef HAVE_FMRADIO
45#include "radio.h"
46#endif
44 47
45#include "lang.h" 48#include "lang.h"
46 49
@@ -258,6 +261,9 @@ bool main_menu(void)
258 struct menu_items items[] = { 261 struct menu_items items[] = {
259 { str(LANG_SOUND_SETTINGS), sound_menu }, 262 { str(LANG_SOUND_SETTINGS), sound_menu },
260 { str(LANG_GENERAL_SETTINGS), settings_menu }, 263 { str(LANG_GENERAL_SETTINGS), settings_menu },
264#ifdef HAVE_FMRADIO
265 { "FM Radio", radio_screen },
266#endif
261#ifdef HAVE_MAS3587F 267#ifdef HAVE_MAS3587F
262 { str(LANG_RECORDING), recording_screen }, 268 { str(LANG_RECORDING), recording_screen },
263 { str(LANG_RECORDING_SETTINGS), recording_menu }, 269 { str(LANG_RECORDING_SETTINGS), recording_menu },
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
new file mode 100644
index 0000000000..7206fe08f3
--- /dev/null
+++ b/apps/recorder/radio.c
@@ -0,0 +1,189 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include <stdio.h>
22#include <stdbool.h>
23#include "lcd.h"
24#include "mas.h"
25#include "settings.h"
26#include "button.h"
27#include "fmradio.h"
28#include "status.h"
29#include "kernel.h"
30#include "mpeg.h"
31
32#ifdef HAVE_FMRADIO
33
34#define MAX_FREQ (110000000)
35#define MIN_FREQ (80000000)
36#define FREQ_STEP 100000
37
38static int curr_freq = 99400000;
39static int pll_cnt;
40
41void fm_set_frequency(int freq)
42{
43 /* We add the standard Intermediate Frequency 10.7MHz before calculating
44 ** the divisor
45 ** The reference frequency is set to 50kHz, and the VCO output is prescaled
46 ** by 2.
47 */
48
49 pll_cnt = (freq + 10700000) / 50000 / 2;
50
51 /* 0x100000 == FM mode
52 ** 0x000002 == Microprocessor controlled Mute
53 */
54 fmradio_set(1, 0x100002 | pll_cnt << 3);
55}
56
57bool radio_screen(void)
58{
59 char buf[128];
60 bool done = false;
61 int button;
62 int val;
63 int freq;
64 int i_freq;
65 bool lock;
66 bool stereo;
67 int search_dir = 0;
68
69 lcd_clear_display();
70 lcd_setmargins(0, 8);
71 status_draw(false);
72
73 /* Enable the Left and right A/D Converter */
74 mas_codec_writereg(0x0, 0xccc7);
75
76 mas_codec_writereg(6, 0x4000);
77
78 fmradio_set(2, 0x108884); /* 50kHz, 7.2MHz crystal */
79 fm_set_frequency(curr_freq);
80
81 while(!done)
82 {
83 if(search_dir)
84 {
85 curr_freq += search_dir * FREQ_STEP;
86 if(curr_freq < MIN_FREQ)
87 curr_freq = MAX_FREQ;
88 if(curr_freq > MAX_FREQ)
89 curr_freq = MIN_FREQ;
90
91 /* Tune in and delay */
92 fm_set_frequency(curr_freq);
93 sleep(10);
94
95 /* Start IF measurement */
96 fmradio_set(1, 0x100006 | pll_cnt << 3);
97 sleep(10);
98
99 /* Now check how close to the IF frequency we are */
100 val = fmradio_read(3);
101 i_freq = (val & 0x7ffff) / 80;
102 lcd_puts(0, 5, "Debug data:");
103 snprintf(buf, 128, "IF: %d.%dMHz",
104 i_freq / 100, (i_freq % 100) / 10);
105 lcd_puts(0, 6, buf);
106
107 /* Stop searching if the IF frequency is close to 10.7MHz */
108 if(i_freq > 1065 && i_freq < 1075)
109 search_dir = 0;
110 }
111
112 freq = curr_freq / 100000;
113 snprintf(buf, 128, "Freq: %d.%dMHz", freq / 10, freq % 10);
114 lcd_puts(0, 1, buf);
115
116 val = fmradio_read(3);
117 stereo = (val & 0x100000)?true:false;
118 lock = (val & 0x80000)?true:false;
119 snprintf(buf, 128, "Mode: %s", stereo?"Stereo":"Mono");
120 lcd_puts(0, 2, buf);
121
122 lcd_update();
123
124 if(search_dir)
125 button = button_get(false);
126 else
127 button = button_get_w_tmo(HZ/2);
128 switch(button)
129 {
130 case BUTTON_OFF | BUTTON_REL:
131 done = true;
132 break;
133
134 case BUTTON_LEFT:
135 curr_freq -= 100000;
136 if(curr_freq < MIN_FREQ)
137 curr_freq = MIN_FREQ;
138
139 fm_set_frequency(curr_freq);
140 search_dir = 0;
141 break;
142
143 case BUTTON_RIGHT:
144 curr_freq += 100000;
145 if(curr_freq > MAX_FREQ)
146 curr_freq = MAX_FREQ;
147
148 fm_set_frequency(curr_freq);
149 search_dir = 0;
150 break;
151
152 case BUTTON_LEFT | BUTTON_REPEAT:
153 search_dir = -1;
154 break;
155
156 case BUTTON_RIGHT | BUTTON_REPEAT:
157 search_dir = 1;
158 break;
159
160 case BUTTON_UP:
161 case BUTTON_UP | BUTTON_REPEAT:
162 case BUTTON_RC_VOL_UP:
163 global_settings.volume++;
164 if(global_settings.volume > mpeg_sound_max(SOUND_VOLUME))
165 global_settings.volume = mpeg_sound_max(SOUND_VOLUME);
166 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
167 status_draw(false);
168 settings_save();
169 break;
170
171 case BUTTON_DOWN:
172 case BUTTON_DOWN | BUTTON_REPEAT:
173 case BUTTON_RC_VOL_DOWN:
174 global_settings.volume--;
175 if(global_settings.volume < mpeg_sound_min(SOUND_VOLUME))
176 global_settings.volume = mpeg_sound_min(SOUND_VOLUME);
177 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
178 status_draw(false);
179 settings_save();
180 break;
181
182 case BUTTON_NONE:
183 status_draw(true);
184 break;
185 }
186 }
187 return false;
188}
189#endif
diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h
new file mode 100644
index 0000000000..dafa46d90d
--- /dev/null
+++ b/apps/recorder/radio.h
@@ -0,0 +1,26 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef RADIO_H
20#define RADIO_H
21
22#ifdef HAVE_FMRADIO
23bool radio_screen(void);
24#endif
25
26#endif
diff --git a/firmware/drivers/fmradio.c b/firmware/drivers/fmradio.c
new file mode 100644
index 0000000000..0d947f4480
--- /dev/null
+++ b/firmware/drivers/fmradio.c
@@ -0,0 +1,133 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "lcd.h"
20#include "sh7034.h"
21#include "kernel.h"
22#include "thread.h"
23#include "debug.h"
24
25#ifdef HAVE_FMRADIO
26
27/* Signals:
28 DI (Data In) - PB0 (doubles as data pin for the LCD)
29 CL (Clock) - PB1 (doubles as clock for the LCD)
30 CE (Chip Enable) - PB3 (also chip select for the LCD, but active low)
31 DO (Data Out) - PB4
32*/
33
34#define PB0 0x0001
35#define PB1 0x0002
36#define PB3 0x0008
37#define PB4 0x0010
38
39/* cute little functions */
40#define CE_LO (PBDR &= ~PB3)
41#define CE_HI (PBDR |= PB3)
42#define CL_LO (PBDR &= ~PB1)
43#define CL_HI (PBDR |= PB1)
44#define DO (PBDR & PB4)
45#define DI_LO (PBDR &= ~PB0)
46#define DI_HI (PBDR |= PB0)
47
48#define START (PBDR |= (PB3 | PB1))
49
50/* delay loop */
51#define DELAY do { int _x; for(_x=0;_x<10;_x++);} while (0)
52
53static struct mutex fmradio_mtx;
54
55void fmradio_begin(void)
56{
57 mutex_lock(&fmradio_mtx);
58}
59
60void fmradio_end(void)
61{
62 mutex_unlock(&fmradio_mtx);
63}
64
65int fmradio_read(int addr)
66{
67 int i;
68 int data = 0;
69
70 START;
71
72 /* First address bit */
73 CL_LO;
74 if(addr & 2)
75 DI_HI;
76 else
77 DI_LO;
78 DELAY;
79 CL_HI;
80 DELAY;
81
82 /* Second address bit */
83 CL_LO;
84 if(addr & 1)
85 DI_HI;
86 else
87 DI_LO;
88 DELAY;
89 CL_HI;
90 DELAY;
91
92 for(i = 0; i < 21;i++)
93 {
94 CL_LO;
95 DELAY;
96 data <<= 1;
97 data |= (DO)?1:0;
98 CL_HI;
99 DELAY;
100 }
101
102 CE_LO;
103
104 return data;
105}
106
107void fmradio_set(int addr, int data)
108{
109 int i;
110
111 /* Include the address in the data */
112 data |= addr << 21;
113
114 START;
115
116 for(i = 0; i < 23;i++)
117 {
118 CL_LO;
119 DELAY;
120 if(data & (1 << 22))
121 DI_HI;
122 else
123 DI_LO;
124
125 data <<= 1;
126 CL_HI;
127 DELAY;
128 }
129
130 CE_LO;
131}
132
133#endif
diff --git a/firmware/export/config-fmrecorder.h b/firmware/export/config-fmrecorder.h
index 36b304c46d..63a6ece95b 100644
--- a/firmware/export/config-fmrecorder.h
+++ b/firmware/export/config-fmrecorder.h
@@ -39,3 +39,7 @@
39 39
40/* FM recorders can wake up from RTC alarm */ 40/* FM recorders can wake up from RTC alarm */
41#define HAVE_ALARM_MOD 1 41#define HAVE_ALARM_MOD 1
42
43/* Define this if you have an FM Radio */
44#define HAVE_FMRADIO 1
45
diff --git a/firmware/export/fmradio.h b/firmware/export/fmradio.h
new file mode 100644
index 0000000000..2877501361
--- /dev/null
+++ b/firmware/export/fmradio.h
@@ -0,0 +1,25 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef FMRADIO_H
20#define FMRADIO_H
21
22extern int fmradio_read(int addr);
23extern void fmradio_set(int addr, int data);
24
25#endif