create every day - 福野泰介の一日一創

レジスタ不足に上位レジスタとスタック操作 / IchigoJamではじめるArmマシン語その12

2018/02/17 23:55:00
#IchigoJam #asm 

Armマシン語でWS2812Bマトリクスの表示ドライバのようにちょっと大きめのプログラムをつくると陥るレジスタ不足。 この時の、対処方法は2つ。上位レジスタとスタックです。

1. 上位レジスタを活用する
Arm Cortex-M0には、R0〜R15まで16コのレジスタ、R8〜R15は使える命令が5コに制限されますが、カウンタの回数チェックや、割り算ルーチンのポインタを格納しておくなど用途を選べば活用できます。(Cortex-M0 Armマシン語表より)

Rd=Rm Rd+=Rm Rn-Rm GOTO Rm GOSUB Rm

R8〜R11: 呼び出し元に帰る前に際には元に戻す必要がありますが自由に使えます。
R12: 破壊してOK。自由に使えます。
R13: スタックレジスタで、スタックに積んである一番上を指すポインタです。
R14: 呼び出し元のアドレスが入ったリンクレジスタ、GOSUBで呼び出す際に更新されます。
R15: プログラムカウンタ、実行中のアドレスの2つ先(4byte先)を指すポインタです。

上位レジスタをカウンタの回数チェックに使う(R0に指定した数までカウント)

R12=R0 R0=0 R0+=1 R0-R12 IF !0 GOTO -2 RET

上位レジスタを使った割り算(R0に指定した数を7で割る R0)
※IchigoJam BASIC ver1.2からR3に除算ポインタがセットされています

R12=R3 R0=7 GOTO R12

上位レジスタを使った割り算の余り(R0に指定した数を7で割った余り R1)

PUSH {LR} R12=R3 R0=7 GOTO R12 R0=R1 POP {PC}

R8〜R11までをフルに使うためにスタックに保存する

PUSH {R4-R7,LR} R4=R8 R5=R9 R6=R10 R7=R11 PUSH {R4-R7} ' R0-R12まで使い放題 POP {R4-R7} R8=R4 R9=R5 R10=R6 R11=R7 POP {R4-R7,PC}

参考、フル活用例「IchigoJam で BASIC と C とアセンブラ速度比較と最適化あそび - Qiita
マシン語で書くと、BASICの1万6千倍も速い!

1. スタックを活用する
その5で解説したスタック、POPしなくても参照できる便利な命令があります。

※u7/u8:4byte単位
※PUSH:regsの大きいレジスタから順に、SPを減らしSPへ積む 例)PUSH {R1,R2}
※POP:regsの小さいレジスタから順に、SPから読み込みSPを増やす 例)POP {R1,R2}
※N:指定したレジスタの数、PCへPOPした場合4+Ncycles(それ以外は1+Ncycles)
Cortex-M0 Armマシン語表 (asm15表記、抜粋)

SPは、R13の別名です。SPのアドレスには最後に積んだ値が入っています。+1で2番目、+2で3番目とアクセス可能です。 WS2812Bのパレットドライバをこれを利用して作っています。

' 配列の物理アドレスをPUSHしておく R2=8 R2=R2<<8 R2+=R1 PUSH {R2-R7,LR} ' 中略 ' R1をスタックに退避し、スタック2番目、配列のアドレスを取得 PUSH {R1} R1=[SP+1]L R1+=R3 ' 中略 POP {R1} ' 中略 POP {R2-R7,PC}

スタックへの書き込みも移動も自由自在ですが、ちょっと間違うとすぐ暴走しちゃいます。


Cortex-M0 Armマシン語表 (asm15表記、抜粋)」(PDF)

参考に、WS2812Bの32x8マトリクスのパレット対応ドライバのArmマシン語 asm15表記プログラムの全文です。

' OUT1用 WS2812B 32x8 @OUTを変更でOUT1-4で変更可能、#800に3byteパレット最大64色パレット、R, G, B(キャラクターコード、"0"=48から順番) ' R0 - data count ' R1 - data address #900(VRAM)から1byte 1pixel = 1color palette #800 ' R2 - temp OUT value 0/#FF, & 15 ' R3 - data value, temp ' R4 - GPIO address ' R5 - bit count ' R6 - wait count buf ' R7 - wait count ' R12 - increment or decrement address @WS2812B R2=8 R2=R2<<8 R2+=R1 PUSH {LR,R2,R4,R5,R6,R7} CPSID R0=0 R4=9 R4=R4<<8 R1=R1+R4 R4=1 R12=R4 R4=[@OUT]L @LOOP_DATA R3=[R1] ' palette R3-=48 R2=63 R3&=R2 R3=R3<<1 PUSH {R1} R1=[SP+1]L R1=R1+R3 R3=[R1] ' G R3=R3>>4 GOSUB @SEND_BYTE R3=[R1]W ' R R3=R3>>8 GOSUB @SEND_BYTE R3=[R1] ' B R2=15 R3&=R2 GOSUB @SEND_BYTE POP {R1} R1+=R12 R0+=1 R2=31 R0&R2 IF !0 GOTO @LOOP_DATA R2=R0>>5 R2-8 IF 0 GOTO @END R1+=31 R3=1 R5=-R3 R12=R5 R2&R3 IF !0 GOTO @LOOP_DATA R1+=2 R12=R3 GOTO @LOOP_DATA @END CPSIE POP {PC,R1,R4,R5,R6,R7} @SEND_BYTE R5=#80 ' R3+=2 ' offset @LOOP_BIT R2=#FF [R4]L=R2 R7=3 '(3*4+1)=13 <- 16.8+-7.2 R6=9 '(9*4+1)=37 <- 43.2+-7.2 R3&R5 IF 0 GOTO @SKIP_LOOP_BIT R7=9 '(9*4+1)=37 <- 43.2+-7.2 R6=3 '(3*4+1)=13 <- 16.8+-7.2 @SKIP_LOOP_BIT R7-=1 'wait R7*4+1 clock IF !0 GOTO -1 R2=0 [R4]L=R2 R6-=1 'wait R6*4+1 clock IF !0 GOTO -1 R5=R5>>1 IF !0 GOTO @LOOP_BIT RET @OUT DATA L #50010004

