CentSDRã®ä¿¡å·åŠçã«ãããDCãªãã»ããè£å
CentSDRã®å®éšãããŠããéçšã§ãDCãªãã»ããç±æ¥ã®äžèŠä¿¡å·ã®å¯ŸçãããŠããŸããåå ã¯2ç®æãããããããéã£ãèŠå ã§çããŠããŸãããåèã«ãªããããããŸããã®ã§ãå°ã解説ããŠãããŸãã
Continue Reading
äžã®åçã¯ã¢ã³ãããæ¥ç¶ããç¡ä¿¡å·ã®ç¶æ
ã§ãµã³ããªã³ã°ããä¿¡å·ã®ã¹ãã¯ãã©ã ã衚瀺ãããã®ã§ããç¡ä¿¡å·ã«ãããããããäžå€®ã«ä¿¡å·ãèŠããŠããŸããå
éšã®SSB埩調信å·åŠçã®éœåäžã1.3kHzãããäœçœ®ã«èŠããŠããã®ã§ãããADCããåã蟌ãã æç¹ã§ã¯0Hzããªãã¡DCæåã§ãããµã³ãã«å€ã«åžžã«0ããã®ãããæ®ã£ãŠããç¶æ
ãšãªã£ãŠããããã§ãã
埩調åŸã®ãªãŒãã£ãªä¿¡å·ã®ã¹ãã¯ãã©ã ãäžèšã§ãããã¡ãã§ã0Hzã«å¿çãèŠããŠããŸãã
ãã®DCãªãã»ããã¯ADCç±æ¥ã§ããæ¬æ¥ç¡ä¿¡å·ã§ããã°ãŒããšãªã£ãŠã»ããã®ã¯ãã§ãããã©ãããŠãããŸããŸãªèŠå ãããªãã»ãããçããŠããŸããŸããç¡çšãªæåã§ãã®ã§æ¶ããŠããŸãããšãæãŸããã察çã¯ãDC=0Hzãéããªããã£ã«ã¿ãããªãã¡HPFãå
¥ããããšã«ãªããŸããã«ãããªãåšæ³¢æ°ã¯ãæ°HzçšåºŠãšãªãããã«ããŸãã
HPFãå®è£
ããå
·äœçæ¹æ³ã§ããã䜿çšããŠããCodecãããTLV320AIC3204ã«ã¯DSPãããã¯ãå«ãŸããŠããŸãã®ã§ãããªãã®èªç±åºŠã§ããžã¿ã«ãã£ã«ã¿ãå
¥ããããšãã§ããŸããCodecå
éšã®DSPã䜿ãããšã§ãMPUã®ãµã€ã¯ã«ãæ¶è²»ããã«æžãããã§ããäžèšã«åºæ¬æ§æã®å Žåã®ãããã¯å³ã瀺ããŸãããã®æ§æã®ä»ã«ãFIRãIIRãªã©ãããŸããŸãªãã¿ãŒã³ãçšæãããŠããŸãã詳ããã¯ãªãã¡ã¬ã³ã¹ã¬ã€ããã芧ãã ããã
ãã®å³äžã®â1st Order IIRâããADCã®DCãªãã»ãããåé€ããããã«èšãããããã£ã«ã¿ãããã¯ã§ããDCãªãã»ããåæžçšåºŠã®åŠçã§ããã°ç·©ãç¹æ§ã§OKã§ãã®ã§ã1次ã®IIRã§ååãšããããã§ããããã«é©åãªä¿æ°ãäžããŠããã°ãæã¿ã®ãã£ã«ã¿ç¹æ§ãåŸãããŸãã
ãã®HPFçšã®ä¿æ°ãèšèšããŸãããã€ãã®Jupyter notebookã§ãã£ãŠã¿ãŸãããŸãã¯æºåãšããŠäžèšãã€ã³ããŒãããŠãããŸãã
%matplotlib inline import pylab as pl import numpy as np from scipy import signal
scipy.signalã®iirfilter颿°ã䜿ã£ãŠã1次ã®IIRãã£ã«ã¿ããHigh Pass FilterãšããŠèšèšããŸããã«ãããªãåšæ³¢æ°ã¯é©åœã«0.0001ãšæå®ããŠããŸãããããã¯ãã€ãã¹ãåšæ³¢æ°ã«å¯ŸããŠ0.0001ãããªãã¡ãµã³ããªã³ã°åšæ³¢æ°48kHzã®å Žåããã€ãã¹ãåšæ³¢æ°ã¯24kHzãªã®ã§ãã«ãããªãã¯2.4Hzãšããããšã§ãã
ãã®åšæ³¢æ°ç¹æ§ã確èªããŠã¿ãŸãã䞡察æ°ã°ã©ãã«ããããã瀺ããŸããã¡ãããšHPFã®åœ¢ã«ãªã£ãŠããããšãããããŸãã察æ°ãªã®ã§èŠããŠããŸãããã0Hzã®å¿çã¯0ãšãªã£ãŠããŸãã
ããŠãä¿æ°ããDSPã«çµã¿èŸŒãããã«ã¯ã24ãããã®ç¬Šå·ä»ãåºå®å°æ°ç¹ã«å€æããå¿
èŠããããŸãããã«ããã«ãããŠããããããã€ãåã«å€æããŸãã
b[0] = 0x7f, 0xfa, 0xda b[1] = 0x80, 0x5, 0x26 -a[1] = 0x7f, 0xf5, 0xb5
ãããI2Cçµç±ã§ãããã«æžã蟌ã¿ãŸããã³ãŒããäžèšã«ç€ºããŸãã2ã€ã®ãã£ãã«ã§ã¬ãžã¹ã¿ãéããŸãã®ã§ãããããåãããŒã¿ãæžã蟌ã¿ãŸããä¿æ°ãæžã蟌ãã ããšãä¿æ°ãããã¡ãåãæ¿ããããšã§ãã£ã«ã¿ã®åäœã«åæ ãããŸããADCãåäœãããªããåãæ¿ããå Žåã¯ãã®äžæéãå¿
èŠã§ããåäœéå§åã«ä¿æ°ãèšå®ããã®ã§ããã°ãããã¡åãæ¿ãã¯äžèŠã§ãã
const uint8_t adc_iir_filter_dcreject[] = { /* len, page, reg, data.... */ /* left channel C4 - C6 */ 12, 8, 24, /* Pg8 Reg24-35 */ 0x7f, 0xfa, 0xda, 0x00, 0x80, 0x05, 0x26, 0x00, 0x7f, 0xf5, 0xb5, 0x00, /* right channel C36 - C38 */ 12, 9, 32, /* Pg9 Reg 32-43 */ 0x7f, 0xfa, 0xda, 0x00, 0x80, 0x05, 0x26, 0x00, 0x7f, 0xf5, 0xb5, 0x00, 0 /* sentinel */ }; void tlv320aic3204_config_adc_filter() { const uint8_t *p = adc_iir_filter_dcreject; while (*p != 0) { uint8_t len = *p++; uint8_t page = *p++; uint8_t reg = *p++; I2CWrite(AIC3204_ADDR, 0x00, page); while (len-- > 0) I2CWrite(AIC3204_ADDR, reg++, *p++); } I2CWrite(AIC3204_ADDR, 0x00, 0x08); /* Select Page 8 */ I2CWrite(AIC3204_ADDR, 0x01, 0x05); /* ADC Coefficient Buffers will be switched at next frame boundary */ I2CWrite(AIC3204_ADDR, 0x00, 0x00); /* Back to page 0 */ }
ãããçµã¿èŸŒã¿ãŸããããã»ã©ãšåæ§ã«ç¡ä¿¡å·æã®ã¹ãã¯ãã©ã ãèŠãŠã¿ããšãDCã®ä¿¡å·ãæ¶ããŠã¡ãããšãã©ããã«ãªã£ãŠããŸãã
ãªãŒãã£ãªã®ã¹ãã¯ãã©ã ãèŠãŠã¿ããšã0Hzã®æåã¯æ¶ããã®ã§ãããå¥ã®å°ããªä¿¡å·ãæ®ã£ãŠããããšãããããŸãã
ä¿¡å·åŠçéçšã®äžéã®ä¿¡å·ãèŠãŠã¿ããšããŸããã0Hzã«äžèŠä¿¡å·ãçããŠããããšãããããŸãã
SSB埩調ã®ä¿¡å·åŠçãããã¯å³ã瀺ããŸããADCã§åã蟌ãã ä¿¡å·ããŸãæåã«1.3kHzåšæ³¢æ°ã·ãããæ¬¡ãã§fc=1.3kHzã®LPFãéããŸããæåŸã«ããŸã1.3kHzéåãã«åšæ³¢æ°ã·ããããŠããŸããããããŠ2.6kHzå¹
ã®åŸ©èª¿åž¯åå¹
ãåŸãŠããŸããLPFã«CMSIS DSPã©ã€ãã©ãªã䜿ã£ãŠã6次ã®Biquad IIRãã£ã«ã¿ãå®è£
ããŠããŸãããã®å
éšã§DCæåãçããŠããããã§ããæåŸã«ãŸãåšæ³¢æ°ã·ããããŠããã®ã§çµæãšããŠ1.3kHzä»è¿ã®äžèŠä¿¡å·ãšãªã£ãŠããããã§ãã
CMSIS DSPã©ã€ãã©ãªã®ãœãŒã¹ã³ãŒãã調ã¹ãŠã¿ãŸãããã¡ã€ã«
CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c
arm_biquad_cascade_df1_q15() 颿°ã§ã(141è¡ç®ä»è¿)ã
åºå®å°æ°ç¹ã®ã·ããã䜿ã£ãèšç®ãããŠããã®ã§ãããé©åã§ãªãç®æãããããã§ãã2ã¹ãã®å²ãç®ãã·ããã§è¡ãããšã¯ããããããšãªã®ã§ããã笊å·ã®æ±ãã«ã¯æ³šæãå¿
èŠã§ããããšãã°ãæ£ã®æ°ã«å¯ŸããŠå³ã·ãããç¹°ãè¿ããš8â4â2â1â0ãšã©ããªæ°ãæåŸã«ã¯0ã«ãªããŸãããšãããè² ã®æ°ãå³ã·ããããå Žåã¯ã-7â-3â-1â-1â-1â-1 ãšã-1ããªãã¡å
šãããã1ã«ãªã£ãããšã¯å€åããªããªããŸãããã®ããã«å³ã·ããã«ããå²ãç®ã¯ãæ£ãšè² ã§çµæãé察称ã«ãªã£ãŠããŸãã®ã§ãé©åã«æ±ãããŠããªããšæåŸ
ããªãçµæãçããŸããCMSIS DSPã©ã€ãã©ãªã§çããŠããDCãªãã»ããã¯ãããåå ã®ããã§ãã
ãããåé¿ããããäžèšã®ä¿®æ£(FIXã³ã¡ã³ãã®è¡)ã远å ããŸãã0ãš-1ã®ã®ã£ãããåããããã«0.5ãè¶³ããŠããã®ã§ãã
/* acc += a1 * y[n-1] + a2 * y[n-2] */ acc = __SMLALD(a1, state_out, acc); /* FIX: compensate dc offset caused from bit shift operation */ acc += 1 << lShift; /* The result is converted from 3.29 to 1.31 if postShift = 1, and then saturation is applied */ /* Calc lower part of acc */ acc_l = acc & 0xffffffff; /* Calc upper part of acc */ acc_h = (acc >> 32) & 0xffffffff;
ãã®å¯Ÿçãæœããšãç¡äºDCæåãæ¶ããŸãããç¡ä¿¡å·ã§ãªãŒãã£ãªãã©ããã§ãããã£ãã!
å
¬åŒã«ARMããæäŸãããŠããCMSIS DSPã©ã€ãã©ãªãšããã©ããæ³šæããŠäœ¿çšããå¿
èŠãããããã§ããä»åã®å¯Ÿçã¯ãLPFãå®è£
ããç®çã«ã¯å¹æããããŸããããäžè¬ã«é©çšããã«ã¯æ³šæãå¿
èŠãããããŸããã
ãšããããã§ãåããDCãªãã»ããã«é¢ãããããã¯ã§ããããããŒããŠã§ã¢ãããœãããŠã§ã¢ãŸã§ããããããªåå ãããåŸãŸãããã®å¯Ÿç2é¡ã§ããã
ããã«ããŠãã¹ãã¯ãã©ã ã宿©ã§è¡šç€ºã§ããã®ã¯ãšãŠã䟿å©ã§ããåã¯ããŒã¿ãåãåºããŠã°ã©ããæãããããŠããã®ã§ãããç»é¢ãèŠãã°äžç®ã§å¹æãããããŸãã
ããŸãã§CentSDRã®ããŒããŠã§ã¢ãããã¯å³ã§ããè¥å¹²æ°ã®ãããé åžã®æºåãããŠããŸããããªããªã鲿ããŸãããã¢ããŠã³ã¹ããåŸ
ã¡ãã ããã
CentSDRãçµã¿ç«ãŠãŠã¿ãŸãã http://ttrftech.tumblr.com/post/164219455216/
TLV320AIC3204 Application Reference Guide http://www.ti.com/lit/ml/slaa557/slaa557.pdf
CMSIS DSPã©ã€ãã©ãªÂ https://github.com/ARM-software/CMSIS
åå ç®æÂ https://github.com/ARM-software/CMSIS/blob/master/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c#L143