SNSへはこちら

LPC1114にIchigoJamを入れて遊ぶ

久々に LPC114514 1114 をいじろうという気が起きたんですが、これを期に aitendo 等でよく見かける IchigoJam を超簡易的に作ってみようと思った記事です。

簡易的なので、ハンダの類は一切使用しません。すべてブレッドボード上で作り上げます。

参考にしたサイト

マイコン

当然 LPC1114 です。型が同じなら SSOP 版でも DIP 版でもなんでも良いです。今回はオリジナルと同じの DIP 版(FN28)があったのでこちらを使います。秋月の販売サイトはこちら。

使用ハードウェア

中心になってくるのは LPC1114 マイコンです。こちらですべての処理が行われます。電源電圧は 3.3V なのでご注意を。更に USB-シリアル変換モジュールも必要ですね。僕は自作基板とマイコンを接続しました。接続した LPC1114 のピン配置は以下の通り。

pin # ピン名 備考
15 TXD シリアル変換モジュールの RXD と接続
16 RXD シリアル変換モジュールの TXD と接続
21 VDD 3.3V と接続
22 GND
23 PIO0_0 リセット端子。Lowでリセット状態
24 PIO0_1 リセット時、ここのロジックによってブートモードが変わる

...これだけです。後はファームウェアを書き込むだけで環境構築完了!ブザーとかは使う時逐一付けてしまえば良いんです。ファームウェアは落として ichigojam-ntsc-jpkbd.bin を書き込みます。FlashMagic を使う人は頑張って。lpc21isp の方は以下のコマンドでいいでしょう。

$ lpc21isp -bin ichigojam-ntsc-jpkbd.bin /dev/tty.usbmodem1412 115200 120000

書き込み時は PIO0_1 を Low にして、PIO0_0 を Low から High に立ち上げると良いです。その後 PIO0_1 を High にして、再度 PIO0_0 を立ち上げてください。

通信用ソフト

いつものように screen を使えばいい...と思ったんですが、改行コードの関係で非常に都合が悪いです。こんな感じに↓

ということで、HOME of IJUtilitiesから IJUtilities を利用します。僕は Mac64bit 版を選択しました。この中の README 的なものに従っておけばいいです。すると下のように良い感じの開発環境が整ったことになります。

ピン配置

CPU ピン配置 - イチゴジャム レシピに良い感じにありますのでご参照を。

実行モード(?)

よく分かっていないんですが、行番号を付けずに1行入力すると即座に実行されるインタプリタモード(?)的な挙動になるようです。一方で行番号を行頭に付した場合、プログラムの打ち込みモード的なものになって、最後に run を打つことで実行されるとのことです。後者はプログラムを繰り返して実行できるという点で(run を再度打つだけで直前のプログラムを実行可能)ちがいます。

プログラムの保存・呼び出し

打ち込んだプログラムは保存することが出来ます。インタプリタのものではなく、行番号を付けて打ち込んだ一連のプログラムが対象です。プログラムは LPC1114 マイコンの Flash 領域に保存することが出来、スロットは 0 から 3 までの4つのみとなっています。

save 0 ' 0番に保存

呼び出しは load で行うことが出来、メモリにロードされたプログラムを確認するには list を打ちます。