@LOOP_DATAで、#900の画面を読み取り、48=ASC("0")を引き、63でアンドをとって64色パレットとしています。[0]から[63]までの配列に入った、RGB、各4bitを@SEND_BYTEを呼び出し送信しています。

@SEND_BYTE内のR7とR6を使ってシリアル信号のタイミングは仕様に収まるようにしていますが、短い方を1、長い方を5まで短縮が可能でした。(個体によるかもしれないので要確認)

対応強化したasm15用Armアセンブラ「asm15 assembler」を使ってIchigoJamで動かしましょう。
Armマシン語表を使ってハンドアセンブルしてもOKです!

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作

生きていたZ80!? 国産8bit/16bit CPU、RL78のマシン語はほぼZ80

2018/01/20 23:55:00
#asm #MSX 

小学生の頃、MSXの投稿されてすごいゲームが使っていたZ80マシン語に憧れ、挑戦したハンドアセンブル。
16進数で、#CD = サブルーチンのCALL、#C9 は、RET(サブルーチンから戻る)、#00 はNOP(何もせずスキップ)くらいは、ずっと覚えているまま。

国産ルネサスの8bit/16bit CPU、RL78用IchigoJamの移植も進む中、Z80 to RL78 converterを考えてみる。

RL78 ファミリ ユーザーズマニュアル ソフトウェア編」を見てみると、懐かしいレジスタ群!

A, B, C, D, E, H, Lという8bitレジスタ構成はZ80とほぼいっしょ。Xレジスタという、AXと合わせて16bitにできるレジスタや、1Mbyteまでのメモリ空間を扱うための、ES、CSレジスタを使うあたりに成長したZ80の姿を見た気がして感動できる。

RL78は16bit CPUと分類されているが、厳密にはRL78/G10のS1コアは8bit CPU、G13など一般ライン用S2コアは16bit、G14のS3コアは更に乗除算積和演算命令が加わっている。そんなこと言いながら本当は全部8bit CPUなんじゃないかと思ったが、レジスタを16bitとして使う命令に必要なクロックが、S1コアは2clock、S2/S3コアは1clockになっているので、確かにS2/S3は16bit CPUっぽい。 Z80の上位互換CPU、R800を積んだMSXturboRみたいなものだと思うと、一層愛着が湧いてくる。

命令表は下記のような感じでこれもまた馴染みやすい。

「命令マップ (1st MAP)」
RL78 ファミリ ユーザーズマニュアル ソフトウェア編に複数バイト命令用マーク追記

さすがにバイナリ互換ではないが、Z80のCALL:CD nn nn → FD nn nn、RET:CC → D7、NOP:00 → 00。など、ほぼ読み替えでいける。 Z80では、LDと表記するところ、MOV表記になっていたり、16bit操作命令が大幅増、レジスタに0や1をセットするCLRB/CLRW/ONEB/ONEWなど、進化しているなど、RL78はZ80愛好家が作ったに違いない親しみやすいマシン語となっている。

以前、逆アセンブルして解析したMSX用太字処理をするZ80のコードをRL78でかいてみると、こんな感じになる

MOVW BC,700H MOVW HL,100H @LOOP CALL 004AH MOV E,A SHL A OR A,E CALL 004DH INCW HL DECW BC MOV A,B OR A,C BNZ @LOOP RET

LD → MOV/MOVW、SRL → SHL、JR NZ → BNZ、ORはオペランドを取るのでOR A,Eなどと変わるところ、DECWでBCを1減らしてもゼロフラグが変わらないので、Aレジスタを使ってなんとかするスタイルも一緒。
*すみません、記述当初は16bitレジスタで普通にゼロフラグが使えると思っていましたが、間違ってました。Z80感覚で正しいようです。

かつてのソニーのパソコン、SMC-70の後継機、SMC-777Cの紹介記事「御三家に食い込むことはできなかった技術の結晶「ソニー SMC-777C」 - AKIBA PC Hotline!」から気になったANN表記は、asm15と同じような思想で作られていた。

BASICのようにイコールでレジスタ間転送がかけてシンプル。ローテートやジャンプ命令も短い記号を使ったところがちょっとややこしく感じちゃう点と、小文字を使って敷居が高く見えちゃう点が残念だったのかも。

