3 #include <t_services.h>
4 #include <s_services.h>
11 static void init_sport0_rx(void);
12 static void init_sport0_tx(void);
13 static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsigned int * sec_ch);
14 static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata );
15 static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq );
16 static void set_command_data( unsigned int command, unsigned int data );
20 struct dma_descripter{
21 struct dma_descripter * next_descripter;
22 unsigned int * start_address;
23 unsigned short config;
24 unsigned short x_count;
25 unsigned short x_modify;
30 struct dma_descripter rx_dma_dsc[2]; // FPGAからのデータDMAデスクリプタ
31 struct dma_descripter tx_dma_dsc[2]; // FPGAへのデータDMAデスクリプタ
33 unsigned int rxif_buffer[2][RXIF_BUFSIZE]; // FPGAからのデータDMAバッファ
34 unsigned int af_buffer[2][AF_BUFSIZE]; // FPGAへのデータDMAバッファ
35 int index; // パッカーが使う。現在のワードインデックスが0か1か
36 short wide_fm_i[WIDE_FM_OVERSAMPE]; // Wide FMを複数サンプルまとめて処理するためのバッファ
37 short wide_fm_q[WIDE_FM_OVERSAMPE]; // Wide FMを複数サンプルまとめて処理するためのバッファ
38 int wide_fm_index; // 次のバッファ格納位置。現在のバッファ長でもある。
41 // ラジオアルゴリズムとのやりとりに使う変数
46 #if defined (DEBUG_QUEUEDEPTH)
47 static int debug_queue_level = 0;
48 static int debug_queue_max = INT_MIN;
49 static int debug_queue_min = INT_MAX;
54 * \brief RX_IF受信データの処理タスク
55 * \param cfgファイルから値を渡すための引数。使っていない
56 * \details 受信データをDMAバッファから取り出して復調し、データキューに
57 * 書き込む。データキューは \ref af_task との共用である。
59 * また、受信DMA内のRX-IFデータにはコマンドが含まれている。これらの
60 * コマンドを内部変数に記録して復調器が利用できるようにしておく。
62 void rx_if_task(VP_INT exinf)
66 // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
67 unsigned int af_pri_ch, af_sec_ch;
69 vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
70 syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (INT) exinf);
72 syscall(serial_ctl_por(TASK_PORTID,
73 (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
75 // データキューのプリフィル。半分まで詰める
76 for ( i=0; i<AF_QUESIZE/2; i+=2)
78 pack_af_sample(0, 0, &af_pri_ch, &af_sec_ch);
79 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
80 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
81 #ifdef DEBUG_QUEUEDEPTH
82 debug_queue_level +=2;
83 if ( debug_queue_level > debug_queue_max)
84 debug_queue_max = debug_queue_level;
85 #endif // DEBUG_QUEUEDEPTH
89 framework.index = FALSE; // パッカーのインデックスの初期値設定。実のところ、初期値はランダムでも構わない。
91 framework.wide_fm_index = 0; // 配列内部の有効データ数
94 for ( i=0; i<PARAMDATA_NUM; i++)
100 // SPORT0の送受割り込み受付を可能にする
101 syscall(ena_int(INTNO_SPORT0_RX));
102 syscall(ena_int(INTNO_SPORT0_TX));
105 init_sport0_tx(); // 送信DMA開始。割り込みはまだ生成しない
106 init_sport0_rx(); // 受信DMA開始。割り込みイネーブル。
108 // AF送信を開始する。ただし、送信DMA割り込みはまだ発生しない。
109 *pDMA2_CONFIG |= DMAEN; // TX SPORT DMA Enable
110 *pSPORT0_TCR1 |= TSPEN; // TX SPORT Enable
115 tslp_tsk(1); // DMAがFIFOを充填するのに十分な時間待つ。
116 syscall(act_tsk(TASK_AF)); // AFデータ送信タスクをアクティブにする
118 // 頃合いなので送信DMA割り込みを開始する。
119 // CPUロックするのは割り込みにより、タイミングがずれるのを嫌って。
121 framework.tx_dma_dsc[0].config |= 1 << DI_EN_P;
122 framework.tx_dma_dsc[1].config |= 1 << DI_EN_P;
125 // RX受信を開始する。転送と同時に割り込みが始まる
126 *pDMA1_CONFIG |= DMAEN; // RX SPORT DMA Enable
127 *pSPORT0_RCR1 |= RSPEN; // RX SPORT Enable
133 * 受信DMA割り込み待ってから、DMAバッファ内部のデータを解析して然るべき受信処理を行う。
137 unsigned int* filled_buffer;
139 struct dma_descripter * next;
144 // SPORT0受信DMAがバッファを埋めるのを待つ。
145 syscall(wai_sem(SEM_SPORT0_RX));
148 // SPORT0受信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
149 // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
150 // 割り込みが完了したDMAのデスクリプタである
151 next = (struct dma_descriptor *) *pDMA1_NEXT_DESC_PTR;
153 // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
154 filled_buffer = next->start_address;
156 // RX-IF DMAバッファ内部のデータを処理
157 for ( i= 0; i<RXIF_BUFSIZE; i+=2)
163 // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
164 unsigned int af_pri_ch, af_sec_ch;
167 // Wide FMモードフラグはプライマリチャンネルでのみ確認可能である。
168 // プライマリ・チャンネルは必ずバッファの偶数番目に位置する。
169 if ( filled_buffer[i] & WIDE_FM_FLAG )
171 // データはバッファにまとめて WIDE_FM_OVERSAMPE個ごとに処理する
172 // 同時にFPGAから送られてくるデータも紐解いて格納する
173 unpack_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata );
174 framework.wide_fm_i[framework.wide_fm_index] = idata;
175 framework.wide_fm_q[framework.wide_fm_index] = qdata;
176 framework.wide_fm_index++;
179 if ( framework.wide_fm_index >= WIDE_FM_OVERSAMPE )
183 radio_demodulate_wide_FM( framework.wide_fm_i, framework.wide_fm_q, &left, &right );
185 framework.wide_fm_index = 0;
186 // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
187 pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
189 // パック済みオーディオサンプルをAFキューに送信する
190 // キューに空きがなければ、待たずにエラーをもって帰る
191 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
192 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
193 #ifdef DEBUG_QUEUEDEPTH
194 debug_queue_level += 2;
195 if ( debug_queue_level > debug_queue_max)
196 debug_queue_max = debug_queue_level;
197 #endif // DEBUG_QUEUEDEPTH
206 // 問答無用でWide FMのバッファ済みデータを消す
207 // これで変数の値が変わるのはシステム稼働中多くても1回である。
208 // 必要な場合だけ書き換えるとif文が増えるのでこうしている
209 framework.wide_fm_index = 0;
211 // 同時にFPGAから送られてくるデータも紐解いて格納する
212 unpack_non_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata, &is_valid_iq );
213 // IQデータが有効の場合だけデコードする
216 // 非ワイドFM受信アルゴリズムを呼び出す
217 radio_demodulate_non_wide_FM( idata, qdata, &left, &right);
218 // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
219 pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
220 // パック済みオーディオサンプルをAFキューに送信する
221 // キューに空きがなければ、待たずにエラーをもって帰る
222 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
223 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
224 #ifdef DEBUG_QUEUEDEPTH
225 debug_queue_level += 2;
226 if ( debug_queue_level > debug_queue_max)
227 debug_queue_max = debug_queue_level;
228 #endif // DEBUG_QUEUEDEPTH
233 } // RX-IF DMAバッファ内部のデータを処理
238 syslog(LOG_NOTICE, "rx_if_task ends.");
244 * \brief AF送信データの処理タスク。
245 * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
246 * \details データキューから取り出したAF信号をDMAバッファに転送する。
247 * このタスクは受信データ処理タスクより優先順位が高い。これは、DMAの送信割り込みへの
248 * 応答が遅れると、バッファを埋め終わる前に送信が始まってしまうからである。
250 * このタスクではあまり多くの時間を割くべきではなく、そのため、データキューへデータを
251 * 送り込む段階でAFデータの組み立ては終わっている。また、データの初期化などは全部
254 void af_task(VP_INT exinf)
256 syslog( LOG_NOTICE, "TASK_AF activatred!" );
260 unsigned int* filled_buffer;
262 struct dma_descripter * next;
268 syscall(wai_sem(SEM_SPORT0_TX));
271 // SPORT0送信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
272 // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
273 // 割り込みが完了したDMAのデスクリプタである
274 next = (struct dma_descriptor *) *pDMA2_NEXT_DESC_PTR;
276 // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
277 filled_buffer = next->start_address;
280 // AF DMAバッファに送信すべきデータを書く
281 for ( i= 0; i<AF_BUFSIZE; i++)
285 // AFキューから送信すべきデータを取り出す
286 // SVCにポーリングを使用しているため、取り出すべきデータがなければ待ちに入らずに
288 syscall(prcv_dtq( DTQ_AF, (VP_INT)&data));
290 filled_buffer[i] = data;
291 #ifdef DEBUG_QUEUEDEPTH
292 debug_queue_level --;
293 if ( debug_queue_min > debug_queue_level)
294 debug_queue_min = debug_queue_level;
295 #endif // DEBUG_QUEUEDEPTH
303 * \brief AFサンプルをパックしてデータキューに書き込みできる形式に変換する
304 * \param left 左チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
305 * \param right 右チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
306 * \param pri_ch パック済みオーディオデータ。最初にデータキューにコピーする。
307 * \param sec_ch パック済みオーディオデータ。2番めにデータキューにコピーする。
309 * 与えられたステレオ・データから、データキュー書き込み用のデータを組み立てる。
310 * 書き込みデータはSPORTのプライマリ・チャンネル用、セカンダリ・チャンネル用がある。
311 * さらに、これらがindex ==0 および 1の場合に別れる。
313 * この関数はindexを af_ctrl.index で管理しており、その値に応じて適切な
314 * プライマリ・チャンネル、セカンダリ・チャンネル用のデータを組み立てる。
316 * なお、セカンダリ・チャンネルはindex = 1の時にサブ・オーディオを伝送するが、
317 * TRX-305はサブ・オーディオを使わないためこのルーチンは常に値を0としている。
319 static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsigned int * sec_ch)
321 // オーディオデータは15bitしか使わない。Rchの16bit目は0に固定する
322 right >>= 1; // 15bitに変換
323 right &= 0x7FFF; // 本当はMSBは無視されるのだが、念の為0にする
325 left >>= 1; //15bitに変換
327 if ( framework.index )
329 left |= 0x8000; // MSBを1にする
331 // indexが1のとき、セカンダリチャンネルはサブオーディオとなっている。
332 // TRX-305はサブオーディオを使わないのでindexデータのみ送る
333 *sec_ch = 0x00008000;
337 left &= 0x7FFF; // MSBを0にする
339 // indexが0のとき、セカンダリオーディオはDSPからSH2へのデータ回線である
342 radio.flags; // flagsのbit15は0なので、indexも0になる
346 *pri_ch = (right << 16) | left;
349 framework.index = ! framework.index; // indexの論理反転
353 * \brief ワイドFMのRX-IFデータを解析する
354 * \param pri_ch プライマリ・チャンネルからのデータ
355 * \param sec_ch セカンダリ・チャンネルからのデータ
356 * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式
357 * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式
360 static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata )
362 int command, data, exp, i, q;
365 // iデータとqデータを抽出する。両者とも16bitで、bit14からbit29に格納されている
366 i = ( pri_ch << 2 ) & 0xFFFF0000;
367 q = ( sec_ch << 2 ) & 0xFFFF0000;
369 // ブロック浮動小数点処理。expでスケーリングする。
370 exp = ( pri_ch >> 10 ) & 0x0F;
374 #ifdef DEBUG_BLOCK_FLOAT
376 static int tested = 0;
377 if ( (i & 0x80000000) && ! tested )
380 syslog( LOG_NOTICE, "i: %8x, exp: %d, idata:%8x", i, exp, *idata);
384 // パラメータ・データを配列に格納する。
385 // 配列インデックスは comaddr、データはcomdataから。
386 // comdataはpri/secに分散している。
388 command = ( pri_ch >> 6 ) & 0x0F;
390 (( pri_ch << 10 ) & 0xF000) | //
391 (( sec_ch >> 2 ) & 0x0FFF);
392 // パラメータ・データをrx_parameter.data配列に格納する。
393 // 配列インデックスは comaddr、データはcomdataから。
395 set_command_data( command, data);
397 radio.comdata[ command ] = data;
401 * \brief 非ワイドFMのRX-IFデータを解析する
402 * \param pri_ch プライマリ・チャンネルからのデータ
403 * \param sec_ch セカンダリ・チャンネルからのデータ
404 * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
405 * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
406 * \param valid_iq IQデータが有効の時真、無効の時は偽
410 static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq )
413 if ( sec_ch & 0x02 ) // bit1が1ならindex = 1
415 // IQデータはbit[29:2]に格納されている
416 *idata = (pri_ch << 2); // プライマリ・チャンネルの場合はマスク不要
417 *qdata = (sec_ch << 2) & 0xFFFFFFF0;
426 command = ( pri_ch >> 6 ) & 0x0F;
427 data = ( sec_ch >> 2 ) & 0xFFFF;
428 // パラメータ・データをrx_parameter.data配列に格納する。
429 // 配列インデックスは comaddr、データはcomdataから。
431 set_command_data( command, data);
439 * \brief SHからのコマンドとパラメタを保存する
440 * \param command コマンド種別
441 * \param data コマンドパラメータ
442 * \details このルーチンはSHからFPGA経由で受け取ったコマンドとそのデータを内部変数に格納する。
443 * 格納されたデータはユーザーが実装した復調アルゴリズムから、API経由で利用される。
445 static void set_command_data( unsigned int command, unsigned int data )
448 if ( radio.comdata[command] != data ){
449 syslog(LOG_NOTICE, "Command : %d, Data : %d", command, data );
452 radio.comdata[ command ] = data;
458 * \brief SPORT0 受信割り込みハンドラ
459 * \details このルーチンはcfgファイルで宣言され、SPORT0 RX 割り込みハンドラとして登録される。
460 * SPORT0 RX DMAがバッファの受信を終えるたびに呼び出される。
461 * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと受信タスクへの通知しかしていない。
463 void sport0_rx_int_handler(void)
466 *pDMA1_IRQ_STATUS = DMA_DONE;
467 // タスクにSPORT0受信DMAのバッファが埋まったと知らせる。
468 syscall(isig_sem(SEM_SPORT0_RX)); // デバッグとりあえずタスクは殺しておく。
475 * \brief SPORT0 送信割り込みハンドラ
476 * \details このルーチンはcfgファイルで宣言され、SPORT0 TX 割り込みハンドラとして登録される。
477 * SPORT0 TX DMAがバッファの送信を終えるたびに呼び出される。
478 * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと送信タスクへの通知しかしていない。
480 void sport0_tx_int_handler(void)
483 *pDMA2_IRQ_STATUS = DMA_DONE;
485 // タスクにSPORT0送信DMAのバッファが空いたと知らせる。
486 syscall(isig_sem(SEM_SPORT0_TX));
494 * \param p イニシャライザにコンフィギュレータから与えられる数値。使っていない。
495 * \details この関数はATT_INIによってコンフィギュレータによりイニシャライザとして
496 * 登録される。システムが起動すると、マルチタスク処理が始まる前にこの関数が一度だけ呼ばれる。
499 void init_peripherals(VP_INT p)
512 * \brief SPORT0 RX 関連の初期化
513 * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
514 * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
517 static void init_sport0_rx(void)
522 for ( i = 0; i < RXIF_BUFSIZE; i++)
524 framework.rxif_buffer[0][i] = 0;
525 framework.rxif_buffer[0][i] = 0;
528 // 受信SPORTの設定。WORD長は30bitで、アーリー同期信号。外部クロック入力。
530 0 << 14 | // RCKFE, 0:sample at down edge, 1:sample at up edge
531 0 << 13 | // LARFS, 0:early frame sync, 1:late frame sync
532 0 << 12 | // LRFS, 0:Active high RFS, 1:Active low RFS
533 1 << 10 | // RFSR, 0:RFS is not required every word, 1:RFS is required every word
534 0 << 9 | // IRFS, 0:external RFS, 1:internal RFS
535 0 << 4 | // RLSBIT, 0:MSB first transmission, 1:LSB first transmission
536 0 << 2 | // RDTYPE 0:zero fill, 1:sign extend, 2:u-law, 3:a-law
537 0 << 1 | // IRCLK, 0:external clock generation, 1:internal clock generation
538 0 << 0 ; // RSPEN 0:Rx disable, 1:Rx enable
541 0 << 10 | // RRFST, 0:left streo ch first, 1:right stereo ch first
542 0 << 9 | // RSFESE, 0:normal frame sync, 1:LR frame clock
543 1 << 8 | // RXSE, 0:secondary ch disable, 1:secondary ch enable
544 29 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
550 framework.rx_dma_dsc[0].next_descripter = &framework.rx_dma_dsc[1];
551 framework.rx_dma_dsc[1].next_descripter = &framework.rx_dma_dsc[0];
553 framework.rx_dma_dsc[1].start_address = framework.rxif_buffer[1];
554 framework.rx_dma_dsc[0].start_address = framework.rxif_buffer[0];
556 framework.rx_dma_dsc[0].x_count =
557 framework.rx_dma_dsc[1].x_count = RXIF_BUFSIZE;
559 framework.rx_dma_dsc[0].x_modify =
560 framework.rx_dma_dsc[1].x_modify = sizeof(framework.rxif_buffer[1][0]);
562 framework.rx_dma_dsc[0].config =
563 framework.rx_dma_dsc[1].config =
564 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
565 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
566 1 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
567 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
568 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
569 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
570 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
571 1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
572 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
575 // SPORT0 受信DMAコントローラの初期状態設定
576 // ここではDMAをイネーブルにしない。また、バッファクリアする
578 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
579 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
580 1 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
581 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
582 1 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
583 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
584 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
585 1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
586 0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
587 *pDMA1_NEXT_DESC_PTR = &framework.rx_dma_dsc[0];
593 * \brief SPORT0 TX 関連の初期化
594 * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
595 * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
598 static void init_sport0_tx(void)
603 for ( i = 0; i < AF_BUFSIZE; i++)
605 framework.af_buffer[0][i] = 0;
606 framework.af_buffer[0][i] = 0;
610 // 送信SPORTの設定。WORD長は31bitで、アーリー同期信号。外部クロック入力。
612 0 << 14 | // TCKFE, 0:sample at down edge, 1:sample at up edge
613 0 << 13 | // LATFS, 0:early frame sync, 1:late frame sync
614 0 << 12 | // LTFS, 0:Active high TFS, 1:Active low TFS
615 0 << 11 | // DITFS, 0:data dependent TFS generation, 1:data independent TFS generation
616 1 << 10 | // TFSR, 0:TFS is not required every word, 1:TFS is required every word
617 1 << 9 | // ITFS, 0:external TFS, 1:internal TFS
618 0 << 4 | // TLSBIT, 0:MSB first transmission, 1:LSB first transmission
619 0 << 2 | // TDTYPE 0:normal, 1:reserved, 2:u-law, 3:a-law
620 0 << 1 | // ITCLK, 0:external clock generation, 1:internal clock generation
621 0 << 0 ; // TSPEN 0:Tx disable, 1:Tx enable
624 0 << 10 | // TRFST, 0:left streo ch first, 1:right stereo ch first
625 0 << 9 | // TSFESE, 0:normal frame sync, 1:LR frame clock
626 1 << 8 | // TXSE, 0:secondary ch disable, 1:secondary ch enable
627 30 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
629 *pSPORT0_TFSDIV = 255; // TFS period -1 ( The period is 256 )
633 // 注意:制御の都合上、最初はDMA割り込みをオフにしておく。これは
634 // DMA及びSPORT FIFOへの書き込みによるスタート後のラッシュで割り込みが
635 // 起きないようにするためである。ラッシュで送信されるのはダミーデータのみ
636 // である。rx_if_taskの初期化部でSPORT受信部を起動する際に、送信部の割り込みも
638 framework.tx_dma_dsc[0].next_descripter = &framework.tx_dma_dsc[1];
639 framework.tx_dma_dsc[1].next_descripter = &framework.tx_dma_dsc[0];
641 framework.tx_dma_dsc[0].start_address = framework.af_buffer[0];
642 framework.tx_dma_dsc[1].start_address = framework.af_buffer[1];
644 framework.tx_dma_dsc[0].x_count =
645 framework.tx_dma_dsc[1].x_count = AF_BUFSIZE;
647 framework.tx_dma_dsc[0].x_modify =
648 framework.tx_dma_dsc[1].x_modify = sizeof(framework.af_buffer[0][0]);
650 framework.tx_dma_dsc[0].config =
651 framework.tx_dma_dsc[1].config =
652 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
653 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
654 0 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
655 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
656 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
657 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
658 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
659 0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
660 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
663 // SPORT0 送信DMAコントローラの初期状態設定
664 // ここではDMAをイネーブルにしない。また、バッファクリアする
666 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
667 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
668 0 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
669 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
670 1 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
671 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
672 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
673 0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
674 0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
675 *pDMA2_NEXT_DESC_PTR = &framework.tx_dma_dsc[0];
680 * \brief デバッグ用モニタ・タスク
681 * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
682 * \details 一定時間ごとにシステム状態をモニターする。通常は使っていないが、
683 * 開発時に各種システム量を計算、取得するために動かす低順位タスクである。
686 void monitor_task(VP_INT exinf)
692 unsigned int cycle_start, cycle_end, total_idle_cycle, total_cycle;
696 asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_start) : : "R0");
698 #endif // DEBUG_DSPLOAD
700 tslp_tsk(1000); // 1秒待つ
704 asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_end) : : "R0");
707 total_cycle = cycle_end - cycle_start;
708 // ここまでの通算アイドル時間を取得する
709 total_idle_cycle = idle_cycle;
714 total_idle_cycle >>=16;
716 syslog(LOG_NOTICE, "DSP Load : %d%%", (total_cycle - total_idle_cycle) * 100 / total_cycle);
718 #endif // DEBUG_DSPLOAD
720 #ifdef DEBUG_QUEUEDEPTH
721 { // AF TASK, RX IF TAXK間のキューの深さを報告する
723 syslog( LOG_NOTICE, "Queue depth max : %d, min : %d ", debug_queue_max, debug_queue_min);
725 #endif // DEBUG_QUEUEDEPTH
727 #ifdef DEBUG_COMMAND_API
728 syslog( LOG_NOTICE, "radio_api_getARM_mode() %d", radio_api_getARM_mode() );
729 syslog( LOG_NOTICE, "radio_api_getAIS_if_shift() %d", radio_api_getAIS_if_shift() );
730 syslog( LOG_NOTICE, "radio_api_getAAT_attack() %d", radio_api_getAAT_attack() );
731 syslog( LOG_NOTICE, "radio_api_getAFA_fade() %d", radio_api_getAFA_fade() );
732 syslog( LOG_NOTICE, "radio_api_getAST_noise_squelch_level() %d", radio_api_getAST_noise_squelch_level() );
733 syslog( LOG_NOTICE, "radio_api_getACP_cw_pitch() %d", radio_api_getACP_cw_pitch() );
734 syslog( LOG_NOTICE, "radio_api_getADN_denoiser() %d", radio_api_getADN_denoiser() );
735 syslog( LOG_NOTICE, "radio_api_getAAN_auto_notch() %d", radio_api_getAAN_auto_notch() );
736 syslog( LOG_NOTICE, "radio_api_getAGL_gain_level() %d", radio_api_getAGL_gain_level() );
737 syslog( LOG_NOTICE, "radio_api_getAIF_filter() %d", radio_api_getAIF_filter() );
738 syslog( LOG_NOTICE, "radio_api_getABN_noise_blanker_on() %d", radio_api_getABN_noise_blanker_on());
739 syslog( LOG_NOTICE, "radio_api_getARG_agc_on() %d", radio_api_getARG_agc_on());
740 syslog( LOG_NOTICE, "radio_api_getANE_noise_squelch_on() %d", radio_api_getANE_noise_squelch_on());
741 syslog( LOG_NOTICE, "radio_api_getAAF_hpf() %d", radio_api_getAAF_hpf() );
742 syslog( LOG_NOTICE, "radio_api_getAAF_lpf() %d", radio_api_getAAF_lpf() );
743 syslog( LOG_NOTICE, "radio_api_getAVP_voice_squelch_level() %d", radio_api_getAVP_voice_squelch_level() );
744 syslog( LOG_NOTICE, "radio_api_getAVS_voice_squelch_on() %d", radio_api_getAVS_voice_squelch_on() );
745 #endif // DEBUG_COMMAND_API