load 0 ` 0番のプログラムを呼び出し

実行する場合は run とすれば良いです。

プログラム例

とりあえずLチカ

LED を点灯させるだけなら簡単です。とりあえずLEDを接続し(#14)、ポート名 値 と書けばよし。どうやら値は 0 以外を True と見るようです。LED ポートを付けるには LED 1 ですね。
以下は LED をチカチカさせる例。wait 値で値は100分の1秒を指定するようです。

10 led 1
20 wait 50
30 led 0
40 wait 50
50 goto 10
run

無限ループなので Esc を押してブレークしてください。なおこのように行番号を使って書いた場合は、その番号を重複させて別のプログラムを書くことは出来ないようです(エラーは出ないが)。なので逐一 new を実行して現在のプログラムを破棄するようにしましょう。

LED ボヤァ

ホタルのように3回光ります。ポートは PWM 制御の関係で OUT4(#12)となります。

10 let c, 0 
20 for i=0 to 2000 step 20 : pwm 4, i : next
30 for i=0 to 2000 step 20 : pwm 4, 2000 - i : next
40 let c, c + 1
50 if c <> 3 goto 20
run

サイコロ

要は乱数を出せばいいだけです。ということで run を除けば一行で終了。

10 print rnd(5) + 1
run

run を何度も叩けば繰り返しサイコロを振れますね。

圧電ブザーを鳴らす

SOUND端子(#25)に圧電ブザーを接続すると(ブザーの端子の他方はGNDに固定)、IchigoJam で音の演奏ができます。というか特に設定しなくても、エラー時にピッっと音がなるんですね。楽しい。

play "T120<CDEFEDC" ' ちょっと音痴なカエルの歌冒頭
play "T250<CDE2DCRRCDEDCD1" ' チャルメラ

フィボナッチ数列の計算

Fib(n)(n: 整数)、Fib(0) = 0, Fib(1) = 1 としてフィボナッチ数列(Fib(n+2) = Fib(n) + Fib(n+1) を満たす数列: Fib(n) for n >= 0)を求めるプログラムです。こちらではサブルーチン呼び出しを行っています。といっても、行番号を指定してカタマリの最後に return を書くだけです。なおメインルーチンで end を書かない場合、10 -> 20 -> ... と実行されていって、ついにはサブルーチン内に入り込みます。そして最終的に return が実行されて戻り先がないためエラーになってしまいます。サブルーチンを使う時はメインルーチンを end で〆ましょう

また、以下では配列操作を行っています。配列は無名の [0] から [100] までの100個あり、それぞれインデックス番号にて参照・書き込み可能です。

' こちらが計算をするルーチン
100 [0] = 0 : [1] = 1
110 for i=0 to x-2
120    [i+2] = [i] + [i+1]
130 :next
140 return

' メインルーチン
' とりあえずFib(10)まで求めて順に出力
10 x = 10
20 gosub 100
30 for i=0 to x
40     print [i]
50 :next
60 end
run

ARM アセンブリ

なんと、ARM の命令をハンドアセンブルして打ち込むことが出来ます! poke 命令を使えば、指定したメモリアドレスにデータを連続的に書くことが出来るのです。
はじめてのマシン語 - IchigoJamではじめるArmマシン語その1 #IchigoJam #KidsIT #Arm / 福野泰介の一日一創 / Create every day by Taisuke Fukunoを参考にされたし。

以下は 指定した数値まで足していくプログラムです(Σ i を求めるもの)。
まず疑似コードを考えました。そしたらこの参照先のページと全くおなじになってしまったんですが、一応以下に掲載します。

r1 = 0
r1 = r1 + r0
r0 = r0 - 1
IF Not ZeroFlag GOTO -2
r0 = r1
RET

これをハンドアセンブルして機械語を #700 番地に書き込んだものが以下。実際にハンドアセンブルすると上位8ビットと下位8ビットが逆転しているのに気が付くとおもいますが、これは ARM がリトルエンディアンであるためです。

あとついでに、上のサイトで機械語表のジャンプ先アドレスに << 1 が付いている理由ですが、これはまあ命令コードが 16bit なもんで、1命令に 2Byte 分のサイズが必要ですよね。ですので命令1個単位で見ると2倍になっているということです。そして更に更に、 GOTO の相対的なジャンプ先命令位置に -2 をする理由なのですが、ARM はプログラムカウンタが実行中の命令の2つ先を指しているので、これに対応するものだと思われます。

poke #700, #00,#21,#09,#18,#01,#38,#FC,#D1,#08,#43,#70,#47

あとは usr で実行・返り値の取得ができます。第一引数は開始メモリアドレス、第二引数は r0 に渡す値です。print usr(#700, 100) とすると 1/2 * 100 * (100 + 1) = 5050 と同じ値が出るはずです。
なおこの機能はユーザが打ち込んだ機械語を素直に実行してくれるものですから、ブレーク等は一切聞かず、暴走したらしっぱなしです。返ってこなかったら諦めて電源を落としましょう。

その他制御・演算

A to Z

AからZまで、各行に表示する

for i=asc("A") to asc("Z") : ?chr$(i) : next

2の補数計算

ベタですみません。。。。ビット演算の練習に。

print ~10 + 1 + 5

いやぁ、こんなレガシーな BASIC というものを手軽に、そしてものづくりに応用できるようなシステムを作るなんてすごいです〜
YouTube とか観てると「基板作ってみた」とか「プログラム書いてみた」とかありますよね。そんな軽いノリで黒い画面に立ち向かえる人が増えることを期待します。

ちなみに以下はこの IchigoJam を作った jig.jp さんのページです。

このページのサンプルは気が向き次第追記していきます〜〜〜

見つけた良い感じの教材

追記したい

  • I2C

コメント

  1. 福野泰介 より:

    マシン語まで使ったご紹介ありがとうございます!IchigoJamをつくっている者です。

    WAITのパラメーターは垂直同期の数を使っているので、1/100secではなく1/60sec(PALの場合1/50sec)となってます。小学生に紹介する時には秒間60コマの超高速紙芝居だよっと説明してます。(ゲーム好き学生にはFPS値で通じますね)

    本日リリースした、IchigoJam BASIC ver 1.4 では、例外を使用して暴走が起きにくい状態としたので、少し気軽にマシン語で遊べるようになりました!
    https://fukuno.jig.jp/2487

    APIテーブルを用意したのでオールマシン語プログラムでできる幅も広がってます。
    https://fukuno.jig.jp/2498

    • shima-529 より:

      福野さん

      コメントありがとうございます!実はTwitterで相互フォロー頂いています(笑)
      WAITに関しまして、ご指摘ありがとうございます。そういう意味があったんですね〜〜

      僕は高レイヤなフレームワークは好きではないのですが、BASIC上で機械語を打てるということに好感を持ちまして記事にさせて頂きました。
      いろいろ試している時は暴走が面倒くさいなと思っていたのですが(でもおそらくHardFault_Handlerに飛んでいますよね)、その点を準備してくださったことはとても有り難いなあと感じます。

      IchigoJamはワンコマンドでLチカを楽しめる比較的高レイヤなプログラミング環境である一方、このように低レイヤな環境としても大きく楽しめることは非常に魅力を感じております。

      今後とも楽しませていただきます。コメントありがとうございました。