SharpKey Multi-HID Interface ファームウェアガイド

概要


後期ヴィンテージのSharpコンピュータには、キーボードに関する重大な問題があります。何らかの理由(紛失、保管中、またはコレクターによる購入)により、MZ-2500/2800/3500/X1/X68000マシンの大部分がキーボードなしで販売されています。ジョイスティックで'なんとか'使えるX68000を除き、キーボードなしではただのペーパーウェイトです。販売者はこれを知っており、販売されているものはGBP100〜200以上になることがあります。

resourcefulな日本のユーザー(classicpc.org、またはYoukan)と8bity.czのMartinは、一般的なPS/2またはUSB PCキーボードを変換してキーボードなしのSharpマシンで動作するインターフェースを開発しました。X1とX68000については概して完璧に動作し、プロフェッショナルな小型ケースに収められています。しかしMZ-2500のインターフェースにはいくつかの問題があります。特に利用可能な設計はST開発ボードに基づいており、ファームウェアはクローズドソースです。秋葉原での販売用にプロフェッショナルなアダプタとして作られましたが、現在は入手できないようです。私の場合、Webで入手できるMZ-2500インターフェースの開発バージョン(少なくとも私が組み立てたバージョン)は気まぐれで、MZ-2800では動作しません(一部の日本のコンタクトで確認)。改修中のMZ-2500/MZ-2800マシン(すべてキーボードなし)を完成させるために信頼性の高い動作ユニットが必要なため、他の選択肢を検討する必要がありました。
現在2台のMZ-2500マシンを改修中で、1台を保持予定です。またMZ-2800も改修中です。YoukanのDevelopmentボードベースのインターフェースの限界を考慮して、8bity.czのMartinが使用したKM24の小型ケースデバイスという物理的な形式を使用して独自の設計を行うことにしました。最初は、Sato Kyouchiの非常に信頼性の高いX1インターフェースに使用されているRenesas R8Cプロセッサを検討し、サポートハードウェアを追加して2 in 1デバイス(PS/2 → X1/MZ-2500/2800)を作成することを望んでいました。R8Cは素晴らしい小型MCUで作業とプログラムが容易ですが、この要件ではパフォーマンスの問題がありました。20MHzでも割り込みへの応答に1uSかかります。これはほとんどのアプリケーション(PS/2やX1キーボードプロトコルを含む)には問題ありませんが、MZ-2500には遅すぎました。

MZ-2500は、MZ-80Bとほぼ同じキーボードマトリクスを使用しており、2行追加され、メインユニットとキーボード間の4ビットバスでシリアライズされています。メインユニットは600nSで行を送信し、キーボードは2ニブル、300nSに一つのデータを返します。したがって、キーボードマトリクスの1行はキーボードからメインユニットまで1.2uSかかり、14行の密なループで繰り返されます。そのため、メインユニットが行を送信する(RTSN)のを検出して読み取り、この行のキーマトリクス値を600nS未満で検索できる必要があります。データはニブル(MPX)としてメインユニットに提示する必要があります。まず上位ニブルを300nS以内に、次に下位ニブルを次の300nS以内に。

MZ-2500/MZ-2800とのインターフェースの要件を理解するために、以下のセクションではハードウェアとそのプロトコルをより詳細に説明します。

MZ-2500 キーボードプロトコル

ハードウェアインターフェースは、シールドされた8ピンミニDINソケットとプラグを使用した7つの信号、5VとGNDで構成されています。

KeyboardPinout

RTSN、KD4、MPXはメインユニット側からの出力信号です。KD[3:0]はRTSNを使用してメインユニット制御下での方向を持つ双方向バスです。

信号 方向 論理状態 説明
RTSN
行ストローブ
メインユニット -> キーボード HIGH (‘1’) 行アドレスがメインユニットからキーボードに送信されています。
    LOW (‘0’) キーボードは4ビット双方向バスKD[3:0]で要求されたデータを送信しています。
KD4
タイプストローブ
メインユニット -> キーボード HIGH (‘1’) キーボードは行番号が参照する実際のキーマトリクスデータを返さなければなりません。
    LOW (‘0’) キーボードはすべてのキーの論理AND(D0 = ROW 0〜13のビット0のAND、D1 = ROW 0〜13のビット1のANDなど)を返さなければなりません。
MPX
ニブルMUXストローブ
メインユニット -> キーボード HIGH (‘1’) 要求されたROW(またはKD4が指示するANDされた行データ)の上位ニブルがキーボードからメインユニットに送信されます。
    LOW (‘0’) 下位ニブルが送信されます。
KD[3:0]
双方向バス
メインユニット -> キーボード   RTSN = HIGH (‘1’)の場合にアクティブ、キーボードマトリクスから行データの4ビット行番号を送信します。
  キーボード -> メインユニット   RTSN = LOW (‘0’)の場合にアクティブ、要求された行の8ビット列データの4ビットを送信します。


動作モードは主に2つあります。キー押下を待機している間に使用するすべて(STROBEALL)のキーテストモードと、押されたキーの位置を特定するためにすべての行を手動スキャンするモードです。

