OSDN Git Service

[v1.0][Doc] v1.0(.0) Release.
[openi2cradio/OpenI2CRadio.git] / akc6955.c
index b8f2f35..6bba528 100644 (file)
--- a/akc6955.c
+++ b/akc6955.c
 
 #include <stdarg.h>
 #include <stdio.h>
+#ifdef __SDCC
 #include <delay.h>
+#else
+#include <xc.h>
+#endif
 #include <string.h>
 #include "akc6955.h"
 #include "i2c_io.h"
+#include "idle.h"
+#include "power.h"
+#include "commondef.h"
+#include "menu.h"
 
 
-
-void akc6955_writecmd(unsigned char reg, unsigned char data)
+unsigned char akc6955_get_amband(void)
 {
-    i2c_idle();
-    OPENASMASTER();
-    i2c_writechar(AKC6955_ADDRESS);
-    i2c_writechar(reg);
-    i2c_writechar(data);
-    CLOSEASMASTER();
+   return akc6955_get_band() >> 3;
 }
 
-unsigned char akc6955_readcmd(unsigned char reg)
+unsigned char akc6955_get_fmband(void)
 {
-    unsigned char c;
-    i2c_idle();
-    OPENASMASTER();
-    i2c_writechar(AKC6955_ADDRESS);
-    i2c_writechar(reg);
-    c = i2c_readchar();
-    CLOSEASMASTER();
-    return c;
+   return akc6955_get_band() & 0x07;
 }
 
+void akc6955_chg_fm(unsigned char f, unsigned int freq)
+{
+    __bitops_t b;
+    b.byte = akc6955_readcmd(AKC6955_POWER);
+    b.b6 = 0;
+    if(f != 0){
+        b.b6 = 1;
+        akc6955_set_fmband(setup.fmband);
+        akc6955_writecmd(AKC6955_POWER, b.byte);
+        akc6955_set_freq(freq);
+        return;
+    }
+    akc6955_writecmd(AKC6955_POWER, b.byte);
+    akc6955_set_amband(setup.amband);
+    akc6955_set_freq(freq);
+
+}
 
-void akc6955_chg_fm(unsigned char fm)
+unsigned char akc6955_get_fm(void)
 {
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_POWER);
-    if(fm != 0){
-        b |= 0x40;
-    } else {
-        b &= 0xbf;
+    __bitops_t b;
+    b.byte = akc6955_readcmd(AKC6955_POWER);
+    if(b.b6){
+        return 0xff;
     }
-    akc6955_writecmd(AKC6955_POWER, b);
+    return 0;
 }
 
+
 void akc6955_set_amband(unsigned char band)
 {
     unsigned char b;
+    unsigned char c;
+
+    c = RFAMP_SW;
+    if((band < AKC6955_BAND_SW1) || (band == AKC6955_BAND_MW4)) {
+        c = RFAMP_MWLW;
+    }
+    rfamp_power(c);
     b = akc6955_readcmd(AKC6955_BAND);
     b &= 0x07; // extract FM
     b = b | ((band & 0x1f) << 3);
     akc6955_writecmd(AKC6955_BAND, b);
+    akc6955_do_tune();
 }
 
 void akc6955_set_fmband(unsigned char band)
 {
     unsigned char b;
+    rfamp_power(RFAMP_FM);
     b = akc6955_readcmd(AKC6955_BAND);
     b &= 0xf8; // extract AM
     b = b | (band & 0x07);
     akc6955_writecmd(AKC6955_BAND, b);
+    akc6955_do_tune();
 }
 
-unsigned char akc6955_get_amband(void)
+unsigned char akc6955_get_band(void)
 {
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_BAND);
-    b = (b & 0xf8) >> 3;
-    return b;
+    return akc6955_readcmd(AKC6955_BAND);
 }
 
-unsigned char akc6955_get_fmband(void)
-{
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_BAND);
-    b = b & 0x07;
-    return b;
-}
 
 void akc6955_set_power(unsigned char on)
 {
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_POWER);
+    __bitops_t b;
+    b.byte = akc6955_readcmd(AKC6955_POWER);
+    b.b7 = 0;
     if(on != 0){
-        b |= 0x80;
-    } else {
-        b &= 0x7f;
+        b.b7 = 1;
     }
