diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2003-05-03 02:40:09 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2003-05-03 02:40:09 +0000 |
commit | 331c7d9255e7873d3583aceea6bd00c7360f2366 (patch) | |
tree | d0dfb9e1eb62e8e96ef14e01b013179118c6c6f1 | |
parent | 86704740792ae81add713f4f4b619c57fee79e47 (diff) | |
download | rockbox-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.c | 6 | ||||
-rw-r--r-- | apps/recorder/radio.c | 189 | ||||
-rw-r--r-- | apps/recorder/radio.h | 26 | ||||
-rw-r--r-- | firmware/drivers/fmradio.c | 133 | ||||
-rw-r--r-- | firmware/export/config-fmrecorder.h | 4 | ||||
-rw-r--r-- | firmware/export/fmradio.h | 25 |
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 | |||
38 | static int curr_freq = 99400000; | ||
39 | static int pll_cnt; | ||
40 | |||
41 | void 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 | |||
57 | bool 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 | ||
23 | bool 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 | |||
53 | static struct mutex fmradio_mtx; | ||
54 | |||
55 | void fmradio_begin(void) | ||
56 | { | ||
57 | mutex_lock(&fmradio_mtx); | ||
58 | } | ||
59 | |||
60 | void fmradio_end(void) | ||
61 | { | ||
62 | mutex_unlock(&fmradio_mtx); | ||
63 | } | ||
64 | |||
65 | int 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 | |||
107 | void 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 | |||
22 | extern int fmradio_read(int addr); | ||
23 | extern void fmradio_set(int addr, int data); | ||
24 | |||
25 | #endif | ||