キーデータ取得のプロトコルは以下の通りです:

  1. RTSNがアクティブHIGHになり1.08usアクティブ状態を維持します。STROBEALLでキーを検出した後の最初のRTSN期間は1.08usアクティブHIGH、660nsインアクティブLOWです。その後は均一に660nsアクティブHIGH、680nsインアクティブLOWです。
  2. メインボードはキーボードにスキャン行を送信し、RTSNの立ち上がりエッジから160ns後に有効になります。
  3. スキャン行はKD[3:0]から残りの920nsでキーボードによって読み取られます。KD4の状態(または状態変化)はRTSNの立ち上がりエッジに先行します。
  4. KD4がサンプリングされ、LOWの場合は列ごとのすべてのキーの論理ANDが設定され、HIGHの場合は選択された行の実際の列が設定されます。
  5. RTSNの立ち下がりエッジで、MPXは320nsHIGHになり、MPXの立ち上がりエッジから20ns後にKD[3:0]上に上位ニブルが出力されます。データはMPXがLOWになるまでの残り300ns以内に読み取られます。MPXがLOWになると下位ニブルが同じ320nsタイミングで出力されます。320ns後にRTSNが再び立ち上がります。
  6. 上記はキーが押されている間繰り返されます。
  7. キーが押されていない場合はSTROBEALLモードに切り替えます。

STROBEALLモードのプロトコルは以下の通りです:

  1. STROBEALLモード中、KD4はLOWに保持されており、18.996msから198.83msの間で変化する20nsのグリッチを除いて状態は変化しません。このグリッチはハードウェアの見落としのように見えます。
  2. STROBEALLモード中、RTSNは均一な期間(660nsアクティブHIGH、660nsアクティブLOW)を持ちます。行は無視されます(意味のない定数値4を繰り返し続けます)。
  3. KD4がサンプリングされます。
  4. RTSNの立ち下がりエッジで、MPXは320nsHIGHになり、上位ニブルが出力されます。MPXがLOWになると下位ニブルが出力されます。320ns後にRTSNが再び立ち上がります。
  5. キーが押されている場合はキーデータ取得モードに切り替え、そうでなければ上記をループで繰り返します。

信号は以下のロジックアナライザ図で可視化できます:

MZ2500 Keyboard Protocol 1

非アクティブ中、メインボードのゲートアレイはSTROBEALLコマンドを送信します。これはKD4がLOWであることで認識されます。

MZ2500 Keyboard Protocol 2

STROBEALLでキーが押されたことが検出されると、KD4がHIGHになり、メインボードがキーを特定し始めます。Row 11から始まります(特殊キーCTRL、SHIFT、LOCK、KANA、GRAPHを含む)。

MZ2500 Keyboard Protocol 3

Row 11のスキャンはスイッチバウンスに対応するためだと思われる約30usの間行われます。

MZ2500 Keyboard Protocol 5

Row 11の調査後、Row 12(日本語変換キーを含む)に切り替わります。Row 12は約50usの間スキャンされます。

MZ2500 Keyboard Protocol 6

Row 11と12の調査後、Row 0から順次スキャンが開始されます。

MZ2500 Keyboard Protocol 4

順次スキャンは押されたキー(この場合はRow 4 Column 3の’C’)を見つけるまで続きます。キーバウンスを判定するために同じ行が600us以上スキャンされます。

MZ-2500が使用するハードウェアは以下の2つの回路で確認できます。

KeyboardHardware

この回路図はキーボード回路を表しており、ゲートアレイと双方向バッファで構成されています。

MainUnitKeyboardHardware

この回路図はメインユニット回路を表しており、Z-80B PIOに接続されたゲートアレイで構成されています。ゲートアレイはRow番号(0〜13)を送出し、キーボードから2ニブルで8ビットのデータブロックを受け取ります。

MZ-2800 キーボードプロトコル

MZ-2800はMZ-2500の後継機であり、8ビットZ80ベースのMZ-2500モードと16ビット80286モードが組み込まれています。MZ-2500と同様に、キーボードハードウェアインターフェースは7つの信号、5VとGNDで構成されていますが、旧式のAMP 9ピンUSBスタイルコネクタを使用しています。

MZ-2800マザーボードには標準的な9ピンヘッダがあり、AMP ソケットが取り付けられた娘基板に接続されています。ヴィンテージ機器を改造することを避けたいため代替品を探し(現在開発中で証明後にここに掲載します)、AMPコネクタと同じサイズのD-Subを使用した解決策を見つけました。これにより、オリジナルのMZ-2800キーボードを入手できた場合でも素早くAMPコネクタに戻せます。

信号の概要は以下のテーブルに示します。物理的にはMZ-2500と同一です。

RTSN、KD4、MPXはメインユニット側からの出力信号です。KD[3:0]はRTSNを使用してメインユニット制御下での方向を持つ双方向バスです。

信号 方向 論理状態 説明
RTSN
行ストローブ
メインユニット -> キーボード HIGH (‘1’) 行アドレスが送信されています。
    LOW (‘0’) キーボードがデータを送信しています。
KD4
タイプストローブ
メインユニット -> キーボード HIGH (‘1’) 実際のキーマトリクスデータを返す。
    LOW (‘0’) すべてのキーの論理ANDを返す。
