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_readcmd(unsigned char reg)
47 return i2c_read_byte(AKC6955_ADDRESS, reg);
50 void akc6955_writecmd(unsigned char reg,unsigned char data)
52 i2c_send_byte(AKC6955_ADDRESS, reg, data);
55 unsigned char akc6955_get_band(void)
57 return akc6955_readcmd(AKC6955_BAND);
60 unsigned char akc6955_get_amband(void)
62 return akc6955_get_band() >> 3;
65 unsigned char akc6955_get_fmband(void)
67 return akc6955_get_band() & 0x07;
71 void akc6955_chg_fm(unsigned char f, unsigned int freq)
74 b.byte = akc6955_readcmd(AKC6955_POWER);
78 akc6955_set_fmband(setup.fmband);
79 akc6955_writecmd(AKC6955_POWER, b.byte);
80 akc6955_set_freq(freq);
83 akc6955_writecmd(AKC6955_POWER, b.byte);
84 akc6955_set_amband(setup.amband);
85 akc6955_set_freq(freq);
89 unsigned char akc6955_get_fm(void)
92 b.byte = akc6955_readcmd(AKC6955_POWER);
100 void akc6955_set_amband(unsigned char band)
106 if((band < AKC6955_BAND_SW1) || (band == AKC6955_BAND_MW4)) {
110 b = akc6955_readcmd(AKC6955_BAND);
111 b &= 0x07; // extract FM
112 b = b | ((band & 0x1f) << 3);
113 akc6955_writecmd(AKC6955_BAND, b);
117 void akc6955_set_fmband(unsigned char band)
120 rfamp_power(RFAMP_FM);
121 b = akc6955_readcmd(AKC6955_BAND);
122 b &= 0xf8; // extract AM
123 b = b | (band & 0x07);
124 akc6955_writecmd(AKC6955_BAND, b);
128 void akc6955_set_power(unsigned char on)
131 b.byte = akc6955_readcmd(AKC6955_POWER);
136 akc6955_writecmd(AKC6955_POWER, b.byte);
139 void akc6955_do_tune(void)
142 b.byte = akc6955_readcmd(AKC6955_POWER) & 0b11001111;
143 // b.b5 = 0; // Tun = '0'
144 // b.b4 = 0; // Force abort scan.
145 akc6955_writecmd(AKC6955_POWER, b.byte);
147 // Need sleep?-> Need! this sequence re fer from reference code.
148 b.b5= 1; // Tun = '1'
149 akc6955_writecmd(AKC6955_POWER, b.byte);
152 akc6955_writecmd(AKC6955_POWER, b.byte);
156 unsigned char akc6955_tune(void)
159 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
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 unsigned char akc6955_get_mode3k(void)
185 c.byte = akc6955_readcmd(AKC6955_CNR_AM);
192 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
198 unsigned int start, stop;
201 while(akc6955_chk_donescan() == 0) { // Wait for before completed
204 f = akc6955_get_fm();
207 band = akc6955_get_amband();
208 if(band == AKC6955_BAND_AMUSER){
209 start = userband.am_usrbands[setup.am_userbandnum].start * 32;
210 stop = userband.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 = userband.fm_usrbands[setup.fm_userbandnum].start * 32;
224 stop = userband.fm_usrbands[setup.fm_userbandnum].stop * 32;
226 start = ((fmbands[band].start - 3000) * 2) / 5;
227 stop = ((fmbands[band].end - 3000) * 2) / 5;;
230 if(i > stop) i = stop; // ADD
231 if(i < start) i = start;
234 akc6955_writecmd(AKC6955_CH_LO, b.byte);
239 b.b5 = 1; // Mode 3K ON
241 akc6955_writecmd(AKC6955_CH_HI, b.byte);
246 void akc6955_do_scan(unsigned char up)
251 //20130823 Need wait for scan/tune completed w/o SDCC 3.3.x.
253 while(akc6955_chk_donescan() == 0)
255 if(pollkey_single_timeout(1, 0) == charcode_a) return; // 23ms, if 'A' Abort.
258 b.byte = akc6955_readcmd(AKC6955_POWER) & 0b11000111;
262 // 20130823 : Is this collect?
265 akc6955_writecmd(AKC6955_POWER, b.byte);
269 b.b5 = 1; // Tune 0->1.
270 akc6955_writecmd(AKC6955_POWER, b.byte);
277 akc6955_writecmd(AKC6955_POWER, b.byte); // Raise seek bit to '1'.
281 void akc6955_abort_scan(void)
284 b.byte = akc6955_readcmd(AKC6955_POWER);
286 akc6955_writecmd(AKC6955_POWER, b.byte); // Falldown seek bit to '0'.
289 void akc6955_set_scanrate_fm(unsigned char rate)
292 c = akc6955_readcmd(AKC6955_SPACE);
293 c = (c & 0xcf) | ((rate & 0x03) << 4);
294 akc6955_writecmd(AKC6955_SPACE, c);
297 unsigned char akc6955_get_scanrate_fm(void)
300 // c = akc6955_readcmd(AKC6955_SPACE);
301 // c = (c & 0x30) >> 4;
302 return (akc6955_readcmd(AKC6955_SPACE) & 0x30) >> 4;
305 unsigned char akc6955_chk_donescan(void)
308 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
315 unsigned int akc6955_get_channel(void)
319 l = akc6955_readcmd(AKC6955_RCH_LO) ;
320 h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
326 * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
328 unsigned int akc6955_get_freq(void)
337 f = akc6955_get_fm();
338 i = akc6955_get_channel();
340 freq = i * 2 + i / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
342 b.byte = akc6955_readcmd(AKC6955_CH_HI);
343 band = akc6955_get_amband();
344 if((band == AKC6955_BAND_MW2) || (band == AKC6955_BAND_LW) || (b.b5)){
354 void akc6955_set_freq(unsigned int freq)
362 f = akc6955_get_fm();
364 band = akc6955_get_fmband();
366 ch = ((freq - 3000) * 2) / 5;
368 band = akc6955_get_amband();
369 mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
370 if((band == AKC6955_BAND_MW2) || (band == AKC6955_BAND_LW) || (mode3k.b7)){
379 akc6955_set_tune(mode3k.b7, ch);
382 void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int ch, unsigned char mode3k)
386 f = akc6955_get_fm();
387 akc6955_writecmd(AKC6955_UCH_ST, start);
388 akc6955_writecmd(AKC6955_UCH_EN, stop);
390 akc6955_set_fmband(AKC6955_BAND_FMUSER);
392 akc6955_set_amband(AKC6955_BAND_AMUSER);
394 akc6955_set_tune(mode3k, ch);
398 unsigned char akc6955_get_cnr(void)
402 f = akc6955_get_fm();
404 b.byte = akc6955_readcmd(AKC6955_CNR_FM);
406 b.byte = akc6955_readcmd(AKC6955_CNR_AM);
412 int akc6955_read_level(void)
415 unsigned char rflevel, iflevel;
422 f = akc6955_get_fm();
423 b = akc6955_readcmd(AKC6955_PGALEVEL);
424 rflevel = (b & 0xe0) >> 5;
425 iflevel = (b & 0x1c) >> 2;
426 totallevel = rflevel + iflevel;
428 rssi = (int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
429 level = (int)(totallevel * 6 + rssi);
431 level = 103 - level; // totallevel * 6
433 band = akc6955_get_amband();
434 if((band >= AKC6955_BAND_SW1) && (band <= AKC6955_BAND_AMUSER)) { // SW
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 = akc6955_get_fm();
467 void akc6955_up_freq(unsigned int step)
470 // __bitops_t mode3k;
471 unsigned char mode3k;
473 freq = akc6955_get_channel();
475 // mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
476 // akc6955_set_tune(mode3k.b7, freq);
477 mode3k = akc6955_get_mode3k();
478 akc6955_set_tune(mode3k, freq);
482 void akc6955_down_freq(unsigned int step)
485 unsigned char mode3k;
487 freq = akc6955_get_channel();
488 if(freq <= step) return;
490 // mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
491 mode3k = akc6955_get_mode3k();
492 akc6955_set_tune(mode3k, freq);
495 void akc6955_setvolumemode(unsigned char flag)
498 c.byte = akc6955_readcmd(AKC6955_ENABLE);
503 akc6955_writecmd(AKC6955_ENABLE, c.byte);
506 unsigned char akc6955_getvolumemode(void)
509 c.byte = akc6955_readcmd(AKC6955_ENABLE);
516 void akc6955_setvolume(unsigned char level)
519 // c = akc6955_readcmd(AKC6955_VOLUME) & 0x03;
520 if(level > 63) level = 63;
521 akc6955_writecmd(AKC6955_VOLUME, ((akc6955_readcmd(AKC6955_VOLUME) & 0x03) | (level << 2)));
524 unsigned char akc6955_getvolume(void)
527 c = akc6955_readcmd(AKC6955_VOLUME) >> 2;
531 void akc6955_set_prevolume(unsigned char level)
534 c = akc6955_readcmd(AKC6955_PRE) & 0xf3;
535 c |= ((level & 0x03) << 2);
536 akc6955_writecmd(AKC6955_PRE, c);
539 unsigned char akc6955_get_prevolume(void)
542 // c = akc6955_readcmd(AKC6955_PRE) & 0x0c;
544 return (akc6955_readcmd(AKC6955_PRE) & 0x0c) >> 2;
548 void akc6955_setphase(unsigned char flag)
551 c.byte = akc6955_readcmd(AKC6955_VOLUME);
557 akc6955_writecmd(AKC6955_VOLUME, c.byte);
560 void akc6955_setline(unsigned char flag)
563 c.byte = akc6955_readcmd(AKC6955_VOLUME);
568 akc6955_writecmd(AKC6955_VOLUME, c.byte);
571 void akc6955_set_lowboost(unsigned char flag)
574 c.byte = akc6955_readcmd(AKC6955_STEREO);
579 akc6955_writecmd(AKC6955_STEREO, c.byte);
582 void akc6955_set_stereomode(unsigned char mode)
585 c = akc6955_readcmd(AKC6955_STEREO);
586 mode = (mode & 0x03) << 2;
587 c = (c & 0xf3) | mode;
588 akc6955_writecmd(AKC6955_STEREO, c);
591 unsigned char akc6955_get_stereo(void)
594 // c = akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
595 return akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
603 unsigned int akc6955_get_battery(void)
607 c = akc6955_readcmd(AKC6955_VBAT) & 0x3f;
615 void akc6955_set_fmbandwidth(unsigned char bw)
617 unsigned char c = akc6955_readcmd(AKC6955_STEREO);
618 c = (c & 0xfc) | (bw & 0x03);
619 akc6955_writecmd(AKC6955_STEREO, c);
622 unsigned char akc6955_get_fmbandwidth(void)
624 return (akc6955_readcmd(AKC6955_STEREO) & 0x03);
629 void akc6955_set_thresh_fmstereo(unsigned char a)
633 setup.threshold_fmstereo = a;
634 b = akc6955_readcmd(AKC6955_THRESH) & 0xfc;
635 akc6955_writecmd(AKC6955_THRESH, a | b);
638 void akc6955_set_thresh_width(unsigned char a)
642 setup.threshold_width = a;
644 b = akc6955_readcmd(AKC6955_THRESH) & 0xf3;;
645 akc6955_writecmd(AKC6955_THRESH, a | b);
648 void akc6955_set_thresh_amcnr(unsigned char a)
652 setup.threshold_amcnr = a;
654 b = akc6955_readcmd(AKC6955_THRESH) & 0xcf;
655 akc6955_writecmd(AKC6955_THRESH, a | b);
658 void akc6955_set_thresh_fmcnr(unsigned char a)
662 setup.threshold_fmcnr = a;
664 b = akc6955_readcmd(AKC6955_THRESH) & 0x3f;
665 akc6955_writecmd(AKC6955_THRESH, a | b);