CH559picoでTOYOSHIKI-BASIC
今年の目標の一つ
積んCPUを使ってみることにした。
2020年に買ったCH559pico を使ってみることにした。
CH559picoボード↓
CH559はざっくり8051core+USB I/F+Flash 60KB+RAM 6KBだ。
単体でBASIC 52が動きそうだ。
USB I/FがあるのでCDCクラスを実装すると、USBコネクタに刺すだけでお手軽BASIC マイコンになりそうだ。
昔、EZ-USBで遊んでいたときに、思いついたのだが、EZ-USBはメモリが少なくて実現出来なかった。
CH55xシリーズはarduinoIDEで開発できることがわかった。
しかも、CDCクラスのシリアルデバイスとして認識する。
何とお手軽
ここを参考にCH55xduinoをインストールし、blinkを書き込むとあっけなく動いた。
先達に感謝
arduinoでシリアルの入出力は、aerial.begin()で初期化してaerial.Read、Serial.write()でデータを送受信する。
USBSerialでは関数に先頭にUSBをつけてUSBSerial_Read()
Serial.Begin()での初期化は必要ない。
こんなスケッチを書いUSBシリアルのループバックテストをやってみた。
void setup() {
while (!USBSerial());
}
// the loop function runs over and over again forever
void loop() {
uint8_t c;
if (USBSerial_available()) {
c=USBSerial_read();
USBSerial_write('[');
USBSerial_write(c);
USBSerial_write(']');
}
}
1字づつ送受信出来ることが分かった。
大量のデータを転送するなら、パケットサイズを大きくして一度の転送で多くのデータを送受信した方が効率が良い。
今回は、BASICのコンソールに使うので、速度よりリアルタイム性が重要だ。BASIC52を実装する前に、
鈴木哲也氏の著書「タイニーBASICをCで書く」で、豊四季BASICがarduinoに実装されているのを思い出したので、これを動かしてみることにした。
arduino用の豊四季BASICはこのページ(https://vintagechips.wordpress.com/2015/12/06/豊四季タイニー BCbasic確定版 /)のリンクからダウンロードできる。
豊四季BASICは、c_getch, c_putch, c_kbhit, rand, を環境に合わせて実装すれば動くようになっている。
書籍では、Serial.read(), Serial.write(), Serial.available()を使う方法が説明されている。
今回は、USBシリアルを使用するので、
#define c_getch(c) USBSerial_read(c)
#define c_putch() USBSerial_write()
#define c_kbhit() USBSerial_available()
rand() はCH55xduinoのコンパイラsdccにもあるのでそのまま使える。
rand()に使用するシードの初期化は、randomseed()になるべくランダムな値を使用しする。
組み込み用のCPUではアナログポートから読み取った値を使う方法が紹介されている。
今回は、USBシリアルの初期化が終了した時刻を取得してシードとした。
randomseed(moicros());
arduinoIDEのシリアルの設定をCOMx(CH559picoが認識されているポート)にすると、シリアルモニタが使える。
arduino用豊四季BASICは、ttbasic.ino 内のloop() から、ttbasic.ccpのbasic() 関数を呼び出している。
arduinoIDEで検証(Check)すると、キャストのwarningが出るが、コンパイルできて、USB経由で書き込むことができる。
書き込むと自動的にリセットされて、バナーが表示されるはずだが、いくら待っても表示されない。
ENTERを連打すると、バナーが表示され、> OK がたくさん表示される。
コマンドを入力してもエコーバックされず、一定数キー入力するとまとめて入力されているようだ。
テストプログラムを書いて調べたら、
loop()の外でUSBSerial_read()を呼ぶと1文字づつ取得できないことが判った。
豊四季BASICはbasic()関数内の無限ループで、c_gets()で1行取得し、処理するようになっている。
c_gets()関数も、関数内のwhileループでENTERまで文字をバッファに格納するようになっている。
loop()関数の中なら1文字づつ取得できるので、basic()を初期化部、1行取得部、処理部に分けて、初期化部をsetup()に書いて、loop()内で1行取得して、BASICの処理部を呼ぶようにしたら、動くようになった。
ところが、INPUT A を実行しようとすると、1文字づつ取得できない。
調べてみると、INPUTコマンドで入力する数字を数値に変化する関数 getnum()のwhileループ内で文字入力していることが分かった。
c_gets(),getnum()で使用する文字入力でloop()を呼ぶようにすればよさそうだが、loop()関数内でarduinoの内部関数を呼んでいると良くないことが起こりそうだ、と考えソースを見てみたら、
main()関数の中の無限ループがloop()を呼ぶシンプル構成だった。
CH55xduinoの main()の部分
void main(void) {
init();
//!!!initVariant();
setup();
for (;;) {
loop();if (1) {
#ifndef USER_USB_RAM
USBSerial_flush();
#endif
// serialEvent();
}
}
// return 0;
}
よく見ると、無限ループの中でUSBSerial_refresh()
を実行していることを発見した。
どうやらこれが解決方法のようだ。
ということで、
c_gets(), getnum()の中のループから、USBSerial_flush()を実行するように書き換えたら動いた。
BASICが動くようになったらお約束の8queen問題を解くプログラムを書てみたら挙動がおかしい。
同じプログラムを豊四季BASIC linux版で動かしたら正常だった。
A=5, B=2, @(2)=3 のとき、A-@(B)の結果が 0 になっている。
つづく...
【最近の投稿】【最近のCPUボード】【最近のプログラミング】【2019の投稿】【2018の投稿】【2017の投稿】【2016の投稿】【2015の投稿】
最近のコメント