ブログの練習

ブログを書く練習です。
最近はレトロな計算機(電卓、マイコン、パソコンなど)
に関することを書き始めました。

CH32V003でBASICインタプリタを動かしてみる

2023-06-30 15:13:52 | マイコン

秋月電子で売ってる40円のマイコン(CH32V003J4M6)がTwitterで話題になっていてちょっと気になっていたのですが、かんぱぱさん(@kanpapa)のブログにArduino IDEでの使い方がまとめられていて簡単に使えそうだったので試しに買ってみることにしました。

 

40円RISC-Vマイコン(CH32V003)をArduino IDEでLチカをしてみました | きょうのかんぱぱ

秋月電子さんに新商品のマイコンが入荷したようです。1個40円の32ビットRISC...

きょうのかんぱぱ

 

40円は税込価格で本体は37円。1個づつ個別包装です。袋とシリカゲルで数円分ぐらいかかってるのではないだろうか。書き込みにはWCH−LinkEエミュレーターなるものが必要とのことなので別途購入しましたが、これも750円と安価です。

スペックを見ると、

  • プログラムメモリ:16kB
  • RAM:2KB

とあります。このくらいあればBASICインタプリタが動くのではと思い、試してみることにしました。

とりあえず端末と通信できないことにはどうにもならないので、まずは通信周りについて調査。WCH-LinkEエミュレータにTX、RXなる端子があるのでこれを使えばUART通信ができるのかな?と思ってググってみたところ、こちらのブログとGitHubに関連情報を見つけました。

 

CH32V003をArduinoで使おう(CH32V203も) - Qiita

CH32V003 が Arduino で使えるようになりました。それでは、ArduinoIDEで使えるようにしましょう。ArduinoIDEに設定するファイル→環境設定追加のボードマネージャ ...

Qiita

 
 

arduino_core_ch32/variants/CH32V00x/CH32V003F4/PeripheralPins.c at main · openwch/arduino_core_ch32

Core library for CH32duino. Contribute to openwch/arduino_core_ch32 development by creating an account on GitHub.

GitHub

 

これによると、TXはPD_5=Pin 8、RXはPD_6=Pin 1のようです。

WCH-LinkEのTXをCH32のRX(Pin 1)、WCH-LinkEのRXをCH32のTX(Pin 8)に継げます。(ややこしいです。いつも混乱します。)

Pin 8はプログラム用の信号入力SWDIOも継がっているので共用になります。そのせいでトラブル発生。プログラムを書き替えようとしても継がらなくなってしまいました。

そういえば秋月のFAQに何か書いてあったような気がします。

32ビットRISC-Vマイコン CH32V003J4M6の質問と回答

なるほど。でもこれだけのためにMounRiver Studioを使うのは大袈裟だなあと思っていたところ、WCH-LinkUtilityにもこの機能があることを発見。こちらを使って無事クリアすることができました。

しかしすぐには動いてくれず、CH32→PCは継がるのに、PC→CH32の通信が出来ないという状態。原因を見つけるのに結構苦労したのですが、Serial.available()が常に-1なのが原因でした。RXにデータが来てるかどうかのチェックを、

if(Serial.available() > 0){
  c = Serial.read();
}

ではなく、

c = Serial.read();
if(c > 0){
  ...
}

とすることで通信できるようになりました。Arduino用の環境がCH32V003F4用に作られているせいなのかもしれませんがよくわかりません。

ともかくUARTで通信ができるようになったので、いよいよBASICインタプリタの実装に移ります。1から作るのは大変なので何か使えるものはないかと探してみたところ、電脳伝説さん(@vintagechips)の著書「タイニーBASICをCで書く」に掲載されている豊四季Tiny BASICがコンパクトで良さそうだったので試してみることにしました。ソースは本に記載されているサイトからダウンロードしたのですが、GitHubにほぼ同じものが公開されていました。

 

GitHub - vintagechips/ttbasic_arduino: TOYOSHIKI Tiny BASIC for Arduino. Tested in Arduino Uno.

TOYOSHIKI Tiny BASIC for Arduino. Tested in Arduino Uno. - GitHub - vintagechips/ttbasic_arduino: TOYOSHIKI Tiny BASIC for Arduino. Tested in Arduino Uno.

GitHub

 

Arduino用に作られているのでそのままコンパイル可能ですが、プログラム領域256byteではASCIIART.BASが入らないので512に変更しました。

#define SIZE_LIST 512 //List buffer size

最適化オプションが"Smallest (-Os default)"だと2kBほどサイズオーバーになり、"smallest (-Os) with LTO"だと16kB以内に収まりました。しかし、with LTOの方だと通信周りがちゃんと動かないようで、最初の1文字"T"が出て止まってしまいました。通信周りを直すか、別の開発環境を使えばうまくいくような気もしますが、とりあえずASCIIART.BASを走らせることを優先しようと思い、インタプリタの機能を削って小さくすることにしました。

