#author("2023-05-14T09:49:13+09:00","","")
* ラジパイアドバンス拡張ボード [#r637e32d]
#author("2023-05-14T19:50:00+09:00","","")
* ラズパイアドバンス拡張ボード [#r637e32d]
エミュレータも良いけれど実機プレイもしてみたい。そんなあなたにオススメなのはCUBIC STYLEさんの同人ハードウェア3点セットになります。必要なレシピは以下のとおりです。

#ref(9.png,nolink,80%)

https://cubic-style.booth.pm/

- ラズパイアドバンス拡張ボード
- 開発用フラッシュカートリッジ 64Mbit
- マルチブート対応通信ケーブル

電子工作取扱店にて入手
- Raspberry Pi 2/3/4/Zero の内1台
- Raspberry Pi に対応したアダプタ
- micro SDカード(OSを書き込む用)

** 50分でできるインストールクッキング [#x2cab7eb]
** rapberry piのインストール [#x2cab7eb]

- 1.[[公式サイト:https://www.raspberrypi.com/software/]]よりRaspberry Pi Imagerをインストールします。
- 2.アプリ起動したら(0.4GB程度)「Raspberry Pi OS Lite(32-bit) A port of Debian Bullseye with ''no desktop environment''」を選択。
- 3.ストレージをSDカードのドライブを選択
- 4.右下のナットの形をしたアイコンをクリック
ホスト名チェック
SSHを有効化するチェック
ユーザー名とパスワードを設定するチェック
Wi-Fiを設定するチェック(パスワードを間違うとで戻りが激しいので注意してください!)
ロケール設定をするチェック
- 5.書き込むボタンを押下
- 6.OSを書き込むのに10分程度待ちます。
#ref(1.png,nolink,80%)

その間にraspberry pi本体と拡張ボードをドッキングさせておきましょう。
- 2.アプリ起動したら「OSを選ぶ」「Raspberry Pi OS Other」「Raspberry Pi OS Lite(32-bit) A port of Debian Bullseye with ''no desktop environment''」(0.4GB程度)を選択。
#ref(2.png,nolink,80%)

tera termを別途インストールしてください。
- 3.SDカードを挿入して「ストレージを選ぶ」よりドライブを選択。
#ref(3.png,nolink,80%)

- 7.SDカードをraspberry pi本体に移植します。
- 8.raspberry piに電源のオン、オフボタンはありません。本体に通電したときがオンになります。
- 9.tera termでログインする。
- 10.アップデートを行う。
- 11.
- 4.右下のナットの形をしたアイコンをクリック。
#ref(4.png,nolink,80%)

- 5. 自分の環境に合わせて設定をします。 
| ホスト名 | raspberrypi(デフォルトでOK) |
| SSHを有効化する | パスワード認証を行う |
| ユーザー名とパスワードを設定する | ユーザ名:pi パスワード:おまかせ |
| Wi-Fiを設定する | SSIDとパスワードを入力 |
| Wifiを使う国| JP |
| ロケール設定をする | タイムゾーン:Asia/Tokyo キーボードレイアウト:jp |
※Wi-Fiは5Ghz帯と2.5Ghz帯があるので注意してください。たとえばRaspberry Pi 3 model Bの場合は2.5Ghzのみの対応になります。

ストール
 「rpa」はカートリッジを読み書きするコマンド型のアプリケーションです。
 まずライブラリのインストールと SPI を有効にします。
 1. WiringPi ライブラリインストール
$ wget https://project-downloads.drogon.net/wiringpi-latest.deb
$ sudo dpkg -i wiringpi-latest.deb
2. SPI を有効にする
$ sudo raspi-config
raspi-config ではラズパイの各設定が行えます。
5 Interfacing Options を選択して Enter
P4 SPI を選択して Enter
Would you like the SPI interface to be enabled? と表示、「 Yes 」
The SPI interface is enabled を表示、 「 OK 」
raspi-config を終了します。
正常に設定が行われると /dev/spidev0.0 、 /dev/spidev0.1 のデバイスファイ
ルが見えるようになります。
3. rpa コマンドのインストール
$ wget http://cubic-style.jp/rpa/raspiadvrw.deb
$ sudo dpkg -i raspiadvrw.deb
2
4. rpa コマンド動作確認
 拡張ボードにカートリッジを挿します。rpa コマンドを実行します。rpa コマンドは、
 root 権限が必要なので root でログインするか、sudo で実行してください。
$ sudo rpa
~ コマンドオプション一覧 ~
Main ROM mode =>
 Cartridge type: MASK ROM
 Game title: XXXXXXXXXXX
カートリッジの種類が表示されます。ちゃんと挿さっていないと認識されません。
■カートリッジから ROM データを読み取る(吸い出す)
 スロットにカートリッジを挿します。-r オプションで ROM データ保存先のファイル名
 を指定します。
$ sudo rpa -r game.gba
MAIN MEMORY:
READ MODE =>
[##################################################] 100%
read finish
 吸い出した ROM データはエミュレータ等でプレイ可能です。
 -L オプションで吸い出すサイズ(MB)を指定できます(デフォルト 16MB)
   カートリッジの ROM サイズに合わせて設定してください。
■カートリッジに書き込む
 対応しているフラッシュカートリッジを挿します。-w オプションで書き込む ROM ファイ
 ルを指定して書き込みます。フラッシュカートリッジは書き込む前に、Flash を消して
 空の状態にする必要があります。 フラッシュカートリッジの消去は -E オプション
 です。
$ sudo rpa -w game.gba
MAIN MEMORY:
WRITE START =>
[##################################################] 100%
write finish!
■バックアップメモリからセーブデータを読み込む
 カートリッジのバックアップメモリの読み書きは -s オプションを指定します。 -s -r
オプションで、バックアップメモリに保存されたセーブデータを保存します。 -w オプ
ションでセーブデータを書き込めます。
$ sudo rpa -s -r game.sav
Backup memory mode =>
 Memory type: Sram(Fram)
 Size: 32 KB
READ START =>
[##################################################] 100%
read finish
■通信ポートでマルチブート
 マルチブートには、両コネクタの端子が全結線されている通信ケーブルで GBA 本体と接
 続する必要があります。GB ポケット用通信ケーブルを用いると、そのままのケーブルで
3
 マルチブートが可能です。
 注) GBA 専用通信ケーブルは、マルチブートは対応していません。
 マルチブートする。GBA 本体と接続、本体を起動して受信待ち画面にします。
$ sudo multiboot example_mb.gba (マルチブート用 ROM ファイルを指定)
 マルチブート用サンプル ROM をダウンロード
$ git clone https://github.com/cubicstyle/multiboot.git
 マルチブート用プログラムは XXXXX_mb.gba のようなファイル名になっています。
■rpa コマンドソースコード
rpa コマンドは機能追加やバグ修正を随時行っていますので、CUBIC STYLE のウェブ
 サイトや Twitter をご確認ください。ソースコードを公開しています。
 バグ報告や機能追加・修正のご要望もお待ちしております。
Github リポジトリ
https://github.com/cubicstyle/raspiadvrw
■その他
 拡張ボードの解説やラズパイを使った GBA 開発についてまとめた同人誌「ラズパイアド
バンス」も頒布中です。拡張ボードのハンダ不良、動作不良などありましたらご連絡くだ
さい。Twitter 等で最新の開発状況などを随時発信していますので、チェッ
- 6.書き込むボタンを押下。10分程度待ちます。

- 7.待っている間にraspberry pi本体と拡張ボードをドッキングさせておきましょう。また、tera termを別途[[インストール:https://ttssh2.osdn.jp/]]します。
#ref(5.png,nolink,80%)

- 8.SDカードをraspberry pi本体に移植します。
- 9.raspberry piに電源のオン、オフボタンはありません。本体に通電したときがオンになります。OS起動に1分ぐらいかかるので少し持ちます。
- 10.tera termを起動。ホストに''raspberrypi''を入力してOKボタン。
#ref(6.png,nolink,80%)

- 11.セキュリティ警告のメッセージが出てきた場合は読んだのち、続行ボタン。
- 12.ユーザ名とパスワードを入力してOKボタン。ログインするとこのような表示になります。
#ref(7.png,nolink,80%)

- 13.ログインできましたらアップデートをするので以下のコマンドを1行コピペして実行します。

 sudo apt update
 sudo apt upgrade -y
 sudo apt dist-upgrade -y
 sudo apt autoremove -y
 sudo apt autoclean
 sudo reboot

** 開発環境のインストール [#x2cab7eb]

- 1.再起動後、開発環境を整えていきます。まず、WiringPi ライブラリのインストールです。 
 wget https://project-downloads.drogon.net/wiringpi-latest.deb
 sudo dpkg -i wiringpi-latest.deb

- 2.SPIを有効にします。
 sudo raspi-config

#ref(8.png,nolink,80%)

raspi-config ではラズパイの各設定が行えます。「3 Interface Options」を選択。「I4 SPI」を選択。Would you like the SPI interface to be enabled? と表示されるので「Yes」を選択。「The SPI interface is enabled」と表示されます。「 OK 」を押したらメニュー画面に戻されるのでTabキーを使って「Finish」を選択。raspi-configを終了させます。

- 3.SPIが有効か確認します。正常に設定が行われると /dev/spidev0.0 、/dev/spidev0.1 のデバイスファイルが見えるようになります。
 pi@raspberrypi:~ $ ls /dev | grep spi
 spidev0.0
 spidev0.1

- 4.拡張ボード制御ツールのインストール
 wget http://cubic-style.jp/rpa/raspiadvrw.deb
 sudo dpkg -i raspiadvrw.deb
rpaコマンドはroot 権限が必要なのでrootでログインするか、sudoで実行してください。

- 5.動作確認
カードッジを挿入してrpaを実行します。カートリッジの種類が表示されていることを確認してください。
pi@raspberrypi:~ $sudo rpa
 
 Copyright (C) 2022 CUBIC STYLE
 
 rpa [-w gbarom] [-r dstfile] [-l size] [-L size(MB)]-c [-a address]
   -s                    Backup memory mode (Sram, Fram, Flash, ...Not yet supported EEPROM)
 
   -c                    ROM info
   -r <filename>         Read ROM(or backup memory)
   -w <filename>         Write ROM(or backup memory)
   -e                    block erase
   -E                    chip erase
   -B                    blank check
   -d                    dump
   -a                    rom address
   -b                    block address
   -n                    erase block num
   -h                    this help
 
 Main ROM mode =>
   Cartridge type:  Cubic Flash Cartridge
   Size:            256 Mbit
   Device:          MX29GL256F
   Game title:      test

** 各オプション [#ba585e6f]
以下、説明書からの抜粋です。

*** カートリッジから ROM データを読み取る(吸い出す) [#j615720e]
 $ sudo rpa -r game.gba
-L オプションで吸い出すサイズ(MB)を指定できます(デフォルト 16MB)カートリッジの ROM サイズに合わせて設定してください。

*** カートリッジに書き込む [#peb504d1]
 $ sudo rpa -w game.gba

対応しているフラッシュカートリッジを挿します。-w オプションで書き込む ROM ファイルを指定して書き込みます。''フラッシュカートリッジは書き込む前に、Flashを消して空の状態にする必要があります。フラッシュカートリッジの消去は-E オプションです。''

*** バックアップメモリからセーブデータを読み込む [#d8534390]
カートリッジのバックアップメモリの読み書きは -s オプションを指定します。-s -rオプションで、バックアップメモリに保存されたセーブデータを保存します。-wオプションでセーブデータを書き込めます。
 $ sudo rpa -s -r game.sav

*** 通信ポートでマルチブート [#nffffc52]
マルチブートには、両コネクタの端子が全結線されている通信ケーブルで GBA 本体と接続する必要があります。GB ポケット用通信ケーブルを用いると、そのままのケーブルでマルチブートが可能です。 GBA 専用通信ケーブルは、マルチブートは対応していません。マルチブートする。GBA 本体と接続、本体を起動して受信待ち画面にします。マルチブートに対応したらROMを用意しないといけないので注意してください。
 $ git clone https://github.com/cubicstyle/multiboot.git
 $ sudo multiboot mb.gba

*** raspberry piの電源の切り方 [#x47cac74]
 sudo shutdown -h now

コマンド入力後、緑のLEDランプが点灯しなくなるまで待ちます(30秒ぐらい。あとは電源ケーブルを抜いてください。

** ファイル転送 [#n028addd]
ロムファイルを転送するにはTera Termウィンドウにドラッグ&ドロップしてOKボタンを押すとホームディレクトリに転送されます。
#ref(10.png,nolink,80%)

** CUBIC STYLE ROMのFlash書き込みテスト [#y5b42281]
 #include "flash.h"
 #include "bg.h"
 
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashInit(void)
 {
 	BgDrawPrintf(0, 0, "MemoryBackup Cubic Test");
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashExec(void)
 {
 	if(FlashIsExist() == FALSE)
 	{
 		BgDrawPrintf(0, 2, "Flash not found");
 		for(;;){}
 	}
 
 	BgDrawPrintf(2, 1, "Type : Flash");
 	BgDrawPrintf(2, 2, "Id   : %x", FlashGetId());
 
 	BgDrawPrintf(2, 4, "Erase 0, 1, 2");
 	FlashEraseSector(0);
 	FlashEraseSector(1);
 	FlashEraseSector(2);
 
 	FlashByte(0x0000, 1);
 	FlashByte(0x0001, 2);
 	FlashByte(0x0002, 3);
 
 	FlashByte(0x1000, 4);
 	FlashByte(0x1001, 5);
 	FlashByte(0x1002, 6);
 
 	FlashByte(0x2000, 7);
 	FlashByte(0x2001, 8);
 	FlashByte(0x2002, 9);
 
 	BgDrawPrintf(3,  5, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002));
 	BgDrawPrintf(3,  6, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002));
 	BgDrawPrintf(3,  7, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002));
 
 	BgDrawPrintf(2,  8, "Erase 1");
 	FlashEraseSector(1);
 
 	BgDrawPrintf(3,  9, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002));
 	BgDrawPrintf(3, 10, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002));
 	BgDrawPrintf(3, 11, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002));
 
 	BgDrawPrintf(2, 12, "Erase Chip");
 	FlashEraseChip();
 
 	BgDrawPrintf(3, 13, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002));
 	BgDrawPrintf(3, 14, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002));
 	BgDrawPrintf(3, 15, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002));
 
 	BgDrawPrintf(2, 16, "Done");
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashByte(u16 adr, u8 dat)
 {
 	// Byte-Program
 	FlashWrite(0x5555, 0xAA);
 	FlashWrite(0x2AAA, 0x55);
 	FlashWrite(0x5555, 0xA0);
 	FlashWrite(adr, dat);
 
 	// 20us
 	FlashWait(400);
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE u8 FlashRead(u16 adr)
 {
 	u8* p = (u8*)SRAM + adr;
 
 	u8 ret = *p;
 
 	return ret;
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashWrite(u16 adr, u8 cmd)
 {
 	u8* p = (u8*)SRAM + adr;
 
 	*p = cmd;
 
 	__asm("NOP");
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashEraseChip(void)
 {
 	// Chip-Erase
 	FlashWrite(0x5555, 0xAA);
 	FlashWrite(0x2AAA, 0x55);
 	FlashWrite(0x5555, 0x80);
 	FlashWrite(0x5555, 0xAA);
 	FlashWrite(0x2AAA, 0x55);
 	FlashWrite(0x5555, 0x10);
 
 	// 100ms
 	FlashWait2(10);
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashEraseSector(u16 sec)
 {
 	_ASSERT(sec < 0x10);
 
 
 	// Sector-Erase
 	FlashWrite(0x5555, 0xAA);
 	FlashWrite(0x2AAA, 0x55);
 	FlashWrite(0x5555, 0x80);
 	FlashWrite(0x5555, 0xAA);
 	FlashWrite(0x2AAA, 0x55);
 	FlashWrite(sec * 0x1000, 0x30);
 
 	// 25ms
 	FlashWait2(3);
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashWait(u32 cnt)
 {
 	for(vu32 i=0; i<cnt; i++)
 	{
 		// 1週 0.0625us(大雑把に)
 		__asm("NOP");
 	}
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE void FlashWait2(u32 cnt)
 {
 	for(vu32 i=0; i<cnt; i++)
 	{
 		// 1週 16.743ms
 		while(REG_VCOUNT >= 160) {};
 		while(REG_VCOUNT <  160) {};
 	}
 }
 //---------------------------------------------------------------------------
 // SST39VF010 : BF D5
 // SST39VF020 : BF D6
 // SST39VF040 : BF D7
 EWRAM_CODE u16 FlashGetId(void)
 {
 	// ID Entry
 	FlashWrite(0x5555, 0xAA);
 	FlashWrite(0x2AAA, 0x55);
 	FlashWrite(0x5555, 0x90);
 
 	// Read ID
 	u8 id0 = FlashRead(0x0000);
 	u8 id1 = FlashRead(0x0001);
 
 	// ID Exit
 	FlashWrite(0x5555, 0xAA);
 	FlashWrite(0x2AAA, 0x55);
 	FlashWrite(0x5555, 0xF0);
 
 	return id0 | (id1 << 8);
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE bool FlashIsExist(void)
 {
 	// 読み込み、書き込みテスト
 	u8 t1 = FlashRead(0x7FFF);
 	u8 t2 = ~t1;
 
 	FlashWrite(0x7FFF, t2);
 
 	if(FlashRead(0x7FFF) != t2)
 	{
 		FlashWrite(0x7FFF, t1);
 
 		return TRUE;
 	}
 
 	return FALSE;
 }

** 動作画面 [#e75a4df3]
#ref(11.png,nolink,50%)

** 履歴 [#j0abcb62]
- 2023/05/12


トップ   一覧 検索 最終更新   ヘルプ   最終更新のRSS