LPC

LPC810を使ったコンソール(技術編)

2015年1月20日

先日公開した、Console 810の技術的なことに関するノート。特徴は、以下の通り。

・NXPのDIP-8の石、LPC810を使用
・モニター出力はNTSCビデオ信号
・キー入力はPS/2キーボード
・9600 bpsでのシリアル入出力

もともと、LPC810を見たとき、こういったコンソールには最適だと思っていた。ピンの数は8本で、電源に2本、NTSCビデオ信号に2本、PS/2キーボードに2本、シリアル入出力に2本には、過不足無い。RAMが1024 bytesあるので、32x24文字のディスプレイなら可能であり、文字数も、まずまず許せる範囲。本当は、80x24文字の物を作りたいのであるが、それ用には、LPC812を使う必要があるだろう。

LPC810は、Switch Matrixと呼ばれる機能により、電源以外のピンを自由に配置することが出来る。この設定に関しては、GUIの、Switch Matrix toolというソフトウェアが用意されているので、このソフトウェアの利用が便利である(要Java)。デフォルトで幾つかのピンがGPIOになっていないなど、Switchi Matrixには幾つかはまりどころがあるので、こういったツールを利用するのが確実のように思った。以下は、このツールを用いてアサインしたピン配置図。
2015-01-20-Image1.png
この石は、5番ピンの扱い方がミソのようで、電源投入時やリセット時に、5番ピンの入力がHになるようにしておかないといけないらしい。今回のプロジェクトでは、PS/2キー入力用にプルアップしたラインを繋げた。

NTSCのビデオシグナルを作成する場合、同期信号として以下のような物を出力する必要がある(ソースコードの、ntsc.cより、修正して抜粋)。
/* Video sync signal construction
 * 1 line: 1524 (+/- 16) clocks (15748 Hz; 63.5 usec)
 *
 * line #0-#2
 *     ________    ________
 * |__|        |__|
 * 2.3 usec    2.3 usec 
 *
 *
 * line #3-#5
 *          ___         ___
 * |_______|   |_______|
 *          4.7 usec    4.7 usec
 *
 *
 * line #6-#8
 *     ________    ________
 * |__|        |__|
 * 2.3 usec    2.3 usec
 *
 *
 * line #9-#261
 *      ___________________
 * |___|
 * 4.7 usec
 *
 *
 * This must produces 16275 Hz sync signal.
 *
 */
これを作成するのに、SCTという機能を利用した。

