OSDN Git Service

[EEPROM][V2.0] DO NOT CLEAR USERBAND on initializing.
[openi2cradio/OpenI2CRadio.git] / akc6955.c
index 170027b..18f99cd 100644 (file)
--- a/akc6955.c
+++ b/akc6955.c
 #include "power.h"
 #include "commondef.h"
 #include "menu.h"
+#include "ui.h"
 
-void akc6955_writecmd(unsigned char reg, unsigned char data)
+unsigned char akc6955_readcmd(unsigned char reg)
 {
-#ifdef __SDCC
-    i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
-    I2C_START();
-    i2c_writechar(0x20);
-    i2c_writechar(reg);
-    i2c_writechar(data);
-    I2C_STOP();
-    i2c_close();
-    delay100tcy(2);
-#else
-    OpenI2C(MASTER, SLEW_OFF);
-    StartI2C();
-    WriteI2C(0x20);
-    //delay1ktcy(8);
-    WriteI2C(reg);
-    //delay1ktcy(8);
-    WriteI2C(data);
-    //delay1ktcy(8);
-    StopI2C();
- //   delay1ktcy(8);
-    CloseI2C();
-//    CLOSEASMASTER();
-#endif  //    i2c_idle();
+   return i2c_read_byte(AKC6955_ADDRESS, reg);
 }
 
-unsigned char akc6955_readcmd(unsigned char reg)
+void akc6955_writecmd(unsigned char reg,unsigned char data)
 {
-    unsigned char c;
-    //    OPENASMASTER();
-#ifdef __SDCC
-    i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
-#else
-    OpenI2C(MASTER, SLEW_OFF);
-#endif
-#ifdef __SDCC
-    I2C_START();
-    i2c_writechar(0x20);
-    i2c_writechar(reg);
-    I2C_STOP();
-    delay100tcy(2);
-    I2C_START();
-    i2c_writechar(0x21);
-    c = i2c_readchar();
-    I2C_ACK();
-    I2C_STOP();
-    i2c_close();
-#else
-    StartI2C();
-    WriteI2C(0x20);
-  //  delay1ktcy(8);
-    WriteI2C(reg);
-  //  delay1ktcy(8);
-    StopI2C();
-    __delay_us(13);
-    StartI2C();
-    WriteI2C(0x21);
-  //  delay1ktcy(8);
-    c = ReadI2C();
-    AckI2C();
-    StopI2C();
- //   delay1ktcy(8);
-    CloseI2C();
-#endif
-    //    CLOSEASMASTER();
+    i2c_send_byte(AKC6955_ADDRESS, reg, data);
+}
 
-    return c;
+unsigned char akc6955_get_band(void)
+{
+    return akc6955_readcmd(AKC6955_BAND);
+}
+
+unsigned char akc6955_get_amband(void)
+{
+   return akc6955_get_band() >> 3; 
+}
+
+unsigned char akc6955_get_fmband(void)
+{
+   return akc6955_get_band() & 0x07; 
 }
 
+
 void akc6955_chg_fm(unsigned char f, unsigned int freq)
 {
     __bitops_t b;
@@ -118,13 +75,13 @@ void akc6955_chg_fm(unsigned char f, unsigned int freq)
     b.b6 = 0;
     if(f != 0){
         b.b6 = 1;
-        akc6955_set_fmband(fmband);
+        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(amband);
+    akc6955_set_amband(setup.amband);
     akc6955_set_freq(freq);
 
 }
@@ -168,12 +125,6 @@ void akc6955_set_fmband(unsigned char band)
     akc6955_do_tune();
 }
 
-unsigned char akc6955_get_band(void)
-{
-    return akc6955_readcmd(AKC6955_BAND);
-}
-
-
 void akc6955_set_power(unsigned char on)
 {
     __bitops_t b;
@@ -216,6 +167,9 @@ unsigned char akc6955_tune(void)
 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){
@@ -223,34 +177,60 @@ void akc6955_mode3k(unsigned char flag)
     }
     akc6955_writecmd(AKC6955_CH_HI, b.byte);
     akc6955_do_tune();
