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;
142 unsigned int akc6955_mode3k(unsigned char flag)
145 b = akc6955_readcmd(AKC6955_CH_HI);
151 akc6955_writecmd(AKC6955_CH_HI, b);
152 // akc6955_do_tune();
153 _AKC6955_WAIT_62_5MS();
154 return akc6955_get_freq();
157 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
165 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
168 band = akc6955_get_amband();
174 i = i / 3; // On MW2, Channnel must be multiple of 3.
175 i = (i << 1) + i; // i = (i/3) * 3
177 if(i > 0x1fff) i = 0x1fff;
181 b = ((i >> 8) & 0x1f) | 0x40; // 32.768KHz clock
183 b = ((i >> 8) & 0x1f) | 0x60;
185 akc6955_writecmd(AKC6955_CH_HI, b);
187 akc6955_writecmd(AKC6955_CH_LO, b);
190 // Use software-delay, but recommands hardware-delay ;-(
191 //_AKC6955_WAIT_12_5MS();
192 idle(65535 - 100 + 1); // 0.128 * 100 = 12.8ms
193 } while(akc6955_tune() == 0);
196 void akc6955_do_scan(unsigned char up)
200 b = akc6955_readcmd(AKC6955_POWER);
205 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
207 akc6955_writecmd(AKC6955_POWER, b); // Raise seek bit to '1'.
210 void akc6955_abort_scan(void)
213 b = akc6955_readcmd(AKC6955_POWER);
215 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
218 void akc6955_set_scanrate_fm(unsigned char rate)
221 c = akc6955_readcmd(AKC6955_SPACE);
222 c = (c & 0xcf) | ((rate & 0x03) << 4);
223 akc6955_writecmd(AKC6955_SPACE, c);
226 unsigned char akc6955_chk_donescan(void)
229 b = akc6955_readcmd(AKC6955_RCH_HI) & 0x40;
236 * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
238 unsigned int akc6955_get_freq(void)
240 unsigned char b, h, l;
245 b = akc6955_readcmd(AKC6955_CNR_AM) & 0x80;
246 l = akc6955_readcmd(AKC6955_RCH_LO) ;
247 h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
248 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
250 if(fm != 0){ // 25KHz
251 freq = i << 1 + i >> 1 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
253 // freq = freq' + 30MHz = freq' + 3000[10KHz]
256 freq = i << 2 + i; // freq = 5*i[KHz] = (4+1)*i[KHz]
258 freq = i << 1 + i; // freq = 3i[KHz] = (2+1)i[KHz]
264 void akc6955_set_freq(unsigned int freq)
268 unsigned char mode3k = 0;
270 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
274 ch = ch / 10; // 10/25 = 0.4
276 mode3k = akc6955_readcmd(AKC6955_CNR_AM) & 0x80;
283 akc6955_set_tune(mode3k, ch);
286 void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int ch, unsigned char mode3k)
289 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
290 akc6955_writecmd(AKC6955_UCH_ST, start);
291 akc6955_writecmd(AKC6955_UCH_EN, stop);
293 akc6955_set_amband(AKC6955_BAND_AMUSER);
295 akc6955_set_fmband(AKC6955_BAND_FMUSER);
297 akc6955_set_tune(mode3k, ch);
301 unsigned char akc6955_get_cnr(void)
305 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
307 b = akc6955_readcmd(AKC6955_CNR_FM);
309 b = akc6955_readcmd(AKC6955_CNR_AM);
315 int akc6955_read_level(void)
318 unsigned char rflevel, iflevel;
322 unsigned int totallevel;
325 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
326 b = akc6955_readcmd(AKC6955_PGALEVEL);
327 rflevel = (b & 0xe0) >> 5;
328 iflevel = (b & 0x1c) >> 2;
329 totallevel = rflevel + iflevel;
331 rssi = (unsigned int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
332 // totallevel = rssi + 6*totallevel;
333 level = (int)((totallevel << 2) + (totallevel << 1) + rssi);
335 level = 103 - level; // totallevel * 6
337 freq = akc6955_get_freq();
338 if(freq > 2560) { // ASSUME SW
340 } else { // ASSUME MW,LW
347 // Get diff. unit = 100Hz.
348 int akc6955_get_diff(void)
353 diff = akc6955_readcmd(AKC6955_FDNUM);
355 n = (int)diff & 0x007f;
357 n = -((int)(diff & 0x007f));
359 fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
363 return (n << 3 + n << 1); // 10n
367 unsigned int akc6955_up_freq(unsigned int step)
370 freq = akc6955_get_freq();
372 akc6955_set_freq(freq);
373 return akc6955_get_freq();
377 unsigned int akc6955_down_freq(unsigned int step)
380 freq = akc6955_get_freq();
381 if(freq <= step) return freq;
383 akc6955_set_freq(freq);
384 return akc6955_get_freq();
386 void akc6955_setvolumemode(unsigned char flag)
389 c = akc6955_readcmd(AKC6955_ENABLE) & 0xf7;
393 akc6955_writecmd(AKC6955_ENABLE, c);
396 void akc6955_setvolume(unsigned char level)
399 c = akc6955_readcmd(AKC6955_VOLUME) & 0x03;
400 if(level > 63) level = 63;
401 akc6955_writecmd(AKC6955_VOLUME, (c | (level << 2)));
404 unsigned char akc6955_getvolume(void)
407 c = (akc6955_readcmd(AKC6955_VOLUME) & 0xfc) >> 2;
411 void akc6955_set_prevolume(unsigned char level)
414 c = akc6955_readcmd(AKC6955_PRE) & 0xf3;
415 c |= ((level & 0x03) << 2);
416 akc6955_writecmd(AKC6955_PRE, c);
419 unsigned char akc6955_get_prevolume(void)
422 c = akc6955_readcmd(AKC6955_PRE) & 0x0c;
428 void akc6955_setphase(unsigned char flag)
431 c = akc6955_readcmd(AKC6955_VOLUME);
438 akc6955_writecmd(AKC6955_VOLUME, c);
441 void akc6955_setline(unsigned char flag)
444 c = akc6955_readcmd(AKC6955_VOLUME);
451 akc6955_writecmd(AKC6955_VOLUME, c);
454 void akc6955_set_lowboost(unsigned char flag)
457 c = akc6955_readcmd(AKC6955_STEREO);
463 akc6955_writecmd(AKC6955_STEREO, c);
466 void akc6955_set_stereomode(unsigned char mode)
469 c = akc6955_readcmd(AKC6955_STEREO);
470 mode = (mode & 0x03) << 2;
471 c = (c & 0xf3) | mode;
472 akc6955_writecmd(AKC6955_STEREO, c);
475 unsigned char akc6955_get_stereo(void)
478 c = akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
479 if(c == 0) return 0x00;
483 void akc6955_set_fm_threash(unsigned char val)
485 unsigned char c = akc6955_readcmd(AKC6955_THRESH);
487 c = (c & 0x3f) | (val << 6);
488 akc6955_writecmd(AKC6955_THRESH, c);
491 void akc6955_set_am_threash(unsigned char val)
493 unsigned char c = akc6955_readcmd(AKC6955_THRESH);
495 c = (c & 0xcf) | (val << 4);
496 akc6955_writecmd(AKC6955_THRESH, c);
499 void akc6955_set_fd_threash(unsigned char val)
501 unsigned char c = akc6955_readcmd(AKC6955_THRESH);
503 c = (c & 0xf3) | (val << 2);
504 akc6955_writecmd(AKC6955_THRESH, c);
507 void akc6955_set_stereo_threash(unsigned char val)
509 unsigned char c = akc6955_readcmd(AKC6955_THRESH);
511 c = (c & 0xfc) | val ;
512 akc6955_writecmd(AKC6955_THRESH, c);
520 unsigned int akc6955_get_battery(void)
524 c = akc6955_readcmd(AKC6955_VBAT) & 0x3f;
525 batt = 180 + (c << 2) + c;
535 void akc6955_set_fmbandwidth(unsigned char bw)
537 unsigned char c = akc6955_readcmd(AKC6955_STEREO);
538 c = (c & 0xfc) | (bw & 0x03);
539 akc6955_writecmd(AKC6955_STEREO, c);
542 unsigned char akc6955_get_fmbandwidth(void)
544 unsigned char c = akc6955_readcmd(AKC6955_STEREO) & 0x03;