streaming server for AM/FM radio via UDP connection.
Dependencies: mbed EthernetNetIf
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
Generated on Fri Jul 15 2022 13:48:29 by 1.7.2