3 * RADIO CHIP AKC6955 Handler
4 * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
11 * This library / program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this library; see the file COPYING. If not, write to the
18 * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
21 * As a special exception, if you link this(includeed from sdcc) library
22 * with other files, some of which are compiled with SDCC,
23 * to produce an executable, this library does not by itself cause
24 * the resulting executable to be covered by the GNU General Public License.
25 * This exception does not however invalidate any other reasons why
26 * the executable file might be covered by the GNU General Public License.
38 void akc6955_writecmd(unsigned char reg, unsigned char data)
42 i2c_writechar(AKC6955_ADDRESS);
48 unsigned char akc6955_readcmd(unsigned char reg)
53 i2c_writechar(AKC6955_ADDRESS);
61 void akc6955_chg_fm(unsigned char fm)
64 b = akc6955_readcmd(AKC6955_POWER);
70 akc6955_writecmd(AKC6955_POWER, b);
73 void akc6955_set_amband(unsigned char band)
76 b = akc6955_readcmd(AKC6955_BAND);
77 b &= 0x07; // extract FM
78 b = b | ((band & 0x1f) << 3);
79 akc6955_writecmd(AKC6955_BAND, b);
82 void akc6955_set_fmband(unsigned char band)
85 b = akc6955_readcmd(AKC6955_BAND);
86 b &= 0xf8; // extract AM
87 b = b | (band & 0x07);
88 akc6955_writecmd(AKC6955_BAND, b);
91 unsigned char akc6955_get_amband(void)
94 b = akc6955_readcmd(AKC6955_BAND);
99 unsigned char akc6955_get_fmband(void)
102 b = akc6955_readcmd(AKC6955_BAND);
107 void akc6955_set_power(unsigned char on)
110 b = akc6955_readcmd(AKC6955_POWER);
116 akc6955_writecmd(AKC6955_POWER, b);
119 void akc6955_do_tune(void)
122 b = akc6955_readcmd(AKC6955_POWER);
123 b &= 0xdf; // Tun = '0'
124 akc6955_writecmd(AKC6955_POWER, b);
126 b |= 0x20; // Tun = '1'
127 akc6955_writecmd(AKC6955_POWER, b);
130 unsigned char akc6955_tune(void)
133 b = akc6955_readcmd(AKC6955_RCH_HI) & 0x20;
141 unsigned int akc6955_mode3k(unsigned char flag)
144 b = akc6955_readcmd(AKC6955_CH_HI);
150 akc6955_writecmd(AKC6955_CH_HI, b);
151 // akc6955_do_tune();
152 _AKC6955_WAIT_62_5MS();
153 return akc6955_get_freq();
156 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
164 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
167 band = akc6955_get_amband();
175 if(i > 0x1fff) i = 0x1fff;
179 b = ((i >> 8) & 0x1f) | 0x40; // 32.768KHz clock
181 b = ((i >> 8) & 0x1f) | 0x60;
183 akc6955_writecmd(AKC6955_CH_HI, b);
185 akc6955_writecmd(AKC6955_CH_LO, b);
188 // Use software-delay, but recommands hardware-delay ;-(
189 _AKC6955_WAIT_12_5MS();
190 } while(akc6955_tune() == 0);
193 void akc6955_do_scan(unsigned char up)
197 b = akc6955_readcmd(AKC6955_POWER);
202 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
204 akc6955_writecmd(AKC6955_POWER, b); // Raise seek bit to '1'.
207 void akc6955_abort_scan(void)
210 b = akc6955_readcmd(AKC6955_POWER);
212 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
215 unsigned char akc6955_chk_donescan(void)
218 b = akc6955_readcmd(AKC6955_RCH_HI) & 0x40;
225 * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
227 unsigned int akc6955_get_freq(void)
229 unsigned char b, h, l;
232 b = akc6955_readcmd(AKC6955_CNR_AM) & 0x80;
233 l = akc6955_readcmd(AKC6955_RCH_LO) ;
234 h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
235 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
237 if(fm != 0){ // 25KHz
238 i = i * 10; // 25 / 10 = 10/4
241 } else if(b == 0){ // 5K
249 void akc6955_set_freq(unsigned int freq)
253 unsigned char mode3k = 0;
255 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
259 ch = ch / 10; // 10/25 = 0.4
261 mode3k = akc6955_readcmd(AKC6955_CNR_AM) & 0x80;
268 akc6955_set_tune(mode3k, ch);
272 unsigned char akc6955_get_cnr(void)
276 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
278 b = akc6955_readcmd(AKC6955_CNR_FM);
280 b = akc6955_readcmd(AKC6955_CNR_AM);
286 int akc6955_read_level(void)
289 unsigned char rflevel, iflevel;
295 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
296 b = akc6955_readcmd(AKC6955_PGALEVEL);
297 rflevel = (b & 0xe0) >> 5;
298 iflevel = (b & 0x1c) >> 2;
299 rssi = (unsigned int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
301 level = 103 - (rssi + 6 * (rflevel + iflevel));
303 freq = akc6955_get_freq();
304 if(freq > 2560) { // ASSUME SW
305 level = 103 - (rssi + 6 * (rflevel + iflevel));
306 } else { // ASSUME MW,LW
307 level = 123 - (rssi + 6 * (rflevel + iflevel));
313 unsigned int akc6955_up_freq(unsigned int step)
316 freq = akc6955_get_freq();
318 akc6955_set_freq(freq);
319 return akc6955_get_freq();
323 unsigned int akc6955_down_freq(unsigned int step)
326 freq = akc6955_get_freq();
327 if(freq <= step) return freq;
329 akc6955_set_freq(freq);
330 return akc6955_get_freq();