2017-09-07
マシン語の気持ちいいところは、実行時間が正確に読めるところ。
割り込みを止めて、各命令の所要クロック数を数えることで、さまざまなデバイスとつながります。

一応動いた「DMX512対応の照明」仕様書とちょっと違った動きの謎は、オシロスコープで解けました。

照明業界の標準規格「DMX512」は、250kbpsの差動信号によるシリアル通信で、25byte〜513byteまでを一塊にデータを送る仕様です。(ケーブル加工方法
塊の始まりを示す信号などに特徴があり、stopbitもIchigoJamの標準1bitと異なるので、IchigoJamのシリアル通信を使わず、OUT1とOUT2ポートで制御することにします。

とはいっても、250kbpsとは、1bitを4μ秒で表現となかなかに高速なため、IchigoJam BASICでは追いつきませんし、C言語では細かい時間が合わせができません。 そこで登場、マシン語です!

1命令、約21nsec(21ナノ秒=1/48MHz)で動くIchigoJamのArmマシン語なら、この1bitの送信時間内に192クロック分使えるので、十分に対応できそうです。

まずはループを使って正確に待つプログラムをつくります。

@WAIT R0-=1 IF !0 GOTO @WAIT RET

Armマシン語表を見て、必要クロック数を計算します。
R0-=1 は 1
IF !0 はジャンプする時 3、しない時 1
RET は 3
ということで、R0が1のときは5クロック、2で9、3で13・・・R0*4+1クロック分、待ちます。
R0に30000を指定すると、1/48000000*(30000*4+1)*1000=2.5m(秒)
R0に183を16bit左シフトした値で、約1秒となります。

R0=R0<<16 @WAIT R0-=1 IF !0 GOTO @WAIT RET

これをマシン語に変換して、TICKで測ってみましょう

[0]=`00000 10000 000 000 :'r0=r0<<16 [1]=`00111 000 00000001 :'r0-=1 [2]=`11010001 11111101 :'if!0goto@wait [3]=`01000111 01110000 :'ret CLT:U=USR(#800,183):?TICK() 126

おや、1秒=60のはずが2秒ちょっとかかってしまいました。
実はこの差は割り込みから来ます。IchigoJamは常時、画面出力処理を割り込み処理によって行っているので、その分遅くなってしまうわけです。

VIDEO0:CLT:U=USR(#800,183):?TICK():VIDEO1 69

だいぶ1秒に近づきました。ただ実はまだフルスピードではないのです。TICK()の値すすめるために内部でのカウントや、キーボードの割り込みなどが残っています。 完全に割り込み処理を止めるマシン語、CPSID(割込禁止)とCPSIE(割込許可)を使います。

CPSID R0=R0<<16 @WAIT R0-=1 IF !0 GOTO @WAIT CPSIE RET

アセンブル

[0]=`1011011001110010 :'CPSID [1]=`00000 10000 000 000 :'r0=r0<<16 [2]=`00111 000 00000001 :'r0-=1 [3]=`11010001 11111101 :'if!0goto@wait [4]=`1011011001100010 :'CPSIE [5]=`01000111 01110000 :'ret CLT:U=USR(#800,183):?TICK() 0

画面出力が一旦途切れて、1秒後戻ってきましたか?
TICK()の数値が0になるのは、割り込み処理が完全に止まっていた証拠です。

正確に待ち時間をコントロールすることができるようになったので、DMX512制御プログラムを作ってみます。
制御コードと24ch〜512chのデータを1byteずつ送るので、送るチャンネル数の半分を先頭に指定し、制御コード、チャンネルデータと指定することにして、マシン語プログラムを作ります。

' R0 - 開始アドレス 送信数/4(6で24ch、128で512ch)、送信コード(0)、ch1、ch2・・・送信個数分 ' R1 - base address (初期はRAM offset) ' R2 - OUT value (初期はROM offset) R2=1(off) R2=2(on) ' R3 - DMX value ' R4 - loop1 ' R5 - loop2 ' R6 - #100 ' R7 - loopwait @DMX512 PUSH {LR,R4,R5,R6,R7} CPSID R0=R0+R1 R1=#50 'R1=#50010000 GPIO1 R1=R1<<8 R1+=1 R1=R1<<16 R6=#80 R6=R6<<1 R2=1 [R1+`11]L=R2 R7=4 'wait 22*192clock R7=R7<<8 R7+=29 GOSUB @WAIT R2=2 [R1+`11]L=R2 R7=93 GOSUB @WAIT R4=[R0] R4=R4<<2 R4+=1 R0+=1 @LOOP2 R2=1 [R1+`11]L=R2 R7=45 GOSUB @WAIT R5=1 R3=[R0] @LOOP3 R2=1 R3&R5 IF 0 GOTO @SKIP R2=2 @SKIP [R1+`11]L=R2 R7=44 GOSUB @WAIT R5=R5<<1 R5-R6 IF !0 GOTO @LOOP3 R2=2 [R1+`11]L=R2 R7=93 GOSUB @WAIT R0+=1 R4-=1 IF !0 GOTO @LOOP2 CPSIE POP {PC,R4,R5,R6,R7} @WAIT R7-=1 IF !0 GOTO @WAIT RET