MPX
ニブルMUXストローブ
メインユニット -> キーボード HIGH (‘1’) 上位ニブルを送信。
    LOW (‘0’) 下位ニブルを送信。
KD[3:0]
双方向バス
メインユニット -> キーボード   4ビット行番号を送信。
  キーボード -> メインユニット   8ビット列データの4ビットを送信。

MZ-2800のプロトコルはMZ-2500と同じ物理的な信号を共有しますが、主にタイミングが異なります。

STROBEALLとキーデータ取得の両モードの主要プロトコルは以下の通りです:

  1. RTSNがアクティブHIGHになり、メインボードがキーボードにスキャン行を送信します。
  2. KD4をサンプリングする前にRTSNがアクティブになってから少なくとも200ns待ちます。
  3. ROWを読み取る前に少なくとも650ns待ちます。
  4. スキャン行がKD[3:0]から読み取られます。
  5. KD4がサンプリングされます。
  6. RTSNがインアクティブLOWになるのを待ちます。
  7. MPX = HIGHの場合、上位ニブルが出力されます。MPX = LOWの場合、下位ニブルが出力されます。MPXはMZ-2500と同じ期間(640ns、320nsアクティブHIGH、320nsLOW)を持ちます。
  8. 上記が繰り返されます。

MZ2800 Keyboard Protocol 2

STROBEALLモード。メインボードはKD4をLOWに保持してキー押下を待機しています。

MZ2800 Keyboard Protocol 10

キーが押されると、KD4がHIGHになり、メインボードは列データを取得するために有効な行番号の送信を開始します。

Timing Key Read

RTSNがアクティブになってから行データが利用可能になるまでのタイミング遅延。

MZ2800 Keyboard Protocol 9

上の画像で順次スキャンが確認できます。

MZ2800 Keyboard Protocol 1

スキャンが押されたキー(’C’ - Row 4 Column 3)の行に達すると、デバウンスのために同じ行が100usの間読み取られます。

MZ2800 Keyboard Protocol 7

キーが押し続けられると、スキャンが2回目に押されたキーに到達すると300us以上スキャンします(上記の例ではキー’A’が押されています)。

MZ2800 Keyboard Protocol 6

キーが押されてから離される瞬間までの完全なサイクル。

MZ2800 Keyboard Protocol 4

MZ-2800キーボードとMZ-2500キーボードの違いの一つは14番目の行の追加です。MZ-2500モードのMZ-2800ではRow 14はスキャンされず、MZ-2800モードの場合にのみスキャンされます。

MZ-2800が使用するハードウェアは以下の2つの回路で確認できます。

KeyboardHardware

この回路図はキーボード回路を表しており、ゲートアレイと双方向バッファで構成されています。

MainUnitKeyboardHardware

この回路図はメインユニット回路を表しており、Z-80B PIOに接続されたゲートアレイで構成されています。Row番号(MZ-2500モードでは0〜13、MZ-2800モードでは0〜14)を送出し、2ニブルで8ビットのデータを受け取ります。


ESP-32S AI Thinker

要件をより深く理解した上で、R8Cに4ビットラッチと既に含まれている74LS257 2-1クワッドマルチプレクサを追加することを検討しました。これはRTSN信号に応答して行をラッチし、MPX制御下で2ニブルを出力するという問題の一部を解決しますが、利用可能なGPIOビット数(データ出力8、データ入力4、制御入力3)と割り込みレイテンシが仮想マトリクスからデータ出力タイミングを満たせないという欠点がありました。

評価ボードのいくつかを見ていると、Gowin G1WN-4NSR FPGAの使用を検討し始めました。有限状態機械を使用してハードウェアで行うため最良の解決策であり、ゲートレベルで作業することでMZ-2500のタイミング要件を満たすことの制限がなくなります。G1WN-4NSRはARM Cortex-M3も組み込んでおり、設定可能なマッピングに使用できました。残念ながらMacで動作する仮想Linuxマシンからデバイスをプログラムする際に多くの問題が発生し、ネイティブのMacサポートがないためこのアイデアを断念しなければなりませんでした。

数年前にEspressifのESP-8266をいじり、その32ビット製品のESP-32の開発を密接に追いかけていました。AI Thinker(ESP-32S WROOM)から2年前に5つのサンプルユニットを購入し、tranZPUterプロジェクトに使用しようとしていましたが、様々な理由でNXPのARM Cortex-M4を使用することになりました。ESP-32はこうして眠ったままでしたが、今こそ問題を探している解決策の場合が見つかりました:PS/2からMZ-2500へのインターフェース!データシートを掘り出して読み、PS/2ライブラリなどの利用可能なハードウェアとソフトウェアリソースおよびArduinoプラットフォームを通じた開発エコシステムを調べると、ESP-32はこのプロジェクトの要件に適しているように見えました。ArduinoをまずはじめてみましたがArduinoは制限であることが明らかになりました:MZ-2500側のインターフェースのために1つのCPUコアを専用にし、必要なタイミングを満たすためにもう1つのコアでPS/2キーボードをサービスする必要があります。ArduinoでFreeRTOSを設定してコアをデタッチする(FreeRTOSスピンロックを使用するかコア内の割り込みを無効にしてFreeRTOSがそのコアにタスクをスケジュールしないようにする)ことは容易にはできませんでした。解決策を長い時間探した末に、CMake/Ninjaビルドシステム下のFreeRTOSとEspressifの多数のサポートライブラリを使用するよりネイティブなFreeRTOS環境を使用することにしました。CMake/NinjaはLinuxカーネルビルド環境を含む過去に経験があったため、すぐに慣れてこの方向に進むことにしました。いくつかの設定の後、1つのコアがFreeRTOSから切り離され(スピンロックを使用)MZ-2500インターフェースを管理するための恒久的なタイトループを実行し、もう1つのコアがPS/2コードを読み込んで仮想マトリクスを組み立てます。この分析と調査の末、ESP-32Sデュアルコア SoCをEspressifの開発エコシステム下のFreeRTOSで使用することを決定しました。

