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"
43 void akc6955_writecmd(unsigned char reg, unsigned char data)
46 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
55 OpenI2C(MASTER, SLEW_OFF);
70 unsigned char akc6955_readcmd(unsigned char reg)
75 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
77 OpenI2C(MASTER, SLEW_OFF);
113 void akc6955_chg_fm(unsigned char f, unsigned int freq)
117 b.byte = akc6955_readcmd(AKC6955_POWER);
120 rfamp_power(RFAMP_FM);
122 akc6955_set_fmband(fmband);
123 akc6955_writecmd(AKC6955_POWER, b.byte);
124 akc6955_set_freq(freq);
128 if((amband < AKC6955_BAND_SW1) || (amband == AKC6955_BAND_MW4)) {
132 akc6955_writecmd(AKC6955_POWER, b.byte);
133 akc6955_set_amband(amband);
134 akc6955_set_freq(freq);
138 unsigned char akc6955_get_fm(void)
141 b.byte = akc6955_readcmd(AKC6955_POWER);
149 void akc6955_set_amband(unsigned char band)
152 b = akc6955_readcmd(AKC6955_BAND);
153 b &= 0x07; // extract FM
154 b = b | ((band & 0x1f) << 3);
155 akc6955_writecmd(AKC6955_BAND, b);
159 void akc6955_set_fmband(unsigned char band)
162 b = akc6955_readcmd(AKC6955_BAND);
163 b &= 0xf8; // extract AM
164 b = b | (band & 0x07);
165 akc6955_writecmd(AKC6955_BAND, b);
169 unsigned char akc6955_get_band(void)
171 return akc6955_readcmd(AKC6955_BAND);
175 void akc6955_set_power(unsigned char on)
178 b.byte = akc6955_readcmd(AKC6955_POWER);
183 akc6955_writecmd(AKC6955_POWER, b.byte);
186 void akc6955_do_tune(void)
189 b.byte = akc6955_readcmd(AKC6955_POWER);
190 b.b5 = 0; // Tun = '0'
191 b.b4 = 0; // Force abort scan.
192 akc6955_writecmd(AKC6955_POWER, b.byte);
194 // Need sleep?-> Need! this sequence re fer from reference code.
195 b.b5= 1; // Tun = '1'
196 akc6955_writecmd(AKC6955_POWER, b.byte);
199 akc6955_writecmd(AKC6955_POWER, b.byte);
203 unsigned char akc6955_tune(void)
206 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
214 void akc6955_mode3k(unsigned char flag)
217 b.byte = akc6955_readcmd(AKC6955_CH_HI);
222 akc6955_writecmd(AKC6955_CH_HI, b.byte);
224 _AKC6955_WAIT_62_5MS();
227 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
235 do { // Wait for before completed
236 comp = akc6955_chk_donescan();
238 } while(comp == 0x00);
239 f.byte = akc6955_readcmd(AKC6955_POWER);
242 akc6955_get_amband(band);
245 if(band == AKC6955_BAND_MW2){
247 i = ch / 3; // On MW2, Channnel must be multiple of 3.
248 i = i * 3; // i = (i/3) * 3
250 if(i > 0x1fff) i = 0x1fff;
254 akc6955_writecmd(AKC6955_CH_LO, b.byte);
259 b.b5 = 1; // Mode 3K ON
261 akc6955_writecmd(AKC6955_CH_HI, b.byte);
266 void akc6955_do_scan(unsigned char up)
269 // akc6955_do_tune();
270 b.byte = akc6955_readcmd(AKC6955_POWER);
274 akc6955_writecmd(AKC6955_POWER, b.byte);
275 b.b5 = 1; // Tune 0->1.
277 akc6955_writecmd(AKC6955_POWER, b.byte);
283 akc6955_writecmd(AKC6955_POWER, b.byte); // Raise seek bit to '1'.
286 void akc6955_abort_scan(void)
289 b = akc6955_readcmd(AKC6955_POWER);
291 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
294 void akc6955_set_scanrate_fm(unsigned char rate)
297 c = akc6955_readcmd(AKC6955_SPACE);
298 c = (c & 0xcf) | ((rate & 0x03) << 4);
299 akc6955_writecmd(AKC6955_SPACE, c);
302 unsigned char akc6955_chk_donescan(void)
305 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
312 unsigned int akc6955_get_channel(void)
316 l = akc6955_readcmd(AKC6955_RCH_LO) ;
317 h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
323 * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
325 unsigned int akc6955_get_freq(void)
332 f.byte = akc6955_readcmd(AKC6955_POWER);
333 i = akc6955_get_channel();
335 freq = (i * 5) / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
337 b.byte = akc6955_readcmd(AKC6955_CH_HI);
338 akc6955_get_amband(band);
340 if((band == AKC6955_BAND_MW2) || (b.b5)){
347 void akc6955_set_freq(unsigned int freq)
353 unsigned int start, stop;
355 f.byte = akc6955_readcmd(AKC6955_POWER);
357 akc6955_get_fmband(band);
359 if(band == AKC6955_BAND_FMUSER){
360 start = fm_usrbands[fm_userbandnum].start * 32;
361 stop = fm_usrbands[fm_userbandnum].stop * 32;
363 start = fmbands[band].start;
364 stop = fmbands[band].end;
369 akc6955_get_amband(band);
370 // if(band >= AKC6955_BAND_AMEND) band = AKC6955_BAND_AMEND - 1;
371 if(band == AKC6955_BAND_AMUSER){
372 start = am_usrbands[am_userbandnum].start * 32;
373 stop = am_usrbands[am_userbandnum].stop * 32;
375 start = ambands[band].start;
376 stop = ambands[band].end;
378 mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
379 if(band == AKC6955_BAND_MW2) {
380 ch = (freq / 9) * 3; // See datasheet.
381 } else if(band == AKC6955_BAND_MW3) {
383 } else if(mode3k.b7){
389 if(freq < start) freq = start;
390 if(freq >= stop) freq = stop - 1;
391 akc6955_set_tune(mode3k.b7, ch);
394 void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int ch, unsigned char mode3k)
398 f.byte = akc6955_readcmd(AKC6955_POWER);
399 akc6955_writecmd(AKC6955_UCH_ST, start);
400 akc6955_writecmd(AKC6955_UCH_EN, stop);
402 akc6955_set_fmband(AKC6955_BAND_FMUSER);
404 akc6955_set_amband(AKC6955_BAND_AMUSER);
406 akc6955_set_tune(mode3k, ch);
410 unsigned char akc6955_get_cnr(void)
414 f.byte = akc6955_readcmd(AKC6955_POWER);
416 b.byte = akc6955_readcmd(AKC6955_CNR_FM);
418 b.byte = akc6955_readcmd(AKC6955_CNR_AM);
424 int akc6955_read_level(void)
427 unsigned char rflevel, iflevel;
434 f.byte = akc6955_readcmd(AKC6955_POWER);
435 b = akc6955_readcmd(AKC6955_PGALEVEL);
436 rflevel = (b & 0xe0) >> 5;
437 iflevel = (b & 0x1c) >> 2;
438 totallevel = rflevel + iflevel;
440 rssi = (int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
441 // totallevel = rssi + 6*totallevel;
442 level = (int)(totallevel * 6 + rssi);
444 level = 103 - level; // totallevel * 6
446 freq = akc6955_get_freq();
447 if(freq > 2560) { // ASSUME SW
449 } else { // ASSUME MW,LW
457 // Get diff. unit = 100Hz.
458 int akc6955_get_diff(void)
464 diff.byte = akc6955_readcmd(AKC6955_FDNUM);
467 n = -((int) diff.byte);
473 f.byte = akc6955_readcmd(AKC6955_POWER);
480 void akc6955_up_freq(unsigned int step)
485 freq = akc6955_get_channel();
487 mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
488 akc6955_set_tune(mode3k.b7, freq);
492 void akc6955_down_freq(unsigned int step)
497 freq = akc6955_get_channel();
498 if(freq <= step) return;
500 mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
501 akc6955_set_tune(mode3k.b7, freq);
504 void akc6955_setvolumemode(unsigned char flag)
507 c.byte = akc6955_readcmd(AKC6955_ENABLE);
512 akc6955_writecmd(AKC6955_ENABLE, c.byte);
515 unsigned char akc6955_getvolumemode(void)
518 c.byte = akc6955_readcmd(AKC6955_ENABLE);
525 void akc6955_setvolume(unsigned char level)
528 // c = akc6955_readcmd(AKC6955_VOLUME) & 0x03;
529 if(level > 63) level = 63;
530 akc6955_writecmd(AKC6955_VOLUME, ((akc6955_readcmd(AKC6955_VOLUME) & 0x03) | (level << 2)));
533 unsigned char akc6955_getvolume(void)
536 c = akc6955_readcmd(AKC6955_VOLUME) >> 2;
540 void akc6955_set_prevolume(unsigned char level)
543 c = akc6955_readcmd(AKC6955_PRE) & 0xf3;
544 c |= ((level & 0x03) << 2);
545 akc6955_writecmd(AKC6955_PRE, c);
548 unsigned char akc6955_get_prevolume(void)
551 c = akc6955_readcmd(AKC6955_PRE) & 0x0c;
557 void akc6955_setphase(unsigned char flag)
560 c.byte = akc6955_readcmd(AKC6955_VOLUME);
566 akc6955_writecmd(AKC6955_VOLUME, c.byte);
569 void akc6955_setline(unsigned char flag)
572 c.byte = akc6955_readcmd(AKC6955_VOLUME);
577 akc6955_writecmd(AKC6955_VOLUME, c.byte);
580 void akc6955_set_lowboost(unsigned char flag)
583 c.byte = akc6955_readcmd(AKC6955_STEREO);
588 akc6955_writecmd(AKC6955_STEREO, c.byte);
591 void akc6955_set_stereomode(unsigned char mode)
594 c = akc6955_readcmd(AKC6955_STEREO);
595 mode = (mode & 0x03) << 2;
596 c = (c & 0xf3) | mode;
597 akc6955_writecmd(AKC6955_STEREO, c);
600 unsigned char akc6955_get_stereo(void)
603 c = akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
612 unsigned int akc6955_get_battery(void)
616 c = akc6955_readcmd(AKC6955_VBAT) & 0x3f;