Mitosis 是一款使用 QMK 作為韌體所開發的無線分離式鍵盤,它不僅僅是與電腦之間無線,它的左右兩部分之間也沒有實體連線,可謂是「真 • 無線」。就我所知,有許多基於 QMK 的無線分離式鍵盤都是受到 Mitosis 的啓發。
本文將會概略性地介紹 Mitosis 是如何做到無線的。
硬體與基本架構
首先,Mitosis 是擁有並需要自製的專用接收器,而 QMK 實際上只在此接收器上運作。
Mitosis 的架構中,主要擁有這些硬體:
- 1 個 Pro Micro(ATmega32U4)。接收器的一部分,QMK 實際上只在 Pro Micro 上運作,以 USB 線連接電腦。
- 3 個 nRF51822。這是一個整合了 BLE(Bluetooth Low Energy,藍牙低功耗)等無線功能的 SoC(System On Chip)。
- 第 1 個 nRF51822 作為接收器的一部分,負責接收來自左右兩部分鍵盤的訊號,並將其透過 UART 傳給 Pro Micro。
- 第 2、3 個 nRF51822 分別在左右兩鍵盤上,負責讀取鍵盤上的按鍵狀態,並將其透過 Gazell 傳給接收器的 nRF51822。
PC
|
<USB>
|
Pro Micro(QMK)
|
<UART>
|
nRF51822(#1)
/ \
<Gazell> <Gazell>
/ \
nRF51822(#2) nRF51822(#3)
| |
Left Keyboard Right Keyboard
可以看出,Mitosis 的架構其實很簡單。雖然這樣的架構要用上更多的 IC,以導致它感覺起來不夠精簡,但這也其容易達成、理解或修改。
總的來說,左右鍵盤上的 nRF51822 會處理各自的按鍵狀態,並各自將其透過 Gazell 傳輸給接收器上的 nRF51822,接收器受到新的按鍵狀態後,會將左右部分的按鍵狀態組合在一起,並透過 UART 傳給 Pro Micro,Pro Micro 收到來自 UART 的封包後就解析按鍵狀態,並交由 QMK 處理。
程式
從基本架構可以得知,Mitosis 總共有 4 個 MCU(1 個 Pro Micro 的 ATmega32U4,3 個 nRF51822),而它們執行的程式當然也不一樣,以下就一一介紹不同部分的程式。
左右手鍵盤(nRF51822)
首先,這部分的程式在:reversebias/mitosis/mitosis-keyboard-basic/。主要有:
main.c
是主程式。
config/mitosis.h
是包含了腳位設定的標頭檔。
左右手鍵盤上 nRF51822 的程式是同一個,僅透過 #define COMPILE_RIGHT
或 #define COMPILE_LEFT
來切換不同的腳位設定和通道編號(Pipe number)而已。
在這裡有幾個重要的函數(僅列出函數名稱):
read_keys()
send_data()
handler_maintenance()
handler_debounce()
handler_debounce()
先看到 handler_debounce()
這個函數,它負責處理按鍵防彈跳(Debounce)。內容如下:
handler_debounce()
每秒會觸發 1000 次(也就是以 1000 Hz運作,由 RTC1
處理)。
它會先判斷目前是否在防彈跳中(if (debouncing)
),如果沒有的話會去判斷目前的按鍵狀態是否和最後一次一樣,如果不一樣代表有按鍵按下或放開了,透過 read_keys()
讀取目前的按鍵狀態,並儲存為快照 keys_snapshot
,同時開始防彈跳(將 deboducing
設為 true
)。
一旦開始防彈跳,它就會一直確認快照與目前的按鍵狀態是否一樣,一旦不一樣就停止防彈跳,若累計達到設定的防彈跳次數就會承認快照的按鍵狀態,並將快照的值給目前的鍵值 keys
,並呼叫 send_data()
開始傳送。
handler_maintenance()
此函數的功能顯而易見,就是以 8 Hz 的頻率次數呼叫 send_data()
傳送資料。此函數由 RTC0 處理。
send_data()
此函數就是將目前的鍵值 keys
打包成資料封包並傳輸出去。keys
的值會在 handler_debounce()
中更新。
PIPE_NUMBER
的值左右鍵盤不同(在 mitosis.h
中定義),接收器藉此判斷收到的資料是來自左還是右鍵盤。
read_keys()
此函數的功能也是很直觀,就是讀取並回傳所有的按鍵狀態。
從這裡也可以得知,Mitosis 是不用矩陣掃描(Matrix scan)的,畢竟它的按鍵數本來就比較少(左右各 23 鍵),又是分離式的鍵盤,一個 nRF51822 的 GPIO 足以分配到每個按鍵上,自然不用掃描,直接讀值就好。
接收器(nRF51822)
這部分的程式在:reversebias/mitosis/mitosis-receiver-basic/。主要有:
其中有幾個重要的函數(僅列出函數名稱):
nrf_gzll_host_rx_data_ready()
main()
nrf_gzll_host_rx_data_ready()
這是接收處理函數。當接收到資料時,以 pipe
判斷這是來自左還是右鍵盤,並設定好資料。
main()
以下省略一些不重要的程式:
這裡就是來負責將 Gazell 接收到的左右鍵盤按鍵狀態重新打包,只要確認了來自 QMK 的輪詢請求(s
),就透過 UART 傳送出去。
傳給 QMK 的封包除了按鍵狀態外,還有一個 0xE0
作為結束封包。
QMK / 接收器(Pro Micro)
這部分的程式在:qmk/qmk_firmware/keyboards/mitosis。主要有:
rules.mk
config.h
matrix.c
rules.mk
這裡可以注意到作者使用了 QMK 的「Custom Matrix」功能 (CUSTOM_MATRIX = yes
及 SRC += matrix.c
),因為 Mitosis 不像一般的鍵盤透過矩陣掃描得知按鍵狀態,而是讀取來自 nRF51822 透過 UART 傳送的封包。
config.h
config.h
主要是設定 QMK 中的各種東西,稍微熟悉 QMK 的人都不陌生。這裡僅列出重要的地方,也就是 UART 的相關設定:
matrix.c
matrix.c
是為了使用 QMK 的「Custom Matrix」功能所必要的檔案。
重點在 matrix_scan()
:
首先此函數會傳送一個 s
以請求 nRF51822 開始傳送按鍵狀態封包。
接著,一個 for
迴圈會處理來自 UART 的按鍵狀態封包。當接收完成後,判斷結束封包是否正確(為 0xE0
),如果沒問題的話就將按鍵狀態封包處理並賦值給 matrix[]
,接下來就是讓 QMK 去處理了。
結語
本次簡單地介紹 Mitosis 鍵盤是如和達成無線的,但我其實沒用過 nRF51822,對 QMK 的瞭解也還很粗淺,很多細節沒辦法講解,而如果上述內容有任何錯誤也請指正。
撰寫本文時的 Mitosis 相關 repo 資訊:
文章修改記錄 2022/02/23:原本寫的各個 nRF51822 之間的通訊方式是 BLE,但應該是 Gazell,故更新內容。
相關文章
留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)