3 #include <t_services.h>
4 #include <s_services.h>
10 #define PARAMDATA_NUM 16
12 static void init_sport0_rx(void);
13 static void init_sport0_tx(void);
14 static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsigned int * sec_ch);
15 static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata );
16 static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq );
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 // ラジオアルゴリズムとのやりとりに使う変数
44 unsigned short smeter;
45 unsigned short comdata[PARAMDATA_NUM];
50 #if defined (DEBUG_QUEUEDEPTH)
51 static int debug_queue_level = 0;
52 static int debug_queue_max = INT_MIN;
53 static int debug_queue_min = INT_MAX;
58 * \brief RX_IF受信データの処理タスク
59 * \param cfgファイルから値を渡すための引数。使っていない
60 * \details 受信データをDMAバッファから取り出して復調し、データキューに
61 * 書き込む。データキューは \ref af_task との共用である。
63 * また、受信DMA内のRX-IFデータにはコマンドが含まれている。これらの
64 * コマンドを内部変数に記録して復調器が利用できるようにしておく。
66 void rx_if_task(VP_INT exinf)
70 // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
71 unsigned int af_pri_ch, af_sec_ch;
73 vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
74 syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (INT) exinf);
76 syscall(serial_ctl_por(TASK_PORTID,
77 (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
79 // データキューのプリフィル。半分まで詰める
80 for ( i=0; i<AF_QUESIZE/2; i+=2)
82 pack_af_sample(0, 0, &af_pri_ch, &af_sec_ch);
83 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
84 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
85 #ifdef DEBUG_QUEUEDEPTH
86 debug_queue_level +=2;
87 if ( debug_queue_level > debug_queue_max)
88 debug_queue_max = debug_queue_level;
89 #endif // DEBUG_QUEUEDEPTH
93 framework.index = FALSE; // パッカーのインデックスの初期値設定。実のところ、初期値はランダムでも構わない。
95 framework.wide_fm_index = 0; // 配列内部の有効データ数
98 for ( i=0; i<PARAMDATA_NUM; i++)
104 // SPORT0の送受割り込み受付を可能にする
105 syscall(ena_int(INTNO_SPORT0_RX));
106 syscall(ena_int(INTNO_SPORT0_TX));
109 init_sport0_tx(); // 送信DMA開始。割り込みはまだ生成しない
110 init_sport0_rx(); // 受信DMA開始。割り込みイネーブル。
112 // AF送信を開始する。ただし、送信DMA割り込みはまだ発生しない。
113 *pDMA2_CONFIG |= DMAEN; // TX SPORT DMA Enable
114 *pSPORT0_TCR1 |= TSPEN; // TX SPORT Enable
119 tslp_tsk(1); // DMAがFIFOを充填するのに十分な時間待つ。
120 syscall(act_tsk(TASK_AF)); // AFデータ送信タスクをアクティブにする
122 // 頃合いなので送信DMA割り込みを開始する。
123 // CPUロックするのは割り込みにより、タイミングがずれるのを嫌って。
125 framework.tx_dma_dsc[0].config |= 1 << DI_EN_P;
126 framework.tx_dma_dsc[1].config |= 1 << DI_EN_P;
129 // RX受信を開始する。転送と同時に割り込みが始まる
130 *pDMA1_CONFIG |= DMAEN; // RX SPORT DMA Enable
131 *pSPORT0_RCR1 |= RSPEN; // RX SPORT Enable
137 * 受信DMA割り込み待ってから、DMAバッファ内部のデータを解析して然るべき受信処理を行う。
141 unsigned int* filled_buffer;
143 struct dma_descripter * next;
148 // SPORT0受信DMAがバッファを埋めるのを待つ。
149 syscall(wai_sem(SEM_SPORT0_RX));
152 // SPORT0受信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
153 // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
154 // 割り込みが完了したDMAのデスクリプタである
155 next = (struct dma_descriptor *) *pDMA1_NEXT_DESC_PTR;
157 // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
158 filled_buffer = next->start_address;
160 // RX-IF DMAバッファ内部のデータを処理
161 for ( i= 0; i<RXIF_BUFSIZE; i+=2)
167 // オーディオ送信プライマリチャンネルとセカンダリチャンネルデータ
168 unsigned int af_pri_ch, af_sec_ch;
171 // Wide FMモードフラグはプライマリチャンネルでのみ確認可能である。
172 // プライマリ・チャンネルは必ずバッファの偶数番目に位置する。
173 if ( filled_buffer[i] & WIDE_FM_FLAG )
175 // データはバッファにまとめて WIDE_FM_OVERSAMPE個ごとに処理する
176 // 同時にFPGAから送られてくるデータも紐解いて格納する
177 unpack_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata );
178 framework.wide_fm_i[framework.wide_fm_index] = idata;
179 framework.wide_fm_q[framework.wide_fm_index] = qdata;
180 framework.wide_fm_index++;
183 if ( framework.wide_fm_index >= WIDE_FM_OVERSAMPE )
187 radio_demodulate_wide_FM( framework.wide_fm_i, framework.wide_fm_q, &left, &right );
189 framework.wide_fm_index = 0;
190 // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
191 pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
193 // パック済みオーディオサンプルをAFキューに送信する
194 // キューに空きがなければ、待たずにエラーをもって帰る
195 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
196 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
197 #ifdef DEBUG_QUEUEDEPTH
198 debug_queue_level += 2;
199 if ( debug_queue_level > debug_queue_max)
200 debug_queue_max = debug_queue_level;
201 #endif // DEBUG_QUEUEDEPTH
210 // 問答無用でWide FMのバッファ済みデータを消す
211 // これで変数の値が変わるのはシステム稼働中多くても1回である。
212 // 必要な場合だけ書き換えるとif文が増えるのでこうしている
213 framework.wide_fm_index = 0;
215 // 同時にFPGAから送られてくるデータも紐解いて格納する
216 unpack_non_wide_fm(filled_buffer[i], filled_buffer[i+1], &idata, &qdata, &is_valid_iq );
217 // IQデータが有効の場合だけデコードする
220 // 非ワイドFM受信アルゴリズムを呼び出す
221 radio_demodulate_non_wide_FM( idata, qdata, &left, &right);
222 // デコード済みオーディオサンプルを、DMAから送信できる形式にパックする
223 pack_af_sample( left, right, &af_pri_ch, &af_sec_ch);
224 // パック済みオーディオサンプルをAFキューに送信する
225 // キューに空きがなければ、待たずにエラーをもって帰る
226 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_pri_ch));
227 syscall(psnd_dtq(DTQ_AF, (VP_INT)af_sec_ch));
228 #ifdef DEBUG_QUEUEDEPTH
229 debug_queue_level += 2;
230 if ( debug_queue_level > debug_queue_max)
231 debug_queue_max = debug_queue_level;
232 #endif // DEBUG_QUEUEDEPTH
237 } // RX-IF DMAバッファ内部のデータを処理
242 syslog(LOG_NOTICE, "rx_if_task ends.");
248 * \brief AF送信データの処理タスク。
249 * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
250 * \details データキューから取り出したAF信号をDMAバッファに転送する。
251 * このタスクは受信データ処理タスクより優先順位が高い。これは、DMAの送信割り込みへの
252 * 応答が遅れると、バッファを埋め終わる前に送信が始まってしまうからである。
254 * このタスクではあまり多くの時間を割くべきではなく、そのため、データキューへデータを
255 * 送り込む段階でAFデータの組み立ては終わっている。また、データの初期化などは全部
258 void af_task(VP_INT exinf)
260 syslog( LOG_NOTICE, "TASK_AF activatred!" );
264 unsigned int* filled_buffer;
266 struct dma_descripter * next;
272 syscall(wai_sem(SEM_SPORT0_TX));
275 // SPORT0送信DMAコントローラが次にロードするデスクリプタへのポインタを取得する。
276 // このデスクリプタは、「現在使われていない」DMAデスクリプタであり、逆に言うと
277 // 割り込みが完了したDMAのデスクリプタである
278 next = (struct dma_descriptor *) *pDMA2_NEXT_DESC_PTR;
280 // 取得したデスクリプタから、割り込みを発生したバッファを割り出す。
281 filled_buffer = next->start_address;
284 // AF DMAバッファに送信すべきデータを書く
285 for ( i= 0; i<AF_BUFSIZE; i++)
289 // AFキューから送信すべきデータを取り出す
290 // SVCにポーリングを使用しているため、取り出すべきデータがなければ待ちに入らずに
292 syscall(prcv_dtq( DTQ_AF, (VP_INT)&data));
294 filled_buffer[i] = data;
295 #ifdef DEBUG_QUEUEDEPTH
296 debug_queue_level --;
297 if ( debug_queue_min > debug_queue_level)
298 debug_queue_min = debug_queue_level;
299 #endif // DEBUG_QUEUEDEPTH
307 * \brief AFサンプルをパックしてデータキューに書き込みできる形式に変換する
308 * \param left 左チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
309 * \param right 右チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
310 * \param pri_ch パック済みオーディオデータ。最初にデータキューにコピーする。
311 * \param sec_ch パック済みオーディオデータ。2番めにデータキューにコピーする。
313 * 与えられたステレオ・データから、データキュー書き込み用のデータを組み立てる。
314 * 書き込みデータはSPORTのプライマリ・チャンネル用、セカンダリ・チャンネル用がある。
315 * さらに、これらがindex ==0 および 1の場合に別れる。
317 * この関数はindexを af_ctrl.index で管理しており、その値に応じて適切な
318 * プライマリ・チャンネル、セカンダリ・チャンネル用のデータを組み立てる。
320 * なお、セカンダリ・チャンネルはindex = 1の時にサブ・オーディオを伝送するが、
321 * TRX-305はサブ・オーディオを使わないためこのルーチンは常に値を0としている。
323 static void pack_af_sample( short left, short right, unsigned int * pri_ch, unsigned int * sec_ch)
325 // オーディオデータは15bitしか使わない。Rchの16bit目は0に固定する
326 right >>= 1; // 15bitに変換
327 right &= 0x7FFF; // 本当はMSBは無視されるのだが、念の為0にする
329 left >>= 1; //15bitに変換
331 if ( framework.index )
333 left |= 0x8000; // MSBを1にする
335 // indexが1のとき、セカンダリチャンネルはサブオーディオとなっている。
336 // TRX-305はサブオーディオを使わないのでindexデータのみ送る
337 *sec_ch = 0x00008000;
341 left &= 0x7FFF; // MSBを0にする
343 // indexが0のとき、セカンダリオーディオはDSPからSH2へのデータ回線である
346 radio.flags; // flagsのbit15は0なので、indexも0になる
350 *pri_ch = (right << 16) | left;
353 framework.index = ! framework.index; // indexの論理反転
357 * \brief ワイドFMのRX-IFデータを解析する
358 * \param pri_ch プライマリ・チャンネルからのデータ
359 * \param sec_ch セカンダリ・チャンネルからのデータ
360 * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式
361 * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式
364 static void unpack_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata )
367 // iデータとqデータを抽出する。両者とも16bitで、bit14からbit29に格納されている
368 *idata = ( pri_ch << 2 ) & 0xFFFF0000;
369 *qdata = ( sec_ch << 2 ) & 0xFFFF0000;
371 // パラメータ・データを配列に格納する。
372 // 配列インデックスは comaddr、データはcomdataから。comdataはpri/secに分散している。
373 radio.comdata[ ( pri_ch >> 6 ) & 0x0F ] =
374 (( pri_ch << 6 ) & 0xF000) | //
375 (( sec_ch >> 2 ) & 0x0FFF);
379 * \brief 非ワイドFMのRX-IFデータを解析する
380 * \param pri_ch プライマリ・チャンネルからのデータ
381 * \param sec_ch セカンダリ・チャンネルからのデータ
382 * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
383 * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
384 * \param valid_iq IQデータが有効の時真、向こうの時は偽
388 static void unpack_non_wide_fm( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq )
391 if ( sec_ch & 0x02 ) // bit1が1ならindex = 1
393 // IQデータはbit[29:2]に格納されている
394 *idata = (pri_ch << 2); // プライマリ・チャンネルの場合はマスク不要
395 *qdata = (sec_ch << 2) & 0xFFFFFFF0;
401 // パラメータ・データをrx_parameter.data配列に格納する。
402 // 配列インデックスは comaddr、データはcomdataから。
403 radio.comdata[ ( pri_ch >> 6 ) & 0x0F ] =
404 ( sec_ch >> 2 ) & 0xFFFF;
412 * \brief SPORT0 受信割り込みハンドラ
413 * \details このルーチンはcfgファイルで宣言され、SPORT0 RX 割り込みハンドラとして登録される。
414 * SPORT0 RX DMAがバッファの受信を終えるたびに呼び出される。
415 * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと受信タスクへの通知しかしていない。
417 void sport0_rx_int_handler(void)
420 *pDMA1_IRQ_STATUS = DMA_DONE;
421 // タスクにSPORT0受信DMAのバッファが埋まったと知らせる。
422 syscall(isig_sem(SEM_SPORT0_RX)); // デバッグとりあえずタスクは殺しておく。
429 * \brief SPORT0 送信割り込みハンドラ
430 * \details このルーチンはcfgファイルで宣言され、SPORT0 TX 割り込みハンドラとして登録される。
431 * SPORT0 TX DMAがバッファの送信を終えるたびに呼び出される。
432 * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと送信タスクへの通知しかしていない。
434 void sport0_tx_int_handler(void)
437 *pDMA2_IRQ_STATUS = DMA_DONE;
439 // タスクにSPORT0送信DMAのバッファが空いたと知らせる。
440 syscall(isig_sem(SEM_SPORT0_TX));
448 * \param p イニシャライザにコンフィギュレータから与えられる数値。使っていない。
449 * \details この関数はATT_INIによってコンフィギュレータによりイニシャライザとして
450 * 登録される。システムが起動すると、マルチタスク処理が始まる前にこの関数が一度だけ呼ばれる。
453 void init_peripherals(VP_INT p)
466 * \brief SPORT0 RX 関連の初期化
467 * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
468 * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
471 static void init_sport0_rx(void)
476 for ( i = 0; i < RXIF_BUFSIZE; i++)
478 framework.rxif_buffer[0][i] = 0;
479 framework.rxif_buffer[0][i] = 0;
482 // 受信SPORTの設定。WORD長は30bitで、アーリー同期信号。外部クロック入力。
484 0 << 14 | // RCKFE, 0:sample at down edge, 1:sample at up edge
485 0 << 13 | // LARFS, 0:early frame sync, 1:late frame sync
486 0 << 12 | // LRFS, 0:Active high RFS, 1:Active low RFS
487 1 << 10 | // RFSR, 0:RFS is not required every word, 1:RFS is required every word
488 0 << 9 | // IRFS, 0:external RFS, 1:internal RFS
489 0 << 4 | // RLSBIT, 0:MSB first transmission, 1:LSB first transmission
490 0 << 2 | // RDTYPE 0:zero fill, 1:sign extend, 2:u-law, 3:a-law
491 0 << 1 | // IRCLK, 0:external clock generation, 1:internal clock generation
492 0 << 0 ; // RSPEN 0:Rx disable, 1:Rx enable
495 0 << 10 | // RRFST, 0:left streo ch first, 1:right stereo ch first
496 0 << 9 | // RSFESE, 0:normal frame sync, 1:LR frame clock
497 1 << 8 | // RXSE, 0:secondary ch disable, 1:secondary ch enable
498 29 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
504 framework.rx_dma_dsc[0].next_descripter = &framework.rx_dma_dsc[1];
505 framework.rx_dma_dsc[1].next_descripter = &framework.rx_dma_dsc[0];
507 framework.rx_dma_dsc[1].start_address = framework.rxif_buffer[1];
508 framework.rx_dma_dsc[0].start_address = framework.rxif_buffer[0];
510 framework.rx_dma_dsc[0].x_count =
511 framework.rx_dma_dsc[1].x_count = RXIF_BUFSIZE;
513 framework.rx_dma_dsc[0].x_modify =
514 framework.rx_dma_dsc[1].x_modify = sizeof(framework.rxif_buffer[1][0]);
516 framework.rx_dma_dsc[0].config =
517 framework.rx_dma_dsc[1].config =
518 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
519 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
520 1 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
521 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
522 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
523 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
524 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
525 1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
526 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
529 // SPORT0 受信DMAコントローラの初期状態設定
530 // ここではDMAをイネーブルにしない。また、バッファクリアする
532 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
533 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
534 1 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
535 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
536 1 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
537 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
538 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
539 1 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
540 0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
541 *pDMA1_NEXT_DESC_PTR = &framework.rx_dma_dsc[0];
547 * \brief SPORT0 TX 関連の初期化
548 * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
549 * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
552 static void init_sport0_tx(void)
557 for ( i = 0; i < AF_BUFSIZE; i++)
559 framework.af_buffer[0][i] = 0;
560 framework.af_buffer[0][i] = 0;
564 // 送信SPORTの設定。WORD長は31bitで、アーリー同期信号。外部クロック入力。
566 0 << 14 | // TCKFE, 0:sample at down edge, 1:sample at up edge
567 0 << 13 | // LATFS, 0:early frame sync, 1:late frame sync
568 0 << 12 | // LTFS, 0:Active high TFS, 1:Active low TFS
569 0 << 11 | // DITFS, 0:data dependent TFS generation, 1:data independent TFS generation
570 1 << 10 | // TFSR, 0:TFS is not required every word, 1:TFS is required every word
571 1 << 9 | // ITFS, 0:external TFS, 1:internal TFS
572 0 << 4 | // TLSBIT, 0:MSB first transmission, 1:LSB first transmission
573 0 << 2 | // TDTYPE 0:normal, 1:reserved, 2:u-law, 3:a-law
574 0 << 1 | // ITCLK, 0:external clock generation, 1:internal clock generation
575 0 << 0 ; // TSPEN 0:Tx disable, 1:Tx enable
578 0 << 10 | // TRFST, 0:left streo ch first, 1:right stereo ch first
579 0 << 9 | // TSFESE, 0:normal frame sync, 1:LR frame clock
580 1 << 8 | // TXSE, 0:secondary ch disable, 1:secondary ch enable
581 30 << 0 ; // SLEN 0-1:not allowed,2-31:Serial word length - 1
583 *pSPORT0_TFSDIV = 255; // TFS period -1 ( The period is 256 )
587 // 注意:制御の都合上、最初はDMA割り込みをオフにしておく。これは
588 // DMA及びSPORT FIFOへの書き込みによるスタート後のラッシュで割り込みが
589 // 起きないようにするためである。ラッシュで送信されるのはダミーデータのみ
590 // である。rx_if_taskの初期化部でSPORT受信部を起動する際に、送信部の割り込みも
592 framework.tx_dma_dsc[0].next_descripter = &framework.tx_dma_dsc[1];
593 framework.tx_dma_dsc[1].next_descripter = &framework.tx_dma_dsc[0];
595 framework.tx_dma_dsc[0].start_address = framework.af_buffer[0];
596 framework.tx_dma_dsc[1].start_address = framework.af_buffer[1];
598 framework.tx_dma_dsc[0].x_count =
599 framework.tx_dma_dsc[1].x_count = AF_BUFSIZE;
601 framework.tx_dma_dsc[0].x_modify =
602 framework.tx_dma_dsc[1].x_modify = sizeof(framework.af_buffer[0][0]);
604 framework.tx_dma_dsc[0].config =
605 framework.tx_dma_dsc[1].config =
606 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
607 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
608 0 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
609 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
610 0 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
611 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
612 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
613 0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
614 1 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
617 // SPORT0 送信DMAコントローラの初期状態設定
618 // ここではDMAをイネーブルにしない。また、バッファクリアする
620 FLOW_LARGE | // FLOW, 0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
621 NDSIZE_7 | // NDSIZE, the # of element of the next descripter to fetch
622 0 << DI_EN_P | // DI_EN, 0:No interrupt at the end, 1:Interrupt at the end
623 0 << DI_SEL_P | // DI_SEL, 0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
624 1 << RESTART_P | // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
625 0 << DMA2D_P | // DMA2D, 0:Linear DMA, 1:2D DMA
626 WDSIZE_32 | // WDSIZE, 0:8bit, 1:16bit, 2:32bit,3:reserved
627 0 << WNR_P | // WNR, 0:Read from memory, 1:Write to Memory
628 0 << 0 ; // DMA_EN, 0:Disable DMA, 1:Enable DMA
629 *pDMA2_NEXT_DESC_PTR = &framework.tx_dma_dsc[0];
634 * \brief デバッグ用モニタ・タスク
635 * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
636 * \details 一定時間ごとにシステム状態をモニターする。通常は使っていないが、
637 * 開発時に各種システム量を計算、取得するために動かす低順位タスクである。
640 void monitor_task(VP_INT exinf)
646 unsigned int cycle_start, cycle_end, total_idle_cycle, total_cycle;
650 asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_start) : : "R0");
652 #endif // DEBUG_DSPLOAD
654 tslp_tsk(1000); // 1秒待つ
658 asm volatile ("r0 = cycles;%0 = r0;" : "=d"(cycle_end) : : "R0");
661 total_cycle = cycle_end - cycle_start;
662 // ここまでの通算アイドル時間を取得する
663 total_idle_cycle = idle_cycle;
668 total_idle_cycle >>=16;
670 syslog(LOG_NOTICE, "DSP Load : %d%%", (total_cycle - total_idle_cycle) * 100 / total_cycle);
672 #endif // DEBUG_DSPLOAD
674 #ifdef DEBUG_QUEUEDEPTH
675 { // AF TASK, RX IF TAXK間のキューの深さを報告する
677 syslog( LOG_NOTICE, "Queue depth max : %d, min : %d ", debug_queue_max, debug_queue_min);
679 #endif // DEBUG_QUEUEDEPTH