やったことは、

  1. エラーメッセージの文字数削減
  2. ASCIIART.BASで使っていない機能を削る

です。

"2."の方はかなり乱暴で、配列、INPUT、GOSUB、RETURN、STOP、REM、RND、ABSを削りました。

これでやっと、

Sketch uses 16184 bytes (98%) of program storage space. Maximum is 16384 bytes.

Global variables use 1512 bytes (73%) of dynamic memory, leaving 536 bytes for local variables. Maximum is 2048 bytes.

に収まって無事起動。Serial.read, Serial.available周りに修正が必要かと思っていたのですが何も変更せずに動作しました。 ASCIIART.BASの方は、以前にFairchild F8 Family (F3850)Zilog Z8671 BASIC/Debug用に作った整数型BASIC用のプログラムをくっつけて作りました。

10 F=50
20 FOR Y=-12 TO 12
30 FOR X=-39 TO 39
40 C=X*229/100
50 D=Y*416/100
60 A=C; B=D
70 I=0
90 Q=B/F; S=B-Q*F
100 T=(A*A-B*B)/F+C
110 B=2*(A*Q+A*S/F)+D
120 A=T
130 P=A/F; Q=B/F
140 IF (P*P+Q*Q)>4 GOTO 200
150 I=I+1;IF I<=15 GOTO 90
160 PRINT " ",
170 GOTO 300
200 IF I<10 PRINT I,; GOTO 300
210 IF I=10 PRINT "A",; GOTO 300
220 IF I=11 PRINT "B",; GOTO 300
230 IF I=12 PRINT "C",; GOTO 300
240 IF I=13 PRINT "D",; GOTO 300
250 IF I=14 PRINT "E",; GOTO 300
260 IF I=15 PRINT "F",
300 NEXT X
310 PRINT
320 NEXT Y

動作している様子です。8秒です。さすが21世紀のマイコンは速いですね。

今回は動作させることを最優先にしたので機能を削るという乱暴な方法で実装しましたが、おそらくライブラリが余計なメモリを食っているような気がするので、開発環境を精査すれば16KBもあればフルセットで実装できると思います。

※追記(2023/6/30)

Serial関連のライブラリがかなりメモリを食ってる感じなのでそこを自分で書き直すのが良さそうかも。

※追記(2023/7/1)

メーカー推奨の開発環境MounRiver Studioだとフルセットでもオブジェクトサイズ9KB以下に収まりました。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Intel 4004 (その17) 周辺回路を現代の部品で作ってみる(TangNano編)

2023-06-14 18:03:16 | マイコン(4004)
4004の周辺回路を現代の部品で作る試みの第3弾、TangNano編です。やっと完成したのでブログにまとめることにしたのですが、かれこれ1ヶ月以上前からやっていて、最初の頃のことは自分でもすっかり忘れているので、twitterで自分のツイートを読み返しながら書きます。トラブったことや部品選定の話をとりとめもなく書くだけなので、技術的な話はGitHubの回路図やソースを見てもらう方がいいと思います。
GitHub - ryomuk/tangnano-MCS4memory: Memory system for Intel 4004 using Tang Nano 20K

GitHub - ryomuk/tangnano-MCS4memory: Memory system for Intel 4004 using Tang Nano 20K

Memory system for Intel 4004 using Tang Nano 20K. Contribute to ryomuk/tangnano-MCS4memory development by creating an account on GitHub.

GitHub

 


Tang Nanoというのは、Gowin SemiconductorのFPGAを使ってSipeedが製造販売しているFPGA評価ボードです。
当初Tang Nano 9Kというボードで試しており、64KBのメモリを実装するにはリソースがギリギリ足りないので実機と完全コンパチには出来ず、ブレッドボードでVTLを走らせるところまで試してさてどうしたものかと思っていたのですが、つい先日20Kという新製品が発売され、64KBのメモリを実装できるようになり、実機と完全互換のものが作れました。
9Kでブレッドボードで試していたときの写真がこれ。


この実験をしているときに、3.3V→15Vのレベル変換IC(CD40109)のGNDを継ぎ忘れていたせいでTangNano9Kを1つ壊してしまいました。40109にGNDを継げずに15Vと3.3Vだけ継げて検証実験をしたところ、入力端子(TangNano側の出力端子)に4.2Vの電圧が発生。


結構な時間こんな状態が続いていたのでまあ壊れるのも納得です。で、すぐに予備の9Kを2つ秋月に発注したのですが、なんとその日の夜にSipeedがtwitterで新製品の20Kの発売開始を発表。
とりあえず20Kの方もコントローラー付属のゲームキット1つとピンヘッダー無しを2つ注文しました。巷では5月25日頃に到着の報告を見かけたのですが、どうやらゲームキットもいっしょに注文したのがまずかったようで、発送が遅れて6月1日にやっと届きました。(しかも1個足りなくて、再送してもらいました。)