次の決断は、インターフェースをどのように構築するかです。8bity.czのMartinのX68000インターフェースをいくつか構築した後すぐに明らかな解決策が見つかりました。KM-24ケース、小型でコンパクトで整然としています。ESP-32Sといくつかのコンポーネントを未使用のX68000ボードに仮組みしてみると、KM-24ケースに収まりそうでしたので、実際のプロトタイプ設計を始めました!

回路図

AI ThinkerのESP-32Sについて調べ、参照設計を出発点として潜在的な回路をまとめ、必要な変更を加えてプロトタイプを組み立て、テストし、2つのリビジョンを経て以下の最終的な回路に落ち着きました。

Schematic

この設計はESP-32S WROOMを中心に構成されています。これは動作に最小限のサポートコンポーネントしか必要としないデュアルコア240MHz WiFi/BT対応SoCです。

このデバイスは5V耐性がありますが3.3Vで動作します。そのため電源の明らかな選択肢は、tranZPUterに使用して在庫がたくさんあったAMS1117 3.3vコンバータでした。比較的効率が良く、約30mA(WiFiモードが有効な場合は150mA)で1.1vのみ降下し、安定した低リップル出力を供給します。通常の条件下では、デバイスはMZ-2500キーボードインターフェースから電源を供給されますが、プログラミングインターフェースに接続する必要がある場合もあります。MZ-2500とプログラミングインターフェースを同時に接続する「ミス」を避けるために、2つの電源を分離するための整流ダイオードが使用されています。また、開発やプロービング中に何か故障したりショートが発生した場合にMZ-2500を保護するためのヒューズも使用されています。

プログラミングインターフェースは非常にシンプルです(ここではARM Cortexの複雑なプログラミングはありません):3.3/5V UARTからの2本のシリアルワイヤ。Espressif IDBビルドとプログラミングシステムとシームレスに動作するために、自動ブートストラップ回路(Q1A/B)が追加されRTS/DTRで駆動されます。これにより、ビルドシステムがESP-32Sをプログラミングモードに配置し、プログラムしてからリセットを強制できます。非常に簡単な開発を実現します!

PS/2インターフェースはEspressifのソリューションで使用される標準的な設計です。I2Cに類似したプロトコルでPS/2キーボードを駆動する2本の双方向ピンです。ESP32は追加のトランジスタなしにPS/2仕様を満たすために十分な電流をシンク/ソースできます。

MZ-2500インターフェースのタイミングは時間的に重要で、2つのニブルを300ns離れて送信する必要があるため、MZ-2500の制御下で2-1マルチプレクサにESP32から1バイトを駆動する方が適切だと考えました。そのためタイミング要件が緩和されます。RTSN信号がHIGHになるのを検出すると、ESP32は行番号を読み込み、(入力PS/2キーから構築した)マトリクス値を検索してバイトをmuxに出力します。MZ-2500のすべての信号に電流を制限してラインリフレクションを減らすためにレジスタが追加されています。

ESP32の潜在的なパワーを考慮して、オンボードWiFiトランシーバーを有効にするための追加スイッチを追加しました。通常は電力節約と干渉防止のために電源オフにしますが、このデバイスをOTAで設定できるようにしたいと思っています。通常の状況では、設定されていないキーマッピングを見つけた場合は、ソースを編集して再コンパイルすれば簡単に修正できますが、Webブラウザからキーマッピングを変更できればいいですね。

このESP-32設計の素晴らしい点は、5本の双方向信号と1本の入力により異なるケーブルとファームウェアでX1やX68000などの他のマシンにも簡単に使用できることです。

インターフェースをMZ-2800用に構築する場合はケーブルの端が異なります。MZ-2500では8ピンミニDINですが、代替コネクタを使用したMZ-2800ではD-subコネクタになります。

PCB

設計した回路のプロトタイプを作成してその制御ソフトウェアの大部分を書いた後、PCBの設計に取り掛かりました。KM24ケースに収まるように小型でなければならず、コンポーネントの数とサイズを考えると、PCBの両面を使用する必要がありました。

PCB

製造に出た完成した回路基板。 PCB Top View PCB Bottom View

組み立て済みインターフェース

以下の写真は完成した、組み立て済みで動作するインターフェースを示しています。

