Hello, FemtoRuby in Corne v4 Cherry
結構前に買ったキーボード corne v4 cherry を prk_firmware でうごかそうとして1年くらい放置してた。 そしたらいつのまにか deprecated になって picoruby-keyboard を利用することに なっていました。
Corne V4
prk_firmware をしばらく Corne V3 でつかってたのですが、 動いてる以上替える意味もなかったので替えていなかった。 いろいろと変更された Corne V4 になったときに変更をしようとしています。 この変更も Corne V4 自体がキー配線方式がマトリクス方式から ダイレクトピン方式に変更されてるためという事情もあります。
まずは prk_firmware で V4 を動かそうとします。 まあうごかないんですよ。理由は上記にあるダイレクトピン方式になったためですね。 でいろいろと試したんですが、左右通信が上手くいかず断念。 ということで1年ほど放置。
picoruby-keyboard
そしたら rubykaigi 2026 で prk_firmware 作者の @hasumikin にもうやってない。と告げられてそのかわり picoruby-keyboard でやってるという話になったのでそちらを利用することを決意。
まず picoruby-keyboard を picoruby のリリースページ からダウンロードしてきます。 ここでダウンロードのパッケージとして R2P2-FEMTORUBY と R2P2-PICORUBY の UF2 ファイルがあります。 R2P2 の説明はリンクにあります。 FEMTORUBY と PICORUBY の違いなのですが、Femto Ruby は mruby/c の VM 版だそうです。
どちらを利用するといい?という話になりますよね? これは picoruby-keyboard が利用できればどちらでもよいのですが、 今回の Corne V4 は RP2040 を搭載しています。 そのため対応する R2P2-FEMTORUBY-PICO を利用します。
ただ使っているモジュールが異なるので単純な比較はできないのですが、 picoruby 4.0.5 でのファイルサイズはそれぞれ FemtoRuby 版は 約1.4MB 、 PicoRuby 版は 約4.4MB となっています。 github にある Corne V4 Cherry の公式基板データ(基板上の表記はv4.1.0)を読むと、 128Mbit(16MiB)の外付けFLASHが搭載されているようです。 さらに実際に使用できる領域はファームウェアの構成によって異なります。
まずは Corne V4 にダウンロードしたファイルをインストールしましょう。 インストール自体は問題はなく、完了。 インストールがおわったら次に picoruby が動いてるかどうか確認しましょう。 PicoRuby Web Terminal を開いて R2P2 が動いてることを確認します。 確認できたらつぎはキー配列をキーボードへ送り込みます。 送り込むときは、 Open local file でキー配列を定義したrubyファイルを選択します。 選択したら Plain と Compile があるので Compile をクリックし、Upload でコンパイルされたキー配列 mrb ファイルを送り込みます。

trouble!!!
ここからが本題。 なにが問題だったかというと結局、この Femto Ruby にしても問題は変ってなく、 左右の通信が上手くいかなかったんですよ。 ということでここからは Codex を利用してトラブルシューティング。
HUMAN SIDE KANSO
まず今回の問題というか諦めかけてた問題は、左側をマスターとしたとき右側との通信が 上手くいっていないという問題でした。 といったけどこの時点ではそもそも通信できていないのか、片側が死んでいるのか判断は できていないです。なぜできないのかということを探ります。
まず、 そもそも app.mrb のキー配置が間違えていないかを疑ってみます。 そもそも V3 では Adafruit KB2040 を使っていたのでピン配列部分の移植に ミスがないかを確認。 また、上記で述べたとおり、配線方式が マトリクス方式 から ダイレクトピン方式 に変っているためそこも疑います。 がどうもそこらへんではないようです。
埒があかないので、 QMK Firmware から Corne V4 がどう使っているかの定義を Codex に見てもらうことに。 そしたら、いきなり Codex が「6個押せるようにPatchあてました」と言いだして なにか picoruby-keyboard のバグを修正してくれましたね。 バグがあったとは報告はきいたものの、この時点ではまだダウンロード版の FemtoRuby を利用してます。
このとき 6個同時押しのパッチを適用するため自前ビルドすることにしました。 自前でビルドした picoruby でいったん デバッグ 用ログを仕込むようにしてくれました。 出力されたログを見てわかったのは送ってはいるが受け取れてなさそうということ。 これにはボーレート(baud rate)が怪しそうという助言をもらったので変更。 状況はかわらず。関係はないことがわかる。
ここでハードウェア自体の故障疑惑が出てくるが、Codex はほぼないとのこと。 またうまくいかず。次に送っているデータの配列をログ化。 こわれてることは確認できたがよくわからないこわれかた。 とここでもういちど picoruby 側の実装を見てた Codex から 「内蔵 RP2040 の PIO クロックを止めてる」との報告が。 UART 通信を実現するために PIO を利用しているため、これが止まるとまずそう。 ということで picoruby 側を修正して、ようやく左右の通信を確認。 一件落着と。
AI SIDE KANSO
最初に確認する必要があったのは、「右側のキーが入力できない」という症状が、 どこで発生しているかでした。 キーの読み取り、左右間の通信、左側でのキー処理、USBへの出力と、 入力が届くまでにはいくつかの段階があります。 この時点では、右側が動いていないのか、通信だけが失敗しているのかは 判断できていませんでした。
まず QMK Firmware の定義を確認し、Corne V4.1 の各キーに対応する GPIOと、左右間の通信に使用するピンを調べました。 V3 のマトリクス方式とは異なり、V4.1 はダイレクトピン方式なので、 キーの読み取りもそれに合わせる必要があります。 また、左右の判定と、右側のキー位置を左側のキーマップへ対応させる処理も確認しました。
途中で追加した「6個のキーを同時押しできるパッチ」は、 左右間通信とは別の修正です。 今回使用した FemtoRuby のUSB HIDバインディングでは、 複数のキーコードをまとめて送るための変更が必要でした。 これは既存のパッチを見つけて適用したものではなく、 今回の作業で作成した変更でした。
左右間の通信については、右側の送信数と、左側の受信数、 さらに正常なパケットとして解釈できた数をログへ出しました。 右側ではキーを押すと状態が変わり、送信処理も進んでいました。 一方、左側ではデータを受信しても、正常なパケットとして扱えるものが ほとんどありませんでした。
ただし、送信数が増えているだけでは、正しい信号がピンから出ているとは限りません。 ボーレートを下げても改善しなかったため、速度だけでは説明できない状態でした。 ハードウェア故障も、この段階では完全には除外できませんでした。
そこで、同じ基板内で送信したデータを受信するループバックテストを行いました。 左右をつなぐケーブルを介さずに確認しても失敗したため、 まず PIO の送受信処理や、ファームウェア側を調べることにしました。
そこで見つかったのが、RP2040 の待機時のクロック設定でした。 今回の左右間通信は PIO で UART を実装していますが、 待機中にPIOのクロックが止まる設定になっていました。 そのため、CPUが待機に入ると、通信のタイミングも崩れてしまいます。
PIOのクロックを待機中も動かすよう修正すると、 ループバックテストで送信した8バイトが正しく受信できるようになりました。 その後、実際の左右間通信でも正常なパケットとキー状態の変化を確認し、 右側からの入力が通りました。 最終的には、ボーレート 9600 でも動作を確認できました。
yey yey vibe coding!!!
Corne V4 のファームウェアを picoruby に変えてみたのですが、 いろいろと大変でした。とはいえ何とかうごいたのでおわり
それとdiff https://github.com/katsyoshi/picoruby/commit/4aecb0d5338699748893234245fcf68636b7b6cc