初物なのでいろいろトラブルがありました。主なのは2つかな。
1つ目はpin25とpin26がデータシートで逆に描かれているという問題。pin25に継げたスイッチが全く反応しないので何がおかしいのか調べていたらどうやらpin25とpin26が逆の様子。これは6月8日のアップデートで修正されました。
2つ目はpin75から信号が出ない、信号入力もできないという問題。当初全く動かないので、twitterでSipeed宛てにpin75が動かないよ~と下記画像を付けてツイートしてみました。

いろいろ調べているうちに、なぜか手動で信号をGNDと+3Vに切り替えると0、1はちゃんと入力できることがわかり、これはもしかしてと周波数を変えて試してみたところ、高い周波数がカットされているらしいという現象を見つけて追加でツイート。

これに対して別の人から、pin75はコンデンサにつながってるとのリプライがあり、原因がわかりました。

Sipeedからも、そのcapを外せばいいというツイートがあったので外して試してみたところ無事直りました。


pin75が使えないと基板作り直しだなあと思っていたので作り直さずに済んで良かったです。(今は未使用のCMRAM1_nの信号につなげているので実害は無いのですが気持ちが悪いので。)
同様の信号がpin51にもあるのですが、こちらのコンデンサはパターンだけあって実装されていません。pin75のコンデンサも次期ロットあたりから外されるのかな。

今回の試作でもうひとつトラブったのが電源周りの話です。(こちらはTang Nanoとは無関係な話です。)
周辺回路をほとんどTangNanoに入れてしまったので、15Vの電源が必要なのは4004とクロックドライバだけになります。4004のデータシートを見ると、平均消費電流は最大40mA、絶対定格で1Wとあり、クロックも4004にしか供給されないので、多く見積っても全部で50mAもあれば良さそうです。
5V→15V、1WのDCDCでいけるだろうと思ってブレッドボードで試していたのですが、電圧が14Vぐらいまでしか上がらないという謎な現象に遭遇しました。
3WのDCDCにとりかえて電流を測定してみたところ、なんと最初に90mAぐらい流れています。

15V1Wは67mAなので、これは過負荷です。14Vまでしか上がらないのも納得。
これが1分ほどで想定通りの33mAぐらいに落ちつきます。

最初は温度の問題かと思ったのですが、電源を入れなおすとまた90mAぐらい流れるので温度の問題では無さそう。4004とクロックドライバを疑って個別に計測してみたのですが特に問題無し。
CMOSゲートの4049を測ってみたところなんと1つあたり30mA流れていることが判明。これが犯人でした。いや、犯人は私なんですけどね・・・
4049の未使用入力をオープンにしていたのが原因でした。基板を作るときはちゃんとVCCかGNDに継げますが、ブレッドボードでは面倒なのでサボっていました。ごめんなさい。

電源がらみでもう1つ。DC/DCの選定にあたり、秋月で売ってるMINMAXにするか、ワールドワイドで入手性がいいRECOMのどちらにするか試してから決めようと思っていろいろ買ってみたのですが、RECOMの3WのRI3-0515Sがばかに電圧高めに出るなあと思っていたところ、DC/DCにはregulatedとunregulatedがあるということに気がつきました。

全部regulatedだと思ってたのですが、
MINMAXは1WのMAUはunregulatedで3WのMCWIはregulated。RECOMもROEやRI3はunregulated。regulatedが欲しければRS3なのでした。
3Wのunregulatedを0.5Wぐらいで使うと電圧は高くなってしまうというのは仕様通りの挙動。いろいろ買って試してみてやっと気がつきました。

1Wを0.5Wぐらいで使うのは丁度いいようなので、今回はワールドワイドで入手性のいいRECOMのROE-0515Sを採用することにしました。

最後に部品選定の話をもう1つ。クロックドライバについてです。
昔の4004の回路では、DS0026というドライバが使われていました。若松でしか売ってないレベルの昔の部品です。現行品を使う方がいいかなと思い、teensyやPIC版では秋月で売ってるMicrochipのMCP1402に変えてみたのですが、やっぱりSOT23+変換基板というのは美しくないのでいろいろ調べた結果、同じくMicrochipのMIC4427というのがDIPの現行品らしいのでこれを使うことにしました。


これについて調べてたときに、Microchipのこの表を見て途方に暮れていたのですが、


TIが作ってくれたこの表に助けられました。


これに限らず、TIの資料は本当にわかりやすいです。

で、なんやかんやで完成した基板がこれ。

部品のほとんどはレベル変換用IC(15V←→3.3V, 15Vクロックドライバ, UART用5V耐圧バッファ)です.

ほとんど昔の部品で作った基板はこちら。この赤で囲んだ部分が全部Tang Nanoに入ったことになります。


一定の成果が得られたので、4004の周辺回路を現代の部品で作る試みはひとまずこれでひとくぎりにします。当たり前ですが、ハードウェアをエミュレートするのはCやアセンブラよりverilogの方が簡単でした。
次は何をやろうかな。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする