あーさん日記

https://akkera102.sakura.ne.jp/gbadev/ の中の人

RustとGBA その1

同人誌「RustでGBAのプログラムを作ろう!」のwindows版インストール手順書です。
devkitProを使って極力簡単にしてみました。


■devkitProのインストール
省略。


■Visual C++ 2015 Build Toolsのインストール
http://landinghub.visualstudio.com/visual-cpp-build-tools
Rustに必要です。普通に2, 3GB取られます。ひどすぎ。


■Rustのインストール
https://www.rust-lang.org/ja-JP/
rustup-init.exeを実行。

Current installation options:

   default host triple: x86_64-pc-windows-msvc
     default toolchain: stable
  modify PATH variable: yes

   default host triple: x86_64-pc-windows-msvc
     default toolchain: nightly ←
  modify PATH variable: yes

nightlyに変えます。


インストール後、コマンドプロンプトで作業します。
最新のnightlyだとエラーになるので同人誌と同じ環境を作ります。
(arm-none-eabi.json内の何かのパラメータがよくないみたいです)

rustup install nightly-2016-11-24
rustup show

Default host: x86_64-pc-windows-msvc

installed toolchains
--------------------

nightly-2016-11-24-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc (default)

active toolchain
----------------

nightly-x86_64-pc-windows-msvc (default)
rustc 1.18.0-nightly (3b5754e5c 2017-04-10)
cargo install xargo
rustup component add rust-src
rustup default nightly-2016-11-24-x86_64-pc-windows-msvc
rustup component add rust-src
rustup default nightly-x86_64-pc-windows-msvc

add rust-srcを2回しているのはそれぞれxargo、コンパイル時に必要な為です。


■サンプルプログラムのコンパイル
https://github.com/kotetuco/Rust-BareMetal-GBA-Sample
Rust-BareMetal-GBA-Sample-masterを解凍、フォルダに移動します。
Makefileの28行目

	RUST_TARGET_PATH=$(PWD) rustup run nightly `which xargo` build -v \

	RUST_TARGET_PATH=$(PWD) rustup run nightly-2016-11-24 `which xargo` build -v \

に変更。

set PATH=C:\devkitPro\devkitARM\bin;c:\devkitPro\msys\bin;%PATH%
make

buildフォルダにrom.mbができます。
f:id:akkera102:20170412002538p:plain


ただ、xargo使わない方がromの容量も小さく高速でした。
原因はよくわからず・・・というか調べてないです。


追記:
本にCargo.toml内opt-levelの違いです、と書いてありました。m(__)m


■xargoを使わない方法
まず、libcoreを作ります。
https://github.com/rust-lang/rust/releases


nightly-2016-11-24と合わせるため、バージョン1.15.0をダウンロードします。
解凍後(ごちゃごちゃある中の)libcoreフォルダをプロジェクトフォルダにコピー。
あとはおまじないを唱えます。

rustc --target=arm-none-eabi.json --crate-type=rlib -C opt-level=2 -C no-prepopulate-passes -Z no-landing-pads -o build/libcore.rlib libcore/lib.rs

rustc --target=arm-none-eabi.json --crate-type=staticlib --emit=obj -C lto -C opt-level=2 -C no-prepopulate-passes -C relocation-model=static -Z verbose -Z no-landing-pads -o build/first.o src/lib.rs --extern core=build/libcore.rlib

arm-none-eabi-ld -t -T rom.ld -o build/rom.elf build/crt.o build/first.o -Map build/rom.map

arm-none-eabi-objcopy -O binary build/rom.elf build/rom.mb

