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.
41 #include "commondef.h"
45 unsigned char akc6955_get_amband(void)
47 return akc6955_get_band() >> 3;
50 unsigned char akc6955_get_fmband(void)
52 return akc6955_get_band() & 0x07;
55 void akc6955_chg_fm(unsigned char f, unsigned int freq)
58 b.byte = akc6955_readcmd(AKC6955_POWER);
62 akc6955_set_fmband(setup.fmband);
63 akc6955_writecmd(AKC6955_POWER, b.byte);
64 akc6955_set_freq(freq);
67 akc6955_writecmd(AKC6955_POWER, b.byte);
68 akc6955_set_amband(setup.amband);
69 akc6955_set_freq(freq);
73 unsigned char akc6955_get_fm(void)
76 b.byte = akc6955_readcmd(AKC6955_POWER);
84 void akc6955_set_amband(unsigned char band)
90 if((band < AKC6955_BAND_SW1) || (band == AKC6955_BAND_MW4)) {
94 b = akc6955_readcmd(AKC6955_BAND);
95 b &= 0x07; // extract FM
96 b = b | ((band & 0x1f) << 3);
97 akc6955_writecmd(AKC6955_BAND, b);
101 void akc6955_set_fmband(unsigned char band)
104 rfamp_power(RFAMP_FM);
105 b = akc6955_readcmd(AKC6955_BAND);
106 b &= 0xf8; // extract AM
107 b = b | (band & 0x07);
108 akc6955_writecmd(AKC6955_BAND, b);
112 unsigned char akc6955_get_band(void)
114 return akc6955_readcmd(AKC6955_BAND);
118 void akc6955_set_power(unsigned char on)
121 b.byte = akc6955_readcmd(AKC6955_POWER);
126 akc6955_writecmd(AKC6955_POWER, b.byte);
129 void akc6955_do_tune(void)
132 b.byte = akc6955_readcmd(AKC6955_POWER);
133 b.b5 = 0; // Tun = '0'
134 b.b4 = 0; // Force abort scan.
135 akc6955_writecmd(AKC6955_POWER, b.byte);
137 // Need sleep?-> Need! this sequence re fer from reference code.
138 b.b5= 1; // Tun = '1'
139 akc6955_writecmd(AKC6955_POWER, b.byte);
142 akc6955_writecmd(AKC6955_POWER, b.byte);
146 unsigned char akc6955_tune(void)
149 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
156 unsigned char akc6955_get_mode3k(void)
159 c.byte = akc6955_readcmd(AKC6955_CNR_AM);
167 void akc6955_mode3k(unsigned char flag)
170 b.byte = akc6955_readcmd(AKC6955_CH_LO);
171 akc6955_writecmd(AKC6955_CH_LO, b.byte);
173 b.byte = akc6955_readcmd(AKC6955_CH_HI);
178 akc6955_writecmd(AKC6955_CH_HI, b.byte);
182 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
193 do { // Wait for before completed
194 comp = akc6955_chk_donescan();
196 } while(comp == 0x00);
198 f.byte = akc6955_readcmd(AKC6955_POWER);
200 band = akc6955_get_amband();
201 if(band == AKC6955_BAND_MW2){
203 i = ch / 3; // On MW2, Channnel must be multiple of 3.
204 i = i * 3; // i = (i/3) * 3
207 } else if(mode_3k != 0) {
213 if(band == AKC6955_BAND_AMUSER) {
214 start = setup.am_usrbands[setup.am_userbandnum].start * 32;
215 stop = setup.am_usrbands[setup.am_userbandnum].stop * 32;
217 start = ambands[band].start / q;
218 stop = ambands[band].end / q;
221 band = akc6955_get_fmband();
222 if(band == AKC6955_BAND_FMUSER) {
223 start = setup.fm_usrbands[setup.fm_userbandnum].start * 32;
224 stop = setup.fm_usrbands[setup.fm_userbandnum].stop * 32;
226 start = ((fmbands[band].start - 3000) * 4) / 10;
227 stop = ((fmbands[band].end - 3000) * 4) / 10;
231 if(i > 0x1fff) i = 0x1fff;
232 if(i > stop) i = stop;
233 if(i < start) i = start;
236 akc6955_writecmd(AKC6955_CH_LO, b.byte);
240 if((setup.fm == 0) && (mode_3k != 0)){
241 b.b5 = 1; // Mode 3K ON
246 akc6955_writecmd(AKC6955_CH_HI, b.byte);
251 void akc6955_do_scan(unsigned char up)
255 //20130823 Need wait for scan/tune completed w/o SDCC 3.3.x.
257 while(akc6955_chk_donescan() == 0)
262 b.byte = akc6955_readcmd(AKC6955_POWER);
265 // 20130823 : Is this collect?
268 akc6955_writecmd(AKC6955_POWER, b.byte);
272 b.b5 = 1; // Tune 0->1.
273 akc6955_writecmd(AKC6955_POWER, b.byte);
280 akc6955_writecmd(AKC6955_POWER, b.byte); // Raise seek bit to '1'.
284 void akc6955_abort_scan(void)
287 b = akc6955_readcmd(AKC6955_POWER);
289 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
292 void akc6955_set_scanrate_fm(unsigned char rate)
295 c = akc6955_readcmd(AKC6955_SPACE);
296 c = (c & 0xcf) | ((rate & 0x03) << 4);
297 akc6955_writecmd(AKC6955_SPACE, c);
300 unsigned char akc6955_get_scanrate_fm(void)
303 c = akc6955_readcmd(AKC6955_SPACE);
308 unsigned char akc6955_chk_donescan(void)
311 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
318 unsigned int akc6955_get_channel(void)
322 l = akc6955_readcmd(AKC6955_RCH_LO) ;
323 h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
329 * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
331 unsigned int akc6955_get_freq(void)
338 f.byte = akc6955_readcmd(AKC6955_POWER);
339 i = akc6955_get_channel();
341 freq = (i * 5) / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
343 b.byte = akc6955_readcmd(AKC6955_CH_HI);
344 band = akc6955_get_amband();
346 if((band == AKC6955_BAND_MW2) || (b.b5)){
353 void akc6955_set_freq(unsigned int freq)
360 f.byte = akc6955_readcmd(AKC6955_POWER);
362 band = akc6955_get_fmband();
366 band = akc6955_get_amband();
367 mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
368 if(band == AKC6955_BAND_MW2) {
369 ch = (freq / 9) * 3; // See datasheet.
370 } else if(band == AKC6955_BAND_MW3) {
372 } else if(mode3k.b7){
378 akc6955_set_tune(mode3k.b7, ch);
381 void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int ch, unsigned char mode3k)
385 f.byte = akc6955_readcmd(AKC6955_POWER);
386 akc6955_writecmd(AKC6955_UCH_ST, start);
387 akc6955_writecmd(AKC6955_UCH_EN, stop);
389 akc6955_set_fmband(AKC6955_BAND_FMUSER);
391 akc6955_set_amband(AKC6955_BAND_AMUSER);
393 akc6955_set_tune(mode3k, ch);
397 unsigned char akc6955_get_cnr(void)
401 f.byte = akc6955_readcmd(AKC6955_POWER);
403 b.byte = akc6955_readcmd(AKC6955_CNR_FM);
405 b.byte = akc6955_readcmd(AKC6955_CNR_AM);
411 int akc6955_read_level(void)
414 unsigned char rflevel, iflevel;
421 f.byte = akc6955_readcmd(AKC6955_POWER);
422 b = akc6955_readcmd(AKC6955_PGALEVEL);
423 rflevel = (b & 0xe0) >> 5;
424 iflevel = (b & 0x1c) >> 2;
425 totallevel = rflevel + iflevel;
427 rssi = (int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
428 // totallevel = rssi + 6*totallevel;
429 level = (int)(totallevel * 6 + rssi);
431 level = 103 - level; // totallevel * 6
433 freq = akc6955_get_freq();
434 if(freq > 2560) { // ASSUME SW
436 } else { // ASSUME MW,LW
444 // Get diff. unit = 100Hz.
445 int akc6955_get_diff(void)
451 diff.byte = akc6955_readcmd(AKC6955_FDNUM);
454 n = -((int) diff.byte);
460 f.byte = akc6955_readcmd(AKC6955_POWER);
467 void akc6955_up_freq(unsigned int step)
472 freq = akc6955_get_channel();
474 // mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
475 // akc6955_set_tune(mode3k.b7, freq);
476 akc6955_set_tune(setup.am_mode3k, freq);
480 void akc6955_down_freq(unsigned int step)
485 freq = akc6955_get_channel();
486 if(freq <= step) return;
488 // mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
489 // akc6955_set_tune(mode3k.b7, freq);
490 akc6955_set_tune(setup.am_mode3k, freq);
493 void akc6955_setvolumemode(unsigned char flag)
496 c.byte = akc6955_readcmd(AKC6955_ENABLE);
501 akc6955_writecmd(AKC6955_ENABLE, c.byte);
504 unsigned char akc6955_getvolumemode(void)
507 c.byte = akc6955_readcmd(AKC6955_ENABLE);
514 void akc6955_setvolume(unsigned char level)
517 // c = akc6955_readcmd(AKC6955_VOLUME) & 0x03;
518 if(level > 63) level = 63;
519 akc6955_writecmd(AKC6955_VOLUME, ((akc6955_readcmd(AKC6955_VOLUME) & 0x03) | (level << 2)));
522 unsigned char akc6955_getvolume(void)
525 c = akc6955_readcmd(AKC6955_VOLUME) >> 2;
529 void akc6955_set_prevolume(unsigned char level)
532 c = akc6955_readcmd(AKC6955_PRE) & 0xf3;
533 c |= ((level & 0x03) << 2);
534 akc6955_writecmd(AKC6955_PRE, c);
537 unsigned char akc6955_get_prevolume(void)
540 c = akc6955_readcmd(AKC6955_PRE) & 0x0c;
546 void akc6955_setphase(unsigned char flag)
549 c.byte = akc6955_readcmd(AKC6955_VOLUME);
555 akc6955_writecmd(AKC6955_VOLUME, c.byte);
558 void akc6955_setline(unsigned char flag)
561 c.byte = akc6955_readcmd(AKC6955_VOLUME);
566 akc6955_writecmd(AKC6955_VOLUME, c.byte);
569 void akc6955_set_lowboost(unsigned char flag)
572 c.byte = akc6955_readcmd(AKC6955_STEREO);
577 akc6955_writecmd(AKC6955_STEREO, c.byte);
580 void akc6955_set_stereomode(unsigned char mode)
583 c = akc6955_readcmd(AKC6955_STEREO);
584 mode = (mode & 0x03) << 2;
585 c = (c & 0xf3) | mode;
586 akc6955_writecmd(AKC6955_STEREO, c);
589 unsigned char akc6955_get_stereo(void)
592 c = akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
601 unsigned int akc6955_get_battery(void)
605 c = akc6955_readcmd(AKC6955_VBAT) & 0x3f;
610 void akc6955_set_thresh_fmstereo(unsigned char a)
614 setup.threshold_fmstereo = a;
615 b = akc6955_readcmd(AKC6955_THRESH) & 0xfc;
616 akc6955_writecmd(AKC6955_THRESH, a | b);
619 void akc6955_set_thresh_width(unsigned char a)
623 setup.threshold_width = a;
625 b = akc6955_readcmd(AKC6955_THRESH) & 0xf3;;
626 akc6955_writecmd(AKC6955_THRESH, a | b);
629 void akc6955_set_thresh_amcnr(unsigned char a)
633 setup.threshold_amcnr = a;
635 b = akc6955_readcmd(AKC6955_THRESH) & 0xcf;
636 akc6955_writecmd(AKC6955_THRESH, a | b);
639 void akc6955_set_thresh_fmcnr(unsigned char a)
643 setup.threshold_fmcnr = a;
645 b = akc6955_readcmd(AKC6955_THRESH) & 0x3f;
646 akc6955_writecmd(AKC6955_THRESH, a | b);