-    _AKC6955_WAIT_62_5MS();
+}
+
+unsigned char akc6955_get_mode3k(void)
+{
+    __bitops_t c;
+    c.byte = akc6955_readcmd(AKC6955_CNR_AM);
+    if(c.b7) {
+        return 0xff;
+    }
+    return 0;
 }
 
 void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
 {
     unsigned char band;
-    __bitops_t f;
+    unsigned char f;
     __bitops_t b;
     unsigned int i = ch;
     unsigned char comp;
+    unsigned int start, stop;
+    unsigned char q;
 
     do { // Wait for before completed
         comp = akc6955_chk_donescan();
         idle_time_35ms();
     } while(comp == 0x00);
-    f.byte = akc6955_readcmd(AKC6955_POWER);
-    band = 0;
-    if(!f.b6){
-        akc6955_get_amband(band);
-    }
 
-    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
+    f = akc6955_get_fm();
+    band = 0;
+    if(f == 0){
+        band = akc6955_get_amband();
+        if(band == AKC6955_BAND_AMUSER){
+            start = userband.am_usrbands[setup.am_userbandnum].start * 32;
+            stop = userband.am_usrbands[setup.am_userbandnum].stop * 32;
+        } else {
+            if(mode_3k != 0) {
+                q = 3;
+            } else {
+                q = 5;
+            }
+            start = ambands[band].start / q;
+            stop  = ambands[band].end / q;
+        }
+    } else {
+        band = akc6955_get_fmband();
+        start = ((fmbands[band].start - 3000) * 2) / 5;
+        stop = ((fmbands[band].end - 3000) * 2) / 5;;
+        if(band == AKC6955_BAND_FMUSER){
+            start = userband.fm_usrbands[setup.fm_userbandnum].start * 32;
+            stop = userband.fm_usrbands[setup.fm_userbandnum].stop * 32;
+        }
     }
-    if(i > 0x1fff) i = 0x1fff;
-    //i = ch & 0x1fff;
+    if(i > stop) i = stop; // ADD
+    if(i < start) i = start;
 
     b.byte = i & 0xff;
     akc6955_writecmd(AKC6955_CH_LO, b.byte);
@@ -268,21 +248,37 @@ void akc6955_set_tune(unsigned char mode_3k, unsigned int ch)
 void akc6955_do_scan(unsigned char up)
 {
     __bitops_t b;
- //   akc6955_do_tune();
+    unsigned char c;
+
+    //20130823 Need wait for scan/tune completed w/o SDCC 3.3.x.
+#ifndef __SDCC
+    while(akc6955_chk_donescan() == 0)
+    {
+        c = pollkey_single_timeout(1, 0);  // 23ms
+        if(c == charcode_a) return; // IF 'A' abort.
+        //idle_time_ms(35);
+    }
+#endif
     b.byte = akc6955_readcmd(AKC6955_POWER);
     b.b3 = 0;
     b.b4 = 0;
-    b.b5 = 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.
-    idle_time_35ms();
     akc6955_writecmd(AKC6955_POWER, b.byte);
-    idle_time_35ms();
+    idle_time_ms(35);
+
+    b.b4 = 1;
     if(up != 0) {
         b.b3= 1;
     }
-    b.b4 = 1;
     akc6955_writecmd(AKC6955_POWER, b.byte); // Raise seek bit to '1'.
+    idle_time_ms(35);
 }
 
 void akc6955_abort_scan(void)
@@ -301,6 +297,14 @@ void akc6955_set_scanrate_fm(unsigned char rate)
     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)
 {
     __bitops_t b;
@@ -326,22 +330,26 @@ unsigned int akc6955_get_channel(void)
  */
 unsigned int akc6955_get_freq(void)
 {
-    __bitops_t f, b;
+    __bitops_t b;
     unsigned int i;
     unsigned int freq;
     unsigned char band;
+    unsigned char q;
+    unsigned char f;
 
-    f.byte = akc6955_readcmd(AKC6955_POWER);
+    f = akc6955_get_fm();
     i = akc6955_get_channel();
-    if(f.b6){ // 25KHz
-        freq = (i * 5) / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
+    if(f != 0){ // 25KHz
+        freq = i * 2 + i / 2 + 3000; // freq' = 25*i[KHz] = (25 / 10) *i [10KHz]
     } else { // 5K
        b.byte = akc6955_readcmd(AKC6955_CH_HI);
-       akc6955_get_amband(band);
-       freq = i * 5;
-       if((band == AKC6955_BAND_MW2) || (b.b5)){
-           freq = i * 3;
+       band = akc6955_get_amband();
+       if((band == AKC6955_BAND_MW2) || (band == AKC6955_BAND_LW) || (b.b5)){
+           q = 3;
+       } else {
+           q = 5;
        }
+       freq = i * q;
     }
     return freq;
 }
@@ -349,58 +357,39 @@ unsigned int akc6955_get_freq(void)
 void akc6955_set_freq(unsigned int freq)
 {
     unsigned int ch;
-    __bitops_t f;
     __bitops_t mode3k;
     unsigned char band;
-    unsigned int start, stop;
-
-    f.byte = akc6955_readcmd(AKC6955_POWER);
-    if(f.b6) { // FM
-        akc6955_get_fmband(band);
-//        band &= 7;
-        if(band == AKC6955_BAND_FMUSER){
-            start = fm_usrbands[fm_userbandnum].start * 32;
-            stop = fm_usrbands[fm_userbandnum].stop * 32;
-        } else {
-            start = fmbands[band].start;
-            stop = fmbands[band].end;
-        }
-        ch = freq - 3000;
-        ch = (ch << 2) / 10;
+    unsigned char q;
+    unsigned char f;
+
+    f = akc6955_get_fm();
+    if(f != 0) { // FM
+       band = akc6955_get_fmband();
+       //        band &= 7;
+       ch = ((freq - 3000) * 2) / 5;
     } else {
-        akc6955_get_amband(band);
-//        if(band >= AKC6955_BAND_AMEND) band = AKC6955_BAND_AMEND - 1;
-        if(band == AKC6955_BAND_AMUSER){
-            start = am_usrbands[am_userbandnum].start * 32;
-            stop = am_usrbands[am_userbandnum].stop * 32;
-        } else {
-            start = ambands[band].start;
-            stop = ambands[band].end;
-        }
+        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  if(mode3k.b7){
-            ch = freq / 3;
+        if((band == AKC6955_BAND_MW2) || (band == AKC6955_BAND_LW) || (mode3k.b7)){
+            q = 3;
+            mode3k.b7 = 1;
         } else {
-            ch = freq / 5;
+            q = 5;
+            mode3k.b7 = 0;
         }
+        ch = freq / q;
     }
-    if(freq <  start) freq = start;
-    if(freq >= stop)   freq = stop - 1;
     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;
+    unsigned char f;
 
-    f.byte = akc6955_readcmd(AKC6955_POWER);
+    f = akc6955_get_fm();
     akc6955_writecmd(AKC6955_UCH_ST, start);
     akc6955_writecmd(AKC6955_UCH_EN, stop);
-    if(f.b6){
+    if(f != 0){
         akc6955_set_fmband(AKC6955_BAND_FMUSER);
     } else {
         akc6955_set_amband(AKC6955_BAND_AMUSER);
@@ -411,10 +400,10 @@ void akc6955_set_userband(unsigned char start, unsigned char stop, unsigned int
 
 unsigned char akc6955_get_cnr(void)
 {
-    __bitops_t f;
+    unsigned char f;
     __bitops_t b;
-    f.byte = akc6955_readcmd(AKC6955_POWER);
-    if(f.b6) { // FM
+    f = akc6955_get_fm();
+    if(f != 0) { // FM
         b.byte = akc6955_readcmd(AKC6955_CNR_FM);
     } else { // AM
         b.byte = akc6955_readcmd(AKC6955_CNR_AM);
@@ -425,7 +414,7 @@ unsigned char akc6955_get_cnr(void)
 
 int akc6955_read_level(void)
 {
-    __bitops_t f;
+    unsigned char f;
     unsigned char rflevel, iflevel;
     unsigned char b;
     int rssi;
@@ -433,16 +422,15 @@ int akc6955_read_level(void)
     int totallevel;
     int level;
 
-    f.byte = akc6955_readcmd(AKC6955_POWER);
+    f = akc6955_get_fm();
     b =  akc6955_readcmd(AKC6955_PGALEVEL);
     rflevel = (b & 0xe0) >> 5;
     iflevel = (b & 0x1c) >> 2;
     totallevel = rflevel + iflevel;
 
     rssi = (int)(akc6955_readcmd(AKC6955_RSSI) & 0x7f);
-    // totallevel = rssi + 6*totallevel;
     level = (int)(totallevel * 6 + rssi);
-    if(f.b6){
+    if(f != 0){
         level = 103 - level; // totallevel * 6
     } else {
         freq = akc6955_get_freq();
@@ -460,7 +448,7 @@ int akc6955_read_level(void)
 int akc6955_get_diff(void)
 {
     __bitops_t diff;
-    __bitops_t f;
+    unsigned char f;
     int n;
 
     diff.byte = akc6955_readcmd(AKC6955_FDNUM);
@@ -472,8 +460,8 @@ int akc6955_get_diff(void)
         n = (int)diff.byte;
     }
 
-    f.byte = akc6955_readcmd(AKC6955_POWER);
-    if(f.b6) { // FM
+    f = akc6955_get_fm();
+    if(f != 0) { // FM
         return n * 10;
     }
     return n; // 10n
@@ -620,11 +608,28 @@ unsigned int akc6955_get_battery(void)
     return batt;
 }
 
+/*
+ * Misc
+ */
+void akc6955_set_fmbandwidth(unsigned char bw)
+{
+   unsigned char c = akc6955_readcmd(AKC6955_STEREO);
+   c = (c & 0xfc) | (bw & 0x03);
+   akc6955_writecmd(AKC6955_STEREO, c);
+}
+
+unsigned char akc6955_get_fmbandwidth(void)
+{
+    return (akc6955_readcmd(AKC6955_STEREO) & 0x03);
+}
+
+
+
 void akc6955_set_thresh_fmstereo(unsigned char a)
 {
     unsigned char b;
     a = a & 0x03;
-    threshold_fmstereo = a;
+    setup.threshold_fmstereo = a;
     b = akc6955_readcmd(AKC6955_THRESH) & 0xfc;
     akc6955_writecmd(AKC6955_THRESH, a | b);
 }
@@ -633,7 +638,7 @@ void akc6955_set_thresh_width(unsigned char a)
 {
     unsigned char b;
     a = a & 0x03;
-    threshold_width = a;
+    setup.threshold_width = a;
     a = a << 2; // << 2
     b = akc6955_readcmd(AKC6955_THRESH) & 0xf3;;
     akc6955_writecmd(AKC6955_THRESH, a | b);
@@ -643,7 +648,7 @@ void akc6955_set_thresh_amcnr(unsigned char a)
 {
     unsigned char b;
     a = a & 0x03;
-    threshold_amcnr = a;
+    setup.threshold_amcnr = a;
     a = a << 4; // << 4
     b = akc6955_readcmd(AKC6955_THRESH) & 0xcf;
     akc6955_writecmd(AKC6955_THRESH, a | b);
@@ -653,7 +658,7 @@ void akc6955_set_thresh_fmcnr(unsigned char a)
 {
     unsigned char b;
     a = a & 0x03;
-    threshold_fmcnr = a;
+    setup.threshold_fmcnr = a;
     a = a << 6; // << 4
     b = akc6955_readcmd(AKC6955_THRESH) & 0x3f;
     akc6955_writecmd(AKC6955_THRESH, a | b);