<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>自作キーボード on 髭、はえ初めし頃。</title>
    <link>https://d3.haro.jp/tags/%E8%87%AA%E4%BD%9C%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89/</link>
    <description>Recent content in 自作キーボード on 髭、はえ初めし頃。</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>ja-jp</language>
    <lastBuildDate>Tue, 29 Sep 2026 20:00:00 +0900</lastBuildDate><atom:link href="https://d3.haro.jp/tags/%E8%87%AA%E4%BD%9C%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>TPS43 で円周スクロール（クルクル）を実装した</title>
      <link>https://d3.haro.jp/docs/2026/tps43-circular-scroll/</link>
      <pubDate>Tue, 29 Sep 2026 20:00:00 +0900</pubDate>
      
      <guid>https://d3.haro.jp/docs/2026/tps43-circular-scroll/</guid>
      <description><![CDATA[ <h1 id="tps43-で円周スクロールクルクルを実装した">
  TPS43 で円周スクロール（クルクル）を実装した
  <a class="anchor" href="#tps43-%e3%81%a7%e5%86%86%e5%91%a8%e3%82%b9%e3%82%af%e3%83%ad%e3%83%bc%e3%83%ab%e3%82%af%e3%83%ab%e3%82%af%e3%83%ab%e3%82%92%e5%ae%9f%e8%a3%85%e3%81%97%e3%81%9f">#</a>
</h1>
<p>実装だけじゃなく、ブログ記事まで Claude に手伝ってもらったよ。</p>
<h2 id="人間が書いた部分">
  人間が書いた部分
  <a class="anchor" href="#%e4%ba%ba%e9%96%93%e3%81%8c%e6%9b%b8%e3%81%84%e3%81%9f%e9%83%a8%e5%88%86">#</a>
</h2>
<p>Let&rsquo;s Note のタッチパッドのクルクルいいよねぇという X の投稿を見て、完全同意したので、TPS43 で実装の練習したら、2本指スクロールよりよっぽど使いやすかったので即採用。<br>
ソースコードは <a href="https://github.com/higemaru/vial-qmk/tree/vial/keyboards/kewbie/kewbie36tp_rev2_1" target="_blank" rel="noopener">GitHub においてる</a>
ので興味がある方はそちらを見ていただくとして、自分用メモとして、Claude に記事を書いてもらったよ。</p>
<p>調査、実装、ソースコードの精査・コメント、生成 AI がなかったら、途中でいやになってるよ、きっと。<br>
説明用ブログ記事も、ワシが書くより読みやすい記事書いてくれそうなので、以下、全部 Claude です。</p>
<hr>
<p>Kewbie36tp に載せている角型トラックパッド TPS43 で、指で円を描くとスクロールする「円周スクロール」を実装した。iPod のクリックホイールみたいに、クルクル回すとページが流れていくアレ。</p>
<p>思った以上に快適で、今ではすっかり手放せなくなっている。</p>
<!-- TODO: 動作の GIF / 動画 -->
<h2 id="きっかけ">
  きっかけ
  <a class="anchor" href="#%e3%81%8d%e3%81%a3%e3%81%8b%e3%81%91">#</a>
</h2>
<p>最初は丸いタッチパッドが欲しかった。Cirque の円形トラックパッド（TM040040 など）は QMK が標準で円周スクロールに対応していて、外周をなぞると縦・横スクロールになる。</p>
<p>ただ、国内だと入手しづらい。Mouser では I2C 版の取り扱いがなく、SPI 版を買って抵抗を外す必要がある。送料も考えると、ちょっと試すには敷居が高い。</p>
<p>そこで発想を変えて、<strong>手持ちの TPS43 で同じことをやる</strong>ことにした。サイズは 43×40mm で、短辺いっぱいに円を取れば Cirque 40mm とほぼ同じ感覚になるはず。</p>
<h2 id="仕組み">
  仕組み
  <a class="anchor" href="#%e4%bb%95%e7%b5%84%e3%81%bf">#</a>
</h2>
<h3 id="なぜ絶対座標が要るのか">
  なぜ絶対座標が要るのか
  <a class="anchor" href="#%e3%81%aa%e3%81%9c%e7%b5%b6%e5%af%be%e5%ba%a7%e6%a8%99%e3%81%8c%e8%a6%81%e3%82%8b%e3%81%ae%e3%81%8b">#</a>
</h3>
<p>普段のカーソル移動に使っているのは<strong>相対座標</strong>、つまり「前回からどっちにどれだけ動いたか」だけ。これだけでは円周スクロールはできない。</p>
<p>たとえば「指が右に動いた」という情報だけだと、</p>
<ul>
<li>円の<strong>上側</strong>で右に動いたなら<strong>時計回り</strong></li>
<li>円の<strong>下側</strong>で右に動いたなら<strong>反時計回り</strong></li>
</ul>
<p>と、指がパッドのどこにいるかで意味が逆になる。回転の向きを決めるには、「中心から見て指がどの方向にいるか」、つまり<strong>絶対座標</strong>が必要になる。</p>
<p>相対座標を足し合わせて位置を推測する手もなくはないけど、触り始めた位置がわからないので、どこが中心なのか決められない。外周から触り始めたら円周スクロールにする <code>TP_RING</code> モードも、触った場所そのものがわからないと判定できない。</p>
<h3 id="qmk-の-azoteq-ドライバは絶対座標を捨てている">
  QMK の Azoteq ドライバは絶対座標を捨てている
  <a class="anchor" href="#qmk-%e3%81%ae-azoteq-%e3%83%89%e3%83%a9%e3%82%a4%e3%83%90%e3%81%af%e7%b5%b6%e5%af%be%e5%ba%a7%e6%a8%99%e3%82%92%e6%8d%a8%e3%81%a6%e3%81%a6%e3%81%84%e3%82%8b">#</a>
</h3>
<p>TPS43 に載っている IQS572 は、指の絶対座標をレジスタに持っている。ところが QMK 標準の <code>azoteq_iqs5xx</code> ドライバは、<code>0x000C</code> から 10 バイトだけ読んで通信を終えていて、相対移動量しか使っていない。</p>
<table>
	<thead>
			<tr>
					<th>アドレス</th>
					<th>中身</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>0x000C</td>
					<td>前回の処理時間</td>
			</tr>
			<tr>
					<td>0x000D–0E</td>
					<td>ジェスチャー</td>
			</tr>
			<tr>
					<td>0x000F–10</td>
					<td>システム情報</td>
			</tr>
			<tr>
					<td>0x0011</td>
					<td>指の本数</td>
			</tr>
			<tr>
					<td>0x0012–15</td>
					<td>相対 X / Y</td>
			</tr>
			<tr>
					<td><strong>0x0016–19</strong></td>
					<td><strong>1本目の指の絶対 X / Y</strong></td>
			</tr>
	</tbody>
</table>
<p>絶対座標はそのすぐ後ろにある。これは Linux カーネルの <code>drivers/input/touchscreen/iqs5xx.c</code> で確認した。Linux のドライバは <code>0x000F</code> から構造体ひとつぶんをまとめて読んでいて、その構造体の並び（<code>__packed</code> なので隙間なし）を先頭から数えると、1本目の指の絶対座標が <code>0x0016–19</code> にあるとわかる。QMK が読んでいる <code>0x000F–15</code> の部分（指の本数・相対移動量）は、Linux の構造体とも一致する。</p>
<p>じゃあ <code>0x0016</code> を別に読めばいいかというと、そうもいかない。IQS5xx は計測が終わるたびに通信を受け付けて、<code>0xEEEE</code> に書き込むと通信を閉じて次の計測に入る。QMK のドライバは 10 バイト読んだ直後に自分で通信を閉じてしまうので、同じ計測のデータを追加で読む隙がない。次の周期に <code>0x0016</code> から読むことはできるけど、それだと相対移動量と絶対座標が<strong>別の計測のデータ</strong>になってしまうし、1回ぶんのデータをそろえるのに2周期かかる。</p>
<p>なので、<strong>QMK の読み始め（<code>0x000C</code>）から <code>0x0019</code> まで、14 バイトを1回の通信でまとめて読む</strong>のが正解。ところが QMK のドライバは読み出しが 10 バイト固定で、設定では変えられない。QMK 本体を書き換えずに済ませるため、読み出し部分を自前で書くことにした。</p>
<h3 id="自前ドライバにした">
  自前ドライバにした
  <a class="anchor" href="#%e8%87%aa%e5%89%8d%e3%83%89%e3%83%a9%e3%82%a4%e3%83%90%e3%81%ab%e3%81%97%e3%81%9f">#</a>
</h3>
<p>最初は QMK の Azoteq ドライバの関数を呼んで初期化だけ任せようとしたけど、vial-qmk のバージョンによって関数の戻り値やマクロの有無が違っていて、リンクエラーやコンパイルエラーが続いた。最終的に、初期化も含めて <code>POINTING_DEVICE_DRIVER = custom</code> の自前ドライバにした。中身は QMK のドライバの手順を移植したもので、<code>AZOTEQ_IQS5XX_*</code> の設定はそのまま使える。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span><span style="color:#75715e"># rules.mk
</span></span></span><span style="display:flex;"><span>POINTING_DEVICE_ENABLE <span style="color:#f92672">=</span> yes
</span></span><span style="display:flex;"><span>POINTING_DEVICE_DRIVER <span style="color:#f92672">=</span> custom
</span></span><span style="display:flex;"><span>I2C_DRIVER_REQUIRED <span style="color:#f92672">=</span> yes
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>SRC <span style="color:#f92672">+=</span> tps43_driver.c tp_circular.c
</span></span></code></pre></div><h3 id="角度の変化をスクロール量にする">
  角度の変化をスクロール量にする
  <a class="anchor" href="#%e8%a7%92%e5%ba%a6%e3%81%ae%e5%a4%89%e5%8c%96%e3%82%92%e3%82%b9%e3%82%af%e3%83%ad%e3%83%bc%e3%83%ab%e9%87%8f%e3%81%ab%e3%81%99%e3%82%8b">#</a>
</h3>
<p>やっていることは単純で、パッドの中心からの角度を毎フレーム求めて、前回との差 × 半径（＝弧の長さ）をスクロール量にしているだけ。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">// 画面座標系（Y が下向き）では、atan2 の増加方向が時計回りになる
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">float</span> angle <span style="color:#f92672">=</span> <span style="color:#a6e22e">atan2f</span>(dy, dx);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">float</span> d <span style="color:#f92672">=</span> angle <span style="color:#f92672">-</span> g_prev_angle;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (d <span style="color:#f92672">&gt;</span> (<span style="color:#66d9ef">float</span>)M_PI) d <span style="color:#f92672">-=</span> <span style="color:#ae81ff">2.0f</span> <span style="color:#f92672">*</span> (<span style="color:#66d9ef">float</span>)M_PI;   <span style="color:#75715e">// ±180度をまたいだとき
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (d <span style="color:#f92672">&lt;</span> <span style="color:#f92672">-</span>(<span style="color:#66d9ef">float</span>)M_PI) d <span style="color:#f92672">+=</span> <span style="color:#ae81ff">2.0f</span> <span style="color:#f92672">*</span> (<span style="color:#66d9ef">float</span>)M_PI;
</span></span><span style="display:flex;"><span>g_prev_angle <span style="color:#f92672">=</span> angle;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 弧の長さ → チップの2本指スクロールと同じ単位にそろえる
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">float</span> arc <span style="color:#f92672">=</span> d <span style="color:#f92672">*</span> r <span style="color:#f92672">*</span> g_res_x <span style="color:#f92672">/</span> PAD_W_001MM <span style="color:#f92672">+</span> g_remainder;
</span></span></code></pre></div><p>ポイントはいくつか。</p>
<ul>
<li><strong>X と Y で解像度が違う</strong>（2048×1792）ので、いったん mm 単位にそろえてから角度と半径を計算する</li>
<li><strong>中心付近は無視</strong>する。中心に近いと少し動いただけで角度が大きく変わって暴れるため</li>
<li><strong>端数は繰り越す</strong>。ゆっくり回したときに、スクロールが出ずに消えてしまうのを防ぐ</li>
<li>単位をチップの2本指スクロールにそろえたので、<strong>既存のスクロール速度設定や慣性スクロールがそのまま効く</strong>。回してから指を離すと、惰性でしばらく回り続ける</li>
</ul>
<p>判定ロジックは QMK に依存しない形で <code>tp_circular.c</code> に切り出してあって、PC 上の gcc で単体テストしながら作った。絶対座標が取れるパッドなら、TPS43 以外でもそのまま使えるはず。</p>
<h2 id="モードを-vial-で切り替える">
  モードを Vial で切り替える
  <a class="anchor" href="#%e3%83%a2%e3%83%bc%e3%83%89%e3%82%92-vial-%e3%81%a7%e5%88%87%e3%82%8a%e6%9b%bf%e3%81%88%e3%82%8b">#</a>
</h2>
<p>使っているうちに欲が出て、モードを3つ用意した。</p>
<table>
	<thead>
			<tr>
					<th>キーコード</th>
					<th>動き</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>TP_RING</code></td>
					<td>外周から触り始めたら円周スクロール、内側はカーソル</td>
			</tr>
			<tr>
					<td><code>TP_CIRC</code></td>
					<td>どこから触っても円周スクロール</td>
			</tr>
			<tr>
					<td><code>TP_DRAG</code></td>
					<td>動かした方向に縦横スクロール</td>
			</tr>
	</tbody>
</table>
<p>切り替えは <strong>Vial 上でタッチパッドを1つのキーとして扱う</strong>形にした。マトリクスの空き位置をタッチパッドの「仮想キー」にして、レイヤーごとにそこへモードのキーコードを置く。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">uint8_t</span> <span style="color:#a6e22e">tp_requested_mode</span>(<span style="color:#66d9ef">void</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (g_mode_key_held <span style="color:#f92672">!=</span> KC_NO) {   <span style="color:#75715e">// 実キーに置いた場合は押している間
</span></span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">mode_from_keycode</span>(g_mode_key_held);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#66d9ef">keypos_t</span> pos   <span style="color:#f92672">=</span> {.row <span style="color:#f92672">=</span> TP_VKEY_ROW, .col <span style="color:#f92672">=</span> TP_VKEY_COL};
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#66d9ef">uint8_t</span>  layer <span style="color:#f92672">=</span> <span style="color:#a6e22e">layer_switch_get_layer</span>(pos);   <span style="color:#75715e">// KC_TRNS も解決してくれる
</span></span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">mode_from_keycode</span>(<span style="color:#a6e22e">keymap_key_to_keycode</span>(layer, pos));
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>今の設定はこんな感じ。</p>
<ul>
<li>レイヤー0：カーソル（または <code>TP_RING</code>）</li>
<li>左親指のレイヤー1：<code>TP_CIRC</code></li>
<li>右親指のレイヤー2：<code>TP_DRAG</code></li>
</ul>
<p>親指キーを押しながらパッドに触れると、そのモードで動く。<strong>一度始まったら、キーを離しても指を離すまで続く</strong>ようにしたのが地味に効いていて、回し始めたら親指は自由にしておける。</p>
<!-- TODO: Vial の画面キャプチャ -->
<h2 id="つまずいたところ">
  つまずいたところ
  <a class="anchor" href="#%e3%81%a4%e3%81%be%e3%81%9a%e3%81%84%e3%81%9f%e3%81%a8%e3%81%93%e3%82%8d">#</a>
</h2>
<h3 id="2本指で回す方式は失敗">
  2本指で回す方式は失敗
  <a class="anchor" href="#2%e6%9c%ac%e6%8c%87%e3%81%a7%e5%9b%9e%e3%81%99%e6%96%b9%e5%bc%8f%e3%81%af%e5%a4%b1%e6%95%97">#</a>
</h3>
<p>カーソル移動と円周スクロールの誤爆を減らそうと、「1本指はカーソル、2本指をそろえて回すとスクロール」も試した。2本目の指の座標も読んで、中間点の角度を見る方式。</p>
<p>これは失敗だった。43×40mm のパッドでは2本指で回すには狭すぎて、スクロールに入らなかったり、途中で片方の指が浮いて2本指タップ（右クリック）と誤認識されたりした。結局、キーとの組み合わせで切り替える今の形に落ち着いた。</p>
<h3 id="横スクロールの向き">
  横スクロールの向き
  <a class="anchor" href="#%e6%a8%aa%e3%82%b9%e3%82%af%e3%83%ad%e3%83%bc%e3%83%ab%e3%81%ae%e5%90%91%e3%81%8d">#</a>
</h3>
<p>縦横スクロール（<code>TP_DRAG</code>）を作ったら、縦と横で向きの感覚が逆になった。HID のホイールは「縦は正が上、横は正が右」なので、指の移動量をそのまま入れると、縦は指にコンテンツがついてくる向き、横は逆向きになる。横の符号を反転してそろえた。</p>
<h3 id="rdy-ピンを見て読むようにした">
  RDY ピンを見て読むようにした
  <a class="anchor" href="#rdy-%e3%83%94%e3%83%b3%e3%82%92%e8%a6%8b%e3%81%a6%e8%aa%ad%e3%82%80%e3%82%88%e3%81%86%e3%81%ab%e3%81%97%e3%81%9f">#</a>
</h3>
<p>IQS572 は 10ms ごとに計測していて、計測中に話しかけると、終わるまで I2C のクロックを止めてマイコンを待たせる（クロックストレッチ）。QMK は1本の処理ループでキーの読み取りもしているので、その間はキーの読み取りも止まってしまう。</p>
<p>TPS43 の RDY ピン（計測が終わると High になる）を見て、<strong>High のときだけ読む</strong>ようにした。待たされることがなくなるので、キー入力への影響を小さくできる。</p>
<h2 id="おまけvial-qmk-を久々に更新したら-tap-hold-が変わった">
  おまけ：vial-qmk を久々に更新したら Tap-Hold が変わった
  <a class="anchor" href="#%e3%81%8a%e3%81%be%e3%81%91vial-qmk-%e3%82%92%e4%b9%85%e3%80%85%e3%81%ab%e6%9b%b4%e6%96%b0%e3%81%97%e3%81%9f%e3%82%89-tap-hold-%e3%81%8c%e5%a4%89%e3%82%8f%e3%81%a3%e3%81%9f">#</a>
</h2>
<p>今回、vial-qmk を長いこと更新していなかったので、ついでに本家に追従した。すると、<code>LT(1, KC_SPC)</code> や <code>LGUI_T(KC_TAB)</code> のようなタップとホールドを兼ねるキーで、Cmd+C が Tab → C に、Shift+A が z → a になる誤判定が増えた。</p>
<p>最初はトラックパッドの通信を疑って色々試したけど、結論としては Tap-Hold の設定だった。</p>
<ul>
<li>長期間の更新で、QMK の Tap-Hold 判定の中身がかなり変わっていた</li>
<li><strong>Vial は新しいファームを書き込むたびに、キーマップと QMK Settings を既定値に戻す</strong>（ビルドごとにランダムな ID が埋め込まれていて、それが変わると EEPROM を初期化する）</li>
</ul>
<p>2つ目を知らずに、テスト用のファームを書き込むたびに Permissive Hold が無効に戻っていて、しばらく原因を見誤っていた。今は、EEPROM が初期化されたときに Permissive Hold を有効にするようにファームに仕込んである。</p>
<p>Vial でキーマップをいじっている人は、書き込む前に「File → Save current layout」で <code>.vil</code> に保存しておくのがおすすめ。</p>
<h2 id="コード">
  コード
  <a class="anchor" href="#%e3%82%b3%e3%83%bc%e3%83%89">#</a>
</h2>
<!-- TODO: GitHub のリンク -->
<p>ファイルごとの役割はこんな感じ。上の2つがトラックパッドまわりの中心で、下の2つはキーボード固有の部分。</p>
<pre tabindex="0"><code>tps43_driver.c   … TPS43 と話す（読む・初期化する・モードに振り分ける）
tp_circular.c/h  … 座標から円周スクロール量を計算する（ハード非依存）
config.h         … ピン配置と、各種しきい値の設定
kewbie36tp.c     … モードを決めるキーコードと、慣性スクロールなど
</code></pre><h3 id="tps43_driverctps43-のドライバ">
  tps43_driver.c：TPS43 のドライバ
  <a class="anchor" href="#tps43_driverctps43-%e3%81%ae%e3%83%89%e3%83%a9%e3%82%a4%e3%83%90">#</a>
</h3>
<p>QMK の <code>POINTING_DEVICE_DRIVER = custom</code> として動く、TPS43 専用のドライバ。</p>
<ul>
<li><strong>初期化</strong>：リセット、計測周期（10ms）、ジェスチャー（タップ・2本指タップなど）、回転の設定。QMK の Azoteq ドライバの手順を移植したもので、<code>AZOTEQ_IQS5XX_*</code> の設定がそのまま効く</li>
<li><strong>読み出し</strong>：RDY ピンが High のときだけ、<code>0x000C</code> から 14 バイトを1回で読む。相対移動量と絶対座標を同時に取る</li>
<li><strong>振り分け</strong>：今のモードを見て、カーソル移動・円周スクロール・縦横スクロールのどれとして HID レポートを作るか決める</li>
</ul>
<p>ハードに依存する処理は全部ここに集めてある。別のトラックパッドに移植するなら、書き直すのはこのファイルだけ。</p>
<h3 id="tp_circularc--tp_circularh円周スクロールの計算">
  tp_circular.c / tp_circular.h：円周スクロールの計算
  <a class="anchor" href="#tp_circularc--tp_circularh%e5%86%86%e5%91%a8%e3%82%b9%e3%82%af%e3%83%ad%e3%83%bc%e3%83%ab%e3%81%ae%e8%a8%88%e7%ae%97">#</a>
</h3>
<p>指の本数と絶対座標を受け取って、「中心の周りをどれだけ回ったか」をスクロール量として返す。QMK には依存していないので、PC の gcc でそのまま単体テストできる。</p>
<ul>
<li>絶対座標を mm に換算して、中心からの距離と角度を求める</li>
<li>前回との角度差 × 半径（弧の長さ）をスクロール量にする。端数は次回に繰り越す</li>
<li>開始の条件（外周から触り始めたとき／どこからでも）を呼び出し側が指定できる</li>
<li>一度始まったら、指を全部離すまで続く</li>
</ul>
<p><code>tp_circular.h</code> には、パッドの寸法や判定のしきい値の既定値と説明をまとめてある。</p>
<h3 id="configh設定">
  config.h：設定
  <a class="anchor" href="#configh%e8%a8%ad%e5%ae%9a">#</a>
</h3>
<p>キーボード側で変えたい値はここに置く。円周スクロールに関係するのはこのあたり。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#define TPS43_RDY_PIN GP21                  </span><span style="color:#75715e">// RDY を見て読む（外すと従来の固定間隔で読む）
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#define POINTING_DEVICE_TASK_THROTTLE_MS 1  </span><span style="color:#75715e">// RDY を 1ms ごとに確認
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#define TP_CIRC_DIAMETER_MM 38   </span><span style="color:#75715e">// 回転の基準円の直径
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#define TP_CIRC_RING_PCT    70   </span><span style="color:#75715e">// TP_RING：半径の 70% より外で触り始めたら円周スクロール
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">/* #define TP_CIRC_INVERT 1 */</span>   <span style="color:#75715e">// 回転方向を逆にする
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">/* #define TP_CIRC_DEBUG */</span>      <span style="color:#75715e">// 座標をコンソールに出す
</span></span></span></code></pre></div><p>外周リングの幅や回転方向は、実機で触りながらここで調整する。</p>
<h3 id="kewbie36tpcキーボード側の処理">
  kewbie36tp.c：キーボード側の処理
  <a class="anchor" href="#kewbie36tpc%e3%82%ad%e3%83%bc%e3%83%9c%e3%83%bc%e3%83%89%e5%81%b4%e3%81%ae%e5%87%a6%e7%90%86">#</a>
</h3>
<ul>
<li><code>TP_CIRC</code> / <code>TP_DRAG</code> / <code>TP_RING</code> のキーコード処理と、タッチパッドの仮想キーからモードを決める <code>tp_requested_mode()</code></li>
<li>スクロール速度・カーソル速度・慣性スクロールなど、以前から入れていた処理（円周スクロールにもそのまま効く）</li>
<li>EEPROM 初期化時に Permissive Hold を有効にする処理</li>
<li>起動時に TPS43 の RST（GP20）へリセットパルスを入れる処理。マイコンだけがリセットされたとき（書き込み直後など）に、TPS43 が I2C の途中状態で固まっているのを確実に戻す</li>
</ul>
<p>初期化部分は QMK の Azoteq ドライバを移植しているので、ライセンスは GPL-2.0-or-later。</p>
<h2 id="次にやりたいこと">
  次にやりたいこと
  <a class="anchor" href="#%e6%ac%a1%e3%81%ab%e3%82%84%e3%82%8a%e3%81%9f%e3%81%84%e3%81%93%e3%81%a8">#</a>
</h2>
<p>クルクルに合わせて「カチッ」と振動が返ってきたら、もっと気持ちいいはず。LRA（リニア振動モーター）と DRV2605L を使えば QMK から鳴らせるので、次に基板を作り直すときに載せてみたい。厚みが増えるのが悩みどころ。</p>]]></description>
    </item>
    
  </channel>
</rss>
