OSDN Git Service

Merge branch 'develop'
[trx-305dsp/dsp.git] / hirado / demodulator.h
1 /**
2  * \file demodulator.h
3  * \date 2015/03/10
4  * \brief 復調器関連インクルードファイル
5  */
6
7 #ifndef DEMODULATOR_H_
8 #define DEMODULATOR_H_
9
10
11 #ifndef _MACRO_ONLY
12
13     // Following mode macro can be used only the demodulator
14
15     /** \brief 受信機はワイドFMモードである */
16 #define radio_mode_WFM  2
17     /** \brief 受信機はナローFMモードである */
18 #define radio_mode_NFM  4
19     /** \brief 受信機は振幅変調モードである */
20 #define radio_mode_AM   5
21     /** \brief 受信機は振幅変調モードの同期復調モードである */
22 #define radio_mode_SAM  6
23     /** \brief 受信機はLSB復調モードである */
24 #define radio_mode_LSB  7
25     /** \brief 受信機はUSB復調モードである */
26 #define radio_mode_USB  8
27     /** \brief 受信機はCW復調モードである */
28 #define radio_mode_CW   9
29
30
31 /**
32  * \defgroup radioAPI ラジオAPI
33  * \brief 復調器がSHマイコン/FPGAと情報の授受を行うためのAPI群
34  * \details
35  * このモジュールに含まれるAPIは、復調器の中でユーザー復調アルゴリズムが使うために
36  * 公開されている。制御情報取得用APIはTRX-305からの制御情報を受け取るためのものである。
37  *
38  * 制御情報は周期的に送られてくるため、必ずしも即座に反応する必要はない。具体的には
39  * TRX-305からは16種類の情報が16周期で送られてくる。これらは情報の中身に変更がない場合も
40  * かわらない。
41  */
42 /*@{*/
43
44 /**
45  * \defgroup getInfo 制御情報取得API
46  * \brief 復調器がSHマイコン/FPGAから受け取る制御情報取得用のAPI
47  * \details
48  * ここに列挙されるAPIは、いずれも復調器内のユーザーアルゴリズムから自由に使ってよい。
49  *
50  * TRX-305から送られてくる制御情報は、ほとんどの場合TRX-305A基板にシリアルポートから
51  * 送られてくるコマンドに対応している。コマンドの一覧に関しては、トランジスタ技術誌
52  * 2014年11月号208ページの表を参照。なお、同記事のコマンドはTRX-305AのSHマイコンで
53  * 解釈後にDSPに送られるため、ここで使える命令とは必ずしも一対一対応していない。
54  *
55  * TRX-305Aが受け取るシリアル命令は、SHマイコンにより解釈されたあとにFPGA内部に
56  * 貯めこまれ、繰り返し送り出される。DSPはこの命令を受信し、制御情報として内部に
57  * さらに蓄える。
58  *
59  * なお、これらのAPIが返すのは、あくまで解釈のない「マイコンから送られてきた値」である。
60  * その値の物理的な解釈については、本プロジェクトは最小限に留める。言い換えると、
61  * ここに書いていない解釈は行わない。
62  *
63  * 命令に関してはすべて実際に解析したものであり、参考とした文献は存在しない。
64  * 命令の解析は framework.h の DEBUG_COMMAND のコメントアウトを外すことによって、
65  * DSPからのシリアル出力を監視しながらSHにシリアルコマンドを投入して行う。
66  *
67  *
68  */
69 /*@{*/
70
71
72     // These APIs are published for the demodulator programmer
73     /**
74      * \def radio_api_getARM_mode
75      * \brief 受信モードの取得
76      * \details
77      * このAPIは現在の受信モード(復調モード)を返す。シリアルコマンドARMに対応する。
78      * 復調モードは整数である。
79      * ユーザーに公開されているAPIであるが、2つの理由から使用を推奨しない。
80      *
81      * まず、復調器hののモード管理は radio_demodulate_wide_FM() および
82      * radio_demodulate_wide_FM() がフレームワークと強調する管理で行っており、
83      * プログラマは復調器がどのモードにあるかひと目でわかるようになっている。
84      * そのため、モード管理にこの関数を呼ぶ必要はない。
85      *
86      * また、USBとLSBの復調を概ね共用する場合も、radio_api_is_USB() を呼べば
87      * 事が足りる。したがって、この関数を呼ぶ必要はない。
88      *
89      * どうしてもこのAPIを呼び出すときには、 radio_mode_WFM() をはじめとする専用
90      * 定数と比較してモードを調べること。SHマイコンは外部のシリアルから与えられた
91      * パラメータと違う値を送ってくるため、この注意が必要となる。
92      */
93 #define radio_api_getARM_mode() (radio.comdata[1])
94
95     /**
96      * \brief IFシフト量の取得
97      * \details
98      * シリアルコマンドのAIS命令に対応する。
99      * 16bitの符号付き整数でシフト量を返す。
100      */
101 #define radio_api_getAIS_if_shift() (signed short)(radio.comdata[2])
102
103     /**
104      * \brief AGCアタック値の取得
105      * \details
106      * シリアルコマンドのAAT命令に対応する。
107      * 16bitの符号無し整数でアタック値を返す。
108      */
109 #define radio_api_getAAT_attack() (radio.comdata[3])
110
111     /**
112      * \brief AGCフェード値の取得
113      * \details
114      * シリアルコマンドのAAT命令に対応する。
115      * 16bitの符号無し整数でフェード値を返す。
116      */
117 #define radio_api_getAFA_fade() (radio.comdata[4])
118
119     /**
120      * \brief AGCフェード値の取得
121      * \details
122      * シリアルコマンドのAAT命令に対応する。
123      * 16bitの符号無し整数でフェード値を返す。
124      */
125 #define radio_api_getAST_noise_squelch_level() (radio.comdata[5])
126
127     /**
128      * \brief 再生トーンピッチの取得
129      * \details
130      * シリアルコマンドのACP命令に対応する。
131      *
132      * SHマイコンはシリアルコマンド ACP hhhh (hは16進数)に対して、
133      * hhhhを十進数xに変換し x*16916/4096 の値をDSPに送り込む。
134      * このAPIが返すのは送り込まれてきた変換後の値である。
135      *
136      * 16bitの符号付き整数でピッチ値を返す。
137      */
138 #define radio_api_getACP_cw_pitch()  (signed short)(radio.comdata[6])
139
140     /**
141      * \brief デノイザー値の取得
142      * \details
143      * シリアルコマンドADN命令に対応する。
144      * 16bitの符号無し整数でデノイザー値を返す。
145      */
146 #define radio_api_getADN_denoiser() (radio.comdata[7])
147
148 /**
149      * \brief オートノッチ値の取得
150      * \details
151      * シリアルコマンドAAN命令に対応する。
152      * 16bitの符号無し整数でオートノッチ値を返す。
153      */
154 #define radio_api_getAAN_auto_notch() (radio.comdata[8])
155
156 /**
157      * \brief ゲインレベル値の取得
158      * \details
159      * シリアルコマンドAGL命令に対応する。
160      * 16bitの符号無し整数でゲインレベル値を返す。
161      */
162 #define radio_api_getAGL_gain_level() (radio.comdata[11])
163 // Flag 0
164 /**
165      * \brief IFフィルタ値の取得
166      * \details
167      * シリアルコマンドAIF命令に対応する。
168      * 16bitの符号無し整数でフィルタ情報を返す。値の範囲は0から6である。
169      *
170      * (この情報がDSPへの命令なのか通知情報なのかは、現時点では不明である)
171      */
172 #define radio_api_getAIF_filter() ((radio.comdata[0]>>1)&0x7)
173
174 /**
175      * \brief ノイズブランカ制御命令の取得
176      * \details
177      * シリアルコマンドABN命令に対応する。
178      * 16bitの符号無し整数でノイズブランカ制御値値を返す。
179      * \li 0 : オン
180      * \li 1 : オフ
181      */
182 #define radio_api_getABN_noise_blanker_on() ((~radio.comdata[0]>>11)&0x1)
183
184
185 /**
186      * \brief AGC制御情報の取得
187      * \details
188      * シリアルコマンドARG命令に対応する。
189      * 16bitの符号無し整数でAGC制御情報値を返す。
190      *
191      * \li 0 : オン
192      * \li 1 : オフ
193      */
194 #define radio_api_getARG_agc_on() (~(radio.comdata[0]>>13)&0x1)
195
196 /**
197      * \brief 復調モード情報の取得
198      * \details
199      * SSB復調時に必要に応じて参照する。。
200      * 16bitの符号無し整数でSSBのモードを返す。
201      *
202      * \li 0 : LSB
203      * \li 非0 : USB
204      */
205 #define radio_api_is_USB()  ((radio.comdata[0]>>6)&0x1)     // 1 if USB
206
207 // Flag10
208 /**
209      * \brief ノイズスケルチ制御情報の取得
210      * \details
211      * シリアルコマンドNE命令に対応する。
212      * 16bitの符号無し整数でスケルチ制御情報値を返す。
213      *
214      * \li 1 : オン
215      * \li 0 : オフ
216      *
217      * なお、以上の設定はトランジスタ技術誌の2014年11月号の表に基づくが、
218      * この表には混乱があり、反転している可能性もある。
219      */
220 #define radio_api_getANE_noise_squelch_on() ((radio.comdata[10]>>1)&0x1)
221
222
223 /**
224      * \brief オーディオHPF情報の取得
225      * \details
226      * シリアルコマンドAAF nm命令のnに対応する。
227      * 16bitの符号無し整数でオーディオHPF制御情報値を返す。
228      *
229      * 値の範囲は0-2
230      */
231 #define radio_api_getAAF_hpf() ((radio.comdata[10]>>4)&0x3)
232
233 /**
234      * \brief オーディオLPF情報の取得
235      * \details
236      * シリアルコマンドAAF nm命令のmに対応する。
237      * 16bitの符号無し整数でオーディオLPF制御情報値を返す。
238      *
239      * 値の範囲は0-2
240      */
241 #define radio_api_getAAF_lpf() ((radio.comdata[10]>>2)&0x3)
242
243 // Flag 12
244 /**
245      * \brief ボイススケルチ値の取得
246      * \details
247      * シリアルコマンドAVP命令に対応する。
248      * 16bitの符号無し整数でボイススケルチ値を返す。
249      * 値の範囲は0-127
250      *
251      * シリアルコマンドAVPの引数は0000-FFFF (65556)までの値をとるが、
252      * DSPに渡される値はbit7がAVSによって破壊される。したがって、
253      * AVPコマンドに渡す値は 0000から 007Fに制限すべきである。
254      */
255 #define radio_api_getAVP_voice_squelch_level() ((radio.comdata[12])&0x3F)
256
257 /**
258      * \brief ボイススケルチ情報の取得
259      * \details
260      * シリアルコマンドAVS命令に対応する。
261      * 16bitの符号無し整数でボイススケルチ制御情報値を返す。
262      *
263      * \li 0 : オン
264      * \li 1 : オフ
265      */
266
267 #define radio_api_getAVS_voice_squelch_on() ((~radio.comdata[12]>>7)&0x1)
268 /*@}*/
269 /*  end of defgroup getInfo */
270
271 /**
272  * \defgroup setStat 状態報告API
273  * \brief DSPがFPGA/SHマイコンに情報を送るためのAPI群
274  */
275 /*@{*/
276
277 /**
278  * \def radio_api_set_S_meter
279  * \brief Sメータ値のセット
280  * \details
281  * このAPIはDSPからFPGA/SHマイコンに渡すSメータ値を設定する。値の範囲は
282  * 15bit符号なし整数である。APIは受け取った値をそのままFPGAに送信する。
283  */
284 #define radio_api_set_S_meter(s) radio.smeter = s
285
286         /**
287          * \def radio_api_set_stereo
288          * \brief FMステレオ受信状態の報告
289          * \details
290          * FM復調がモノラルかステレオを報告する。引数は以下のように与える
291          * \li 0 : モノラル
292          * \li 非1 : ステレオ
293          */
294 #define radio_api_set_stereo(s) s ? radio.flags |= (1<<1) : radio.flags &= ~(1<<1)
295
296     /**
297      * \def radio_api_set_voice_squelch
298      * \brief ボイススケルチ状態の報告
299      * \details
300      * 復調器がボイススケルチを持っている場合、その状態を報告する。
301      * \li 0 : ボイススケルチは開いていない
302      * \li 1 : ボイススケルチは開いている
303      */
304 #define radio_api_set_voice_squelch(s)  s ? radio.flags |= (1<<2) : radio.flags &= ~(1<<2)
305
306 /**
307  * \def radio_api_set_noise_squelch
308  * \brief ノイズスケルチ状態の報告
309  * \details
310  * 復調器がノイズスケルチを持っている場合、その状態を報告する。
311      * \li 0 : ノイズスケルチは開いていない
312      * \li 1 : ノイズスケルチは開いている
313  */
314 #define radio_api_set_noise_squelch(s) s ? radio.flags |= (1<<3) : radio.flags &= ~(1<<3)
315
316
317 /*@}*/
318 /*  end of defgroup setStat */
319
320 /*@}*/
321 /*  end of defgroup radioAPI */
322
323 /**
324  * \defgroup callbacks 復調用コールバック関数
325  * \brief フレームワークが復調ように呼び出すコールバック関数群
326  * \details
327  * 復調器のためにフレームワークから呼び出すコールバック関数。復調アルゴリズムは全てこの中に記述する。
328  *
329  * 関数は大きく分けて2種類に分けられる。ひとつは初期化関数で \ref init_demodulator() がこれである。
330  * その他の関数は実際の復調を行う関数である。
331  */
332
333 /*@{*/
334
335
336      /**
337       * \brief 復調器の初期化
338       * \details
339       * 復調アルゴリズムの初期化を行う。アルゴリズムが変数を初期化しなければならないようなときには、
340       * この関数の中に初期化プログラムを書く。
341       *
342       * この関数は、\ref radio_demodulate_wide_FM() や \ref radio_demodulate_non_wide_FM() が
343       * 呼ばれる前に一度だけ呼ばれる。
344       *
345       */
346 void radio_init_demodulator(void);
347
348
349      /**
350       * \brief ワイドFMの復調コールバック関数
351       * \param idata 受信IFのI(in phase)データ配列。32bit符号付き固定小数点数。フォーマットはQ1.31
352       * \param qdata 受信IFのQ(Quadratural phase)データ配列。32bit符号付き固定小数点数。フォーマットはQ1.31
353       * \param left 復調オーディオ信号の左チャンネルデータ。16bit符号付き固定小数点数。フォーマットはQ1.15
354       * \param right 復調オーディオ信号の右チャンネルデータ。16bit符号付き固定小数点数。フォーマットはQ1.15
355       * \details
356      * ワイドFM以外の信号を復調するために呼ばれるコールバック関数。この関数と \ref radio_demodulate_non_wide_FM() の
357      * 切り替えはフレームワークが自動的に行うため、ユーザー側は気にしなくていい。
358      *
359      *
360      * IF入力(idata[], qdata[])、AF出力(*left, *right)ともFsは31.7kHzである(トランジスタ技術誌2015年5月号pp183)。
361      * 1サンプル毎に呼び出されるので、このコールバックは1秒間に31,700回呼び出される。
362      *
363      * IF入力はワイドFMではオーバーサンプルされた値が入力する。そのため、1サンプルあたりのデータ数は1ではない。
364      * 具体的なオーバーサンプル値は、マクロ WIDE_FM_OVERSAMPE で知ることができる。まとめると、この関数の中では
365      * idata/qdataそれぞれ WIDE_FM_OVERSAMPE 個のデータを復調処理して、1個のleft/right データを生成する。
366      *
367      * IF入力データとAF出力データの語長が違うことに注意。データのパック形式は固定小数点型であるため、いずれも
368      * データの値の範囲は[-1,1)となる。しかし、C言語としての取り扱いは整数なので、それぞれの最大値は異なる(IFデータの
369      * 最大値はAFデータの65536倍)。
370      *
371       */
372
373 void radio_demodulate_wide_FM( int idata[], int qdata[], short* left, short* right );
374
375 /**
376  * \brief ワイドFM以外の復調コールバック関数
377  * \param idata 受信IFのI(in phase)データ。32bit符号付き固定小数点数。フォーマットはQ1.31
378  * \param qdata 受信IFのQ(Quadratural phase)データ。32bit符号付き固定小数点数。フォーマットはQ1.31
379  * \param left 復調オーディオ信号の左チャンネルデータ。16bit符号付き固定小数点数。フォーマットはQ1.15
380  * \param right 復調オーディオ信号の右チャンネルデータ。16bit符号付き固定小数点数。フォーマットはQ1.15
381  * \details
382  * ワイドFM以外の信号を復調するために呼ばれるコールバック関数。この関数と \ref radio_demodulate_wide_FM() の
383  * 切り替えはフレームワークが自動的に行うため、ユーザー側は気にしなくていい。
384  *
385  * 非ワイドFM以外のモードにはAM, SAM, LSB, USB, Narrow FM, CW の受信モードがある。これらの受信モードの
386  * 検出は、コールバック関数内部のスケルトンが自動的に切り分けているので、それぞれの場合ごとに復調アルゴリズムを
387  * 書けばよい。
388  *
389  * LSBとUSBの復調コードの大半を共有したい場合には、一部でLSB/USBの判断を行われなければならない。この場合は
390  * \ref radio_api_is_USB() APIを使うことで判別を行う。
391  *
392  * なお、ワイドFMモードから非ワイドFMモードへの切り替えがSHマイコンから出された場合、実際のFMモードからの
393  * 復調器の切り替えは二段階になりうる。最初の段階では radio_demodulate_wide_FM() の呼び出しが終了し、
394  * radio_demodulate_non_wide_FM() の呼び出しへと切り替わる。次の段階では、\ref radio_demodulate_non_wide_FM()
395  * の中で正しい復調モードが検出され、スケルトンの動作が切り替わる。
396  *
397  * この二段階切り替えは必ず起こるというわけではなく、FPGAの実装形態に依存する。単にフレームワークは二段階切り替えにも
398  * 対応できるということである。
399  *
400  * IF入力(idata, qdata)、AF出力(*left, *right)ともFsは31.7kHzである(トランジスタ技術誌2015年5月号pp183)。
401  * 1サンプル毎に呼び出されるので、このコールバックは1秒間に31,700回呼び出される。
402  *
403  * IF入力データとAF出力データの語長が違うことに注意。データのパック形式は固定小数点型であるため、いずれも
404  * データの値の範囲は[-1,1)となる。しかし、C言語としての取り扱いは整数なので、それぞれの最大値は異なる(IFデータの
405  * 最大値はAFデータの65536倍)。
406  *
407  */
408
409 void radio_demodulate_non_wide_FM( int idata, int qdata, short* left, short* right );
410
411 /*@}*/
412 /*  end of defgroupt callbacks */
413
414 #endif /* _MACRO_ONLY */
415
416 #endif /* DEMODULATOR_H_ */