どうしてそうなるの、って話は本を買ってください。(販売促進

TD4 製作 その10

・TD4(ICのみ)の電流値は20mA程度。LEDは1個に付き12mAです。
仮に全てのLEDが点灯した場合、20+12*10=140mAとなります。


・電流はArduino UNOの5Vピン(最大200mA)で十分でした。
アダプタとジャックは買う必要ありません。


・ROMはArduino UNOにまかせてよかった気もします。
https://hackaday.io/project/8442/gallery#9b10d6c3077fde6e4e7ec6aaad3083c8


・部品は調べていたらもっといいものがありました・・・。
タクトスイッチ
http://akizukidenshi.com/catalog/g/gP-08074/
トグルスイッチ
http://akizukidenshi.com/catalog/g/gP-02399/


・書籍は意図して必要な情報を抜いています。
「部品リスト」「配線図」「データシート」はどれも必須です。


・回路図は書籍からコピーします。3ページは忘れずに。
拡大するのもいいかも。本に癖がつくのが嫌な方は、図書館で借りるの手です。


・データシートは「ピン接続図」と「真理値表」をそれぞれ印刷します。
pdfでいいやと思っていると、デバッグのときファイルを開く操作で時間を取ります。
一回の操作どころか、数十回は見積もった方がいいです。やはり紙での作業こそ至高。


・配線図は自分で作ります。といってもデータシートの「ピン接続図」を画像コピーして、
wordなどに紙1枚につきIC2,3個貼り付けるだけです。印刷後、回路図を見つつ接続ピンを自分で書く。
自分用の資料なんだから見栄えはどうでもいいんです。


・全体の配線図はこちらをどうぞ。動作済みだから間違いないです。
超読みにくいですけど、書くの2回目なんで勘弁してください。


・作る順番は電源、クロック、リセット、ROM、CPU。


・「電源、クロック、リセット」を作ったら電源ON。
クロックとリセットにはLEDをそれぞれ付けます。
最悪、5VとGNDを逆にしてもコンデンサ、74HC14だけ壊れるだけです。


・誰得ATMEGA328PのROMソースコード

/*
IDE 物理ピン 名称
3    5       D0
4    6       D1
5   11       D2
6   12       D3
7   13       D4
8   14       D5
9   15       D6
10  16       D7

16  25       A0
17  26       A1
18  27       A2
19  28       A3

※スケッチの書き込み用ピン
-    1       RESET
-   17       MOSI
-   18       MISO
-   19       SCK
*/

#define _A0  16
#define _D0  3

void setup()
{
  for(int i=0; i<4; i++)
  {
    pinMode(_A0+i, INPUT);
  }

  for(int i=0; i<8; i++)
  {
    pinMode(_D0+i, OUTPUT);
  }
}

byte tmp = 0xff;

void loop()
{
  byte t = 0;
  byte d = 0;

  for(int i=0; i<4; i++)
  {
    if(digitalRead(_A0+i) == HIGH)
    {
      t |= (1 << i);
    }
  }

  if(tmp == t)
  {
    return;
  }
  t = 0;

  // 変化中に読み込んだ可能性があるのでリトライ
  for(int i=0; i<4; i++)
  {
    if(digitalRead(_A0+i) == HIGH)
    {
      t |= (1 << i);
    }
  }
  tmp = t;

  // ラーメンタイマー
  switch(t)
  {
  case 0x00: d = B10110111; break;
  case 0x01: d = B00000001; break;
  case 0x02: d = B11100001; break;
  case 0x03: d = B00000001; break;
  case 0x04: d = B11100011; break;
  case 0x05: d = B10110110; break;
  case 0x06: d = B00000001; break;
  case 0x07: d = B11100110; break;
  case 0x08: d = B00000001; break;
  case 0x09: d = B11101000; break;
  case 0x0a: d = B10110000; break;
  case 0x0b: d = B10110100; break;
  case 0x0c: d = B00000001; break;
  case 0x0d: d = B11101010; break;
  case 0x0e: d = B10111000; break;
  case 0x0f: d = B11111111; break;
  }

  for(int i=0; i<8; i++)
  {
    digitalWrite(_D0+i, (d & (1 << i)) ? HIGH : LOW);
  }
}


・全てのICソケットと配線を済ませたら、ショートしていないかチェックをします。
DCジャックの横にある1kを外してやると確実。


・最初の動作テストはROMをすべて0にして、アドレスが一周することを確認。
問題なければラーメンタイマーをセットする。


・おかしい動きをしているアドレスを発見した場合、1つ前のアドレスを確認する。
補助にエミュレータとLEDを使う。
片方をGNDへ。もう一方をICの足にくっつけます。
f:id:akkera102:20170407212627p:plain


デバッグの進め方は大きく分けて2種類。
OUT用LED側か、ROM側か。ROMの方から出発すると発見しやすい。


・プリント基板なんだからショートはないっしょ、
と思っていたらありました。orz
f:id:akkera102:20170407212723p:plain
あれですよ、注文10分前にビアがピンに近すぎるので配線変えて、
ベタGNDを変更しないままガバー作っちゃったって話です。
問題を見つけるだけで2,3時間パー。泣きたい。


・IC取り出し器具は買いましょう。
僕みたいにドライバーでやってぽっきりいかないように。


TD4は作るに当たっての情報収集能力が問われるというか、
よしやるぞっ!て決めてからの意識が違うと思います。
ミスも大量にして、人間間違いをして覚える生き物なんだなと
改めて痛感した次第です。

TD4 製作 その8

先週の月曜日に注文かけた基盤、
後で見直していたら間違いを見つけました。


・一部の部品のシルク塗り忘れ
・基盤の外周にGNDビア忘れ
水晶振動子のノイズ考慮
(全ての)ICのピン番号の順番間違い


・・・諭吉一枚飛びました。泣きますよ、ほんと!
次こそは間違いないように、という意味で強烈な教訓を頂いたと思うしかないです。


改めて作り直し2回目。今度は15x10cmで作れました。
クロック、リセットをATmega328Pに任せたら10x10cmでいけそうですね。
f:id:akkera102:20170312200315p:plain

TD4 製作 その7

今まで思ったことを取り留めなく書いてみます。


・自動配線(Freerouting.exe)をしないとキツいです。
手動配線だったら10~15時間は掛かると思いますので
素直に使うべきです。


・ブレッドボードで作っておくべきテスト順番は、
「電源、リセット信号、クロック信号」
「ROMのみ」「レジスタ、データセレクタ、ALU」。
僕は面倒なので最後のは省略しました。
あとで壮大に後悔する前振りかもしれません・・・。


・道具箱の中で好きなのはロジアナとテスター。
異論は認めます。フラックスも最強だけど四天王では(以下略。


・LEDは抵抗内臓付きのものがいいです。
幸い秋月で売られている5V用は、使っている方もいるので大丈夫そう。
http://akizukidenshi.com/catalog/g/gI-06245/


・最悪配線ミスった部分はブレッドボードに部分移転する予定。


・他の方のTD4動画。並びが綺麗です。
https://www.youtube.com/watch?v=tKO3O2UY_7s
https://www.youtube.com/watch?v=_Ztb2PwnVPc


・クロックは10Hz、1Hz、手動のみ。
ROMとの同期についてはちょっと考えていた時期がありました。
結論からいうとICは、クロックLで信号が決定している状態と、L→Hで状態が変化する
2通りしかないのではないかと考えています。


電源を最初つけたときクロックはLです。たとえばROMは、
A0~A3(アドレス)を読み込み、D0~D7(データ)を決定します。
L→HになったときA0~A3の値が変化します。合わせてD0~D7の値も変えます。
次のL→HまでにD0~D7が決定していればよく、
速度的には全然問題ないと思います。


・予算について。
大雑把に部品代1万(TD4を2個作れる分)。基盤注文代1万。
結構な決断に迫られます。


・プリント基板の大きさ。
20x10cmです。(ROM部分は1チップ化して)
今思うと10x10cmを2つ用意した方が安上がりだったような気も。


・kicad勉強の選択として、2番目にTD4を選んだのは失敗だったのではないかと
後悔しています。配線多いし、自作の回路図綺麗じゃないし。


・DCジャックのフットプリントを作ったときはちょっとうれしくなりました。
部品のデータシートを読んだり、ピンを理解したり。内部が+なのですねー。
内部が+かどうかはアダプタが決定するとか。
http://akizukidenshi.com/catalog/g/gC-01604/


パスコンとベタGNDのありがたみがよくわかりません。
どのあたりがアウトなのか線引きというか、勘もないしなあ。


・ROMをスイッチで作った方は本当に尊敬します。


・書籍のクライマックスは
「加算も移動」「JMPも移動」「クロックで転送」「キャリーは保存」かなと思ってます。
命令のバイナリ数値って、ものすごーく考えて作られているんですね・・・。


レジスタのIC、実はタイマーの用途に使われるものを流用したとか
書いてあったのですけど。タイマー≒レジスタということを頭に描けたことが目から鱗。
コーダー視点だと変数の箱でした。

TD4 製作 その6

ようやくここまで来ました。
土曜日フルに使ったので目と腰が痛いです。
f:id:akkera102:20170304193647p:plain
f:id:akkera102:20170304193654p:plain


今回、電源とリセット、クロック以外は自動配線を使いました。
画像を見ていただくとわかる通り、ないと恐ろしいことになります。
勝手にオートでやってくれるのがどれほどありがたいことか!
身に染みまくりです。とりあえず月曜日には注文できそうです。


参考:
KiCADの自動配線の使い方 - KiCADで基板設計

TD4 製作 その5

f:id:akkera102:20170228222759p:plain
リセット信号とクロック信号(10Hz)を作ってみました。
以下、DCジャックを入れたときの挙動を書いてみます。


追記:配線ミスっていました。orz

・クロック信号
10Hz:0.1秒単位で点灯、点滅。
手動  :最初、点灯、点滅する。ただ、その後にリセットが点灯するので無視される。


・リセット信号
最初の動作が不安定。点灯、点滅、点灯、点滅、点灯してようやく安定する。


うーん、リセット信号、こんなに不安定なんですねえ。
点灯のみ、というわけにいかないようです。


リセットボタンについても0.5秒ほど押し続けないといけませんでした。
一瞬だと反応せず。


・クロック信号
10Hz:0.1秒単位で点灯、点滅。
手動  :ボタンを押して点灯、離すと点滅。


・リセット信号
電源を入れた後に点灯し続けます。動作も安定。


予想通りの結果でした。


お値段的なものもあるでしょうけど、
ATmega328p(1チップ)の凄さを改め感じています。