1 インターフェースの上側。2mmピンヘッダなどのオプションコンポーネントがインストールされています。8ピンプログラミングインターフェースは必要ですが、9ピンMZ2500インターフェースヘッダはケーブルを基板に直接はんだ付けできます。通常の使用では必要ありません(DTR/RTS なしのUARTを使用する場合を除く)。

1 インターフェースの裏側。ESP32がほとんどのスペースを占めています。

1 KM-24ケース内への設置。タイトな収まりです。

1 ピンヘッダを使用することで、あらかじめ作られた8ピンミニDINケーブルを切り離せます(例えばMZ-2800ケーブルへの変更や、X1などの別のマシン用のファームウェア開発のため)。X1はGND、5V、1本の双方向ピンのみが必要なのでうまく機能します。

1 プログラミングハーネス。汎用のUSBからTTL UARTアダプタ、現在のキーマトリクスを出力するためのオプションのOLEDディスプレイ、インターフェースに接続するための2mmヘッダで構成されています。

1 1 完成品。MZ-2500で使用する準備が整いました。MZ-2800についてはインターフェースは動作しますが、奇妙なAMP 9ピンソケットはもはや入手できないため、非破壊的な解決策(例えばMZ-2800のソケットを8ピンミニDINに変更するなど)を考える必要があります。

1 開発中のMZ-2500に接続されたインターフェース。OLEDスクリーンは仮想キーマトリクスを表示するために使用されています。

1 MZ-2500に接続された完成したインターフェース。

組み立て済みMZ-2800インターフェース

先に示したようにMZ-2800はMZ-2500と同じハードウェアインターフェースを持つようですが、プロトコルとそのタイミングが異なります。MZ-2800はまた異なるキーボードプラグとソケットを使用しています。MZ-2500で選択された8ピンミニDINの代わりに、Sharpはより頑丈にするためにチャンキーなAMP 9ピンD-Subプラグとソケットを選択しました。残念ながら9ピン AMP D-SubはDodoの運命をたどり、少なくともすべての主要なベンダーやebayからはもはや入手できません。代替品の調達が必要でした。改造は選択肢ではありませんでした。

1 MZ-2800は9ピンAMPソケットを使用していますがもはや入手できないため、代替品を見つける必要がありました。JST XH2.50mm 9ウェイでメインボードの9ピンヘッダ(CN1)を交換することが解決策でした。これはAMPのコネクタのスペードターミナルがJSTの角型ピンターミナルに合うため、元のAMPソケットとも引き続き機能します。

1 様々なパーツカタログを調べると、3Mが製造する互換ソケットとプラグが見つかりました(10120-6000Lプラグと10220-5212PLソケット)。これらはMZ-2800のケーシングに取り付けるために正確なサイズの20ピンデバイスです。ソケットはJH 9ピンヘッダソケットに配線され、アセンブリがオリジナルと交換できるようになりました。

2 ソケットはケースに完璧に収まります。新しいソケットがネジ付きであったため、2つのネジでケースの壁に固定するだけの簡単な作業でした。

3 ケース外部のソケット。インターフェースとプラグを作成するだけです。

4 MZ25KEYインターフェース、短いリボンケーブル、IDCプラグを使用して、MZ-2800インターフェースが最終的に組み立てられました。インターフェースにロードされたファームウェアはMZ-2800固有のものです。

5 インターフェースの裏側。

6 蛇の頭を持つ一つ目のマウス?

7 テスト中。PS/2キーボードをインターフェースに接続し、インターフェースをMZ-2800に接続します。

8 完成!

ファームウェア

ファームウェアはgcc(++)、git、CMake、NinjaからなるEspressif IDBビルドシステムで書かれています。ビルドシステムはWindows、Linux、macOSで動作しますが、この場合はLinuxを使用しました。PS/2ライブラリはもともとArduino用に書かれていたため、Arduino互換コンポーネントがインストールされています。ファームウェアはCとC++の混合で書かれており、C++が主要な言語です。

ファームウェアのインストール

gitクローンを使用してソフトウェアリポジトリをコンピュータに取得します。

git clone https://git.eaw.app/eaw/mz25key.git

ビルドシステムのインストール

Espressif IDBビルドシステムを作成するには、Espressifのガイドに従ってください:

  1. python v3.7以降がインストールされていることを確認してください。インストールしたら「update-alternatives」を使用して最新バージョンをプライマリインタープリタとして選択します(一部のLinuxインストールでは古い汎用バージョンのPython 2.7がデフォルトになっています)。
  2. このガイドを使用してEspressifリポジトリをインストールします。「git clone」に「-b v4.4」フラグを使用してv4.4をインストールするか、クローン後に「git checkout」を使用してください。Arduino互換モジュールサポートにはv4.4が必要です。
  3. このガイドを使用してEspressif Arduino互換モジュールサポートをインストールします。

ファームウェアのコンパイル

gitからリポジトリを取得してEspressif IDBをインストールした後、プロジェクトを設定する必要があります。KConfigファイル「sdkconfig」はファームウェアに含まれていますが、一部のオプションを変更したい場合があります。これは次のコマンドで実行できます:

idf.py menuconfig

これにより、以下に示す一連のメニューが表示されます。

