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 void akc6955_chg_fm(unsigned char f, unsigned int freq)
48 b.byte = akc6955_readcmd(AKC6955_POWER);
52 akc6955_set_fmband(setup.fmband);
53 akc6955_writecmd(AKC6955_POWER, b.byte);
54 akc6955_set_freq(freq);
57 akc6955_writecmd(AKC6955_POWER, b.byte);
58 akc6955_set_amband(setup.amband);
59 akc6955_set_freq(freq);
63 unsigned char akc6955_get_fm(void)
66 b.byte = akc6955_readcmd(AKC6955_POWER);
74 void akc6955_set_amband(unsigned char band)
80 if((band < AKC6955_BAND_SW1) || (band == AKC6955_BAND_MW4)) {
84 b = akc6955_readcmd(AKC6955_BAND);
85 b &= 0x07; // extract FM
86 b = b | ((band & 0x1f) << 3);
87 akc6955_writecmd(AKC6955_BAND, b);
91 void akc6955_set_fmband(unsigned char band)
94 rfamp_power(RFAMP_FM);
95 b = akc6955_readcmd(AKC6955_BAND);
96 b &= 0xf8; // extract AM
97 b = b | (band & 0x07);
98 akc6955_writecmd(AKC6955_BAND, b);
102 unsigned char akc6955_get_band(void)
104 return akc6955_readcmd(AKC6955_BAND);
108 void akc6955_set_power(unsigned char on)
111 b.byte = akc6955_readcmd(AKC6955_POWER);
116 akc6955_writecmd(AKC6955_POWER, b.byte);
119 void akc6955_do_tune(void)
122 b.byte = akc6955_readcmd(AKC6955_POWER);
123 b.b5 = 0; // Tun = '0'
124 b.b4 = 0; // Force abort scan.
125 akc6955_writecmd(AKC6955_POWER, b.byte);
127 // Need sleep?-> Need! this sequence re fer from reference code.
128 b.b5= 1; // Tun = '1'
129 akc6955_writecmd(AKC6955_POWER, b.byte);
132 akc6955_writecmd(AKC6955_POWER, b.byte);
136 unsigned char akc6955_tune(void)
139 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
147 void akc6955_mode3k(unsigned char flag)
150 b.byte = akc6955_readcmd(AKC6955_CH_LO);
151 akc6955_writecmd(AKC6955_CH_LO, b.byte);
153 b.byte = akc6955_readcmd(AKC6955_CH_HI);
158 akc6955_writecmd(AKC6955_CH_HI, b.byte);
162 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
170 do { // Wait for before completed
171 comp = akc6955_chk_donescan();
173 } while(comp == 0x00);
174 f.byte = akc6955_readcmd(AKC6955_POWER);
177 akc6955_get_amband(band);
180 if(band == AKC6955_BAND_MW2){
182 i = ch / 3; // On MW2, Channnel must be multiple of 3.
183 i = i * 3; // i = (i/3) * 3
185 if(i > 0x1fff) i = 0x1fff;
189 akc6955_writecmd(AKC6955_CH_LO, b.byte);
194 b.b5 = 1; // Mode 3K ON
196 akc6955_writecmd(AKC6955_CH_HI, b.byte);
201 void akc6955_do_scan(unsigned char up)
205 //20130823 Need wait for scan/tune completed w/o SDCC 3.3.x.
207 while(akc6955_chk_donescan() == 0)
212 b.byte = akc6955_readcmd(AKC6955_POWER);
215 // 20130823 : Is this collect?
218 akc6955_writecmd(AKC6955_POWER, b.byte);
222 b.b5 = 1; // Tune 0->1.
223 akc6955_writecmd(AKC6955_POWER, b.byte);
230 akc6955_writecmd(AKC6955_POWER, b.byte); // Raise seek bit to '1'.
234 void akc6955_abort_scan(void)
237 b = akc6955_readcmd(AKC6955_POWER);
239 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
242 void akc6955_set_scanrate_fm(unsigned char rate)
245 c = akc6955_readcmd(AKC6955_SPACE);
246 c = (c & 0xcf) | ((rate & 0x03) << 4);
247 akc6955_writecmd(AKC6955_SPACE, c);
250 unsigned char akc6955_get_scanrate_fm(void)
253 c = akc6955_readcmd(AKC6955_SPACE);
258 unsigned char akc6955_chk_donescan(void)
261 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
268 unsigned int akc6955_get_channel(void)
272 l = akc6955_readcmd(AKC6955_RCH_LO) ;
273 h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
279 * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
281 unsigned int akc6955_get_freq(void)
288 f.byte = akc6955_readcmd(AKC6955_POWER);
289 i = akc6955_get_channel();
291 freq = (i * 5) / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
293 b.byte = akc6955_readcmd(AKC6955_CH_HI);
294 akc6955_get_amband(band);
296 if((band == AKC6955_BAND_MW2) || (b.b5)){
303 void akc6955_set_freq(unsigned int freq)
309 unsigned int start, stop;
311 f.byte = akc6955_readcmd(AKC6955_POWER);
313 akc6955_get_fmband(band);
315 if(band == AKC6955_BAND_FMUSER){
316 start = setup.fm_usrbands[setup.fm_userbandnum].start * 32;
317 stop = setup.fm_usrbands[setup.fm_userbandnum].stop * 32;
319 start = fmbands[band].start;
320 stop = fmbands[band].end;
325 akc6955_get_amband(band);
326 // if(band >= AKC6955_BAND_AMEND) band = AKC6955_BAND_AMEND - 1;
327 if(band == AKC6955_BAND_AMUSER){
328 start = setup.am_usrbands[setup.am_userbandnum].start * 32;
329 stop = setup.am_usrbands[setup.am_userbandnum].stop * 32;
331 start = ambands[band].start;
332 stop = ambands[band].end;
334 mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
335 if(band == AKC6955_BAND_MW2) {
336 ch = (freq / 9) * 3; // See datasheet.
337 } else if(band == AKC6955_BAND_MW3) {
339 } else if(mode3k.b7){
345 if(freq < start) freq = start;
346 if(freq >= stop) freq = stop - 1;
347 akc6955_set_tune(mode3k.b7, ch);
350 void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int ch, unsigned char mode3k)
354 f.byte = akc6955_readcmd(AKC6955_POWER);
355 akc6955_writecmd(AKC6955_UCH_ST, start);
356 akc6955_writecmd(AKC6955_UCH_EN, stop);
358 akc6955_set_fmband(AKC6955_BAND_FMUSER);
360 akc6955_set_amband(AKC6955_BAND_AMUSER);
362 akc6955_set_tune(mode3k, ch);
366 unsigned char akc6955_get_cnr(void)
370 f.byte = akc6955_readcmd(AKC6955_POWER);
372 b.byte = akc6955_readcmd(AKC6955_CNR_FM);
374 b.byte = akc6955_readcmd(AKC6955_CNR_AM);
380 int akc6955_read_level(void)
383 unsigned char rflevel, iflevel;
390 f.byte = akc6955_readcmd(AKC6955_POWER);
391 b = akc6955_readcmd(AKC6955_PGALEVEL);
392 rflevel = (b & 0xe0) >> 5;
393 iflevel = (b & 0x1c) >> 2;
394 totallevel = rflevel + iflevel;
396 rssi = (int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
397 // totallevel = rssi + 6*totallevel;
398 level = (int)(totallevel * 6 + rssi);
400 level = 103 - level; // totallevel * 6
402 freq = akc6955_get_freq();
403 if(freq > 2560) { // ASSUME SW
405 } else { // ASSUME MW,LW
413 // Get diff. unit = 100Hz.
414 int akc6955_get_diff(void)
420 diff.byte = akc6955_readcmd(AKC6955_FDNUM);
423 n = -((int) diff.byte);
429 f.byte = akc6955_readcmd(AKC6955_POWER);
436 void akc6955_up_freq(unsigned int step)
441 freq = akc6955_get_channel();
443 // mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
444 // akc6955_set_tune(mode3k.b7, freq);
445 akc6955_set_tune(setup.am_mode3k, freq);
449 void akc6955_down_freq(unsigned int step)
454 freq = akc6955_get_channel();
455 if(freq <= step) return;
457 // mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
458 // akc6955_set_tune(mode3k.b7, freq);
459 akc6955_set_tune(setup.am_mode3k, freq);
462 void akc6955_setvolumemode(unsigned char flag)
465 c.byte = akc6955_readcmd(AKC6955_ENABLE);
470 akc6955_writecmd(AKC6955_ENABLE, c.byte);
473 unsigned char akc6955_getvolumemode(void)
476 c.byte = akc6955_readcmd(AKC6955_ENABLE);
483 void akc6955_setvolume(unsigned char level)
486 // c = akc6955_readcmd(AKC6955_VOLUME) & 0x03;
487 if(level > 63) level = 63;
488 akc6955_writecmd(AKC6955_VOLUME, ((akc6955_readcmd(AKC6955_VOLUME) & 0x03) | (level << 2)));
491 unsigned char akc6955_getvolume(void)
494 c = akc6955_readcmd(AKC6955_VOLUME) >> 2;
498 void akc6955_set_prevolume(unsigned char level)
501 c = akc6955_readcmd(AKC6955_PRE) & 0xf3;
502 c |= ((level & 0x03) << 2);
503 akc6955_writecmd(AKC6955_PRE, c);
506 unsigned char akc6955_get_prevolume(void)
509 c = akc6955_readcmd(AKC6955_PRE) & 0x0c;
515 void akc6955_setphase(unsigned char flag)
518 c.byte = akc6955_readcmd(AKC6955_VOLUME);
524 akc6955_writecmd(AKC6955_VOLUME, c.byte);
527 void akc6955_setline(unsigned char flag)
530 c.byte = akc6955_readcmd(AKC6955_VOLUME);
535 akc6955_writecmd(AKC6955_VOLUME, c.byte);
538 void akc6955_set_lowboost(unsigned char flag)
541 c.byte = akc6955_readcmd(AKC6955_STEREO);
546 akc6955_writecmd(AKC6955_STEREO, c.byte);
549 void akc6955_set_stereomode(unsigned char mode)
552 c = akc6955_readcmd(AKC6955_STEREO);
553 mode = (mode & 0x03) << 2;
554 c = (c & 0xf3) | mode;
555 akc6955_writecmd(AKC6955_STEREO, c);
558 unsigned char akc6955_get_stereo(void)
561 c = akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
570 unsigned int akc6955_get_battery(void)
574 c = akc6955_readcmd(AKC6955_VBAT) & 0x3f;
579 void akc6955_set_thresh_fmstereo(unsigned char a)
583 setup.threshold_fmstereo = a;
584 b = akc6955_readcmd(AKC6955_THRESH) & 0xfc;
585 akc6955_writecmd(AKC6955_THRESH, a | b);
588 void akc6955_set_thresh_width(unsigned char a)
592 setup.threshold_width = a;
594 b = akc6955_readcmd(AKC6955_THRESH) & 0xf3;;
595 akc6955_writecmd(AKC6955_THRESH, a | b);
598 void akc6955_set_thresh_amcnr(unsigned char a)
602 setup.threshold_amcnr = a;
604 b = akc6955_readcmd(AKC6955_THRESH) & 0xcf;
605 akc6955_writecmd(AKC6955_THRESH, a | b);
608 void akc6955_set_thresh_fmcnr(unsigned char a)
612 setup.threshold_fmcnr = a;
614 b = akc6955_readcmd(AKC6955_THRESH) & 0x3f;
615 akc6955_writecmd(AKC6955_THRESH, a | b);