diff options
author | Laurent Gautier <creposucre@rockbox.org> | 2009-12-01 17:54:40 +0000 |
---|---|---|
committer | Laurent Gautier <creposucre@rockbox.org> | 2009-12-01 17:54:40 +0000 |
commit | 0260852771aef7a6e9045684f0c3d0d7e01909f7 (patch) | |
tree | 6fa4b42230d1289857f84405defad94cc2de86b8 /apps | |
parent | 63d79148fd07aebd2b425c0414b7b9622b312399 (diff) | |
download | rockbox-0260852771aef7a6e9045684f0c3d0d7e01909f7.tar.gz rockbox-0260852771aef7a6e9045684f0c3d0d7e01909f7.zip |
Add support for the ipod FM remote to the 4G, Color, 5G, nano 1G with RDS
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23805 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/iap.c | 208 | ||||
-rw-r--r-- | apps/keymaps/keymap-ipod.c | 52 | ||||
-rw-r--r-- | apps/recorder/radio.c | 63 |
3 files changed, 282 insertions, 41 deletions
diff --git a/apps/iap.c b/apps/iap.c index 29cee22ab5..741ff9fb0c 100644 --- a/apps/iap.c +++ b/apps/iap.c | |||
@@ -37,11 +37,12 @@ | |||
37 | #include "settings.h" | 37 | #include "settings.h" |
38 | #include "metadata.h" | 38 | #include "metadata.h" |
39 | #include "wps.h" | 39 | #include "wps.h" |
40 | 40 | #include "sound.h" | |
41 | #include "action.h" | 41 | #include "action.h" |
42 | #include "powermgmt.h" | ||
42 | 43 | ||
43 | #define RX_BUFLEN 260 | 44 | #include "tuner.h" |
44 | #define TX_BUFLEN 128 | 45 | #include "ipod_remote_tuner.h" |
45 | 46 | ||
46 | static volatile int iap_pollspeed = 0; | 47 | static volatile int iap_pollspeed = 0; |
47 | static volatile bool iap_remotetick = true; | 48 | static volatile bool iap_remotetick = true; |
@@ -115,7 +116,7 @@ void iap_bitrate_set(int ratenum) | |||
115 | checksum (length+mode+parameters+checksum == 0) | 116 | checksum (length+mode+parameters+checksum == 0) |
116 | */ | 117 | */ |
117 | 118 | ||
118 | static void iap_send_pkt(const unsigned char * data, int len) | 119 | void iap_send_pkt(const unsigned char * data, int len) |
119 | { | 120 | { |
120 | int i, chksum; | 121 | int i, chksum; |
121 | 122 | ||
@@ -192,15 +193,15 @@ void iap_periodic(void) | |||
192 | unsigned long time_elapsed = audio_current_track()->elapsed; | 193 | unsigned long time_elapsed = audio_current_track()->elapsed; |
193 | 194 | ||
194 | time_elapsed += wps_get_ff_rewind_count(); | 195 | time_elapsed += wps_get_ff_rewind_count(); |
195 | 196 | ||
196 | data[3] = 0x04; // playing | 197 | data[3] = 0x04; /* playing */ |
197 | 198 | ||
198 | /* If info has changed, don't flag it right away */ | 199 | /* If info has changed, don't flag it right away */ |
199 | if(iap_changedctr && iap_changedctr++ >= iap_pollspeed * 2) | 200 | if(iap_changedctr && iap_changedctr++ >= iap_pollspeed * 2) |
200 | { | 201 | { |
201 | /* track info has changed */ | 202 | /* track info has changed */ |
202 | iap_changedctr = 0; | 203 | iap_changedctr = 0; |
203 | data[3] = 0x01; // 0x02 has same effect? | 204 | data[3] = 0x01; /* 0x02 has same effect? */ |
204 | iap_updateflag = true; | 205 | iap_updateflag = true; |
205 | } | 206 | } |
206 | 207 | ||
@@ -211,12 +212,19 @@ void iap_periodic(void) | |||
211 | iap_send_pkt(data, sizeof(data)); | 212 | iap_send_pkt(data, sizeof(data)); |
212 | } | 213 | } |
213 | 214 | ||
215 | void iap_set_remote_volume(void) | ||
216 | { | ||
217 | unsigned char data[] = {0x03, 0x0D, 0x04, 0x00, 0x00}; | ||
218 | data[4] = (char)((global_settings.volume+58) * 4); | ||
219 | iap_send_pkt(data, sizeof(data)); | ||
220 | } | ||
221 | |||
214 | void iap_handlepkt(void) | 222 | void iap_handlepkt(void) |
215 | { | 223 | { |
216 | 224 | ||
217 | if(!iap_setupflag) return; | 225 | if(!iap_setupflag) return; |
218 | if(serbuf[0] == 0) return; | 226 | if(serbuf[0] == 0) return; |
219 | 227 | ||
220 | /* if we are waiting for a remote button to go out, | 228 | /* if we are waiting for a remote button to go out, |
221 | delay the handling of the new packet */ | 229 | delay the handling of the new packet */ |
222 | if(!iap_remotetick) | 230 | if(!iap_remotetick) |
@@ -224,63 +232,140 @@ void iap_handlepkt(void) | |||
224 | queue_post(&button_queue, SYS_IAP_HANDLEPKT, 0); | 232 | queue_post(&button_queue, SYS_IAP_HANDLEPKT, 0); |
225 | return; | 233 | return; |
226 | } | 234 | } |
227 | 235 | ||
228 | /* Handle Mode 0 */ | 236 | /* Handle Mode 0 */ |
229 | if (serbuf[1] == 0x00) | 237 | if (serbuf[1] == 0x00) |
230 | { | 238 | { |
231 | switch (serbuf[2]) | 239 | switch (serbuf[2]) |
232 | { | 240 | { |
233 | /* get model info */ | 241 | case 0x24: |
234 | case 0x0D: | ||
235 | { | 242 | { |
236 | unsigned char data[] = {0x00, 0x0E, 0x00, 0x0B, 0x00, 0x10, | 243 | /* ipod video send this */ |
237 | 'R', 'O', 'C', 'K', 'B', 'O', 'X', 0x00}; | 244 | unsigned char data[] = {0x00, 0x25, 0x00, 0x00, 0x00, |
245 | 0x00, 0x00, 0x00, 0x00,0x01}; | ||
238 | iap_send_pkt(data, sizeof(data)); | 246 | iap_send_pkt(data, sizeof(data)); |
239 | break; | 247 | break; |
240 | } | 248 | } |
241 | /* No idea ??? */ | 249 | |
242 | case 0x0F: | 250 | case 0x18: |
243 | { | 251 | { |
244 | unsigned char data[] = {0x00, 0x10, 0x00, 0x01, 0x05}; | 252 | /* ciphered authentication command */ |
245 | iap_send_pkt(data, sizeof(data)); | 253 | /* Isn't used since we don't send the 0x00 0x17 command */ |
246 | break; | 254 | break; |
247 | } | 255 | } |
248 | /* FM transmitter sends this: FF 55 06 00 01 05 00 02 01 F1 (mode switch) */ | 256 | |
249 | case 0x01: | 257 | case 0x15: |
250 | { | 258 | { |
251 | if(serbuf[3] == 0x05) | 259 | unsigned char data0[] = {0x00, 0x16, 0x00}; |
260 | iap_send_pkt(data0, sizeof(data0)); | ||
261 | unsigned char data1[] = {0x00, 0x27, 0x00}; | ||
262 | iap_send_pkt(data1, sizeof(data1)); | ||
263 | /* authentication ack, mandatory to enable some hardware */ | ||
264 | unsigned char data2[] = {0x00, 0x19, 0x00}; | ||
265 | iap_send_pkt(data2, sizeof(data2)); | ||
266 | if (radio_present == 1) | ||
252 | { | 267 | { |
253 | sleep(HZ/3); | 268 | /* get tuner capacities */ |
254 | unsigned char data[] = {0x05, 0x02}; | 269 | unsigned char data3[] = {0x07, 0x01}; |
255 | iap_send_pkt(data, sizeof(data)); | 270 | iap_send_pkt(data3, sizeof(data3)); |
256 | } | 271 | } |
272 | iap_set_remote_volume(); | ||
257 | break; | 273 | break; |
258 | } | 274 | } |
259 | /* FM transmitter sends this: FF 55 0E 00 13 00 00 00 35 00 00 00 04 00 00 00 00 A6 (???)*/ | 275 | |
260 | case 0x13: | 276 | case 0x13: |
261 | { | 277 | { |
262 | unsigned char data[] = {0x00, 0x02, 0x00, 0x13}; | 278 | unsigned char data[] = {0x00, 0x02, 0x00, 0x13}; |
263 | iap_send_pkt(data, sizeof(data)); | 279 | iap_send_pkt(data, sizeof(data)); |
264 | unsigned char data2[] = {0x00, 0x27, 0x00}; | 280 | |
265 | iap_send_pkt(data2, sizeof(data2)); | 281 | if (serbuf[6] == 0x35) |
266 | unsigned char data3[] = {0x05, 0x02}; | 282 | /* FM transmitter sends this: */ |
267 | iap_send_pkt(data3, sizeof(data3)); | 283 | /* FF 55 0E 00 13 00 00 00 35 00 00 00 04 00 00 00 00 A6 (??)*/ |
284 | { | ||
285 | unsigned char data2[] = {0x00, 0x27, 0x00}; | ||
286 | iap_send_pkt(data2, sizeof(data2)); | ||
287 | unsigned char data3[] = {0x05, 0x02}; | ||
288 | iap_send_pkt(data3, sizeof(data3)); | ||
289 | } | ||
290 | |||
291 | else | ||
292 | { | ||
293 | /* ipod fm remote sends this: */ | ||
294 | /* FF 55 0E 00 13 00 00 00 8D 00 00 00 0E 00 00 00 03 41 */ | ||
295 | if (serbuf[6] |= 0x80) | ||
296 | radio_present = 1; | ||
297 | unsigned char data4[] = {0x00, 0x14}; | ||
298 | iap_send_pkt(data4, sizeof(data4)); | ||
299 | } | ||
268 | break; | 300 | break; |
269 | } | 301 | } |
270 | /* FM transmitter sends this: FF 55 02 00 05 F9 (mode switch: AiR mode) */ | 302 | |
303 | /* Init */ | ||
304 | case 0x0F: | ||
305 | { | ||
306 | unsigned char data[] = {0x00, 0x10, 0x00, 0x01, 0x05}; | ||
307 | data[2] = serbuf[3]; | ||
308 | iap_send_pkt(data, sizeof(data)); | ||
309 | break; | ||
310 | } | ||
311 | |||
312 | /* get model info */ | ||
313 | case 0x0D: | ||
314 | { | ||
315 | /* ipod is supposed to work only with 5G and nano 2G */ | ||
316 | /*{0x00, 0x0E, 0x00, 0x0B, 0x00, 0x05, 0x50, 0x41, 0x31, 0x34, | ||
317 | 0x37, 0x4C, 0x4C, 0x00}; PA147LL (IPOD 5G 60 GO) */ | ||
318 | unsigned char data[] = {0x00, 0x0E, 0x00, 0x0B, 0x00, 0x10, | ||
319 | 'R', 'O', 'C', 'K', 'B', 'O', 'X', 0x00}; | ||
320 | iap_send_pkt(data, sizeof(data)); | ||
321 | break; | ||
322 | } | ||
323 | |||
324 | /* Ipod FM remote sends this: FF 55 02 00 09 F5 */ | ||
325 | case 0x09: | ||
326 | { | ||
327 | /* ipod5G firmware version */ | ||
328 | unsigned char data[] = {0x00, 0x0A, 0x01, 0x02, 0x01 }; | ||
329 | iap_send_pkt(data, sizeof(data)); | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | /* FM transmitter sends this: */ | ||
334 | /* FF 55 02 00 05 F9 (mode switch: AiR mode) */ | ||
271 | case 0x05: | 335 | case 0x05: |
272 | { | 336 | { |
273 | unsigned char data[] = {0x00, 0x02, 0x06, 0x05, 0x00, 0x00, 0x0B, 0xB8, 0x28}; | 337 | unsigned char data[] = {0x00, 0x02, 0x06, |
338 | 0x05, 0x00, 0x00, 0x0B, 0xB8, 0x28}; | ||
274 | iap_send_pkt(data, sizeof(data)); | 339 | iap_send_pkt(data, sizeof(data)); |
275 | unsigned char data2[] = {0x00, 0x02, 0x00, 0x05}; | 340 | unsigned char data2[] = {0x00, 0x02, 0x00, 0x05}; |
276 | iap_send_pkt(data2, sizeof(data2)); | 341 | iap_send_pkt(data2, sizeof(data2)); |
277 | break; | 342 | break; |
278 | } | 343 | } |
344 | |||
345 | case 0x01: | ||
346 | { | ||
347 | /* FM transmitter sends this: */ | ||
348 | /* FF 55 06 00 01 05 00 02 01 F1 (mode switch) */ | ||
349 | if(serbuf[3] == 0x05) | ||
350 | { | ||
351 | sleep(HZ/3); | ||
352 | unsigned char data[] = {0x05, 0x02}; | ||
353 | iap_send_pkt(data, sizeof(data)); | ||
354 | } | ||
355 | /* FM remote sends this: */ | ||
356 | /* FF 55 03 00 01 02 FA (1st thing sent) */ | ||
357 | else if(serbuf[3] == 0x02) | ||
358 | { | ||
359 | /* useful only for apple firmware */ | ||
360 | } | ||
361 | break; | ||
362 | } | ||
363 | |||
279 | /* default response is with cmd ok packet */ | 364 | /* default response is with cmd ok packet */ |
280 | default: | 365 | default: |
281 | { | 366 | { |
282 | unsigned char data[] = {0x00, 0x02, 0x00, 0x00}; | 367 | unsigned char data[] = {0x00, 0x02, 0x00, 0x00}; |
283 | data[3] = serbuf[2]; //respond with cmd | 368 | data[3] = serbuf[2]; /* respond with cmd */ |
284 | iap_send_pkt(data, sizeof(data)); | 369 | iap_send_pkt(data, sizeof(data)); |
285 | break; | 370 | break; |
286 | } | 371 | } |
@@ -395,6 +480,30 @@ void iap_handlepkt(void) | |||
395 | iap_send_pkt(data, sizeof(data)); | 480 | iap_send_pkt(data, sizeof(data)); |
396 | break; | 481 | break; |
397 | } | 482 | } |
483 | |||
484 | case 0x08: | ||
485 | { | ||
486 | /* ACK */ | ||
487 | unsigned char data[] = {0x03, 0x00, 0x00, 0x08}; | ||
488 | iap_send_pkt(data, sizeof(data)); | ||
489 | break; | ||
490 | } | ||
491 | |||
492 | case 0x0C: | ||
493 | { | ||
494 | /* request ipod volume */ | ||
495 | if (serbuf[3] == 0x04) | ||
496 | { | ||
497 | iap_set_remote_volume(); | ||
498 | } | ||
499 | break; | ||
500 | } | ||
501 | /* get volume from accessory */ | ||
502 | case 0x0E: | ||
503 | if (serbuf[3] == 0x04) | ||
504 | global_settings.volume = (-58)+((int)serbuf[5]+1)/4; | ||
505 | sound_set_volume(global_settings.volume); | ||
506 | break; | ||
398 | } | 507 | } |
399 | } | 508 | } |
400 | /* Handle Mode 4 */ | 509 | /* Handle Mode 4 */ |
@@ -712,6 +821,37 @@ void iap_handlepkt(void) | |||
712 | } | 821 | } |
713 | } | 822 | } |
714 | } | 823 | } |
824 | /* Handle Mode 7 */ | ||
825 | else if (serbuf[1] == 0x07) | ||
826 | { | ||
827 | switch(serbuf[2]) | ||
828 | { | ||
829 | /* tuner capabilities */ | ||
830 | case 0x02: | ||
831 | { | ||
832 | /* do nothing */ | ||
833 | |||
834 | unsigned char data[] = {0x00, 0x27, 0x00}; | ||
835 | iap_send_pkt(data, sizeof(data)); | ||
836 | break; | ||
837 | } | ||
838 | /* actual tuner frequency */ | ||
839 | case 0x0A: | ||
840 | /* fall through */ | ||
841 | /* tuner frequency from scan */ | ||
842 | case 0x13: | ||
843 | { | ||
844 | rmt_tuner_freq(); | ||
845 | break; | ||
846 | } | ||
847 | /* RDS station name 0x21 1E 00 + ASCII text*/ | ||
848 | case 0x21: | ||
849 | { | ||
850 | rmt_tuner_rds_data(); | ||
851 | break; | ||
852 | } | ||
853 | } | ||
854 | } | ||
715 | serbuf[0] = 0; | 855 | serbuf[0] = 0; |
716 | } | 856 | } |
717 | 857 | ||
diff --git a/apps/keymaps/keymap-ipod.c b/apps/keymaps/keymap-ipod.c index 1a8f7a25ff..9b3323bb82 100644 --- a/apps/keymaps/keymap-ipod.c +++ b/apps/keymaps/keymap-ipod.c | |||
@@ -193,6 +193,26 @@ const struct button_mapping button_context_recscreen[] = { | |||
193 | }; /* button_context_recscreen */ | 193 | }; /* button_context_recscreen */ |
194 | #endif | 194 | #endif |
195 | 195 | ||
196 | /** FM Radio Screen **/ | ||
197 | #if CONFIG_TUNER | ||
198 | static const struct button_mapping button_context_radio[] = { | ||
199 | { ACTION_FM_MENU, BUTTON_SELECT | BUTTON_REPEAT, BUTTON_NONE }, | ||
200 | { ACTION_FM_STOP, BUTTON_PLAY | BUTTON_REPEAT, BUTTON_PLAY }, | ||
201 | { ACTION_FM_MODE, BUTTON_SELECT, BUTTON_NONE }, | ||
202 | { ACTION_FM_EXIT, BUTTON_MENU | BUTTON_REL, BUTTON_NONE }, | ||
203 | { ACTION_FM_PLAY, BUTTON_PLAY | BUTTON_REL, BUTTON_PLAY }, | ||
204 | { ACTION_SETTINGS_INC, BUTTON_SCROLL_FWD, BUTTON_NONE }, | ||
205 | { ACTION_SETTINGS_INCREPEAT,BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, | ||
206 | { ACTION_SETTINGS_DEC, BUTTON_SCROLL_BACK, BUTTON_NONE }, | ||
207 | { ACTION_SETTINGS_DECREPEAT,BUTTON_SCROLL_BACK|BUTTON_REPEAT,BUTTON_NONE }, | ||
208 | { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, | ||
209 | { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, | ||
210 | { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE }, | ||
211 | { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, | ||
212 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) | ||
213 | }; /* button_context_radio */ | ||
214 | #endif | ||
215 | |||
196 | #ifdef USB_ENABLE_HID | 216 | #ifdef USB_ENABLE_HID |
197 | static const struct button_mapping button_context_usb_hid[] = { | 217 | static const struct button_mapping button_context_usb_hid[] = { |
198 | { ACTION_USB_HID_MODE_SWITCH_NEXT, BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REL, BUTTON_SELECT|BUTTON_RIGHT }, | 218 | { ACTION_USB_HID_MODE_SWITCH_NEXT, BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REL, BUTTON_SELECT|BUTTON_RIGHT }, |
@@ -311,6 +331,26 @@ static const struct button_mapping remote_button_context_wps[] = { | |||
311 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) | 331 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) |
312 | }; /* remote_button_context_wps */ | 332 | }; /* remote_button_context_wps */ |
313 | 333 | ||
334 | static const struct button_mapping remote_button_context_tree[] = { | ||
335 | { ACTION_TREE_WPS, BUTTON_RC_PLAY|BUTTON_REL, BUTTON_RC_PLAY }, | ||
336 | { ACTION_TREE_STOP, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_RC_PLAY }, | ||
337 | |||
338 | LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) | ||
339 | }; /* remote_button_context_tree */ | ||
340 | |||
341 | #if CONFIG_TUNER | ||
342 | static const struct button_mapping remote_button_context_radio[] = { | ||
343 | { ACTION_FM_STOP, BUTTON_RC_PLAY | BUTTON_REPEAT, BUTTON_NONE }, | ||
344 | { ACTION_FM_PLAY, BUTTON_RC_PLAY | BUTTON_REL, BUTTON_RC_PLAY }, | ||
345 | { ACTION_STD_NEXT, BUTTON_RC_RIGHT|BUTTON_REL, BUTTON_RC_RIGHT }, | ||
346 | { ACTION_STD_NEXTREPEAT, BUTTON_RC_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, | ||
347 | { ACTION_STD_PREV, BUTTON_RC_LEFT|BUTTON_REL, BUTTON_RC_LEFT }, | ||
348 | { ACTION_STD_PREVREPEAT, BUTTON_RC_LEFT|BUTTON_REPEAT, BUTTON_NONE }, | ||
349 | |||
350 | LAST_ITEM_IN_LIST | ||
351 | }; /* remote_button_context_radio */ | ||
352 | #endif | ||
353 | |||
314 | static const struct button_mapping* get_context_mapping_remote( int context ) | 354 | static const struct button_mapping* get_context_mapping_remote( int context ) |
315 | { | 355 | { |
316 | context ^= CONTEXT_REMOTE; | 356 | context ^= CONTEXT_REMOTE; |
@@ -319,6 +359,14 @@ static const struct button_mapping* get_context_mapping_remote( int context ) | |||
319 | { | 359 | { |
320 | case CONTEXT_WPS: | 360 | case CONTEXT_WPS: |
321 | return remote_button_context_wps; | 361 | return remote_button_context_wps; |
362 | case CONTEXT_TREE: | ||
363 | case CONTEXT_CUSTOM|CONTEXT_TREE: | ||
364 | return remote_button_context_tree; | ||
365 | |||
366 | #ifdef CONFIG_TUNER | ||
367 | case CONTEXT_FM: | ||
368 | return remote_button_context_radio; | ||
369 | #endif | ||
322 | default: | 370 | default: |
323 | return remote_button_context_standard; | 371 | return remote_button_context_standard; |
324 | } | 372 | } |
@@ -371,6 +419,10 @@ const struct button_mapping* get_context_mapping(int context) | |||
371 | case CONTEXT_RECSCREEN: | 419 | case CONTEXT_RECSCREEN: |
372 | return button_context_recscreen; | 420 | return button_context_recscreen; |
373 | #endif | 421 | #endif |
422 | #if CONFIG_TUNER | ||
423 | case CONTEXT_FM: | ||
424 | return button_context_radio; | ||
425 | #endif | ||
374 | #ifdef USB_ENABLE_HID | 426 | #ifdef USB_ENABLE_HID |
375 | case CONTEXT_USB_HID: | 427 | case CONTEXT_USB_HID: |
376 | return button_context_usb_hid; | 428 | return button_context_usb_hid; |
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index b70c682922..87614aec15 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c | |||
@@ -49,6 +49,9 @@ | |||
49 | #ifdef HAVE_RECORDING | 49 | #ifdef HAVE_RECORDING |
50 | #include "recording.h" | 50 | #include "recording.h" |
51 | #endif | 51 | #endif |
52 | #ifdef IPOD_ACCESSORY_PROTOCOL | ||
53 | #include "iap.h" | ||
54 | #endif | ||
52 | #include "talk.h" | 55 | #include "talk.h" |
53 | #include "tuner.h" | 56 | #include "tuner.h" |
54 | #include "power.h" | 57 | #include "power.h" |
@@ -114,6 +117,15 @@ | |||
114 | #define FM_MODE | 117 | #define FM_MODE |
115 | #define FM_EXIT | 118 | #define FM_EXIT |
116 | #define FM_PLAY | 119 | #define FM_PLAY |
120 | |||
121 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \ | ||
122 | (CONFIG_KEYPAD == IPOD_1G2G_PAD) | ||
123 | #define FM_MENU | ||
124 | #define FM_STOP | ||
125 | #define FM_EXIT | ||
126 | #define FM_PLAY | ||
127 | #define FM_MODE | ||
128 | |||
117 | #endif | 129 | #endif |
118 | 130 | ||
119 | #define RADIO_SCAN_MODE 0 | 131 | #define RADIO_SCAN_MODE 0 |
@@ -586,7 +598,6 @@ int radio_screen(void) | |||
586 | end_search(); | 598 | end_search(); |
587 | talk = true; | 599 | talk = true; |
588 | } | 600 | } |
589 | |||
590 | trigger_cpu_boost(); | 601 | trigger_cpu_boost(); |
591 | } | 602 | } |
592 | 603 | ||
@@ -873,6 +884,33 @@ int radio_screen(void) | |||
873 | 884 | ||
874 | default: | 885 | default: |
875 | default_event_handler(button); | 886 | default_event_handler(button); |
887 | #ifdef HAVE_RDS_CAP | ||
888 | if (tuner_get(RADIO_EVENT)) | ||
889 | update_screen = true; | ||
890 | #endif | ||
891 | if (!tuner_get(RADIO_PRESENT)) | ||
892 | { | ||
893 | #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) | ||
894 | if(audio_status() == AUDIO_STATUS_RECORD) | ||
895 | audio_stop(); | ||
896 | #endif | ||
897 | keep_playing = false; | ||
898 | done = true; | ||
899 | ret_val = GO_TO_ROOT; | ||
900 | if(presets_changed) | ||
901 | { | ||
902 | if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES))) | ||
903 | { | ||
904 | if(filepreset[0] == '\0') | ||
905 | save_preset_list(); | ||
906 | else | ||
907 | radio_save_presets(); | ||
908 | } | ||
909 | } | ||
910 | |||
911 | /* Clear the preset list on exit. */ | ||
912 | clear_preset_list(); | ||
913 | } | ||
876 | break; | 914 | break; |
877 | } /*switch(button)*/ | 915 | } /*switch(button)*/ |
878 | 916 | ||
@@ -895,11 +933,11 @@ int radio_screen(void) | |||
895 | { | 933 | { |
896 | screens[i].set_viewport(&vp[i]); | 934 | screens[i].set_viewport(&vp[i]); |
897 | peak_meter_screen(&screens[i],0, | 935 | peak_meter_screen(&screens[i],0, |
898 | STATUSBAR_HEIGHT + fh*(top_of_screen + 4), | 936 | STATUSBAR_HEIGHT + fh*(top_of_screen + 4), |
899 | fh); | 937 | fh); |
900 | screens[i].update_rect(0, | 938 | screens[i].update_rect(0, |
901 | STATUSBAR_HEIGHT + fh*(top_of_screen + 4), | 939 | STATUSBAR_HEIGHT + fh*(top_of_screen + 4), |
902 | screens[i].getwidth(), fh); | 940 | screens[i].getwidth(), fh); |
903 | screens[i].set_viewport(NULL); | 941 | screens[i].set_viewport(NULL); |
904 | } | 942 | } |
905 | } | 943 | } |
@@ -963,7 +1001,18 @@ int radio_screen(void) | |||
963 | str(LANG_RADIO_SCAN_MODE)); | 1001 | str(LANG_RADIO_SCAN_MODE)); |
964 | FOR_NB_SCREENS(i) | 1002 | FOR_NB_SCREENS(i) |
965 | screens[i].puts_scroll(0, top_of_screen + 3, buf); | 1003 | screens[i].puts_scroll(0, top_of_screen + 3, buf); |
1004 | #ifndef SIMULATOR | ||
1005 | #ifdef HAVE_RDS_CAP | ||
1006 | snprintf(buf, 128, "%s",tuner_get_rds_info(RADIO_RDS_NAME)); | ||
1007 | FOR_NB_SCREENS(i) | ||
1008 | screens[i].puts_scroll(0, top_of_screen + 4, buf); | ||
966 | 1009 | ||
1010 | snprintf(buf, 128, "%s",tuner_get_rds_info(RADIO_RDS_TEXT)); | ||
1011 | FOR_NB_SCREENS(i) | ||
1012 | screens[i].puts_scroll(0, top_of_screen + 5, buf); | ||
1013 | #endif | ||
1014 | #endif /* SIMULATOR */ | ||
1015 | |||
967 | #if CONFIG_CODEC != SWCODEC | 1016 | #if CONFIG_CODEC != SWCODEC |
968 | if(audio_status() == AUDIO_STATUS_RECORD) | 1017 | if(audio_status() == AUDIO_STATUS_RECORD) |
969 | { | 1018 | { |
@@ -1498,6 +1547,7 @@ static int scan_presets(void *viewports) | |||
1498 | curr_freq = fmr->freq_min; | 1547 | curr_freq = fmr->freq_min; |
1499 | num_presets = 0; | 1548 | num_presets = 0; |
1500 | memset(presets, 0, sizeof(presets)); | 1549 | memset(presets, 0, sizeof(presets)); |
1550 | |||
1501 | tuner_set(RADIO_MUTE, 1); | 1551 | tuner_set(RADIO_MUTE, 1); |
1502 | 1552 | ||
1503 | while(curr_freq <= fmr->freq_max) | 1553 | while(curr_freq <= fmr->freq_max) |
@@ -1563,7 +1613,6 @@ static int fm_recording_screen(void) | |||
1563 | /* switch recording source to FMRADIO for the duration */ | 1613 | /* switch recording source to FMRADIO for the duration */ |
1564 | int rec_source = global_settings.rec_source; | 1614 | int rec_source = global_settings.rec_source; |
1565 | global_settings.rec_source = AUDIO_SRC_FMRADIO; | 1615 | global_settings.rec_source = AUDIO_SRC_FMRADIO; |
1566 | |||
1567 | ret = recording_screen(true); | 1616 | ret = recording_screen(true); |
1568 | 1617 | ||
1569 | /* safe to reset as changing sources is prohibited here */ | 1618 | /* safe to reset as changing sources is prohibited here */ |
@@ -1649,7 +1698,7 @@ MAKE_MENU(radio_settings_menu, ID2P(LANG_FM_MENU), NULL, | |||
1649 | static bool radio_menu(void) | 1698 | static bool radio_menu(void) |
1650 | { | 1699 | { |
1651 | return do_menu(&radio_settings_menu, NULL, NULL, false) == | 1700 | return do_menu(&radio_settings_menu, NULL, NULL, false) == |
1652 | MENU_ATTACHED_USB; | 1701 | MENU_ATTACHED_USB; |
1653 | } | 1702 | } |
1654 | 1703 | ||
1655 | #endif | 1704 | #endif |