ネットワーク電飾 (3) [ColdFire V2]
今回は、さらにDMAタイマを組み合わせて、自動的にLEDを点灯させます。
DTIM0の設定
DTIM0には、0.2秒ごとにDMA1に転送要求を発行させます。 設定項目は、SilentCが使っていないモジュールを探せ(5)の設定から少しだけ変更されています。
レジスタ | 設定値 | 備考 |
---|---|---|
DTMR0 [PS] | 0x3B (60-1) | プリスケーラの分周比を60に設定します。 カウンタを動作させるクロック周期は、1µ秒になります。 |
DTMR0 [CE] | 00 (disable) | 入力キャプチャは使いません。 |
DTMR0 [OM] | 1 (toggle) | 今回は、DTOUT0端子は使わないのですが、トグルに設定しておきます。 何かあったら、デバッグに使えるでしょう。 |
DTMR0 [ORRI] | 1 (enable) | DMA転送要求を発行します。 このビットは、DMA要求と割り込み要求の双方の許可ビットになっています。 どちらの要求を発行するかは、DTXMR0[DMAEN]ビットで設定します。 |
DTMR0 [FRR] | 1 (enable) | リファレンス・レジスタの周期でイベントを発生させます。 |
DTMR0 [CLK] | 01 (BUSCLK×1) | プリスケーラをバスクロック (60MHz) で駆動します。 |
DTMR0 [RST] | 0 (reset) → 1 (run) | リセットした状態でタイマを設定し、最後にこのビットをセットしてタイマを起動します。 |
DTXMR0 [DMAEN] | 1 (DMA) | イベントが発生したら、DMA転送要求を発行します。 |
DMXMR0 [HALTED] | 0 (run when HALT) | STOP状態の時にタイマを停止するかどうかを決定します。 このアプリケーションでは、STOPは使いませんが、STOP状態でも止まらないように設定しておきます。 |
DMXMR0 [MODE16] | 0 (32-bit mode) | タイマカウンタを16-bitレジスタとして使いたい場合にセットします。 このアプリケーションでは、32-bitカウンタとして使います。 |
DTRR0 | 199999 (200000-1) | プリスケーラ出力の200000周期ごとにイベントを発生させます。 プリスケーラ出力は、1µ秒としたので、0.2秒ごとにDMA転送が発生します。 |
設定方針が決まったので、固定点灯パターンを使ったプログラムを作成します。
main() { char *pubpar = 0x40100072; char *portub = 0x40100012; char *ddrub = 0x4010002a; long *dmareqc = 0x40000014; long *sar1 = 0x40000110; long *dar1 = 0x40000114; long *bcr1 = 0x40000118; long *dcr1 = 0x4000011c; char *gpacr0 = 0x40000030; int *dtmr0 = 0x40000400; char *dtxmr0 = 0x40000402; long *dtrr0 = 0x40000404; long *dtcn0 = 0x4000040c; char *alloc; char *pat; alloc = MemoryAlloc(32); pat = (alloc+15)&0xFFFFFFF0; pat[0]=1;pat[1]=3;pat[2]=11;pat[3]=15; pat[4]=14;pat[5]=12;pat[6]=4;pat[7]=0; pat[8]=pat[10]=pat[12]=15; pat[9]=pat[11]=pat[13]=pat[14]=pat[15]=0; *gpacr0 = 0x04; // ACCESS_CTRL=0100 *pubpar = 0x00; // PUBPAR[3:0]=0000 *portub = 0x00; // PORTUB[3:0]=0000 *ddrub = 0x0F; // DDRUB[3:0]=1111 *bcr1 = 0x01000000; // clear DONE *sar1 = pat; // source *dar1 = portub; // destination *bcr1 = 0x00FFFFF0; // byte count *dcr1 = 0x62521080; // See table *dmareqc = 0x00000040; // DMAC1=DTIM0 *dtmr0 = 0x0000; // software reset *dtmr0 = 0x3B3A; // See table *dtxmr0 = 0x80; // enable DMA *dtrr0 = 199999; // period 200000 *dtmr0 |= 0x0001; // RST=1 #stop 0 for(;;){ if (Getc(0)=='q')break; SystemSleep(); } *dtmr0 &= 0xFFFE; // RST=0 *bcr1 = 0x00000000; // reset byte count MemoryFree(alloc); }
プログラムを実行させると、固定パターンでの点滅が始まります。 プログラムを見るとわかるように、レジスタ設定が終わったら、CPUは休眠状態に入っていて、あとはDMAタイマとDMAが自動的にLEDを点滅させています。
ネットワーク電飾
それでは、最後に点灯パターンをネットワークから送り込めるようにUDP受信機能を取り入れます。 今までのプログラムの組み合わせなので、簡単ですね。 PC側のプログラムは、ネットワーク電飾 (1)で作成したJavaのプログラムがそのまま使えます。
main() { char *pubpar = 0x40100072; char *portub = 0x40100012; char *ddrub = 0x4010002a; long *dmareqc = 0x40000014; long *sar1 = 0x40000110; long *dar1 = 0x40000114; long *bcr1 = 0x40000118; long *dcr1 = 0x4000011c; char *gpacr0 = 0x40000030; int *dtmr0 = 0x40000400; char *dtxmr0 = 0x40000402; long *dtrr0 = 0x40000404; long *dtcn0 = 0x4000040c; char *alloc; char *pat; char socket; int errcode; char *buf; alloc = MemoryAlloc(32); pat = (alloc+15)&0xFFFFFFF0; *gpacr0 = 0x04; // ACCESS_CTRL=0100 *pubpar = 0x00; // PUBPAR[3:0]=0000 *portub = 0x00; // PORTUB[3:0]=0000 *ddrub = 0x0F; // DDRUB[3:0]=1111 *bcr1 = 0x01000000; // clear DONE *sar1 = pat; // source *dar1 = portub; // destination *bcr1 = 0x00FFFFF0; // byte count *dcr1 = 0x62521080; // See table *dmareqc = 0x00000040; // DMAC1=DTIM0 *dtmr0 = 0x0000; // software reset *dtmr0 = 0x3B3A; // See table *dtxmr0 = 0x80; // enable DMA *dtrr0 = 199999; // period 200000 *dtmr0 |= 0x0001; // RST=1 socket = CreateSocket(0); // UDP socket Bind(socket, 30049, 1); // Bind to port MemClear(pat,16); #stop 0 for(;;){ if (Getc(0)=='q')break; errcode = RecvFrom(socket, 100); // 1sec if (errcode >= 16){ buf=GetReceiveBuffer(socket,1); BufCopy(pat,buf,16); MemoryFree(buf); } SystemSleep(); } CloseSocket(socket); *dtmr0 &= 0xFFFE; // RST=0 *bcr1 = 0x00000000; // reset byte count MemoryFree(alloc); }
メインループでは、UDPの受信作業しか行っていません。
また、パケット待ちタイムアウト時間は、1秒と長めにしました。 このタイムアウト時間は、プログラムを停止させるための'q'キーの検出時間になるので、1秒にしましたが、キー入力で停止させる必要が無いのであれば、もっともっと長いタイムアウト時間にしてもかまいません。 プログラムがパケット待ちをしている間、DMAタイマとDMAが、せっせとLEDを点滅させてくれます。参考文献
Interface (インターフェース) 2008年 09月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2008/07/25
- メディア: 雑誌
コメント 0