asm15を使ってアセンブル。
DMX512の端子、1をGND、2をOUT1、3をOUT2へ接続。
初期設定としてOUT1が0、OUT2が1をプログラムに加えてテストします。

10 POKE#700,240,181,114,182,64,24,80,33,9,2,1,49,9,4,128,38,118,0,1,34,202,96,4,39,63,2,29,55,0,240,37,248,2,34,202,96,93,39,0,240,32,248,4,120,164,0,1,52,1,48,1,34,202,96,45,39,0,240,23,248,1,37 20 POKE#73E,3,120,1,34,43,66,0,208,2,34,202,96,44,39,0,240,13,248,109,0,181,66,244,209,2,34,202,96,93,39,0,240,5,248,1,48,1,60,229,209,98,182,240,189,1,63,253,209,112,71 30 OUT1,0:OUT2,1 RUN OK POKE#800,6,0,255,0,0,255:U=USR(#700,#800) OK

CH1〜4に設定した、DMX512対応の照明「Lixadaステージライト」が青く光ったら成功です!
この照明の仕様は、1byte目に全体的な明るさ(0-127/255)や点滅(128-250)や、2〜4byte目でR/G/Bの明るさを指定するとありました。 チャンネル数は照明によって異なり、ムービングライトの場合X/Y軸の値なども合わせて指定するためチャンネル数は多くなります。

ランダムに原色を混ぜた7色をじわっと光らせ、じわっと消すプログラムはこうなります。

100 R=RND(7)+1:G=R>>1&1:B=R>>2&1:R=R&1 110 FOR I=0 TO #FF STEP 4 120 POKE#800,12,0,255,R*I,G*I,B*I 130 U=USR(#700,#800) 140 NEXT 150 FOR I=#FF TO 0 STEP -4 160 POKE#800,6,0,255,R*I,G*I,B*I 170 U=USR(#700,#800) 180 NEXT 190 GOTO 100

プロトコルのマシン語制御、うまくいかないときに便利、オシロスコープ!
Break信号の長さがちょっと長かったのでおかしかったと判明。WAITするカウントを1減らして修正完了!

信号の反射を防ぐために、ターミーターを作って接続しておくと良さそうです。(2と3を120Ω1/4Wでつなぐ)
DMX512について|サウンドハウス

DMX512に対応したスモークマシンも!
DMXに対応した自作デバイスづくりにもぜひ挑戦してみてください!

links
- 最大512chの照明コントロール!照明界の標準DMX512 x IchigoJam
- DMX512について|サウンドハウス
- "DMX512 照明"で検索 on Amazon

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作
13. コンパイラはじめのいっぽ、EVAL実現法とマシン語生成
14. サイズを取るかスピードを取るか、割り算のアルゴリズムとマシン語実装
15. マシン語化で1万倍速!? セットで学ぶアルゴリズムとコンピューター

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS