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.
40 #include "commondef.h"
42 void akc6955_writecmd(unsigned char reg, unsigned char data)
46 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
60 OpenI2C(MASTER, SLEW_OFF);
75 unsigned char akc6955_readcmd(unsigned char reg)
80 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
82 OpenI2C(MASTER, SLEW_OFF);
124 void akc6955_chg_fm(unsigned char f)
127 b.byte = akc6955_readcmd(AKC6955_POWER);
132 akc6955_writecmd(AKC6955_POWER, b.byte);
136 unsigned char akc6955_get_fm(void)
139 b.byte = akc6955_readcmd(AKC6955_POWER);
147 void akc6955_set_amband(unsigned char band)
150 b = akc6955_readcmd(AKC6955_BAND);
151 b &= 0x07; // extract FM
152 b = b | ((band & 0x1f) << 3);
153 akc6955_writecmd(AKC6955_BAND, b);
156 void akc6955_set_fmband(unsigned char band)
159 b = akc6955_readcmd(AKC6955_BAND);
160 b &= 0xf8; // extract AM
161 b = b | (band & 0x07);
162 akc6955_writecmd(AKC6955_BAND, b);
165 unsigned char akc6955_get_amband(void)
168 b = akc6955_readcmd(AKC6955_BAND);
173 unsigned char akc6955_get_fmband(void)
176 b = akc6955_readcmd(AKC6955_BAND);
182 void akc6955_set_power(unsigned char on)
185 b.byte = akc6955_readcmd(AKC6955_POWER);
191 akc6955_writecmd(AKC6955_POWER, b.byte);
195 void akc6955_do_tune(void)
198 b.byte = akc6955_readcmd(AKC6955_POWER);
199 b.b5 = 0; // Tun = '0'
200 b.b4 = 0; // Force abort scan.
201 akc6955_writecmd(AKC6955_POWER, b.byte);
203 // Need sleep?-> Need! this sequence re fer from reference code.
204 b.b5= 1; // Tun = '1'
205 akc6955_writecmd(AKC6955_POWER, b.byte);
208 akc6955_writecmd(AKC6955_POWER, b.byte);
213 unsigned char akc6955_tune(void)
216 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
224 unsigned int akc6955_mode3k(unsigned char flag)
227 b.byte = akc6955_readcmd(AKC6955_CH_HI);
233 akc6955_writecmd(AKC6955_CH_HI, b.byte);
235 _AKC6955_WAIT_62_5MS();
236 return akc6955_get_freq();
239 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
247 do { // Wait for before completed
248 comp = akc6955_chk_donescan();
250 } while(comp = 0x00);
251 f.byte = akc6955_readcmd(AKC6955_POWER);
256 band = akc6955_get_amband();
261 i = ch / 3; // On MW2, Channnel must be multiple of 3.
262 i = i * 3; // i = (i/3) * 3
264 if(i > 0x1fff) i = 0x1fff;
268 akc6955_writecmd(AKC6955_CH_LO, b.byte);
273 b.b5 = 1; // Mode 3K ON
275 akc6955_writecmd(AKC6955_CH_HI, b.byte);
280 void akc6955_do_scan(unsigned char up)
283 // akc6955_do_tune();
284 b.byte = akc6955_readcmd(AKC6955_POWER);
288 akc6955_writecmd(AKC6955_POWER, b.byte);
289 b.b5 = 1; // Tune 0->1.
291 akc6955_writecmd(AKC6955_POWER, b.byte);
297 akc6955_writecmd(AKC6955_POWER, b.byte); // Raise seek bit to '1'.
300 void akc6955_abort_scan(void)
303 b = akc6955_readcmd(AKC6955_POWER);
305 akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
308 void akc6955_set_scanrate_fm(unsigned char rate)
311 c = akc6955_readcmd(AKC6955_SPACE);
312 c = (c & 0xcf) | ((rate & 0x03) << 4);
313 akc6955_writecmd(AKC6955_SPACE, c);
316 unsigned char akc6955_chk_donescan(void)
319 b.byte = akc6955_readcmd(AKC6955_RCH_HI);
328 * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
330 unsigned int akc6955_get_freq(void)
337 // b = akc6955_readcmd(AKC6955_CNR_AM) & 0x80;
338 l = akc6955_readcmd(AKC6955_RCH_LO) ;
339 h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
340 f.byte = akc6955_readcmd(AKC6955_POWER);
343 freq = (i * 5) / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
345 // freq = freq' + 30MHz = freq' + 3000[10KHz]
347 b.byte = akc6955_readcmd(AKC6955_CH_HI);
349 freq = i * 3; // freq = 3*i[KHz] = (4+1)*i[KHz]
351 freq = i * 5; // freq = 5i[KHz] = (2+1)i[KHz]
357 void akc6955_set_freq(unsigned int freq)
364 f.byte = akc6955_readcmd(AKC6955_POWER);
366 band = akc6955_get_fmband();
368 // if(freq < fmbands[band].start) freq = fmbands[band].start;
369 // if(freq >= fmbands[band].end) freq = fmbands[band].end - 1;
373 band = akc6955_get_amband();
374 if(band >= AKC6955_BAND_AMEND) band = AKC6955_BAND_AMEND - 1;
375 // if(freq < ambands[band].start) freq = ambands[band].start;
376 // if(freq >= ambands[band].end) freq = ambands[band].end - 1;
377 mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
384 akc6955_set_tune(mode3k.b7, ch);
387 void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int ch, unsigned char mode3k)
391 f.byte = akc6955_readcmd(AKC6955_POWER);
392 akc6955_writecmd(AKC6955_UCH_ST, start);
393 akc6955_writecmd(AKC6955_UCH_EN, stop);
395 akc6955_set_fmband(AKC6955_BAND_FMUSER);
397 akc6955_set_amband(AKC6955_BAND_AMUSER);
399 akc6955_set_tune(mode3k, ch);
403 unsigned char akc6955_get_cnr(void)
407 f.byte = akc6955_readcmd(AKC6955_POWER);
409 b.byte = akc6955_readcmd(AKC6955_CNR_FM);
411 b.byte = akc6955_readcmd(AKC6955_CNR_AM);
417 int akc6955_read_level(void)
420 unsigned char rflevel, iflevel;
427 f.byte = akc6955_readcmd(AKC6955_POWER);
428 b = akc6955_readcmd(AKC6955_PGALEVEL);
429 rflevel = (b & 0xe0) >> 5;
430 iflevel = (b & 0x1c) >> 2;
431 totallevel = rflevel + iflevel;
433 rssi = (int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
434 // totallevel = rssi + 6*totallevel;
435 level = (int)(totallevel * 6 + rssi);
437 level = 103 - level; // totallevel * 6
439 freq = akc6955_get_freq();
440 if(freq > 2560) { // ASSUME SW
442 } else { // ASSUME MW,LW
449 // Get diff. unit = 100Hz.
450 int akc6955_get_diff(void)
456 diff.byte = akc6955_readcmd(AKC6955_FDNUM);
459 n = -((int) diff.byte);
465 f.byte = akc6955_readcmd(AKC6955_POWER);
472 unsigned int akc6955_up_freq(unsigned int step)
478 f.byte = akc6955_readcmd(AKC6955_POWER);
479 freq = akc6955_get_freq();
482 band = akc6955_get_fmband();
483 if(band >= AKC6955_BAND_FMEND) band = AKC6955_BAND_FMEND - 1;
484 if(freq >= fmbands[band].end) freq = fmbands[band].end - 1;
486 band = akc6955_get_amband();
487 if(band >= AKC6955_BAND_AMEND) band = AKC6955_BAND_AMEND - 1;
488 if(freq >= ambands[band].end) freq = ambands[band].end - 1;
490 akc6955_set_freq(freq);
491 return akc6955_get_freq();
495 unsigned int akc6955_down_freq(unsigned int step)
501 freq = akc6955_get_freq();
502 if(freq <= step) return freq;
505 f.byte = akc6955_readcmd(AKC6955_POWER);
507 band = akc6955_get_amband();
508 if(band >= AKC6955_BAND_AMEND) band = AKC6955_BAND_AMEND - 1;
509 if(freq < ambands[band].start) freq = ambands[band].start;
511 band = akc6955_get_fmband();
512 if(band >= AKC6955_BAND_FMEND) band = AKC6955_BAND_FMEND - 1;
513 if(freq < fmbands[band].start) freq = fmbands[band].start;
515 akc6955_set_freq(freq);
516 return akc6955_get_freq();
518 void akc6955_setvolumemode(unsigned char flag)
521 c.byte = akc6955_readcmd(AKC6955_ENABLE);
526 akc6955_writecmd(AKC6955_ENABLE, c.byte);
529 unsigned char akc6955_getvolumemode(void)
532 c.byte = akc6955_readcmd(AKC6955_ENABLE);
539 void akc6955_setvolume(unsigned char level)
542 // c = akc6955_readcmd(AKC6955_VOLUME) & 0x03;
543 if(level > 63) level = 63;
544 akc6955_writecmd(AKC6955_VOLUME, ((akc6955_readcmd(AKC6955_VOLUME) & 0x03) | (level << 2)));
547 unsigned char akc6955_getvolume(void)
550 c = akc6955_readcmd(AKC6955_VOLUME) >> 2;
554 void akc6955_set_prevolume(unsigned char level)
557 c = akc6955_readcmd(AKC6955_PRE) & 0xf3;
558 c |= ((level & 0x03) << 2);
559 akc6955_writecmd(AKC6955_PRE, c);
562 unsigned char akc6955_get_prevolume(void)
565 c = akc6955_readcmd(AKC6955_PRE) & 0x0c;
571 void akc6955_setphase(unsigned char flag)
574 c.byte = akc6955_readcmd(AKC6955_VOLUME);
580 akc6955_writecmd(AKC6955_VOLUME, c.byte);
583 void akc6955_setline(unsigned char flag)
586 c.byte = akc6955_readcmd(AKC6955_VOLUME);
591 akc6955_writecmd(AKC6955_VOLUME, c.byte);
594 void akc6955_set_lowboost(unsigned char flag)
597 c.byte = akc6955_readcmd(AKC6955_STEREO);
602 akc6955_writecmd(AKC6955_STEREO, c.byte);
605 void akc6955_set_stereomode(unsigned char mode)
608 c = akc6955_readcmd(AKC6955_STEREO);
609 mode = (mode & 0x03) << 2;
610 c = (c & 0xf3) | mode;
611 akc6955_writecmd(AKC6955_STEREO, c);
614 unsigned char akc6955_get_stereo(void)
617 c = akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
626 unsigned int akc6955_get_battery(void)
630 c = akc6955_readcmd(AKC6955_VBAT) & 0x3f;