-    akc6955_writecmd(AKC6955_POWER, b);
+    akc6955_writecmd(AKC6955_POWER, b.byte);
 }
 
 void akc6955_do_tune(void)
 {
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_POWER);
-    b &= 0xdf; // Tun = '0'
-    akc6955_writecmd(AKC6955_POWER, b);
-    // Need sleep?
-    b |= 0x20; // Tun = '1'
-    akc6955_writecmd(AKC6955_POWER, b);
+    __bitops_t b;
+    b.byte = akc6955_readcmd(AKC6955_POWER);
+    b.b5 = 0; // Tun = '0'
+    b.b4 = 0; // Force abort scan.
+    akc6955_writecmd(AKC6955_POWER, b.byte);
+    idle_time_ms(1);
+    // Need sleep?-> Need! this sequence re                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 fer from reference code.
+    b.b5= 1; // Tun = '1'
+    akc6955_writecmd(AKC6955_POWER, b.byte);
+    idle_time_ms(1);
+    b.b5 = 0;
+    akc6955_writecmd(AKC6955_POWER, b.byte);
+    idle_time_ms(8);
 }
 
 unsigned char akc6955_tune(void)
 {
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_RCH_HI) & 0x20;
-    if(b == 0x00) {
-        return 0;
-    } else {
+    __bitops_t b;
+    b.byte = akc6955_readcmd(AKC6955_RCH_HI);
+    if(b.b5) {
         return 0xff;
     }
+    return 0;
 }
 