2

ルート画面ではEspressif IDBインストール、コンパイラ、ESP32、FreeRTOSの設定など様々な側面を設定できます。多くの設定を変更できますが、インターフェースについては「MZ25Key設定」オプションを選択してください。

3

PS/2キーボードインターフェース、MZ-2500/2800インターフェース、WiFi、デバッグオプションを設定できます。

4

PS/2設定では、インターフェースに使用するGPIOピンを設定できます。独自のボードを構築して異なるGPIOを使用した場合を除いて、変更する必要はありません。

5

PS/2メニューで選択するもう一つのオプションはキーボードマッピングのタイプです。現在のところWyse KB-3926キーボード用のマッピングのみがあります。

6

MZ-2500/2800インターフェースメニューでは、ターゲットマシン(MZ-2500またはMZ-2800)を選択し、ストローブ入力、スキャンデータ出力、RTSN/KDI4入力に使用するGPIOを設定できます。

7 8

9

WiFiメニュー(現在進行中)では、Wifiモジュールを有効にしてさまざまなデフォルトパラメータを設定できます。

10

デバッグメニューではさまざまなデバッグ補助を有効にできます。接続されている場合OLEDスクリーンはリアルタイムデータを出力するのに役立ちます。テスト用にインターフェースのさまざまなコンポーネントを無効にすることもできます。ESP32はデフォルトでシリアルポートからテキストメッセージを出力するため、USB to TTL UARTアダプタがプログラミングコネクタに接続されている場合、これらのメッセージを確認できます。

11

OLEDタイプを設定する必要があります。ハードウェアはI2Cインターフェースに対応し、解像度は128x64ピクセルです。

12 13

設定が完了したら、次のコマンドでテストビルドを実行します:

idf.py build

すべてが成功したら、USB to TTL UARTアダプタをコンピュータに接続して、mz25keyインターフェースのプログラミングコネクタに接続します。配線は以下の通りです:

13

/devでttyUSB*デバイスを探してUSB to TTL UARTアダプタのdevポートを取得します。通常は/dev/ttyUSB0です。次のコマンドでフルビルド、フラッシュ、モニタリングを実行します:

idf.py -p /dev/ttyUSB0 build flash monitor

システムはファームウェアをコンパイルし、mz25keyインターフェースにフラッシュして、出力されるメッセージを確認できるようにUARTモニタを実行します。例:

1 14 15

使用方法

キーボードはキーボードですよね?正確にはそうではありません。特に1つのキーボードが別のキーボードのふりをしている場合は!

PS/2キーボードはMZ-2500/MZ-2800の出現から数年後にIBM PCまたは互換機のために作られました。また私がアクセスできるキーボードは日本語PS/2ユニットではないため、いくつかの日本語固有のキーが欠けています。これにはマッピングが必要です。PS/2キーボードの未使用のキーを選択して、MZ-2500/MZ-2800キーボードの日本語キーのふりをさせます。

MZ-2500/MZ-2800マシンはオフィスクリーム色であるため、過去にWyseキーボードを使用した経験からWyse KB-3926クリームモデルをMZに最も合わせるために選択しました。MZ-2500、MZ-2800、Wyse KB-3926キーボードは以下に示されており、PS/2キーをMZ-2500キーにマッピングするマッピングテーブルも以下に示されています。

MZ-2500 Keyboard オリジナルのSharp MZ-2500キーボード。

MZ-2800 Keyboard オリジナルのSharp MZ-2800キーボード。

Wyse KB-3926 Keyboard Wyse KB-3926 PS/2キーボード。

マッピングテーブル

MZ-2500 キー MZ-2800 キー PS/2 キー 説明 PS/2 キーボード
LOCK LOCK* Caps Lock 大文字/小文字の切り替えとロック。一度押すと大文字にロック(LED点灯)、もう一度押すと小文字に戻ります。 Wyse KB-3926
HELP HELP* F11 HELP機能  
BREAK BREAK* Pause BREAKキー。PS/2は通常CTRL+BREAKでBREAKを生成しますが、MZ-2500はSHIFT+BREAKを必要とします。SHIFT+PAUSE(BREAKと同じキー)でMZ-2500のBREAKを作成するマッピングが作成されています。  
COPY COPY* F12 COPY機能  
CLR CLR* Shift+Home 画面クリア  
HOME HOME* Home カーソルを0,0位置(HOME)に設定。  
INST INST* Insert カーソル位置に文字を挿入。  
DEL DEL* Delete カーソル位置から文字を削除。  
ARGO ARGO Print Screen ARGO機能。例:BASIC v2でアプレットメニューを表示。  
GRAPH GRAPH Left GUI グラフィック文字入力に変更。  
Yen Yen |\ 円記号を挿入  
KANA KANA Right GUI KANA機能を選択。  
KJ1 Sentence KJ1 Sentence Left ALT KJ1機能  
KJ2 Transform KJ2 Transform Right ALT KJ2機能  
  PREVIOUS* PGDN 前のキー  
  CANCEL* Right CTRL キャンセルキー  
  SF1   特殊機能1 未マッピング
  SF2   特殊機能2 未マッピング
  SF3   特殊機能3 未マッピング
  SF4   特殊機能4 未マッピング

