streaming server for AM/FM radio via UDP connection.

Dependencies:   mbed EthernetNetIf

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ns9542.c Source File

ns9542.c

00001 #include "mbed.h"
00002 
00003 //I2C i2c(p9, p10);        // sda, scl
00004 
00005 DigitalInOut i2c_sda(p9);
00006 DigitalInOut i2c_scl(p10);
00007 
00008 void wait10us()
00009 {
00010   wait(0.000001);
00011 }
00012 
00013 void wait10ms()
00014 {
00015   wait(0.001);
00016 }
00017 
00018 void wait100ms()
00019 {
00020   wait(0.01);
00021 }
00022 
00023 
00024 
00025 #if 1
00026 
00027 // i2c
00028 
00029 void i2c_cl_0()
00030 {
00031     i2c_scl.output();
00032 }
00033 
00034 void i2c_cl_1()
00035 {
00036     i2c_scl.input();
00037 }
00038 
00039 void i2c_da_0()
00040 {
00041     i2c_sda.output();
00042 }
00043 
00044 void i2c_da_1()
00045 {
00046     i2c_sda.input();
00047 }
00048 
00049 int i2c_get_da()
00050 {
00051   return i2c_sda.read();
00052 }
00053 
00054 void i2c_start()
00055 {
00056   i2c_da_0();
00057   wait10us();
00058   i2c_cl_0();
00059   wait10us();
00060 }
00061 
00062 void i2c_stop()
00063 {
00064   i2c_cl_1();
00065   wait10us();
00066   i2c_da_1();
00067   wait10us();
00068 }
00069 
00070 void i2c_repeat()
00071 {
00072   i2c_cl_1();
00073   wait10us();
00074   i2c_da_0();
00075   wait10us();
00076   i2c_cl_0();
00077   wait10us();
00078 }
00079 
00080 bool i2c_write(int c)
00081 {
00082   int i;
00083   bool nack;
00084 
00085   wait10us();
00086 
00087   for (i = 0; i < 8; i++) {
00088     if (c & 0x80) {
00089       i2c_da_1();
00090     } else {
00091       i2c_da_0();
00092     }
00093     c <<= 1;
00094     wait10us();
00095     i2c_cl_1();
00096     wait10us();
00097     i2c_cl_0();
00098     wait10us();
00099   }
00100 
00101   i2c_da_1();
00102   wait10us();
00103 
00104   i2c_cl_1();
00105   wait10us();
00106   nack = i2c_get_da();
00107   i2c_cl_0();
00108 
00109   return nack;
00110 }
00111 
00112 int i2c_read(bool nack)
00113 {
00114   int i, c;
00115 
00116   i2c_da_1();
00117   wait10us();
00118 
00119   c = 0;
00120 
00121   for (i = 0; i < 8; i++) {
00122     i2c_cl_1();
00123     wait10us();
00124     c <<= 1;
00125     if (i2c_get_da()) {
00126       c |= 1;
00127     }
00128     i2c_cl_0();
00129     wait10us();
00130   }
00131 
00132   if (nack) {
00133     i2c_da_1();
00134   } else {
00135     i2c_da_0();
00136   }
00137   wait10us();
00138   i2c_cl_1();
00139   wait10us();
00140   i2c_cl_0();
00141   wait10us();
00142 
00143   return c;
00144 }
00145 
00146 #endif
00147 
00148 
00149 // ns9542
00150 
00151 void ns9542_write(int a, int c)
00152 {
00153 #if 01
00154   i2c_start();
00155   i2c_write(0xc8);
00156   i2c_write(a);
00157   i2c_write(c);
00158   i2c_stop();
00159 #else
00160     char tmp[2];
00161     i2c.start();
00162     tmp[0] = a;
00163     tmp[1] = c;
00164     i2c.write(0xc8, tmp, 2);
00165     i2c.stop();
00166 #endif
00167 }
00168 
00169 int ns9542_read(int a)
00170 {
00171 #if 01
00172   int c;
00173   i2c_start();
00174   i2c_write(0xc8);
00175   i2c_write(a);
00176   i2c_repeat();
00177   i2c_write(0xc9);
00178   c = i2c_read(true);
00179   i2c_stop();
00180   return c;
00181 #else
00182     char tmp[2];
00183     i2c.start();
00184     tmp[0] = a;
00185     tmp[1] = 0xc9;
00186     i2c.write(0xc8, tmp, 1);
00187     i2c.write(0xc8, tmp + 1, 1, true);
00188     unsigned char c = i2c.read(1);
00189     i2c.stop();
00190     return c;
00191 #endif
00192 }
00193 
00194 void ns9542_imf_adjust()
00195 {
00196   int bF, imf, fhm, g_fhm;
00197   bF = 0;
00198   g_fhm = 0xf0;
00199   ns9542_write(0x15, 0x0e);
00200   ns9542_write(0x3d, 0x27);
00201   for (fhm = 0; fhm < 4; fhm++) {
00202     bF = 0;
00203     for (imf = 0; imf < 3; imf++) {
00204       ns9542_write(0x37, fhm);
00205       ns9542_write(0x16, 22 + imf);
00206       wait10ms();
00207       if ((ns9542_read(0x70) & 0x0c) == 0x0c) {
00208         bF++;
00209         if (imf == 1 && g_fhm == 0xf0) {
00210           g_fhm = fhm;
00211         }
00212       }
00213     }
00214     if (bF == 3) {
00215       g_fhm = fhm;
00216       break;
00217     }
00218   }
00219   ns9542_write(0x37, 0x80 | g_fhm);
00220   ns9542_write(0x16, 23);
00221   ns9542_write(0x3d, 0x37);
00222   wait100ms();
00223 }
00224 
00225 void ns9542_best_iml(int iml)
00226 {
00227   ns9542_write(0x32, 0x00);
00228   while (iml < 16) {
00229     ns9542_write(0x17, 0xc0 | iml);
00230     wait10ms();
00231     if (!(ns9542_read(0x70) & 0x08)) {
00232       break;
00233     }
00234     iml++;
00235   }
00236   iml--;
00237   ns9542_write(0x17, 0xc0 | iml);
00238   ns9542_write(0x32, 0x80);
00239   wait10ms();
00240   ns9542_write(0xfe, 0x0a);
00241   wait10ms();
00242   wait10ms();
00243 }
00244 
00245 void ns9542_find_pg(int ialgn, int *fine_phase, int *fine_gain, int *result_pg)
00246 {
00247   int i, j;
00248   for (i = 0; i < 16; i++) {
00249     ns9542_write(0x15, 0x0a | (ialgn << 4));
00250     ns9542_write(0x15, 0x0b | (ialgn << 4));
00251     if (ns9542_read(0x05) & 0x08) {
00252       for (j = 0; j < 20; j++) {
00253         if (!(ns9542_read(0x05) & 0x08)) {
00254           int g = ns9542_read(0x65);
00255           int p = ns9542_read(0x66);
00256           if (g >= 103 && g <= 138 && 2 >= p && p <= 14) {
00257             *fine_gain = g;
00258             *fine_phase = p;
00259             *result_pg = 1;
00260             return;
00261           }
00262         }
00263         wait10ms();
00264       }
00265     }
00266   }
00267   *result_pg = 0;
00268 }
00269 
00270 void ns9542_table_write(int *fine_p, int *fine_g)
00271 {
00272   int i, j, k, result;
00273   result = 0;
00274   for (i = 0; i < 4; i++) {
00275     ns9542_write(0x38, fine_g[i]);
00276     ns9542_write(0x39, fine_p[i] << 4);
00277     for (j = 0; j < 10; j++) {
00278       ns9542_write(0x15, 0x0e | (i << 4));
00279       ns9542_write(0x15, 0x03 | (i << 4));
00280       if (ns9542_read(0x05) & 0x08) {
00281         wait100ms();
00282         for (k = 0; k < 10; k++) {
00283           if (!(ns9542_read(0x05) & 0x08)) {
00284             result++;
00285             goto L1;
00286           }
00287           wait10ms();
00288         }
00289         break;
00290       }
00291     }
00292 L1:;
00293     if (result != i + 1) {
00294       break;
00295     }
00296   }
00297 }
00298 
00299 void ns9542_dsp_align_body()
00300 {
00301   int iml, imf, ialgn, cnt, fp, fg;
00302   int fine_p[5] = { 0, 0, 0, 0, 0 };
00303   int fine_g[5] = { 0, 0, 0, 0, 0 };
00304   iml = 5;
00305   for (ialgn = 0; ialgn < 4; ialgn++) {
00306     ns9542_write(0x15, 0x0a | (ialgn << 4));
00307     wait100ms();
00308     wait100ms();
00309     ns9542_best_iml(iml);
00310     imf = 0;
00311     cnt = 0;
00312     fp = 0;
00313     fg = 0;
00314     for (cnt = 0; cnt < 5; cnt++) {
00315       int fine_phase, fine_gain, result_pg;
00316       ns9542_find_pg(ialgn, &fine_phase, &fine_gain, &result_pg);
00317       if (result_pg == 0) {
00318         return;
00319       }
00320       fp = fp + fine_phase;
00321       fg = fg + fine_gain;
00322       if (cnt == 2 && ialgn < 2) {
00323         cnt++;
00324         break;
00325       }
00326     }
00327     fine_p[ialgn] = fp / cnt;
00328     fine_g[ialgn] = fg / cnt;
00329   }
00330   ns9542_table_write(fine_p, fine_g);
00331 }
00332 
00333 void ns9542_mute(bool mute)
00334 {
00335   if (mute) {
00336     ns9542_write(0x00, ns9542_read(0x00) | 0x02);
00337   } else {
00338     ns9542_write(0x00, ns9542_read(0x00) & ~0x02);
00339   }
00340 }
00341 
00342 void ns9542_tune_am9(int freq) // freq = kHz
00343 {
00344   unsigned short psy;
00345 
00346   psy = freq;
00347 
00348   ns9542_write(0x00, 0x23);
00349 
00350   wait10ms();
00351   wait10ms();
00352 
00353   ns9542_write(0x04, 0x80);
00354   ns9542_write(0x0c, 0xf0);
00355 
00356   ns9542_write(0x10, 0x10);
00357 
00358   ns9542_write(0x02, psy & 0xff);
00359   ns9542_write(0x03, psy >> 8);
00360 
00361   ns9542_write(0x00, 0x21);
00362 }
00363 
00364 void ns9542_tune_fm(int freq) // freq = MHz * 100
00365 {
00366   unsigned short psy;
00367 
00368   psy = freq / 5;
00369 
00370   ns9542_write(0x00, 0x03);
00371 
00372   ns9542_write(0x10, 0x10);
00373 
00374   ns9542_write(0x02, psy & 0xff);
00375   ns9542_write(0x03, psy >> 8);
00376 
00377   ns9542_write(0x00, 0x01);
00378 }
00379 
00380 void ns9542_reset()
00381 {
00382   ns9542_write(0xfe, 0xaa);
00383 }
00384 
00385 void ns9542_power_on()
00386 {
00387   static unsigned char power_on[] = {
00388     0x01, 0x30,
00389     0x0c, 0x80,
00390     0x0e, 0x34,
00391     0x15, 0xc4,
00392     0x20, 0x3c,
00393     0x21, 0x03,
00394     0x22, 0x0a,
00395     0x23, 0x0a,
00396     0x30, 0xff,
00397     0x3d, 0x07,
00398     0x40, 0x1a,
00399     0x41, 0x9a,
00400     0x50, 0xe1,
00401     0x54, 0xb0,
00402     0x55, 0x36,
00403     0x5c, 0xc8,
00404     0x5d, 0x61,
00405     0x5e, 0x88,
00406     0x5f, 0xa5,
00407     0x71, 0x2c,
00408     0x72, 0x06,
00409   };
00410   int i;
00411   for (i = 0; i < sizeof(power_on); i += 2) {
00412     ns9542_write(power_on[i], power_on[i + 1]);
00413   }
00414 
00415   ns9542_write(0x00, ns9542_read(0x00) | 0x03);
00416 }
00417 
00418 void ns9542_dsp_alignment()
00419 {
00420   ns9542_write(0x0e, ns9542_read(0x0e) & ~0x60 | 0x40);
00421   ns9542_write(0x01, 0x08);
00422   ns9542_write(0x15, 0x0c);
00423   ns9542_write(0x16, 0x17);
00424   ns9542_write(0x37, 0x82);
00425   ns9542_write(0x3d, 0x37);
00426   wait100ms();
00427 
00428   ns9542_imf_adjust();
00429   ns9542_dsp_align_body();
00430 
00431   ns9542_write(0x01, 0x38);
00432   ns9542_write(0x0e, ns9542_read(0x0e) & ~0x60 | 0x20);
00433   ns9542_write(0x15, 0xc0);
00434   ns9542_write(0x17, 0x20);
00435   ns9542_write(0x32, 0x00);
00436   ns9542_write(0x37, 0x01);
00437 }
00438 
00439 void ns9542_init()
00440 {                
00441     i2c_sda.mode(PullUp);
00442     i2c_scl.mode(PullUp);
00443     i2c_sda.input();
00444     i2c_scl.input();
00445     i2c_sda.write(0);
00446     i2c_scl.write(0);
00447 
00448     ns9542_reset();
00449     ns9542_power_on();
00450     ns9542_dsp_alignment();
00451 }
00452