OSDN Git Service

AFサンプルのパッキング関数を書いた
[trx-305dsp/dsp.git] / trx305 / rx_if.c
1
2
3 #include <t_services.h>
4 #include <s_services.h>
5 #include "kernel_id.h"
6 #include "rx_if.h"
7 #include <cdefBF533.h>
8
9
10 static void init_sport0_rx(void);
11 static void init_sport0_tx(void);
12 static void pack_af_sample( short left, short right, int * pri_ch, int * sec_ch1);
13 static void parse_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata );
14 static void parse_non_wide_fm(  unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq );
15
16
17
18 struct dma_descripter{
19     struct dma_descripter * next_descripter;
20     unsigned int * start_address;
21     unsigned short config;
22     unsigned short x_count;
23     unsigned short x_modify;
24 };
25
26 static struct {
27     struct dma_descripter rx_dma_dsc[2];
28     struct dma_descripter tx_dma_dsc[2];
29
30     unsigned int rxif_buffer[2][RXIF_BUFSIZE];
31     unsigned int af_buffer[2][AF_BUFSIZE];
32 } sport_ctl;
33
34 static struct {
35     int index;
36     unsigned short flags;
37     unsigned short smeter;
38 } af_ctl;
39
40 /**
41  * \brief RX_IF受信データの処理タスク
42  * \param cfgファイルから値を渡すための引数。使っていない
43  * \details 受信データをDMAバッファから取り出して復調し、データキューに
44  * 書き込む。データキューは \ref af_task との共用である。
45  *
46  * また、受信DMA内のRX-IFデータにはコマンドが含まれている。これらの
47  * コマンドを内部変数に記録して復調器がりようできるようにしておく。
48  */
49 void rx_if_task(VP_INT exinf)
50 {
51
52     vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
53     syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (INT) exinf);
54
55     syscall(serial_ctl_por(TASK_PORTID,
56             (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
57
58     af_ctl.index = FALSE;
59     af_ctl.flags = 0;
60     af_ctl.smeter = 0;
61
62         // SPORT0の送受割り込みを可能にする
63     syscall(ena_int(INTNO_SPORT0_RX));
64     syscall(ena_int(INTNO_SPORT0_TX));
65
66         // SPORT0の送受信を初期化する。
67     init_sport0_tx();       // 送信DMA開始。割り込みはまだ生成しない
68     init_sport0_rx();       // 受信DMA開始。割り込みイネーブル。
69
70         // AF送信を開始する。ただし、送信DMA割り込みはまだ発生しない。
71     *pDMA2_CONFIG |= DMAEN;     // TX SPORT DMA Enable
72     *pSPORT0_TCR1 |= RSPEN;     // TX SPORT Enable
73     ssync();
74
75     tslp_tsk(1);      // DMAがFIFOを充填するのに十分な時間待つ。
76     syscall(act_tsk(TASK_AF));  // AFデータ送信タスクをアクティブにする
77
78         // 頃合いなので送信DMA割り込みを開始する。
79         // CPUロックするのは割り込みにより、タイミングがずれるのを嫌って。
80     loc_cpu();
81     sport_ctl.tx_dma_dsc[0].config |= 1 << DI_EN_P;
82     sport_ctl.tx_dma_dsc[1].config |= 1 << DI_EN_P;
83     unl_cpu();
84
85         // RX受信を開始する
86     *pDMA1_CONFIG |= DMAEN;     // RX SPORT DMA Enable
87     *pSPORT0_RCR1 |= RSPEN;     // RX SPORT Enable
88     ssync();
89
90
91
92
93     int count = 0;
94
95
96     /*
97      *  メインループ
98      */
99     do {
100
101         long int rx[4];
102
103             // SPORT0受信DMAがバッファを埋めるのを待つ。
104         syscall(wai_sem(SEM_SPORT0_RX));
105
106         count++;
107         if ( count > 31500/(RXIF_BUFSIZE/4))
108         {
109             count = 0;
110                 // FIFOにデータがたまったはずである。
111                 // FIFOデータを読みだして下位2bitのみ表示する
112             rx[0] = sport_ctl.rxif_buffer[1][0];    // 下位2bitのみ抽出
113             rx[1] = sport_ctl.rxif_buffer[1][1];    // 下位2bitのみ抽出
114             rx[2] = sport_ctl.rxif_buffer[1][2];    // 下位2bitのみ抽出
115             rx[3] = sport_ctl.rxif_buffer[1][3];    // 下位2bitのみ抽出
116
117             syslog( LOG_NOTICE, "RX word : %08x,%08x,%08x,%08x", rx[0], rx[1], rx[2], rx[3] );
118
119         }
120
121
122
123
124
125     } while (1);
126
127     syslog(LOG_NOTICE, "Sample program ends.");
128     kernel_exit();
129 }
130
131
132 /**
133  * \brief AF送信データの処理タスク。
134  * \param exinf cfgファイルに記述されたパラメタを受け取る引数。使っていない。
135  * \details データキューから取り出したAF信号をDMAバッファに転送する。
136  * このタスクは受信データ処理タスクより優先順位が高い。これは、DMAの送信割り込みへの
137  * 応答が遅れると、バッファを埋め終わる前に送信が始まってしまうからである。
138  *
139  * このタスクではあまり多くの時間を割くべきではなく、そのため、データキューへデータを
140  * 送り込む段階でAFデータの組み立ては終わっている。また、データの初期化などは全部
141  * RX-IF処理タスクに任せている。
142  */
143 void af_task(VP_INT exinf)
144 {
145     syslog( LOG_NOTICE, "TASK_AF activatred!" );
146
147     int i = 0;
148
149     do{
150         syscall(wai_sem(SEM_SPORT0_TX));
151         // ここに送信処理を書く
152
153         if ( i == 0)
154         {
155             i=8000;
156             syslog( LOG_NOTICE, "AF Interrupt" );
157         }
158         i--;
159     }while (1);
160 }
161
162
163 /**
164  * \brief AFサンプルをパックしてデータキューに書き込みできる形式に変換する
165  * \param left  左チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
166  * \param right 右チャンネルのオーディオデータ。[-1,1.0)の固定小数点形式
167  * \param pri_ch パック済みオーディオデータ。最初にデータキューにコピーする。
168  * \param sec_ch パック済みオーディオデータ。2番めにデータキューにコピーする。
169  * \detail
170  * 与えられたステレオ・データから、データキュー書き込み用のデータを組み立てる。
171  * 書き込みデータはSPORTのプライマリ・チャンネル用、セカンダリ・チャンネル用がある。
172  * さらに、これらがindex ==0 および 1の場合に別れる。
173  *
174  * この関数はindexを af_ctrl.index で管理しており、その値に応じて適切な
175  * プライマリ・チャンネル、セカンダリ・チャンネル用のデータを組み立てる。
176  *
177  * なお、セカンダリ・チャンネルはindex = 1の時にサブ・オーディオを伝送するが、
178  * TRX-305はサブ・オーディオを使わないためこのルーチンは常に値を0としている。
179  */
180 static void pack_af_sample( short left, short right, int * pri_ch, int * sec_ch)
181 {
182         // オーディオデータは15bitしか使わない。Rchの16bit目は0に固定する
183     right >>= 1;        // 15bitに変換
184     right &= 0x7FFF;    // 本当はMSBは無視されるのだが、念の為0にする
185
186     left >>= 1;         //15bitに変換
187
188     if ( af_ctl.index )
189     {
190         left |= 0x8000; // MSBを1にする
191
192             // indexが1のとき、セカンダリチャンネルはサブオーディオとなっている。
193             // TRX-305はサブオーディオを使わないのでindexデータのみ送る
194         *sec_ch = 0x00008000;
195     }
196     else
197     {
198         left &= 0x7FFF;    // MSBを0にする
199
200             // indexが0のとき、セカンダリオーディオはDSPからSH2へのデータ回線である
201         *sec_ch =
202                 af_ctl.smeter << 16  |
203                 af_ctl.flags;           // flagsのbit15は0なので、indexも0になる
204     }
205
206         // プライマリ・チャンネルの組み立て
207     *pri_ch = (right << 16) | left;
208
209
210     af_ctl.index = ! af_ctl.index;  // indexの論理反転
211 }
212
213 /**
214  * \brief ワイドFMのRX-IFデータを解析する
215  * \param pri_ch プライマリ・チャンネルからのデータ
216  * \param sec_ch セカンダリ・チャンネルからのデータ
217  * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式
218  * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式
219  * \detail
220  */
221 static void parse_wide_fm ( unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata )
222 {
223
224 }
225
226 /**
227  * \brief 非ワイドFMのRX-IFデータを解析する
228  * \param pri_ch プライマリ・チャンネルからのデータ
229  * \param sec_ch セカンダリ・チャンネルからのデータ
230  * \param idata 抽出したIデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
231  * \param qdata 抽出したQデータ。[-1,1.0)の固定小数点形式。valid_iqが真の時のみ有効
232  * \param valid_iq IQデータが有効の時真、向こうの時は偽
233  * \detail
234  */
235
236 static void parse_non_wide_fm(  unsigned int pri_ch, unsigned int sec_ch, int* idata, int* qdata, int* valid_iq )
237 {
238
239 }
240
241
242 /**
243  * \brief SPORT0 受信割り込みハンドラ
244  * \details このルーチンはcfgファイルで宣言され、SPORT0 RX 割り込みハンドラとして登録される。
245  * SPORT0 RX DMAがバッファの受信を終えるたびに呼び出される。
246  * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと受信タスクへの通知しかしていない。
247  */
248 void sport0_rx_int_handler(void)
249 {
250         // DMA割り込みをクリアする。
251     *pDMA1_IRQ_STATUS = DMA_DONE;
252
253         // タスクにSPORT0受信DMAのバッファが埋まったと知らせる。
254     syscall(isig_sem(SEM_SPORT0_RX));
255
256         // ペリフェラルへの書き込みを待つ。
257     ssync();
258
259 }
260
261 /**
262  * \brief SPORT0 送信割り込みハンドラ
263  * \details このルーチンはcfgファイルで宣言され、SPORT0 TX 割り込みハンドラとして登録される。
264  * SPORT0 TX DMAがバッファの送信を終えるたびに呼び出される。
265  * 割り込み専有時間を小さくするため、実際には、割り込みのクリアと送信タスクへの通知しかしていない。
266  */
267 void sport0_tx_int_handler(void)
268 {
269         // DMA割り込みをクリアする。
270     *pDMA2_IRQ_STATUS = DMA_DONE;
271
272         // タスクにSPORT0送信DMAのバッファが空いたと知らせる。
273      syscall(isig_sem(SEM_SPORT0_TX));
274
275          // ペリフェラルへの書き込みを待つ。
276      ssync();
277
278 }
279
280 /**
281  * \brief ペリフェラルの初期化
282  * \param p イニシャライザにコンフィギュレータから与えられる数値。使っていない。
283  * \details この関数はATT_INIによってコンフィギュレータによりイニシャライザとして
284  * 登録される。システムが起動すると、マルチタスク処理が始まる前にこの関数が一度だけ呼ばれる。
285  */
286
287 void init_peripherals(VP_INT p)
288 {
289         // ペリフェラルをディセーブルにする
290     *pSPORT0_TCR1 = 0;
291     *pSPORT0_RCR1 = 0;
292     *pDMA1_CONFIG = 0;
293     *pDMA2_CONFIG = 0;
294     *pSPI_CTL = 0;
295     *pSIC_IMASK = 0;
296     ssync();
297 }
298
299 /**
300  * \brief SPORT0 RX 関連の初期化
301  * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
302  * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
303  */
304
305 static void init_sport0_rx(void)
306 {
307     int i;
308
309         // DMAバッファを明示的にクリアする
310     for ( i = 0; i < RXIF_BUFSIZE; i++)
311     {
312         sport_ctl.rxif_buffer[0][i] = 0;
313         sport_ctl.rxif_buffer[0][i] = 0;
314     }
315
316         // 受信SPORTの設定。WORD長は30bitで、アーリー同期信号。外部クロック入力。
317     *pSPORT0_RCR1 =
318             0 << 14 |   // RCKFE,   0:sample at down edge, 1:sample at up edge
319             0 << 13 |   // LARFS,   0:early frame sync, 1:late frame sync
320             0 << 12 |   // LRFS,    0:Active high RFS, 1:Active low RFS
321             1 << 10 |   // RFSR,    0:RFS is not required every word, 1:RFS is required every word
322             0 << 9  |   // IRFS,    0:external RFS, 1:internal RFS
323             0 << 4  |   // RLSBIT,  0:MSB first transmission, 1:LSB first transmission
324             0 << 2  |   // RDTYPE   0:zero fill, 1:sign extend, 2:u-law, 3:a-law
325             0 << 1  |   // IRCLK,   0:external clock generation, 1:internal clock generation
326             0 << 0  ;   // RSPEN    0:Rx disable, 1:Rx enable
327
328     *pSPORT0_RCR2 =
329             0 << 10 |   // RRFST,   0:left streo ch first, 1:right stereo ch first
330             0 << 9  |   // RSFESE,  0:normal frame sync, 1:LR frame clock
331             1 << 8  |   // RXSE,    0:secondary ch disable, 1:secondary ch enable
332            29 << 0  ;   // SLEN     0-1:not allowed,2-31:Serial word length - 1
333     ssync();
334
335
336         // 受信DMAデスクリプタを作る
337     sport_ctl.rx_dma_dsc[0].next_descripter = &sport_ctl.rx_dma_dsc[1];
338     sport_ctl.rx_dma_dsc[0].start_address = sport_ctl.rxif_buffer[0];
339     sport_ctl.rx_dma_dsc[0].x_count = RXIF_BUFSIZE;
340     sport_ctl.rx_dma_dsc[0].x_modify = sizeof(sport_ctl.rxif_buffer[0][0]);
341     sport_ctl.rx_dma_dsc[0].config =
342             FLOW_LARGE      |   // FLOW,    0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
343             NDSIZE_7        |   // NDSIZE,  the # of element of the next descripter to fetch
344             1 << DI_EN_P    |   // DI_EN,   0:No interrupt at the end, 1:Interrupt at the end
345             0 << DI_SEL_P   |   // DI_SEL,  0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
346             0 << RESTART_P  |   // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
347             0 << DMA2D_P    |   // DMA2D,   0:Linear DMA, 1:2D DMA
348             WDSIZE_32       |   // WDSIZE,  0:8bit, 1:16bit, 2:32bit,3:reserved
349             1 << WNR_P      |   // WNR,     0:Read from memory, 1:Write to Memory
350             1 << 0          ;   // DMA_EN,  0:Disable DMA, 1:Enable DMA
351
352     sport_ctl.rx_dma_dsc[1].next_descripter = &sport_ctl.rx_dma_dsc[0];
353     sport_ctl.rx_dma_dsc[1].start_address = sport_ctl.rxif_buffer[1];
354     sport_ctl.rx_dma_dsc[1].x_count = RXIF_BUFSIZE;
355     sport_ctl.rx_dma_dsc[1].x_modify = sizeof(sport_ctl.rxif_buffer[1][0]);
356     sport_ctl.rx_dma_dsc[1].config =
357             FLOW_LARGE      |   // FLOW,    0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
358             NDSIZE_7        |   // NDSIZE,  the # of element of the next descripter to fetch
359             1 << DI_EN_P    |   // DI_EN,   0:No interrupt at the end, 1:Interrupt at the end
360             0 << DI_SEL_P   |   // DI_SEL,  0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
361             0 << RESTART_P  |   // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
362             0 << DMA2D_P    |   // DMA2D,   0:Linear DMA, 1:2D DMA
363             WDSIZE_32       |   // WDSIZE,  0:8bit, 1:16bit, 2:32bit,3:reserved
364             1 << WNR_P      |   // WNR,     0:Read from memory, 1:Write to Memory
365             1 << 0          ;   // DMA_EN,  0:Disable DMA, 1:Enable DMA
366
367         // SPORT0 受信DMAコントローラの初期状態設定
368         // ここではDMAをイネーブルにしない。また、バッファクリアする
369     *pDMA1_CONFIG =
370             FLOW_LARGE      |   // FLOW,    0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
371             NDSIZE_7        |   // NDSIZE,  the # of element of the next descripter to fetch
372             1 << DI_EN_P    |   // DI_EN,   0:No interrupt at the end, 1:Interrupt at the end
373             0 << DI_SEL_P   |   // DI_SEL,  0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
374             1 << RESTART_P  |   // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
375             0 << DMA2D_P    |   // DMA2D,   0:Linear DMA, 1:2D DMA
376             WDSIZE_32       |   // WDSIZE,  0:8bit, 1:16bit, 2:32bit,3:reserved
377             1 << WNR_P      |   // WNR,     0:Read from memory, 1:Write to Memory
378             0 << 0          ;   // DMA_EN,  0:Disable DMA, 1:Enable DMA
379     *pDMA1_NEXT_DESC_PTR = &sport_ctl.rx_dma_dsc[0];
380
381
382 }
383
384 /**
385  * \brief SPORT0 TX 関連の初期化
386  * \details この関数は、\ref rx_if_task から一度だけ呼び出される。呼び出されると、
387  * DMAバッファをクリアし、SPORT0 RX関係のレジスタを然るべき値で初期化する。
388  */
389
390 static void init_sport0_tx(void)
391 {
392     int i;
393
394         // DMAバッファを明示的にクリアする
395     for ( i = 0; i < AF_BUFSIZE; i++)
396     {
397         sport_ctl.af_buffer[0][i] = 0;
398         sport_ctl.af_buffer[0][i] = 0;
399     }
400
401
402         // 送信SPORTの設定。WORD長は31bitで、アーリー同期信号。外部クロック入力。
403     *pSPORT0_TCR1 =
404             0 << 14 |   // TCKFE,   0:sample at down edge, 1:sample at up edge
405             0 << 13 |   // LATFS,   0:early frame sync, 1:late frame sync
406             0 << 12 |   // LTFS,    0:Active high TFS, 1:Active low TFS
407             0 << 11 |   // DITFS,   0:data dependent TFS generation, 1:data independent TFS generation
408             1 << 10 |   // TFSR,    0:TFS is not required every word, 1:TFS is required every word
409             0 << 9  |   // ITFS,    0:external TFS, 1:internal TFS
410             0 << 4  |   // TLSBIT,  0:MSB first transmission, 1:LSB first transmission
411             0 << 2  |   // TDTYPE   0:normal, 1:reserved, 2:u-law, 3:a-law
412             0 << 1  |   // ITCLK,   0:external clock generation, 1:internal clock generation
413             0 << 0  ;   // TSPEN    0:Tx disable, 1:Tx enable
414
415     *pSPORT0_TCR2 =
416             0 << 10 |   // TRFST,   0:left streo ch first, 1:right stereo ch first
417             0 << 9  |   // TSFESE,  0:normal frame sync, 1:LR frame clock
418             0 << 8  |   // TXSE,    0:secondary ch disable, 1:secondary ch enable
419            30 << 0  ;   // SLEN     0-1:not allowed,2-31:Serial word length - 1
420
421
422         // 送信DMAデスクリプタを作る
423         // 注意:制御の都合上、最初はDMA割り込みをオフにしておく。これは
424         // DMA及びSPORT FIFOへの書き込みによるスタート後のラッシュで割り込みが
425         // 起きないようにするためである。ラッシュで送信されるのはダミーデータのみ
426         // である。rx_if_taskの初期化部でSPORT受信部を起動する際に、送信部の割り込みも
427         // 有効にする。
428     sport_ctl.tx_dma_dsc[0].next_descripter = &sport_ctl.tx_dma_dsc[1];
429     sport_ctl.tx_dma_dsc[0].start_address = sport_ctl.af_buffer[0];
430     sport_ctl.tx_dma_dsc[0].x_count = RXIF_BUFSIZE;
431     sport_ctl.tx_dma_dsc[0].x_modify = sizeof(sport_ctl.af_buffer[0][0]);
432     sport_ctl.tx_dma_dsc[0].config =
433             FLOW_LARGE      |   // FLOW,    0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
434             NDSIZE_7        |   // NDSIZE,  the # of element of the next descripter to fetch
435             0 << DI_EN_P    |   // DI_EN,   0:No interrupt at the end, 1:Interrupt at the end
436             0 << DI_SEL_P   |   // DI_SEL,  0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
437             0 << RESTART_P  |   // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
438             0 << DMA2D_P    |   // DMA2D,   0:Linear DMA, 1:2D DMA
439             WDSIZE_32       |   // WDSIZE,  0:8bit, 1:16bit, 2:32bit,3:reserved
440             0 << WNR_P      |   // WNR,     0:Read from memory, 1:Write to Memory
441             1 << 0          ;   // DMA_EN,  0:Disable DMA, 1:Enable DMA
442
443     sport_ctl.tx_dma_dsc[1].next_descripter = &sport_ctl.tx_dma_dsc[0];
444     sport_ctl.tx_dma_dsc[1].start_address = sport_ctl.af_buffer[1];
445     sport_ctl.tx_dma_dsc[1].x_count = RXIF_BUFSIZE;
446     sport_ctl.tx_dma_dsc[1].x_modify = sizeof(sport_ctl.af_buffer[1][0]);
447     sport_ctl.tx_dma_dsc[1].config =
448             FLOW_LARGE      |   // FLOW,    0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
449             NDSIZE_7        |   // NDSIZE,  the # of element of the next descripter to fetch
450             0 << DI_EN_P    |   // DI_EN,   0:No interrupt at the end, 1:Interrupt at the end
451             0 << DI_SEL_P   |   // DI_SEL,  0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
452             0 << RESTART_P  |   // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
453             0 << DMA2D_P    |   // DMA2D,   0:Linear DMA, 1:2D DMA
454             WDSIZE_32       |   // WDSIZE,  0:8bit, 1:16bit, 2:32bit,3:reserved
455             0 << WNR_P      |   // WNR,     0:Read from memory, 1:Write to Memory
456             1 << 0          ;   // DMA_EN,  0:Disable DMA, 1:Enable DMA
457
458         // SPORT0 送信DMAコントローラの初期状態設定
459         // ここではDMAをイネーブルにしない。また、バッファクリアする
460     *pDMA2_CONFIG =
461             FLOW_LARGE      |   // FLOW,    0:Stop, 1:Auto buffer, 4:Desc array, 6:Desc List small, 7:Desc, List, Large
462             NDSIZE_7        |   // NDSIZE,  the # of element of the next descripter to fetch
463             0 << DI_EN_P    |   // DI_EN,   0:No interrupt at the end, 1:Interrupt at the end
464             0 << DI_SEL_P   |   // DI_SEL,  0:Interrupt at the end of outer loop, 1:Interrupt at the end of inter loop
465             1 << RESTART_P  |   // RESTART, 0:Keep DMA FIFO before start, 1:Purge DMA FIFO before start
466             0 << DMA2D_P    |   // DMA2D,   0:Linear DMA, 1:2D DMA
467             WDSIZE_32       |   // WDSIZE,  0:8bit, 1:16bit, 2:32bit,3:reserved
468             0 << WNR_P      |   // WNR,     0:Read from memory, 1:Write to Memory
469             0 << 0          ;   // DMA_EN,  0:Disable DMA, 1:Enable DMA
470     *pDMA2_NEXT_DESC_PTR = &sport_ctl.tx_dma_dsc[0];
471
472 }