OSDN Git Service

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