1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * tuner for the ipod fm remote and other ipod remote tuners
11 * Copyright (C) 2009 Laurent Gautier
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
29 #include "tuner.h" /* tuner abstraction interface */
34 static bool powered
= false;
36 static unsigned char tuner_param
= 0x00, old_tuner_param
= 0xFF;
37 /* temp var for tests to avoid looping execution in submenus settings*/
38 int mono_mode
= -1, old_region
= -1;
40 int radio_present
= 0;
41 int tuner_frequency
= 0;
42 int tuner_signal_power
= 0;
46 char rds_radioname
[9];
47 char rds_radioinfo
[65];
50 unsigned long int frequency_radio
;
51 char data_frequency
[4];
54 void rmt_tuner_freq(void)
57 tempdata
[0] = serbuf
[6];
58 tempdata
[1] = serbuf
[5];
59 tempdata
[2] = serbuf
[4];
60 tempdata
[3] = serbuf
[3];
62 memcpy(Frequency
.data_frequency
,tempdata
,4);
63 tuner_frequency
= (Frequency
.frequency_radio
*1000);
65 rmt_tuner_signal_power(serbuf
[7]);
68 void rmt_tuner_set_freq(int curr_freq
)
70 if (curr_freq
!= tuner_frequency
)
73 tuner_signal_power
= 0;
74 /* clear rds name and info */
75 memset(rds_radioname
,' ',sizeof(rds_radioname
));
76 memset(rds_radioinfo
,' ',sizeof(rds_radioinfo
));
77 /* ex: 00 01 63 14 = 90.9MHz */
78 unsigned char data
[] = {0x07, 0x0B, 0x00, 0x01, 0x63, 0x14};
82 curr_freq
= curr_freq
/ 1000;
85 Frequency
.frequency_radio
= curr_freq
;
86 tempdata
[0] = Frequency
.data_frequency
[3];
87 tempdata
[1] = Frequency
.data_frequency
[2];
88 tempdata
[2] = Frequency
.data_frequency
[1];
89 tempdata
[3] = Frequency
.data_frequency
[0];
91 memcpy(data
+2,tempdata
,4);
92 iap_send_pkt(data
, sizeof(data
));
97 void rmt_tuner_signal_power(unsigned char value
)
99 tuner_signal_power
= (int)(value
);
102 void rmt_tuner_sleep(int state
)
107 old_tuner_param
= 0xFF;
114 unsigned char data
[] = {0x07, 0x05, 0x01};
115 iap_send_pkt(data
, sizeof(data
));
117 unsigned char data1
[] = {0x07, 0x24, 0x06 };
118 iap_send_pkt(data1
, sizeof(data1
));
120 unsigned char data2
[] = {0x03, 0x09, 0x04, 0x00, 0x00 };
121 data2
[4] = (char)((global_settings
.volume
+58) * 4);
122 iap_send_pkt(data2
, sizeof(data2
));
124 unsigned char data3
[] = {0x07, 0x20, 0x40, 0x00, 0x00, 0x10 };
125 iap_send_pkt(data3
, sizeof(data3
));
130 unsigned char data
[] = {0x07, 0x24, 0x00};
131 iap_send_pkt(data
, sizeof(data
));
133 unsigned char data1
[] = {0x07, 0x20, 0x00, 0x00, 0x00, 0x00 };
134 iap_send_pkt(data1
, sizeof(data1
));
136 unsigned char data2
[] = {0x07, 0x05, 0x00};
137 iap_send_pkt(data2
, sizeof(data2
));
141 void rmt_tuner_scan(int param
)
143 unsigned char data
[] = {0x07, 0x11, 0x08}; /* RSSI level */
144 unsigned char updown
= 0x00;
146 iap_send_pkt(data
, sizeof(data
));
150 updown
= 0x07; /* scan up */
152 else if (param
== -1)
154 updown
= 0x08; /* scan down */
156 else if (param
== 10)
158 updown
= 0x01; /* scan up starting from beginning of the band */
160 unsigned char data1
[] = {0x07, 0x12, updown
};
161 iap_send_pkt(data1
, sizeof(data1
));
164 void rmt_tuner_mute(int value
)
166 /* mute flag off (play) */
167 unsigned char data
[] = {0x03, 0x09, 0x03, 0x01};
170 /* mute flag on (pause) */
173 iap_send_pkt(data
, sizeof(data
));
176 void rmt_tuner_region(int region
)
178 if (region
!= old_region
)
180 unsigned char data
[] = {0x07, 0x08, 0x00};
183 data
[2] = 0x02; /* japan band */
187 data
[2] = 0x01; /* us eur band */
189 iap_send_pkt(data
, sizeof(data
));
195 /* set stereo/mono, deemphasis, delta freq... */
196 void rmt_tuner_set_param(unsigned char tuner_param
)
198 if(tuner_param
!= old_tuner_param
)
200 unsigned char data
[] = {0x07, 0x0E, 0x00};
202 data
[2] = tuner_param
;
203 iap_send_pkt(data
, sizeof(data
));
204 old_tuner_param
= tuner_param
;
208 static void set_deltafreq(int delta
)
235 static void set_deemphasis(int deemphasis
)
253 static void set_mono(int value
)
257 if (value
!= mono_mode
)
262 rmt_tuner_set_param(tuner_param
);
268 static bool reply_timeout(void)
279 while((ipod_rmt_tuner_get(RADIO_TUNED
) == 0) && (timeout
< TIMEOUT_VALUE
));
281 if (timeout
>= TIMEOUT_VALUE
)
286 void rmt_tuner_rds_data(void)
288 if (serbuf
[3] == 0x1E)
290 strlcpy(rds_radioname
,serbuf
+5,8);
292 else if(serbuf
[3] == 0x04)
294 strlcpy(rds_radioinfo
,serbuf
+5,(serbuf
[0]-4));
299 /* tuner abstraction layer: set something to the tuner */
300 int ipod_rmt_tuner_set(int setting
, int value
)
306 rmt_tuner_sleep(value
);
315 case RADIO_FREQUENCY
:
317 rmt_tuner_set_freq(value
);
323 case RADIO_SCAN_FREQUENCY
:
325 const struct fm_region_data
* const fmr
=
326 &fm_region_data
[global_settings
.fm_region
];
328 /* case: scan for presets, back to beginning of the band */
329 if ((radio_tuned
== 1) && (value
== fmr
->freq_min
))
331 tuner_set(RADIO_FREQUENCY
,value
);
334 /* scan through frequencies */
335 if (radio_tuned
== 1)
337 if ((tuner_frequency
<= fmr
->freq_min
)
338 && (tuner_frequency
>= fmr
->freq_max
))
340 tuner_set(RADIO_FREQUENCY
,value
);
343 if(value
< tuner_frequency
)
352 tuner_set(RADIO_FREQUENCY
,value
);
354 if (reply_timeout() == true)
360 if (tuner_frequency
== value
)
374 /* mute flag sent to accessory */
375 /* rmt_tuner_mute(value); */
381 const struct rmt_tuner_region_data
*rd
=
382 &rmt_tuner_region_data
[value
];
384 rmt_tuner_region(rd
->band
);
385 set_deltafreq(rd
->spacing
);
386 set_deemphasis(rd
->deemphasis
);
387 rmt_tuner_set_param(tuner_param
);
391 case RADIO_FORCE_MONO
:
403 /* tuner abstraction layer: read something from the tuner */
404 int ipod_rmt_tuner_get(int setting
)
406 int val
= -1; /* default for unsupported query */
414 /* if accessory disconnected */
415 if(adc_read(ADC_ACCESSORY
) >= 10)
423 /* radio tuned: yes no */
426 if (radio_tuned
== 1)
430 /* radio is always stereo */
431 /* we can't know when it's in mono mode, depending of signal quality */
432 /* except if it is forced in mono mode */
448 char* ipod_get_rds_info(int setting
)
455 text
= rds_radioname
;
459 text
= rds_radioinfo
;
465 bool tuner_power(bool status
)
467 bool oldstatus
= powered
;