* = MZ-2800では日本語で表記。

その他のキーはPS/2キーボードの記号通りです。Num Lockキーはテンキーを数値とカーソル機能の間で切り替えます。

MZ-2500はMZ-2000とMZ-80Bをエミュレートでき、各マシンにはわずかに異なるマッピングがあります。MZ-2500キーボードがどのようにこれを処理したかは不明ですが、メインユニットのゲートアレイがモデルモードスイッチに応じてその場でマッピングを実行していると推測しています。これに対応するために、マッピングテーブルのコンポーネントとしてマシンモデルを追加しました。通常、キーはすべてのモデルに割り当てられますが、差異が発生した場合はそのモデルに応じてタグ付けされます。この機能を呼び出すには、使用したいマッピングのマシンに応じたキーの組み合わせを押す必要があります:

ホットキー モード
ALT+F1 MZ-2500キーボードマッピング
ALT+F2 MZ-2000キーボードマッピング
ALT+F3 MZ-80Bキーボードマッピング

電源投入時のデフォルトマッピングはMZ-2500に設定されています。

PS/2キーボードはMZ-2500/MZ-2800の電源が入った状態でインターフェースに接続/切断でき、インターフェースもMZ-2500/MZ-2800から切断できます。AMS1117-3.3のリザーバコンデンサは、キーボードが接続されたときの急激な電圧降下に対応するために必要以上に大きくなっています。ソフトウェアは毎秒キーボードの存在を確認し、取り外された場合はキーボードが再接続されることを見越して再初期化と確認を実行します。

Dockerによるビルド

ESP-IDFツールチェーンをネイティブにインストールする代わりに、Espressif公式のDockerイメージを使用する方法があります。Dockerのみのインストールで済み、ツールチェーン、コンパイラ、ビルドシステムのすべてがコンテナ内で実行されます。CI/CDや、ESP-IDFをシステム全体にインストールしたくない開発者に推奨される方法です。
# Install Docker if not already present
sudo apt update && sudo apt install -y docker.io
sudo systemctl enable docker && sudo systemctl start docker

# Clone the repository
git clone https://git.eaw.app/eaw/SharpKey.git
cd SharpKey
git submodule update --init --recursive

# Build the web filesystem
chmod +x build_webfs.sh && ./build_webfs.sh

# Build the firmware using the ESP-IDF v4.4 Docker container
docker run --rm -v $PWD:/project -w /project espressif/idf:v4.4 idf.py build

# Build output:
#   build/main.bin                         - Firmware binary (for OTA update)
#   build/filesys.bin                      - Web filesystem image (for OTA update)
#   build/bootloader/bootloader.bin        - Bootloader
#   build/partition_table/partition-table.bin - Partition table
#   build/ota_data_initial.bin             - OTA data partition
Dockerを使用してSharpKeyインターフェースにファームウェアを書き込むには(USB-to-TTL UARTアダプタの接続が必要です):
# Flash and monitor (requires USB device access)
docker run --rm --privileged \
    --volume /dev:/dev --volume /sys:/sys:ro --volume /dev/bus/usb:/dev/bus/usb \
    -v $PWD:/project -w /project \
    espressif/idf:v4.4 \
    idf.py -p /dev/ttyUSB0 build flash monitor
利便性のために、Dockerコマンドを簡略化するシェルエイリアスを作成できます:
# Add to ~/.bashrc or ~/.zshrc
alias idf44='docker run --rm --privileged --volume /dev:/dev --volume /sys:/sys:ro \
    --volume /dev/bus/usb:/dev/bus/usb -v $PWD:/project -w /project -it \
    espressif/idf:v4.4 idf.py "$@"'

# Then use:
idf44 build
idf44 menuconfig
idf44 -p /dev/ttyUSB0 flash monitor

継続的インテグレーション(Jenkins)

CI/CDとは? 継続的インテグレーション(CI)とは、コード変更をプッシュするたびに専用サーバーが自動的にプロジェクトをビルドする手法です。ファームウェアを手動でコンパイルしてリリースファイルを手作業でアップロードする代わりに、CIサーバーがリポジトリをクローンし、ファームウェアをビルドし、リリース成果物をパッケージ化し、ダウンロードページに公開するまでをすべて自動で行います。ビルドが失敗した場合は、即座にメール通知が届きます。
SharpKeyプロジェクトでは、VPS上で動作するJenkinsを使用して、masterブランチへのプッシュごとにESP32ファームウェアを自動ビルドしています。ビルドには上述のEspressif Dockerイメージを使用するため、サーバーにネイティブのESP-IDFインストールは不要です。