-unsigned int akc6955_mode3k(unsigned char flag)
+unsigned char akc6955_get_mode3k(void)
 {
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_CH_HI);
+    __bitops_t c;
+    c.byte = akc6955_readcmd(AKC6955_CNR_AM);
+    if(c.b7) {
+        return 0xff;
+    }
+    return 0;
+}
+
+
+void akc6955_mode3k(unsigned char flag)
+{
+    __bitops_t b;
+    b.byte = akc6955_readcmd(AKC6955_CH_LO);
+    akc6955_writecmd(AKC6955_CH_LO, b.byte);
+
+    b.byte = akc6955_readcmd(AKC6955_CH_HI);
+    b.b5 = 0;
     if(flag != 0){
-        b |= 0x20;
-    } else {
-        b &= 0xdf;
+        b.b5 = 1;
     }
-    akc6955_writecmd(AKC6955_CH_HI, b);
-//    akc6955_do_tune();
-    _AKC6955_WAIT_62_5MS();
-    return akc6955_get_freq();
+    akc6955_writecmd(AKC6955_CH_HI, b.byte);
+    akc6955_do_tune();
 }
 
 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
 {
     unsigned char band;
-    unsigned char fm;
-    unsigned char b;
-    unsigned int i;
-
-    i = ch;
-    fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
-    if(fm == 0){
-        // AM
-        band = akc6955_get_amband();
+    __bitops_t f;
+    __bitops_t b;
+    unsigned int i = ch;
+    unsigned char comp;
+    unsigned int start;
+    unsigned int stop;
+    unsigned int q;
+
+    do { // Wait for before completed
+        comp = akc6955_chk_donescan();
+        idle_time_35ms();
+    } while(comp == 0x00);
+   
+    f.byte = akc6955_readcmd(AKC6955_POWER);
+    if(!f.b6){ // AM
+       band = akc6955_get_amband(); 
+       if(band == AKC6955_BAND_MW2){
+         // BAND=AM && MW2
+         i = ch / 3; // On MW2, Channnel must be multiple of 3.
+         i = i * 3; // i = (i/3) * 3
+         mode_3k = 0xff;
+         q = 3;
+       } else if(mode_3k != 0) {
+         q = 3;
+       } else {
+         q = 5;
+       }
+       
+        if(band == AKC6955_BAND_AMUSER) {
+           start = setup.am_usrbands[setup.am_userbandnum].start * 32;
+           stop = setup.am_usrbands[setup.am_userbandnum].stop * 32;
+       } else {
+           start = ambands[band].start / q;
+           stop = ambands[band].end / q;
+       }
     } else {
-        band = 0;
-    }
-    if(band == 2){
-        // BAND=AM && MW2
-        i = (i / 3) * 3;
+       band = akc6955_get_fmband(); 
+        if(band == AKC6955_BAND_FMUSER) {
+           start = setup.fm_usrbands[setup.fm_userbandnum].start * 32;
+           stop = setup.fm_usrbands[setup.fm_userbandnum].stop * 32;
+       } else {
+           start = ((fmbands[band].start - 3000) * 4) / 10;
+           stop =  ((fmbands[band].end - 3000) * 4)  / 10;
+       }
     }
+   
     if(i > 0x1fff) i = 0x1fff;
-    //i = ch & 0x1fff;
+    if(i > stop) i = stop;
+    if(i < start) i = start;
+
+    b.byte = i & 0xff;
+    akc6955_writecmd(AKC6955_CH_LO, b.byte);
 
-    if(mode_3k == 0){
-        b = ((i >> 8) & 0x1f) | 0x40; // 32.768KHz clock
+    b.byte = i >> 8;
+    b.b6 = 1;
+    if((setup.fm == 0) && (mode_3k != 0)){
+        b.b5 = 1; // Mode 3K ON
     } else {
-        b = ((i >> 8) & 0x1f) | 0x60;
+       b.b5 = 0;
     }
-    akc6955_writecmd(AKC6955_CH_HI, b);
-    b = i & 0xff;
-    akc6955_writecmd(AKC6955_CH_LO, b);
+
+    akc6955_writecmd(AKC6955_CH_HI, b.byte);
+
     akc6955_do_tune();
-    do{
-        // Use software-delay, but recommands hardware-delay ;-(
-        _AKC6955_WAIT_12_5MS();
-    } while(akc6955_tune() == 0);
 }
 
 void akc6955_do_scan(unsigned char up)
 {
-    unsigned char b;
-    akc6955_do_tune();
-    b = akc6955_readcmd(AKC6955_POWER);
-    b &= 0xe3;
+    __bitops_t b;
+
+    //20130823 Need wait for scan/tune completed w/o SDCC 3.3.x.
+#ifndef __SDCC
+    while(akc6955_chk_donescan() == 0)
+    {
+        idle_time_ms(5);
+    }
+#endif
+    b.byte = akc6955_readcmd(AKC6955_POWER);
+    b.b3 = 0;
+    b.b4 = 0;
+// 20130823 : Is this collect?
+#ifdef __SDCC
+     b.b5 = 0;
+    akc6955_writecmd(AKC6955_POWER, b.byte);
+    idle_time_ms(35);
+#endif
+
+    b.b5 = 1; // Tune 0->1.
+    akc6955_writecmd(AKC6955_POWER, b.byte);
+    idle_time_ms(35);
+
+    b.b4 = 1;
     if(up != 0) {
-        b |= 0x08;
+        b.b3= 1;
     }
-    akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
-    b |= 0x10;
-    akc6955_writecmd(AKC6955_POWER, b); // Raise seek bit to '1'.
+    akc6955_writecmd(AKC6955_POWER, b.byte); // Raise seek bit to '1'.
+    idle_time_ms(35);
 }
 
 void akc6955_abort_scan(void)
@@ -212,120 +289,359 @@ void akc6955_abort_scan(void)
     akc6955_writecmd(AKC6955_POWER, b); // Falldown seek bit to '0'.
 }
 
+void akc6955_set_scanrate_fm(unsigned char rate)
+{
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_SPACE);
+    c = (c & 0xcf) | ((rate & 0x03) << 4);
+    akc6955_writecmd(AKC6955_SPACE, c);
+}
+
+unsigned char akc6955_get_scanrate_fm(void)
+{
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_SPACE);
+    c = (c & 0x30) >> 4;
+   return c;
+}
+
 unsigned char akc6955_chk_donescan(void)
 {
-    unsigned char b;
-    b = akc6955_readcmd(AKC6955_RCH_HI) & 0x40;
-    if(b == 0) return 0;
-    return 0xff;
+    __bitops_t b;
+    b.byte = akc6955_readcmd(AKC6955_RCH_HI);
+    if(b.b6){
+        return 0xff;
+    }
+    return 0;
 }
 