SCT(State Configurable Timer)は、LPC810の目玉機能の一つで、PWMの高機能版と言ったところ。1回のサイクルでシグナルを2回H/Lしたり、何らかの入力でタイマーを停めたり再起動したり、色々なことが出来る。SCTに関して色々と遊んだ記事があるので、興味のある方はそちらをご覧頂きたい。SCTを制御するコードをすべて自分で書くのは、その高機能さのために非常に骨の折れる作業であり、私には無理である。幸いにして、開発環境のLPCEpressoには、"Red State Machine File Generator"というGUIのツールがあるので、これを利用してコードを作成するのが確実である。"Red State Machine File Generator"の使い方については、まとめた記事を以前書いたことがあるので、参照して頂きたい。Console 810では、次のチャートのように、作成してある。
2015-01-20-Image.png
タイマーは、16ビットの物を2つ利用した。一つ(L timer)には、PWMとしての機能を担わせてある。垂直同期信号部分(lines #0-8)に対応させるため、4つのマッチ(MATCH1-3とMATCH0)を用意し、信号をL→H→L→Hと変化させる。但し、最後のマッチ(MATCH0)では、タイマーをリセットするだけではなく、停止させている。その理由は次の通り。NTSC同期信号を作成するためには、デューティー比を決めるMATCH0-3の値をダイナミックに変化させなければならない。タイマーが作動中はMATCH値を変更することが出来ないようで、変更するためには停止しないといけないらしい。その為に、MATCH0ではタイマーをリセットと同時に停止し、かつ割り込みをかけ、割り込みルーチン中でMATCH値を書き換えるようにした。停止したタイマーを再起動させるために、もう一つのタイマー(H timer)を用いるようにした。このように、SCTの持つ機能を使い切ることで、NTSC同期信号をうまく作成することが出来た。

NTSCの文字描画のための信号作成には、SPIを用いている。経験的に、8ドット32文字で計256ドットを出力するには、6 MHzの周波数でシグナル送出するのがベストである。LPC810の内蔵オシレーターは12 MHzだから、6 MHzを作るのにはちょうど良い。2倍の24 MHzをシステムクロックとし、その4分の1の 6 MHzを、SPI用のクロックとした。ところで、NTSC信号一ラインは24 MHzで1524クロック(15748 Hz; 63.5 usec)にしてあるが、この1524という値が、4(「4分の1」という設定に由来)で割り切れることが必要である。4で割り切れない値に設定すると、画面が波打ってしまい(ジッター)、綺麗な表示にならない。

割り込みはSCTにだけ割り当てていて、SPI、UARTと、PS/2キーボード読み取りのためのGPIOには、割り込みを用いていない。UARTの処理は、NTSC信号の水平同期時(63.5 usecごと)に行なえば間に合う。SPIは、割り込みを使うと、割り込みルーチン前後のスタック動作に余分に時間がかかるため、使わないようにした。SPI信号出力時は、CPUはこの仕事に専念している。PS/2キーボード信号の読み取りは結構な速度で行なう必要があるが、幸いにしてキーボードに対してbusy信号を送ることが出来るので、忙しいとき(SPIに集中しないといけないとき)はキーボードからの信号を拒否するようにし、それほど忙しくないとき(垂直同期時)のみ信号を受け付けるようにして、対応した。

最後に、このコンソールには、NTSCビデオ信号とPS/2キーボードという、かなり古い技術を用いている。NTSCは、白黒に限っていえば60年以上前に定められた規格である。最新の機器ではHDMIが主流でありNTSC出力しない物も多くなっているものの、当面の間は、モニターの側でNTSCをサポートするものと思っている。加えて、NTSC→HDMI変換アダプターなどもあるので、10-20年ぐらいは、未だ使える技術ではなかろうか。反面、PS/2キーボードは、入手が難しくなってきている。これについては、USBキーボードに対応したものを作るか、USB→PS/2アダプターのようなものを別途作るかしないといけないかも知れない。ただ、USBホストを作るとなると水晶発振子が必須なので、どうしても回路が大きくなってしまう。今回のような回路構成で扱えるNTSCビデオやPS/2キーボードは、やはり面白いなと思うし、私としてはまだまだ使っていくことになるだろう。

Console 810のダウンロードは、ここから。
ソースコードの管理は、こちら。

コメント

imaki (2018年4月2日 17:40:39)

ブレッドボードで回路を組み、hexファイルを書き込み、101キーボードが動作する事が確認できました。簡単な回路でじつげんされており、とても素晴らしいです。ただ、106キーボードに対応させたいのですが、その\hexファイルの公開を是非ともお願いします。

imaki (2018年4月4日 04:25:25)

上記のhexファイルは、以前に見つけて保存していました。よって、公開は不要です。

Katsumi (2018年4月4日 13:22:16)

コメントをどうも有り難うございます。106キーボードで使用する需要が高まっているようです。ソースコードの若干の修正もありますので、時期配布ファイルでは、106用のhexファイルの公開も考えます。

imaki (2018年4月5日 04:45:42)

返信を有り難うございます。是非とも106用のファイル公開をよろしくお願いします。

Katsumi (2018年4月9日 11:59:31)

2018-04-09:バージョン 0.7を公開しました。106キーボード用のバイナリーも、同梱しました。
https://osdn.net/users/kmorimatsu/pf/console8xx/files/

SAITO (2021年2月28日 22:02:14)

あれから2年もたって、ブレッドボードで回路を組み、con810_070.zipをダウンロードして、添付のhexファイルを書き込み、106キーボードが動作する事が確認できました。しかし、readme.txtの通りLPCXpresso ver 6.1.0を用いてコンパイルをしても何度やってもMFlash4のオーバーフローエラーになってしまい、hexファイルが生成できません。LチカなどはOKです。どこがまずいのでしょうか?

Katsumi (2021年3月3日 10:34:18)

バイナリーが、フラッシュに収まらないというエラーですね。目的のCファイル以外に、余分なファイルがビルドする対象として、含まれてしまっていませんか?

SAITO (2021年3月7日 15:32:25)

ご教示ありがとうございます。チェックして見ます。
ところでLPC810のフラッシュ容量は4Kバイトと認識していますが、
添付のhexファイルcon810_106.hexは10Kバイトほどあります。
エラーにならないのはなぜでしょうか?

Katsumi (2021年3月8日 10:57:28)

hexファイルは、バイナリーではなくテキストファイルで、およそですが、44-45文字が16バイトに相当します。10K文字なら、4k バイト以下に収まる計算ですね。

SAITO (2021年3月9日 17:09:06)

ヘキサ情報をテキストで表現したファイルなんですね。
拡張子がhexなのでてっきりバイナリだと思っていました。
なお、お陰様でその後hexファイルが生成できました。
原因はDebug Buildになっていたことです。
Release Buildとの違いをよく理解していませんでした。
ご教示ありがとうございました。

Katsumi (2021年3月10日 11:12:16)

どういたしまして。うまく行って、良かったです。

コメント送信