動作の仕組み
  1. Giteaリポジトリのmasterブランチにコードをプッシュします。
  2. Giteaがwebhook(HTTP通知)をJenkinsサーバーに送信します。
  3. Jenkinsがリポジトリをクローンし、gitサブモジュールを初期化します。
  4. JenkinsがWebファイルシステムをビルドします(build_webfs.shを実行)。
  5. Jenkinsがファームウェアをビルドします(ESP-IDF Dockerコンテナを起動し、idf.py buildを実行)。
  6. Jenkinsが3つのリリース成果物をパッケージ化します:
    • SharpKey-FW-v*.bin.gz — Webインターフェース経由のOTAアップデート用ファームウェアバイナリ
    • SharpKey-FilePack-v*.bin.gz — OTAアップデート用Webファイルシステムイメージ
    • SharpKey-FlashPack-v*.tar.gz — esptool経由の新規書き込み用完全フラッシュイメージ(ブートローダー + パーティションテーブル + ファームウェア + ファイルシステム)
  7. JenkinsがGitea Releaseを作成し、成果物をダウンロード可能なアセットとして添付します。
  8. Jenkinsがメールを送信し、成功または失敗を報告します。

サーバーセットアップ
Jenkinsサーバーのセットアップは、FusionXプロジェクトと共通です。Docker、docker-compose.yml、初期設定、プラグインのインストールを含む完全なJenkinsインストール手順については、FusionX開発者ガイド — 継続的インテグレーションセクションを参照してください。
SharpKeyビルドに必要な追加要件は、Espressif IDF Dockerイメージのみです:
# Pull the ESP-IDF Docker image on the build server
docker pull espressif/idf:v4.4
Jenkinsのdocker-compose.ymlでは、パイプラインがESP-IDFコンテナを兄弟コンテナとして起動できるよう、Dockerソケットをマウントする必要があります:
volumes:
  - /srv/jenkins/data:/var/jenkins_home
  - /var/run/docker.sock:/var/run/docker.sock    # Required for ESP-IDF sibling container

パイプラインステージ
Jenkinsパイプライン(sharpkey-build.groovy)は以下のステージを実行します:
  1. Checkout: リポジトリをクローンし、gitサブモジュール(arduino-esp32、esp_littlefs)を初期化します。
  2. Determine Version: version.txtを読み取るか、最新のGiteaリリースタグから自動インクリメントします。
  3. Build Web Filesystem: build_webfs.shを実行し、HTML、CSS、JavaScriptをWebファイルシステムにパッケージ化します。
  4. Build Firmware: espressif/idf:v4.4 Dockerコンテナを起動し、idf.py buildを実行します。
  5. Package Release: バージョン付きのファームウェア、ファイルシステム、フラッシュパックのtarballを作成します。
  6. Create Gitea Release: Giteaにタグ付きリリースを作成し、すべての成果物をアップロードします。

Gitea Webhook
Giteaリポジトリで、Settings → Webhooks → Add Webhook → Giteaに移動し、以下を設定します:
  • Target URL: http://your-server:8080/generic-webhook-trigger/invoke?token=sharpkey-build-trigger
  • Content Type: application/json
  • Trigger On: Push Events
保存後、masterにコミットをプッシュしてJenkinsを確認してください。新しいビルドが自動的に表示されるはずです。

WiFi

WiFi機能は現在開発中です。ほとんどのIoTデバイスと同様のWebベースのインターフェースを提供する予定です。WiFiボタンを1秒押すとWiFiが有効になり、10秒押すとアクセスポイントモードが有効になります。ユニットが設定されていない場合は最初のプレスでデフォルトのアクセスポイントモードが有効になります。

アクセスポイントモードにより、ユーザーがインターフェースにクライアントとして接続し、Webブラウザを起動してローカルWiFiルーターに接続するための認証情報を設定できます。

設定後、WiFiモードを有効にすると設定したローカルWifiネットワークに自動的に参加し、キーマップ設定のためのブラウザインターフェースを提供します。

無線規制に関する注意事項

本デバイスは 2.4 GHz ISM バンドで送信する事前認証済み ESP32-S 無線モジュール(AI Thinker)を搭載しており、世界各国の無線周波数規制(米国の FCC Part 15 Subpart C、欧州連合の無線機器指令 2014/53/EU を含む)において意図的放射器に該当します。
ESP32-S モジュールは無改造で使用されており、独自の規制認証(FCC、CE など)を取得しています。ただし、そのモジュールレベルの認証は、モジュールを組み込んだ完成品に自動的に適用されるものではありません。事前認証モジュールの免除規定は、個人の趣味愛好家個人使用、実験、または教育目的で少数のデバイスを製作する場合に、個別の機器認可を取得せずに行うことを許可するものです。
重要な制限事項
  • 組み立てられたデバイスは、完成品が独自にテストされ、該当する管轄区域で機器認可(例:FCC ID、認定機関による CE マーキング評価)を取得しない限り、第三者への販売、販売の申し出、贈与、またはその他の方法での配布を行ってはなりません
  • 個人使用のために少数を製作することは、趣味愛好家および実験使用の規定(例:FCC § 15.23)に基づき、デバイスが有害な干渉を引き起こさない限り、一般的に許可されています。
  • 規制要件は国によって異なります。米国外の製作者は、適用される規則について自国の無線周波数当局に確認してください。
製作者の責任
本設計に基づいて製作されたデバイスが、管轄区域内の適用されるすべての無線周波数規制に準拠することは、製作者の単独の責任です。著者は本設計を個人使用、教育、および趣味愛好家向けに提供しており、本設計から製作されたデバイスが商業的配布の規制要件を満たすことについて、いかなる表明も行いません。