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 );
19 struct dma_descripter{
20 struct dma_descripter * next_descripter;
21 unsigned int * start_address;
22 unsigned short config;
23 unsigned short x_count;
24 unsigned short x_modify;
29 struct dma_descripter rx_dma_dsc[2]; // FPGAからのデータDMAデスクリプタ
30 struct dma_descripter tx_dma_dsc[2]; // FPGAへのデータDMAデスクリプタ
32 unsigned int rxif_buffer[2][RXIF_BUFSIZE]; // FPGAからのデータDMAバッファ
33 unsigned int af_buffer[2][AF_BUFSIZE]; // FPGAへのデータDMAバッファ
34 int index; // パッカーが使う。現在のワードインデックスが0か1か
35 short wide_fm_i[WIDE_FM_OVERSAMPE]; // Wide FMを複数サンプルまとめて処理するためのバッファ
36 short wide_fm_q[WIDE_FM_OVERSAMPE]; // Wide FMを複数サンプルまとめて処理するためのバッファ
37 int wide_fm_index; // 次のバッファ格納位置。現在のバッファ長でもある。
40 // ラジオアルゴリズムとのやりとりに使う変数
45 #if defined (DEBUG_QUEUEDEPTH)
46 static int debug_queue_level = 0;
47 static int debug_queue_max = INT_MIN;
48 static int debug_queue_min = INT_MAX;
53 * \brief RX_IF受信データの処理タスク
54 * \param cfgファイルから値を渡すための引数。使っていない
55 * \details 受信データをDMAバッファから取り出して復調し、データキューに
56 * 書き込む。データキューは \ref af_task との共用である。
58 * また、受信DMA内のRX-IFデータにはコマンドが含まれている。これらの
59 * コマンドを内部変数に記録して復調器が利用できるようにしておく。
61 void rx_if_task(VP_INT exinf)
65 // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
66 unsigned int af_pri_ch, af_sec_ch;
68 vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
69 syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (INT) exinf);
71 syscall(serial_ctl_por(TASK_PORTID,
72 (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
74 // データキューのプリフィル。半分まで詰める
75 for ( i=0; i<AF_QUESIZE/2; i+=2)
77 pack_af_sample(0, 0, &af_pri_ch, &af_sec_ch);
78 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
79 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
80 #ifdef DEBUG_QUEUEDEPTH
81 debug_queue_level +=2;
82 if ( debug_queue_level > debug_queue_max)
83 debug_queue_max = debug_queue_level;
84 #endif // DEBUG_QUEUEDEPTH
88 framework.index = FALSE; // パッカーのインデックスの初期値設定。実のところ、初期値はランダムでも構わない。
90 framework.wide_fm_index = 0; // 配列内部の有効データ数
93 for ( i=0; i<PARAMDATA_NUM; i++)
99 // SPORT0の送受割り込み受付を可能にする
100 syscall(ena_int(INTNO_SPORT0_RX));
101 syscall(ena_int(INTNO_SPORT0_TX));
104 init_sport0_tx(); // 送信DMA開始。割り込みはまだ生成しない
105 init_sport0_rx(); // 受信DMA開始。割り込みイネーブル。
107 // AF送信を開始する。ただし、送信DMA割り込みはまだ発生しない。
108 *pDMA2_CONFIG |= DMAEN; // TX SPORT DMA Enable
109 *pSPORT0_TCR1 |= TSPEN; // TX SPORT Enable
114 tslp_tsk(1); // DMAがFIFOを充填するのに十分な時間待つ。
115 syscall(act_tsk(TASK_AF)); // AFデータ送信タスクをアクティブにする
117 // 頃合いなので送信DMA割り込みを開始する。
118 // CPUロックするのは割り込みにより、タイミングがずれるのを嫌って。
120 framework.tx_dma_dsc[0].config |= 1 << DI_EN_P;
121 framework.tx_dma_dsc[1].config |= 1 << DI_EN_P;
124 // RX受信を開始する。転送と同時に割り込みが始まる
125 *pDMA1_CONFIG |= DMAEN; // RX SPORT DMA Enable
126 *pSPORT0_RCR1 |= RSPEN; // RX SPORT Enable
132 * 受信DMA割り込み待ってから、DMAバッファ内部のデータを解析して然るべき受信処理を行う。
136 unsigned int* filled_buffer;
138 struct dma_descripter * next;
143 // SPORT0受信DMAがバッファを埋めるのを待つ。
144 syscall(wai_sem(SEM_SPORT0_RX));
147 // SPORT0受信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
148 // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
149 // 割り込みが完了したDMAのデスクリプタである
150 next = (struct dma_descriptor *) *pDMA1_NEXT_DESC_PTR;
152 // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
153 filled_buffer = next->start_address;
155 // RX-IF DMAバッファ内部のデータを処理
156 for ( i= 0; i<RXIF_BUFSIZE; i+=2)
162 // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
163 unsigned int af_pri_ch, af_sec_ch;
166 // Wide FMモードフラグはプライマリチャンネルでのみ確認可能である。
167 // プライマリ・チャンネルは必ずバッファの偶数番目に位置する。
168 if ( filled_buffer[i] & WIDE_FM_FLAG )
170 // データはバッファにまとめて WIDE_FM_OVERSAMPE個ごとに処理する
171 // 同時にFPGAから送られてくるデータも紐解いて格納する
172 unpack_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata );
173 framework.wide_fm_i[framework.wide_fm_index] = idata;
174 framework.wide_fm_q[framework.wide_fm_index] = qdata;
175 framework.wide_fm_index++;
178 if ( framework.wide_fm_index >= WIDE_FM_OVERSAMPE )
182 radio_demodulate_wide_FM( framework.wide_fm_i, framework.wide_fm_q, &left, &right );
184 framework.wide_fm_index = 0;
185 // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
186 pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
188 // パック済みオーディオサンプルをAFキューに送信する
189 // キューに空きがなければ、待たずにエラーをもって帰る
190 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
191 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
192 #ifdef DEBUG_QUEUEDEPTH
193 debug_queue_level += 2;
194 if ( debug_queue_level > debug_queue_max)
195 debug_queue_max = debug_queue_level;
196 #endif // DEBUG_QUEUEDEPTH
205 // 問答無用でWide FMのバッファ済みデータを消す
206 // これで変数の値が変わるのはシステム稼働中多くても1回である。
207 // 必要な場合だけ書き換えるとif文が増えるのでこうしている
208 framework.wide_fm_index = 0;
210 // 同時にFPGAから送られてくるデータも紐解いて格納する
211 unpack_non_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata, &is_valid_iq );
212 // IQデータが有効の場合だけデコードする
215 // 非ワイドFM受信アルゴリズムを呼び出す
216 radio_demodulate_non_wide_FM( idata, qdata, &left, &right);
217 // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
218 pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
219 // パック済みオーディオサンプルをAFキューに送信する
220 // キューに空きがなければ、待たずにエラーをもって帰る
221 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
222 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
223 #ifdef DEBUG_QUEUEDEPTH
224 debug_queue_level += 2;
225 if ( debug_queue_level > debug_queue_max)
226 debug_queue_max = debug_queue_level;
227 #endif // DEBUG_QUEUEDEPTH
232 } // RX-IF DMAバッファ内部のデータを処理
237 syslog(LOG_NOTICE, "rx_if_task ends.");
243 * \brief AF送信データの処理タスク。
244 * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
245 * \details データキューから取り出したAF信号をDMAバッファに転送する。
246 * このタスクは受信データ処理タスクより優先順位が高い。これは、DMAの送信割り込みへの
247 * 応答が遅れると、バッファを埋め終わる前に送信が始まってしまうからである。
249 * このタスクではあまり多くの時間を割くべきではなく、そのため、データキューへデータを
250 * 送り込む段階でAFデータの組み立ては終わっている。また、データの初期化などは全部
253 void af_task(VP_INT exinf)
255 syslog( LOG_NOTICE, "TASK_AF activatred!" );
259 unsigned int* filled_buffer;
261 struct dma_descripter * next;
267 syscall(wai_sem(SEM_SPORT0_TX));
270 // SPORT0送信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
271 // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
272 // 割り込みが完了したDMAのデスクリプタである
273 next = (struct dma_descriptor *) *pDMA2_NEXT_DESC_PTR;
275 // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
276 filled_buffer = next->start_address;
279 // AF DMAバッファに送信すべきデータを書く
280 for ( i= 0; i<AF_BUFSIZE; i++)
284 // AFキューから送信すべきデータを取り出す
285 // SVCにポーリングを使用しているため、取り出すべきデータがなければ待ちに入らずに
287 syscall(prcv_dtq( DTQ_AF, (VP_INT)&data));
289 filled_buffer[i] = data;
290 #ifdef DEBUG_QUEUEDEPTH
291 debug_queue_level --;
292 if ( debug_queue_min > debug_queue_level)
293 debug_queue_min = debug_queue_level;
294 #endif // DEBUG_QUEUEDEPTH
302 * \brief AFサンプルをパックしてデータキューに書き込みできる形式に変換する
303 * \param left 左チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
304 * \param right 右チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
305 * \param pri_ch パック済みオーディオデータ。最初にデータキューにコピーする。
306 * \param sec_ch パック済みオーディオデータ。2番めにデータキューにコピーする。
308 * 与えられたステレオ・データから、データキュー書き込み用のデータを組み立てる。
309 * 書き込みデータはSPORTのプライマリ・チャンネル用、セカンダリ・チャンネル用がある。
310 * さらに、これらがindex ==0 および 1の場合に別れる。
312 * この関数はindexを af_ctrl.index で管理しており、その値に応じて適切な
313 * プライマリ・チャンネル、セカンダリ・チャンネル用のデータを組み立てる。
315 * なお、セカンダリ・チャンネルはindex = 1の時にサブ・オーディオを伝送するが、
316 * TRX-305はサブ・オーディオを使わないためこのルーチンは常に値を0としている。
318 static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsigned int * sec_ch)
320 // オーディオデータは15bitしか使わない。Rchの16bit目は0に固定する
321 right >>= 1; // 15bitに変換
322 right &= 0x7FFF; // 本当はMSBは無視されるのだが、念の為0にする
324 left >>= 1; //15bitに変換
326 if ( framework.index )
328 left |= 0x8000; // MSBを1にする
330 // indexが1のとき、セカンダリチャンネルはサブオーディオとなっている。
331 // TRX-305はサブオーディオを使わないのでindexデータのみ送る
332 *sec_ch = 0x00008000;
336 left &= 0x7FFF; // MSBを0にする
338 // indexが0のとき、セカンダリオーディオはDSPからSH2へのデータ回線である
341 radio.flags; // flagsのbit15は0なので、indexも0になる
345 *pri_ch = (right << 16) | left;
348 framework.index = ! framework.index; // indexの論理反転
352 * \brief ワイドFMのRX-IFデータを解析する
353 * \param pri_ch プライマリ・チャンネルからのデータ
354 * \param sec_ch セカンダリ・チャンネルからのデータ
355 * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式
356 * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式
359 static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata )
364 // iデータとqデータを抽出する。両者とも16bitで、bit14からbit29に格納されている
365 *idata = ( pri_ch << 2 ) & 0xFFFF0000;
366 *qdata = ( sec_ch << 2 ) & 0xFFFF0000;
368 // パラメータ・データを配列に格納する。
369 // 配列インデックスは comaddr、データはcomdataから。
370 // comdataはpri/secに分散している。
372 command = ( pri_ch >> 6 ) & 0x0F;
374 (( pri_ch << 10 ) & 0xF000) | //
375 (( sec_ch >> 2 ) & 0x0FFF);
376 // パラメータ・データをrx_parameter.data配列に格納する。
377 // 配列インデックスは comaddr、データはcomdataから。
380 if ( radio.comdata[command] != data ){
381 syslog(LOG_NOTICE, "pri_ch : %8x, sec_ch : %8x, Command : %d, Data : %d", pri_ch, sec_ch, command, data );
385 radio.comdata[ command ] = data;
389 * \brief 非ワイドFMのRX-IFデータを解析する
390 * \param pri_ch プライマリ・チャンネルからのデータ
391 * \param sec_ch セカンダリ・チャンネルからのデータ
392 * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
393 * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
394 * \param valid_iq IQデータが有効の時真、向こうの時は偽
398 static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq )
401 if ( sec_ch & 0x02 ) // bit1が1ならindex = 1
403 // IQデータはbit[29:2]に格納されている
404 *idata = (pri_ch << 2); // プライマリ・チャンネルの場合はマスク不要
405 *qdata = (sec_ch << 2) & 0xFFFFFFF0;
414 command = ( pri_ch >> 6 ) & 0x0F;
415 data = ( sec_ch >> 2 ) & 0xFFFF;
416 // パラメータ・データをrx_parameter.data配列に格納する。
417 // 配列インデックスは comaddr、データはcomdataから。
420 if ( radio.comdata[command] != data ){
421 syslog(LOG_NOTICE, "pri_ch : %8x, sec_ch : %8x, Command : %d, Data : %d", pri_ch, sec_ch, command, data );
424 radio.comdata[ command ] = data;
432 * \brief SPORT0 受信割り込みハンドラ
433 * \details このルーチンはcfgファイルで宣言され、SPORT0 RX 割り込みハンドラとして登録される。
434 * SPORT0 RX DMAがバッファの受信を終えるたびに呼び出される。
435 * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと受信タスクへの通知しかしていない。
437 void sport0_rx_int_handler(void)
440 *pDMA1_IRQ_STATUS = DMA_DONE;
441 // タスクにSPORT0受信DMAのバッファが埋まったと知らせる。
442 syscall(isig_sem(SEM_SPORT0_RX)); // デバッグとりあえずタスクは殺しておく。
449 * \brief SPORT0 送信割り込みハンドラ
450 * \details このルーチンはcfgファイルで宣言され、SPORT0 TX 割り込みハンドラとして登録される。
451 * SPORT0 TX DMAがバッファの送信を終えるたびに呼び出される。
452 * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと送信タスクへの通知しかしていない。
454 void sport0_tx_int_handler(void)
457 *pDMA2_IRQ_STATUS = DMA_DONE;
459 // タスクにSPORT0送信DMAのバッファが空いたと知らせる。
460 syscall(isig_sem(SEM_SPORT0_TX));
468 * \param p イニシャライザにコンフィギュレータから与えられる数値。使っていない。
469 * \details この関数はATT_INIによってコンフィギュレータによりイニシャライザとして
470 * 登録される。システムが起動すると、マルチタスク処理が始まる前にこの関数が一度だけ呼ばれる。
473 void init_peripherals(VP_INT p)
486 * \brief SPORT0 RX 関連の初期化
487 * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
488 * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
491 static void init_sport0_rx(void)
496 for ( i = 0; i < RXIF_BUFSIZE; i++)
498 framework.rxif_buffer[0][i] = 0;
499 framework.rxif_buffer[0][i] = 0;
502 // 受信SPORTの設定。WORD長は30bitで、アーリー同期信号。外部クロック入力。
504 0 << 14 | // RCKFE, 0:sample at down edge, 1:sample at up edge
505 0 << 13 | // LARFS, 0:early frame sync, 1:late frame sync
506 0 << 12 | // LRFS, 0:Active high RFS, 1:Active low RFS
507 1 << 10 | // RFSR, 0:RFS is not required every word, 1:RFS is required every word
508 0 << 9 | // IRFS, 0:external RFS, 1:internal RFS
509 0 << 4 | // RLSBIT, 0:MSB first transmission, 1:LSB first transmission
510 0 << 2 | // RDTYPE 0:zero fill, 1:sign extend, 2:u-law, 3:a-law
511 0 << 1 | // IRCLK, 0:external clock generation, 1:internal clock generation
512 0 << 0 ; // RSPEN 0:Rx disable, 1:Rx enable
515 0 << 10 | // RRFST, 0:left streo ch first, 1:right stereo ch first
516 0 << 9 | // RSFESE, 0:normal frame sync, 1:LR frame clock
517 1 << 8 | // RXSE, 0:secondary ch disable, 1:secondary ch enable
518 29 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
524 framework.rx_dma_dsc[0].next_descripter = &framework.rx_dma_dsc[1];
525 framework.rx_dma_dsc[1].next_descripter = &framework.rx_dma_dsc[0];
527 framework.rx_dma_dsc[1].start_address = framework.rxif_buffer[1];
528 framework.rx_dma_dsc[0].start_address = framework.rxif_buffer[0];
530 framework.rx_dma_dsc[0].x_count =
531 framework.rx_dma_dsc[1].x_count = RXIF_BUFSIZE;
533 framework.rx_dma_dsc[0].x_modify =
534 framework.rx_dma_dsc[1].x_modify = sizeof(framework.rxif_buffer[1][0]);
536 framework.rx_dma_dsc[0].config =
537 framework.rx_dma_dsc[1].config =
538 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
539 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
540 1 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
541 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
542 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
543 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
544 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
545 1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
546 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
549 // SPORT0 受信DMAコントローラの初期状態設定
550 // ここではDMAをイネーブルにしない。また、バッファクリアする
552 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
553 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
554 1 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
555 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
556 1 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
557 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
558 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
559 1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
560 0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
561 *pDMA1_NEXT_DESC_PTR = &framework.rx_dma_dsc[0];
567 * \brief SPORT0 TX 関連の初期化
568 * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
569 * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
572 static void init_sport0_tx(void)
577 for ( i = 0; i < AF_BUFSIZE; i++)
579 framework.af_buffer[0][i] = 0;
580 framework.af_buffer[0][i] = 0;
584 // 送信SPORTの設定。WORD長は31bitで、アーリー同期信号。外部クロック入力。
586 0 << 14 | // TCKFE, 0:sample at down edge, 1:sample at up edge
587 0 << 13 | // LATFS, 0:early frame sync, 1:late frame sync
588 0 << 12 | // LTFS, 0:Active high TFS, 1:Active low TFS
589 0 << 11 | // DITFS, 0:data dependent TFS generation, 1:data independent TFS generation
590 1 << 10 | // TFSR, 0:TFS is not required every word, 1:TFS is required every word
591 1 << 9 | // ITFS, 0:external TFS, 1:internal TFS
592 0 << 4 | // TLSBIT, 0:MSB first transmission, 1:LSB first transmission
593 0 << 2 | // TDTYPE 0:normal, 1:reserved, 2:u-law, 3:a-law
594 0 << 1 | // ITCLK, 0:external clock generation, 1:internal clock generation
595 0 << 0 ; // TSPEN 0:Tx disable, 1:Tx enable
598 0 << 10 | // TRFST, 0:left streo ch first, 1:right stereo ch first
599 0 << 9 | // TSFESE, 0:normal frame sync, 1:LR frame clock
600 1 << 8 | // TXSE, 0:secondary ch disable, 1:secondary ch enable
601 30 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
603 *pSPORT0_TFSDIV = 255; // TFS period -1 ( The period is 256 )
607 // 注意:制御の都合上、最初はDMA割り込みをオフにしておく。これは
608 // DMA及びSPORT FIFOへの書き込みによるスタート後のラッシュで割り込みが
609 // 起きないようにするためである。ラッシュで送信されるのはダミーデータのみ
610 // である。rx_if_taskの初期化部でSPORT受信部を起動する際に、送信部の割り込みも
612 framework.tx_dma_dsc[0].next_descripter = &framework.tx_dma_dsc[1];
613 framework.tx_dma_dsc[1].next_descripter = &framework.tx_dma_dsc[0];
615 framework.tx_dma_dsc[0].start_address = framework.af_buffer[0];
616 framework.tx_dma_dsc[1].start_address = framework.af_buffer[1];
618 framework.tx_dma_dsc[0].x_count =
619 framework.tx_dma_dsc[1].x_count = AF_BUFSIZE;
621 framework.tx_dma_dsc[0].x_modify =
622 framework.tx_dma_dsc[1].x_modify = sizeof(framework.af_buffer[0][0]);
624 framework.tx_dma_dsc[0].config =
625 framework.tx_dma_dsc[1].config =
626 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
627 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
628 0 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
629 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
630 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
631 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
632 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
633 0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
634 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
637 // SPORT0 送信DMAコントローラの初期状態設定
638 // ここではDMAをイネーブルにしない。また、バッファクリアする
640 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
641 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
642 0 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
643 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
644 1 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
645 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
646 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
647 0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
648 0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
649 *pDMA2_NEXT_DESC_PTR = &framework.tx_dma_dsc[0];
654 * \brief デバッグ用モニタ・タスク
655 * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
656 * \details 一定時間ごとにシステム状態をモニターする。通常は使っていないが、
657 * 開発時に各種システム量を計算、取得するために動かす低順位タスクである。
660 void monitor_task(VP_INT exinf)
666 unsigned int cycle_start, cycle_end, total_idle_cycle, total_cycle;
670 asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_start) : : "R0");
672 #endif // DEBUG_DSPLOAD
674 tslp_tsk(1000); // 1秒待つ
678 asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_end) : : "R0");
681 total_cycle = cycle_end - cycle_start;
682 // ここまでの通算アイドル時間を取得する
683 total_idle_cycle = idle_cycle;
688 total_idle_cycle >>=16;
690 syslog(LOG_NOTICE, "DSP Load : %d%%", (total_cycle - total_idle_cycle) * 100 / total_cycle);
692 #endif // DEBUG_DSPLOAD
694 #ifdef DEBUG_QUEUEDEPTH
695 { // AF TASK, RX IF TAXK間のキューの深さを報告する
697 syslog( LOG_NOTICE, "Queue depth max : %d, min : %d ", debug_queue_max, debug_queue_min);
699 #endif // DEBUG_QUEUEDEPTH