コンピューターの進化に関わるエンジニアの想いが直接感じられるのが、マシン語のおもしろいところ。
RL78搭載IchigoJamが登場すれば、マシン語で伝説の16進数を直接手打ちするプログラミングするスーパーテクニックを子供に見せるチャンスかも!?

創ろう!米子高専生へプログラミングの教え方とArmマシン語講座 with IchigoJam

2018/01/09 23:55:00
#tottori #IchigoJam #asm 

米子高専4年生向けにIchigoJamを使ったプログラミング教え方入門。
秒間5000万回の計算速度を持つコンピューターを操る、Armマシン語入門付き!

Armマシン語で、1+1を計算

POKE#700,1,48,112,71 ?USR(#700,1) 2

+10に変更

POKE#700,10,48,112,71 ?USR(#700,1) 11

マシン語から返ってくる命令"112,71"を変更すると・・・、IchigoJamを暴走させることができます!

POKE#700,10,48,11,71
?USR(#700,1)

CPUの命令数、スピード優先、Intel x86アーキテクチャの最新はなんと3500!
消費電力の少なさ優先、Arm Cortex-M0/M0+は56とコンパクトなので学ぶなら、Armがオススメ!
最新スマホや、今後登場するArmサーバーでもIchigoJamでも同じマシン語が使えますよ。
詳しくは「連載、Armマシン語入門」「Cortex-M0 Armマシン語表(抜粋)」をどうぞ!


ゲームも音があると盛り上がる!(圧電サウンダーの接続方法紹介スライド)


LED1で、光った瞬間が一番感動した。
ゲームづくりが楽しかった。
これを1年生でやって置きたかった。
など、感触上々、ぜひ周りのこどもへ広めてみましょう!


「プログラミングを教えよう」スライド(オープンデータなので自由にカット&ペースト&加工してください)


放課後は講演会「楽しいを武器に!」


おいしかったカニ雑炊!


さすが蟹取県!


福井県の小学生向けロボコン、越前がにロボコンとのカニロボ頂上決戦もおもしろいかも。
戦う姿まぶしい小学生、動画でふりかえる「越前がにロボコン」
ASCII.jp:小学生が自作ロボットで競い合う「越前がにロボコン」が熱かった


米子高専の河野先生を代表にPCN米子立ち上げ準備がスタート!
MAKER FES 境港」など、発表の機会もありますねっ

STM32F0版IchigoJam、シリアル通信バージョンβ

2018/01/02 23:55:00
#IchigoJam #stm32 #asm #maker 

お気に入りCPU、Arm Cortex-M0NXP社製LPC1114シリーズと同じクラス、STMicroelectronics社製STM32F0シリーズでIchigoJamが動きました!


シリアル通信でIchigoJamを便利に使える、IJUtilitiesを使うとスクリーンを使ったゲームも動かせます!


今回は、秋月電子で手に入るSTM32F042K6T6へ書き込んだら、そのままシリアル通信で使えます。 (Nucleoにbinファイル書き込みでも動くかもしれません)

I/Oは、まだLED(PB3とPA7)のみ使えます。他、配置と機能、検討中です。

同じArmなので、USRコマンドを使ったマシン語はそのままで動きます!
ハンドアセンブルで超速計算! - IchigoJamではじめるArmマシン語その2
I/Oを使うマシン語は、LPC1114とSTM32F0、I/Oのメモリマップが違う点に注意です。

ターゲットにしている、STM32F030K6T6TRは、LPC1114と同じ48MHz/Flash32KB/RAM4KBで、1コ175円、12,000コ買えば1つあたりなんと74円

STM32で始めるC言語」で紹介した上級者向けミニマム開発環境サンプルも拡充
(GPIO/Clock変更/UART/割り込み/TIM/SPI/Flash書き込み)

ちっちゃいコンピューターをプログラミングで味方に付け、身の回りをどんどん便利にしちゃいましょう!

STM32で始めるC言語、アセンブリ言語と比べてみよう

2017/12/30 23:55:00
#stm32 #asm 

Mbed対応のSTM32の開発環境Nucleoでマシン語でエルチカに成功したので、次はいろいろ製品化を見越して、CPUそのままを使って作ってみます。


今回使用したのは、秋月で売っている一番安いSTM32、STM32F042K6T6です。
Arm Cortex-M0 48MHz, Flash32KB, SRAM6KB, LQFP32
LQFP32に対応するDIP化基板へはんだづけ!
0.8mmピッチなので、0.65mmピッチ28ピンのLPC1114FDH28のはんだづけより簡単です。


USBシリアルを使って書き込みます。LEDとUSBシリアルとの接続の仕方はつぎの通り。
VDDA、VDDIO2にも電源供給が必要です。BOOT0をHIGHにすることで、書き込みモードになります。
RTSが使えない場合は、リセットする際、手でジャンパー線をGNDにつなぐか、タクトスイッチをつけましょう。

3.3VVDD 1STM32F032 VSSGND
OSC_IN 231 BOOT03.3V
OSC_OUT 330 PB7
RTSNRST 429 PB6
3.3VVDDA 528 PB5
PA0 627 PB4
PA1 726 PB3
PA2 825 PA15
PA3 924 PA14
PA4 1023 PA13
PA5 1122 PA12
PA6 1221 PA11
PA7 1320 PA10TXD
PB0 1419 PA9RXD
LEDPB1 1518 PA8
GNDVSS 1617 VDDIO23.3V
USBシリアルの書き込みに、"STM32 FLASH Writer Program Using Python" stm32writerを使わせてもらいました。 stm32用プロジェクト一式をGitHub"my-first-stm32" からダウンロードし、マシン語のエルチカを書き込んでみましょう。(Mac用です。USBシリアルの設定は、makefile内を書き換えてください)

t0-asm$ make ../tools/stm32writer/stm32writer.py --port=/dev/tty.SLAB_USBtoUART --go "obj.mot" stm32writer (version: 20171231py) ...

うまくいけば書き込み終了後に自動的にエルチカが始まります。
書き込み終わっているので、USBシリアルを外して、BOOT0をGNDに接続し、3Vくらいにつなげばエルチカマシンのできあがりです!

アセンブリ言語でマシン語プログラムも楽しいですが、C言語で開発できるようにすると楽です。
例えば、48MHzへの切り替えの一部 (asm15 アセンブリ言語 from STM32エルチカ)

R0=[@RCC]L R3=R0+4 ' RCC_CFGR R1=[R3]L R2=`1111 R2=R2<<18 R2=~R2 R1&=R2 R2=4 ' PLLMUL6 R2=R2&lt;<18 R1|=R2 [R3]L=R1

これがC言語だと1行で書けます!

RCC->CFGR = (RCC->CFGR & ~(0b1111 << 18)) | (4 << 18);

t1-led-blinkがC言語でのエルチカ、t2-clockがクロックを48MHzに変更と、stm32の取説に合わせて必要最小限のプログラムになっているので、C言語の雰囲気をつかむのにのぞいてみてください。

t2-usartではstm32とのシリアル通信が一応できていますが、どうも内蔵クロックの精度が悪く計算上の値とは5%ほどずれてしまう点と、切り替えるべきAF(Alternate Function)の番号がstmのシリーズによって違う点が注意です。

STM32F0シリーズの取説は、日本語版もあって親切丁寧です!
参考資料 RM0091 リファレンスマニュアル STM32F0x1/STM32F0x2/STM32F0x8 advanced ARM-based 32bit MCUs

コンピューターをフル活用できる、マシン語とC言語の世界もぜひどうぞ!

BASICでプログラムの楽しさを知り
マシン語でコンピューターを知り
C言語でツールの便利さを知る
かつての王道、今でも通じる!?

links
- taisukef/my-first-stm32: first step of STM32F0
- IchigoJamではじめるArmマシン語

2019新卒エンジニア募集! 無いものを創ろう - asm15 supported SREC format!

2017/12/29 23:55:00
#jig #asm #web #stm32 

jig.jp、2019年4月入社となる新卒エントリーページをオープン!

新卒採用案内 | スマホ(Android/iPhone)アプリ・携帯アプリならjig.jp(ジグジェイピー)

コンテンツ:代表の想い、募集要項、弊社エンジニアの声、座談会、使用技術、使用言語!
jig.jp本店、鯖江の開発センターの雰囲気にビビっと来た人のエントリー、待ってます!

今日の一日一創は、JavaScriptで無いものづくり。

シンプルなアセンブリ言語を「IchigoJamではじめるArmマシン語入門」の解説用に使っていたら、作ってCC0で公開してくれたboxheadroomさんによるasm15アセンブラ! GitHubに載せてオープンソースでオープンライセンスな気軽に使えるWebアプリとして、必要に応じて成長させています。

ターゲットデバイスへのプログラムのバイナリを記述するためのフォーマット、IntelのHEXフォーマットと並ぶ、SRECフォーマット(モトローラSフォーマット、とも呼ばれる)への対応追加!

IoTに最適Arm Cortex-M0からLinuxが動いちゃうCortex-M7までのシームレス感が美しいSTM32の開発環境整備の一貫です。


asm15」 SREC format supported!!

コードを書き足し、テストして、GitHubへコミット!
検索してあえば使う、無ければ創って、共有する。
エンジニアの醍醐味です。

新卒採用案内 | スマホ(Android/iPhone)アプリ・携帯アプリならjig.jp(ジグジェイピー)

Arm社訪問! クリスマスはArmマイコン IchigoJam を使ったオリジナルツリーづくりはいかがでしょう? Armマシン語 LPC810 x WS2812B 24MHz版

2017/12/19 23:55:00
#IchigoJam #KidsIT #lpc810 #asm #Arm 

Arm社の日本法人、アーム株式会社を訪問。Armと言えば、に、LPC810に、Z80以来のマシン語、楽しませてもらっています!(連載、Armマシン語入門
* 今年、2017.8.1、Arm社は、ARMからArmへと社名とブランドとロゴを変更(ロゴは全部小文字)。合わせて、本ブログ表記もArmへと変更しました。

内海社長ともお会いできました!クリスマスツリーの電飾は、おなじみWS2812B、Armでコントロールされたました!

おみやげに頂いた厚い本「ディジタル回路設計とコンピュータアーキテクチャ[ARM版]
スイッチサイエンスさんも翻訳出版に協力
原著はなんとKindleでも1万円オーバーの超大作「Digital Design and Computer Architecture: ARM Edition

なぜコンピューターは計算が速いのか?」で解説したスイッチの実体、トランジスタや2進数などの基本もしっかり。

マシン語、アセンブリ言語に関する解説もArmの実アーキテクチャーに添っていて実用的!

HDLや、具体的なCPU設計にまで踏み込むマイクロアーキテクチャの章まで揃っていて読み応え抜群。

サイトからI/Oや、C言語に関する解説などをpdfで読むことができます。
Elsevier · Harris, Harris: Digital Design and Computer Architecture · Welcome

2017.12.25(月)、クリスマス。Yahoo! Japan ロッジにて、Armマイコン、IchigoJamで作るクリスマスツリーづくりワークショップを復興庁さん主催で開催!

Fw:東北Weekly 家族でプログラミングしてみよう! 東北発のほやアートをつくってみよう! | Peatix
小中学生のこどもと保護者の方が対象です。プログラミングがはじめての人でもOK!自分だけのオリジナルキラキラツリーを作りましょうっ

(おまけ)Arm訪問記念マシン語プログラム for LPC810、24MHzで800kHz正確コントロール版。

DATA L #10000400 ' stack DATA L #21 ' entry point DATA L 0, 0, 0, 0, 0 DATA L #EFFFFBDF ' VALID_CODE = 0x100000000-0x10000400-0x21 @ENTRY R0=[@SYSAHBCLKCTRL]L R1=#DF 'SWT, GPIO, I2C:off, FLASH, FLASHREG, RAM, ROM, SYS [R0]L=R1 R0=[@FLASHCFG]L R1=[R0]L R2=3 ' flash no wait: set 0b00 R2=~R2 R1&=R2 [R0]L=R1 ' clock setting 24MHz R0=[@PDRUNCFG]L ' PLL power on R1=[R0]L R2=128 R2=~R2 R1&=R2 [R0]L=R1 R0=[@MAINCLKSEL]L R1=3 ' set PLL [R0]L=R1 R0=[@SYSPLLCTRL]L R1=1 ' 0:12MHz 1:24MHz, 2:36MHz, 3:48Mhz, 4:60MHz, 7:96MHz, 8:108MHz NG [R0]L=R1 R0=[@MAINCLKUEN]L R1=0 [R0]L=R1 R1=1 [R0]L=R1 ' GPIO setting R0=[@PINENABLE0]L R1=[@PINENABLE0_DATA]L [R0]L=R1 R0=[@GPIO_DIR0]L R1=`1100 ' PIO0_2 and PIO0_3 [R0]L=R1 R4=[@GPIO_NOT0]L R2=`100 ' PIO0_2 ' WS2812B driver ' R0 - data count ' R1 - data address (G1,R1,B1,G2,R2,B2 ....) ' R2 - OUT value ' R3 - data value ' R4 - GPIO address ' R5 - bit count ' R7 - wait count @WS2812B R0=15 R1=@DATA_LED @LOOP_DATA R5=#80 R3=[R1] @LOOP_BIT [R4]L=R2 R3&R5 IF !0 GOTO @ONE @ZERO ' 10-20clock R7=2 ' wait 2*3 = 6clock R7-=1 IF !0 GOTO -1 NOP [R4]L=R2 R7=3 ' wait 3*3 = 9clock R7-=1 IF !0 GOTO -1 GOTO @JOIN @ONE ' 20-10clock R7=5 ' wait 5*3 = 15clock R7-=1 IF !0 GOTO -1 NOP [R4]L=R2 NOP @JOIN R5=R5>>1 IF !0 GOTO @SKIP2 ' 7clock == 1 R1+=1 R0-=1 IF !0 GOTO @LOOP_DATA GOTO @END @SKIP2 NOP NOP NOP GOTO @LOOP_BIT @END R7=[@WAIT_N]L R7-=1 'wait R7*3+1 clock IF !0 GOTO -1 GOTO @WS2812B ' init @SYSAHBCLKCTRL DATA L #40048080 @FLASHCFG DATA L #40040010 @PINENABLE0 DATA L #4000C1C0 @PINENABLE0_DATA DATA L #FFFFFFBF @GPIO_DIR0 DATA L #A0002000 @GPIO_NOT0 DATA L #A0002300 ' clock setting @MAINCLKSEL DATA L #40048070 @MAINCLKUEN DATA L #40048074 @SYSPLLCTRL DATA L #40048008 @PDRUNCFG DATA L #40048238 ' WS2812B @WAIT_N DATA L 4000000 @DATA_LED DATA B 10,0,0, 0,10,0, 0,0,10, 10,0,10, 0,10,10

正確に10clockと20clockに合わせているので、きれいな800kHzの波形がでているはず!
Flashのwait stateを0にしながら、24MHzが正しいのかはちょっと謎ですが、動いてはいるようです。
asm15 アセンブリ言語、アセンブルは、asm15 Assembler でどうぞ!

LPC810で光るカセットテープ! 富山高専射水キャンパスにてメンタリングとプログラミングの本質体験のススメ

2017/12/18 23:55:00
#IchigoJam #maker #lpc810 #asm #toyama #kosen 

起業家甲子園出場権を手にしたアントレプレナー研究会のある、富山高専射水キャンパスにてメンタリング。
富山高専本郷キャンパスでjigインターンのOB、すがっちとなぽりたんもジョイン!
高専生ならではの感性と創造力で北陸から一石、投じよう!

北陸、福井、鯖江の銘菓、めがね堅パンのハートエディション!

昨日のLPC810 x WS2812Bにバグが見つかり、無事光るカセットテープのLPC810エディションが点灯!

12MHz版だとちょっと信号はいい加減ですが、ちゃんと光りました!
(原因:asm15の DATA B 0,0,0 が、2byteアラインされてしまうため)

マシン語で作る、簡易キラキラプログラムがこちら!
末尾、16byteを変更すると、アニメーションするLEDの色が変わり、その前4byteでウェイトを調整できます。

10 POKE#700,0,4,0,16,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,251,255,239,33,72,223,33,1,96,33,72 20 POKE#728,1,104,3,34,210,67,17,64,1,96,31,72,31,73,1,96,31,72,12,33,1,96,31,76,4,34,15,32,32,161,30,75,14,120,30,112,1,49,1,51 30 POKE#750,1,56,249,209,15,32,26,73,128,37,11,120,34,96,43,66,8,208,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,96,7,224,0,0,34,96 40 POKE#778,0,0,0,0,0,0,0,0,0,0,0,0,109,8,233,209,1,49,1,56,228,209,13,79,1,63,253,209,10,73,14,120,14,32,79,120,15,112,1,49 50 POKE#7A0,1,56,250,209,14,112,213,231,128,128,4,64,16,0,4,64,192,193,0,64,191,255,255,255,0,32,0,160,0,35,0,160,0,0,0,16,128,26,6,0 60 POKE#7C8,20,0,0,20,20,0,20,0,20,20,20,0,0,20,0,0 70 A=#700:L=216:LRUN1 'FILE1 100 'LPC810 Writer 256byte from ADR:A 110 UART3,2:OUT2,0:OUT1,0:WAIT9:OUT1,1 120 CLS:?"?";:GSB@R 130 ?"Synchronized":GSB@R 140 ?12000:?:GSB@R:GSB@R 150 ?"A 0":GSB@R:GSB@R 160 ?"U 23130":GSB@R 170 ?"W 268436096 ";256:GSB@R:UART1,2:LC0,-1:FORI=0TO255:?CHR$(PEEK(A+I));:NEXT:UART3,2:LC0,6 180 ?"P 0 0":GSB@R 190 ?"E 0 0":GSB@R 200 ?"P 0 0":GSB@R 210 ?"C 0 268436096 256":GSB@R 215 '?"G 268436128 T":GSB@R:END 220 OUT2,1:OUT1,0:OUT1,1:END 500 @R:K=INKEY():IF K=13 K=INKEY():WAIT9:RTN ELSE CONT

マシン語のプログラムはこちら。
データを一旦RAM(#10000000)へ転送し、1ループごとにローテートさせています。

DATA L #10000400 ' stack DATA L #21 ' entry point DATA L 0, 0, 0, 0, 0 DATA L #EFFFFBDF ' VALID_CODE = 0x100000000-0x10000400-0x21 @ENTRY R0=[@SYSAHBCLKCTRL]L R1=#DF 'SWT, GPIO, I2C:off, FLASH, FLASHREG, RAM, ROM, SYS [R0]L=R1 R0=[@FLASHCFG]L R1=[R0]L R2=3 ' flash no wait: set 0b00 R2=~R2 R1&=R2 [R0]L=R1 R0=[@PINENABLE0]L R1=[@PINENABLE0_DATA]L [R0]L=R1 R0=[@GPIO_DIR0]L R1=`1100 ' PIO0_2 and PIO0_3 [R0]L=R1 R4=[@GPIO_NOT0]L R2=`100 ' PIO0_2 @COPYTORAM R0=15 R1=@DATA_LED R3=[@RAM]L @COPYTORAM_LOOP R6=[R1] [R3]=R6 R1+=1 R3+=1 R0-=1 IF !0 GOTO @COPYTORAM_LOOP ' WS2812B driver ' R0 - data count ' R1 - data address (G1,R1,B1,G2,R2,B2 ....) ' R2 - OUT value ' R3 - data value ' R4 - GPIO address ' R5 - bit count ' R7 - wait count @WS2812B R0=15 ' R1=@DATA_LED R1=[@RAM]L @LOOP_DATA R5=#80 R3=[R1] @LOOP_BIT [R4]L=R2 R3&R5 IF 0 GOTO @ZERO NOP NOP NOP NOP NOP NOP NOP [R4]L=R2 GOTO @JOIN @ZERO NOP [R4]L=R2 NOP NOP NOP NOP NOP NOP @JOIN R5=R5>>1 IF !0 GOTO @LOOP_BIT R1+=1 '+6clock R0-=1 IF !0 GOTO @LOOP_DATA @WAIT R7=[@WAIT_N]L R7-=1 'wait R7*3+1 clock IF !0 GOTO -1 R1=[@RAM]L R6=[R1] R0=14 @SLIDE R7=[R1+1] [R1]=R7 R1+=1 R0-=1 IF !0 GOTO @SLIDE [R1]=R6 GOTO @WS2812B ' init @SYSAHBCLKCTRL DATA L #40048080 @FLASHCFG DATA L #40040010 @PINENABLE0 DATA L #4000C1C0 @PINENABLE0_DATA DATA L #FFFFFFBF @GPIO_DIR0 DATA L #A0002000 @GPIO_NOT0 DATA L #A0002300 ' WS2812B @RAM DATA L #10000000 @WAIT_N DATA L 400000 @DATA_LED DATA B 20, 0, 0, 20, 20, 0, 20, 0, 20, 20, 20, 0, 0, 20, 0

asm15 assembler」でアセンブルできます!
WS2812Bの信号は、800kHz(秒間80万回、1.2マイクロ秒に1回)の波の形で、0と1とを区別するので、とても人の手では制御できませんが、マシン語ならたった30円のコンピューターにさせれば余裕です。

切っても切れない、社会とコンピューター。誰にでもオススメしたいプログラミング体験。
IchigoJam BASIC で、プログラミングの基本を、マシン語を使ってコンピューターの真の実力を、それぞれかんたんに体験できます!

WS2812Bを観察しよう!IchigoJamで開発するLPC810でフルカラーLED点灯実験

2017/12/17 23:55:00
#IchigoJam #maker #lpc810 #asm 

光るカセットテープで活躍するWS2812Bを、LPC810を使って自在に点灯できたら簡単、気軽にカセットテープ内にボタン電池も含めて収められてうれしいかも? (IchigoJamを書き込んだLPC1114を使って光るカセットテープを作った例 by JO3GBDさん)


LPC810から制御したWS2812B。
拡大してみると、信号が来るDI側から順に、緑、赤、青と小さく光っている様子が分かります。
データを送信する順も緑、赤、青!

プログラムはこの通り、マシン語部分が長くなってきたら、100行以降を別プログラムとして保存しましょう。

10 POKE#700,0,4,0,16,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,251,255,239,24,72,223,33,1,96,24,72 20 POKE#728,1,104,3,34,210,67,17,64,1,96,22,72,22,73,1,96,22,72,12,33,1,96,22,76,4,34,3,32,22,161,128,37,11,120,34,96,43,66,8,208 30 POKE#750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,96,7,224,0,0,34,96,0,0,0,0,0,0,0,0,0,0,0,0,109,8,233,209,1,49 40 POKE#778,1,56,228,209,7,79,1,63,253,209,222,231,128,128,4,64,16,0,4,64,192,193,0,64,191,255,255,255,0,32,0,160,0,35,0,160,64,66,15,0 50 POKE#7A0,2,2,2,0 60 A=#700:L=164:LRUN1 'FILE1 100 'LPC810 Writer 256byte from ADR:A 110 UART3,2:OUT2,0:OUT1,0:WAIT9:OUT1,1 120 CLS:?"?";:GSB@R 130 ?"Synchronized":GSB@R 140 ?12000:?:GSB@R:GSB@R 150 ?"A 0":GSB@R:GSB@R 160 ?"U 23130":GSB@R 170 ?"W 268436096 ";256:GSB@R:UART1,2:LC0,-1:FORI=0TO255:?CHR$(PEEK(A+I));:NEXT:UART3,2:LC0,6 180 ?"P 0 0":GSB@R 190 ?"E 0 0":GSB@R 200 ?"P 0 0":GSB@R 210 ?"C 0 268436096 256":GSB@R 215 '?"G 268436128 T":GSB@R:END 220 OUT2,1:OUT1,0:OUT1,1:END 500 @R:K=INKEY():IF K=13 K=INKEY():WAIT9:RTN ELSE CONT

ちょうど50行、#7A0からの3byteがG(緑)、R(赤)、B(青)の数を指定しています。
書き換えて、実験してみましょう。


LPC810と光ったWS2812B!

マシン語プログラムの解説

asm15でWS2812Bの制御用マシン語プログラムは、LPC1114用を元に、LPC810用に修正します。
Cortex-M0+のLPC810では、OUTポートの扱いがNOTを使えるので短く、1クロックで読み書きできるので高速!
ただ、標準動作の12MHz用に、ウェイトはループではなく、NOPコマンドで調整しました。
厳密にはデータの区切りで速度が追いついていないので、たくさん光らせようとするとおかしくなってしまうため、周波数を上げるかSPIでの制御にしないといけなさそうです。(追記、勘違いでした12MHzでもいけました!

DATA L #10000400 ' stack DATA L #21 ' entry point DATA L 0, 0, 0, 0, 0 DATA L #EFFFFBDF ' VALID_CODE = 0x100000000-0x10000400-0x21 @ENTRY R0=[@SYSAHBCLKCTRL]L R1=#DF 'SWT, GPIO, I2C:off, FLASH, FLASHREG, RAM, ROM, SYS [R0]L=R1 R0=[@FLASHCFG]L R1=[R0]L R2=3 ' flash no wait: set 0b00 R2=~R2 R1&=R2 [R0]L=R1 R0=[@PINENABLE0]L R1=[@PINENABLE0_DATA]L [R0]L=R1 R0=[@GPIO_DIR0]L R1=`1100 ' PIO0_2 and PIO0_3 [R0]L=R1 R4=[@GPIO_NOT0]L R2=`100 ' PIO0_2 ' WS2812B driver ' R0 - data count ' R1 - data address (G1,R1,B1,G2,R2,B2 ....) ' R2 - OUT value ' R3 - data value ' R4 - GPIO address ' R5 - bit count ' R7 - wait count @WS2812B R0=3 R1=@DATA_LED @LOOP_DATA R5=#80 R3=[R1] @LOOP_BIT [R4]L=R2 R3&R5 IF 0 GOTO @ZERO NOP NOP NOP NOP NOP NOP NOP [R4]L=R2 GOTO @JOIN @ZERO NOP [R4]L=R2 NOP NOP NOP NOP NOP NOP @JOIN R5=R5>>1 IF !0 GOTO @LOOP_BIT R1+=1 '+6clock R0-=1 IF !0 GOTO @LOOP_DATA @WAIT R7=[@WAIT_N]L R7-=1 'wait R7*3+1 clock IF !0 GOTO -1 GOTO @WS2812B ' init @SYSAHBCLKCTRL DATA L #40048080 @FLASHCFG DATA L #40040010 @PINENABLE0 DATA L #4000C1C0 @PINENABLE0_DATA DATA L #FFFFFFBF @GPIO_DIR0 DATA L #A0002000 @GPIO_NOT0 DATA L #A0002300 ' WS2812B @WAIT_N DATA L 1000000 @DATA_LED DATA B 2, 2, 2

開始アドレスを0に変えて、hexファイルに変換したものがこちら。
こちらをLPC810に直接書き込んでも動きます!

:1000000000040010210000000000000000000000BB :10001000000000000000000000000000DFFBFFEF18 :100020001848DF210160184801680322D2431140BB :10003000016016481649016016480C210160164CF3 :100040000422032016A180250B7822602B4208D0C1 :10005000000000000000000000000000000022601E :1000600007E0000022600000000000000000000027 :1000700000006D08E9D101310138E4D1074F013F9B :10008000FDD1DEE78080044010000440C0C1004084 :10009000BFFFFFFF002000A0002300A040420F0090 :0400A0000202020056 :00000001FF

links
- IchigoJamでLPC810マイコン開発!(デプロイ・完結編)
- IchigoJamでも光る大五郎! 300コのフルカラーLEDを簡単コントロール! IchigoJam x WS2812B/SK6812/NeoPixel
- はじめてのマシン語 - IchigoJamではじめるArmマシン語その1

もっと楽するコンパイラ、WebAssemblyマシン語入門その3

2017/12/05 23:55:00
#asm #wasm #js 

IchigoJam web(ブラウザで動くIchigoJam)で使っているお気に入り技術、WebAssembly。
マシン語をバイナリで直接書いてみる第一回、初歩的なアセンブラ体験する第二回に続く第三回のテーマは、コンパイラです。

おさらいとして、前回のアセンブラで、param+10 を計算するプログラムを作ってみましょう。

正解はこちら

get_local $0 i32.const 10 i32.add end

paramが1の時、ちゃんと答は11と出ます。では、param+100 を計算するプログラムに変えてみてください。

おや、おかしいですね!?では、128にすると、今度はコンパイルエラーになってしまいます。

WebAssemblyのマシン語での数値は大きさによって1byteから5byteまで長さを変えて表します。最上位bitが1なら、次のbyteを読んで上位に追加していく仕組みになっています。 つまり、1byteで表せる数は、7bitで表せる-64〜63まで。100(2進数で1100100)はこの範囲を超えているので、上位bitを1にして、残りのbitを次のbyteで表すので、1 1100100 (e4) と 0 0000000 (00) となります。

WebAssemblyのコードを書き換えて試してみましょう。

20 0 41 e4 0 6a b

i32.const を表す 41 の後の 64 (=10進数の100) を、e4 に変えてその後ろに 0 を加えて「RUN」
ちゃんと答がでました!

このような計算をいちいち手でやらなくて済む方法は?・・・そうです、プログラムですね。
命令表から手打ちするのも面倒なので、短く楽にプログラムを書けるようにするソフトをつくりましょう。

コンパイラはじめのいっぽ
「P 3 +」と空白区切りで書いたら対応するアセンブリ言語を出力するものです。
※ P は、パラーメータ0を意味することにします

compilebtn.onclick = function() { var src = srcprg.value.split(" "); var asm = []; for (var i = 0; i < src.length; i++) { var s = src[i]; if (s == "P") { asm.push("get_local 0"); } else if (s == "+") { asm.push("i32.add"); } else if (parseInt(s) == s) { asm.push("i32.const " + s); } } asm.push("end"); srcasm.value = asm.join("\n"); }

簡単ですね。このようなソフトをコンパイラといいます。
掛け算とかいろいろ足したものがこちら「WebAssembly poor compiler」です。

WebAssembly poor compiler

「P 3 +」と入力し「COMPILE」「ASSEMBLE」「RUN」と順に押して、答が出してみましょう。

課題:パラメータを自乗して1を足すプログラムをつくってみよう!

アセンブラも上記、大きな数値にも対応するよう改良してあるので、プログラムを確認してみてください。

次はこのコンパイラをもう一歩進めて、もっと自然な数式で書けるように改良してみます。
待ちきれない人は、どんどん進めちゃってください!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作

links
- WebAssembly Advent Calendar 2017 - Qiita 参加!

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / high-res profile image