+unsigned int akc6955_get_channel(void)
+{
+    unsigned char h, l;
+    unsigned int u;
+    l = akc6955_readcmd(AKC6955_RCH_LO) ;
+    h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
+    u = (h << 8) | l;
+    return u;
+}
 
 /*
  * Get AM/FM Frequency: ret = KHz at AM, 10KHz @FM.
  */
 unsigned int akc6955_get_freq(void)
 {
-    unsigned char b, h, l;
-    unsigned char fm;
+    __bitops_t f, b;
     unsigned int i;
-    b = akc6955_readcmd(AKC6955_CNR_AM) & 0x80;
-    l = akc6955_readcmd(AKC6955_RCH_LO) ;
-    h = akc6955_readcmd(AKC6955_RCH_HI) & 0x1f;
-    fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
-    i = l + h * 256;
-    if(fm != 0){ // 25KHz
-        i = i * 10; // 25 / 10 = 10/4
-        i = i / 4;
-        i += 3000; // 30MHz
-    } else if(b == 0){ // 5K
-        i = i * 5;
-    } else { // 3K
-        i = i * 3;
+    unsigned int freq;
+    unsigned char band;
+
+    f.byte = akc6955_readcmd(AKC6955_POWER);
+    i = akc6955_get_channel();
+    if(f.b6){ // 25KHz
+        freq = (i * 5) / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
+    } else { // 5K
+       b.byte = akc6955_readcmd(AKC6955_CH_HI);
+       band = akc6955_get_amband();
+       freq = i * 5;
+       if((band == AKC6955_BAND_MW2) || (b.b5)){
+           freq = i * 3;
+       }
     }
-    return i;
+    return freq;
 }
 
 void akc6955_set_freq(unsigned int freq)
 {
     unsigned int ch;
-    unsigned char fm;
-    unsigned char mode3k = 0;
-
-    fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
-    if(fm != 0) { // FM
-      ch = freq - 3000;
-      ch = ch * 4;
-      ch = ch / 10; // 10/25 = 0.4
+    __bitops_t f;
+    __bitops_t mode3k;
+    unsigned char band;
+
+    f.byte = akc6955_readcmd(AKC6955_POWER);
+    if(f.b6) { // FM
+        band = akc6955_get_fmband();
+        ch = freq - 3000;
+        ch = (ch << 2) / 10;
     } else {
-        mode3k = akc6955_readcmd(AKC6955_CNR_AM) & 0x80;
-        if(mode3k == 0){
+        band = akc6955_get_amband();
+        mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
+        if(band == AKC6955_BAND_MW2) {
+            ch = (freq / 9) * 3; // See datasheet.
+        } else if(band == AKC6955_BAND_MW3) {
             ch = freq / 5;
-        } else {
+        } else  if(mode3k.b7){
             ch = freq / 3;
+        } else {
+            ch = freq / 5;
         }
     }
+    akc6955_set_tune(mode3k.b7, ch);
+}
+
+void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int ch, unsigned char mode3k)
+{
+    __bitops_t f;
+
+    f.byte = akc6955_readcmd(AKC6955_POWER);
+    akc6955_writecmd(AKC6955_UCH_ST, start);
+    akc6955_writecmd(AKC6955_UCH_EN, stop);
+    if(f.b6){
+        akc6955_set_fmband(AKC6955_BAND_FMUSER);
+    } else {
+        akc6955_set_amband(AKC6955_BAND_AMUSER);
+    }
     akc6955_set_tune(mode3k, ch);
 }
 
 
 unsigned char akc6955_get_cnr(void)
 {
-    unsigned char fm;
-    unsigned char b;
-    fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
-    if(fm != 0) { // FM
-        b = akc6955_readcmd(AKC6955_CNR_FM);
+    __bitops_t f;
+    __bitops_t b;
+    f.byte = akc6955_readcmd(AKC6955_POWER);
+    if(f.b6) { // FM
+        b.byte = akc6955_readcmd(AKC6955_CNR_FM);
     } else { // AM
-        b = akc6955_readcmd(AKC6955_CNR_AM);
+        b.byte = akc6955_readcmd(AKC6955_CNR_AM);
     }
-    b &= 0x7f;
-    return b;
+    b.b7 = 0;
+    return b.byte;
 }
 
 int akc6955_read_level(void)
 {
-    unsigned char fm;
+    __bitops_t f;
     unsigned char rflevel, iflevel;
     unsigned char b;
-    unsigned int rssi;
+    int rssi;
     unsigned int freq;
+    int totallevel;
     int level;
 
-    fm = akc6955_readcmd(AKC6955_POWER) & 0x40;
+    f.byte = akc6955_readcmd(AKC6955_POWER);
     b =  akc6955_readcmd(AKC6955_PGALEVEL);
     rflevel = (b & 0xe0) >> 5;
     iflevel = (b & 0x1c) >> 2;
-    rssi = (unsigned int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
-    if(fm != 0){
-        level = 103 - (rssi + 6 * (rflevel + iflevel));
+    totallevel = rflevel + iflevel;
+
+    rssi = (int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
+    // totallevel = rssi + 6*totallevel;
+    level = (int)(totallevel * 6 + rssi);
+    if(f.b6){
+        level = 103 - level; // totallevel * 6
     } else {
         freq = akc6955_get_freq();
         if(freq > 2560) { // ASSUME SW
-            level = 103 - (rssi + 6 * (rflevel + iflevel));
+            level = 103 - level;
         } else { // ASSUME MW,LW
-            level = 123 - (rssi + 6 * (rflevel + iflevel));
+            level = 123 - level;
         }
     }
     return level;
 }
 
-unsigned int akc6955_up_freq(unsigned int step)
+
+// Get diff. unit = 100Hz.
+int akc6955_get_diff(void)
+{
+    __bitops_t diff;
+    __bitops_t f;
+    int n;
+
+    diff.byte = akc6955_readcmd(AKC6955_FDNUM);
+    if(diff.b7) {
+        diff.b7 = 0;
+        n = -((int) diff.byte);
+    } else {
+        diff.b7 = 0;
+        n = (int)diff.byte;
+    }
+
+    f.byte = akc6955_readcmd(AKC6955_POWER);
+    if(f.b6) { // FM
+        return n * 10;
+    }
+    return n; // 10n
+}
+
+void akc6955_up_freq(unsigned int step)
 {
     unsigned int freq;
-    freq = akc6955_get_freq();
+    __bitops_t mode3k;
+
+    freq = akc6955_get_channel();
     freq += step;
-    akc6955_set_freq(freq);
-    return akc6955_get_freq();
+//    mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
+//    akc6955_set_tune(mode3k.b7, freq);
+    akc6955_set_tune(setup.am_mode3k, freq);
 }
 
 
-unsigned int akc6955_down_freq(unsigned int step)
+void akc6955_down_freq(unsigned int step)
 {
     unsigned int freq;
-    freq = akc6955_get_freq();
-    if(freq <= step) return freq;
+    __bitops_t mode3k;
+
+    freq = akc6955_get_channel();
+    if(freq <= step) return;
     freq -= step;
-    akc6955_set_freq(freq);
-    return akc6955_get_freq();
+//    mode3k.byte = akc6955_readcmd(AKC6955_CNR_AM);
+//    akc6955_set_tune(mode3k.b7, freq);
+    akc6955_set_tune(setup.am_mode3k, freq);
+}
+
+void akc6955_setvolumemode(unsigned char flag)
+{
+    __bitops_t c;
+    c.byte = akc6955_readcmd(AKC6955_ENABLE);
+    c.b3 = 0;
+    if(flag != 0x00){
+        c.b3 = 1;
+    }
+    akc6955_writecmd(AKC6955_ENABLE, c.byte);
+}
+
+unsigned char akc6955_getvolumemode(void)
+{
+    __bitops_t c;
+    c.byte = akc6955_readcmd(AKC6955_ENABLE);
+    if(c.b3){
+        return 0xff;
+    }
+    return 0;
+}
+
+void akc6955_setvolume(unsigned char level)
+{
+//    unsigned char c;
+//    c = akc6955_readcmd(AKC6955_VOLUME) & 0x03;
+    if(level > 63) level = 63;
+    akc6955_writecmd(AKC6955_VOLUME, ((akc6955_readcmd(AKC6955_VOLUME) & 0x03) | (level << 2)));
+}
+
+unsigned char akc6955_getvolume(void)
+{
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_VOLUME) >> 2;
+    return c;
+}
+
+void akc6955_set_prevolume(unsigned char level)
+{
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_PRE) & 0xf3;
+    c |= ((level & 0x03) << 2);
+    akc6955_writecmd(AKC6955_PRE, c);
+}
+
+unsigned char akc6955_get_prevolume(void)
+{
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_PRE) & 0x0c;
+    c >>= 2;
+    return c;
+}
+
+
+void akc6955_setphase(unsigned char flag)
+{
+    __bitops_t c;
+    c.byte = akc6955_readcmd(AKC6955_VOLUME);
+
+    c.b0 = 1;
+    if(flag == 0) {
+        c.b0 = 0; //
+    }
+    akc6955_writecmd(AKC6955_VOLUME, c.byte);
+}
+
+void akc6955_setline(unsigned char flag)
+{
+    __bitops_t c;
+    c.byte = akc6955_readcmd(AKC6955_VOLUME);
+    c.b1 = 1;
+    if(flag == 0) {
+        c.b1 = 0;
+    }
+    akc6955_writecmd(AKC6955_VOLUME, c.byte);
+}
+
+void akc6955_set_lowboost(unsigned char flag)
+{
+    __bitops_t c;
+    c.byte = akc6955_readcmd(AKC6955_STEREO);
+    c.b3 = 1;
+    if(flag == 0) {
+        c.b3 = 0;
+    }
+    akc6955_writecmd(AKC6955_STEREO, c.byte);
+}
+
+void akc6955_set_stereomode(unsigned char mode)
+{
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_STEREO);
+    mode = (mode & 0x03) << 2;
+    c = (c & 0xf3) | mode;
+    akc6955_writecmd(AKC6955_STEREO, c);
+}
+
+unsigned char akc6955_get_stereo(void)
+{
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_RCH_HI) & 0x80;
+    return c;
+}
+
+/*
+ * Get battery level.
+ * Unit = 0.01V
+ */
+
+unsigned int akc6955_get_battery(void)
+{
+    unsigned int batt;
+    unsigned char c;
+    c = akc6955_readcmd(AKC6955_VBAT) & 0x3f;
+    batt = 180 + c * 5;
+    return batt;
+}
+
+void akc6955_set_thresh_fmstereo(unsigned char a)
+{
+    unsigned char b;
+    a = a & 0x03;
+    setup.threshold_fmstereo = a;
+    b = akc6955_readcmd(AKC6955_THRESH) & 0xfc;
+    akc6955_writecmd(AKC6955_THRESH, a | b);
+}
+
+void akc6955_set_thresh_width(unsigned char a)
+{
+    unsigned char b;
+    a = a & 0x03;
+    setup.threshold_width = a;
+    a = a << 2; // << 2
+    b = akc6955_readcmd(AKC6955_THRESH) & 0xf3;;
+    akc6955_writecmd(AKC6955_THRESH, a | b);
+}
+
+void akc6955_set_thresh_amcnr(unsigned char a)
+{
+    unsigned char b;
+    a = a & 0x03;
+    setup.threshold_amcnr = a;
+    a = a << 4; // << 4
+    b = akc6955_readcmd(AKC6955_THRESH) & 0xcf;
+    akc6955_writecmd(AKC6955_THRESH, a | b);
+}
+
+void akc6955_set_thresh_fmcnr(unsigned char a)
+{
+    unsigned char b;
+    a = a & 0x03;
+    setup.threshold_fmcnr = a;
+    a = a << 6; // << 4
+    b = akc6955_readcmd(AKC6955_THRESH) & 0x3f;
+    akc6955_writecmd(AKC6955_THRESH, a | b);
 }