linux驅動開發:MT協議

因爲需要做ctp的驅動,然而又需要學習其他衍生的東西。 因爲我們的ctp是支持MT的,所以我們需要研究下多點觸摸協議.

這部分的資料網上有,但原汁原味的資料還是在內核目錄下 doc/input/mt_touch下面。

協議分爲A,B兩類。
For devices handling anonymous contacts (type A), the protocoldescribes how to send the raw data for all contacts to the receiver.
Fordevices capable of tracking identifiable contacts (type B), the protocoldescribes how to send updates for individual contacts via event slots.
多點觸摸的觸摸數據被用單獨的ABS_MT event的包順序發送,這些包不會被 ST(single touch)所識別。所以多點觸摸協議可以在ST Protocol的基礎上實現。
A類:在每個包的結束需調用 input_mt_sync(),聲明一次數據的結束,調用它會發出一個SYN_MT_REPORT事件。來提示接收器接收數據,並準備下一次數據的接收.不能被區分和追蹤.
A類設備的內核驅動:需要生成全部的匿名接觸數據,一次性上報所有數據,將事件過濾和手指跟蹤留給用戶空間處理。
可以用ABS_MT_TOUCH_MAJOR和ABS_MT_WIDTH_MAJOR這兩個消息上報觸摸面積的信息
想象一下,有個人的手指頭壓着一片玻璃,我們從玻璃這邊看手指頭。
可以看到2個區域,中間的區域是實際壓着的部分,外面那個區域是手指頭在玻璃上的投影。
中間區域的直徑 就是ABS_MT_TOUCH_MAJOR。
外面大得區域的直徑 就是ABS_MT_WIDTH_MAJOR。
現在想象一下,壓的力氣變大一些,裏面的區域就會變大,
ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR 的值就能反映壓力的大小,
這個值通常是小於1的。
對於支持壓力檢測的設備來說,ABS_MT_PRESSURE可以用來替代按壓面積,上報壓力。
作爲MAJOR的補充,觸摸點的橢圓形的形狀,還可以用MINOR來說明。
MAJOR和MINOR分別表示最長的方向和短一些的那個方向。
最後也可以用ORIENTATION來說明這個橢圓的方位,是不是水平的
對於type A類型的設備而言,觸摸點形狀的更多特徵還可以使用ABS_MT_BLOB_ID消息進行通知。

B類:在傳送包開始前需調用input_mt_slot(),調用它會發出一個ABS_MT_SLOT事件,提示接收器接收數據,並更新指定槽的數據。假設支持5點觸摸,你同時按下3個點,CTPM會更新這三個點對應槽的數據,以此來區分多個點。
與A類協議的差別:B類協議可通過可被識別的ID來減少發送到用戶空間的數據量。需要 ABS_MT_TRACKING_ID,由硬件或者從原始數據中得到.一個非負數的跟蹤被認爲是一個contact。只有變化的數據被傳播,硬件有能力追蹤並區分觸摸點.用戶空間根據接收到的MT(MultiTouch)消息,應用程序更新當前slot的相關屬性。
ABS_MT_TOOL_TYPE 和 ABS_MT_TRACKING_ID 會被 input core 在暗地裏處理。
因此驅動程序應該調用 input_mt_report_slot_state()
當多點數據包傳送完畢後,需要使用input_sync()作爲一次數據的結束。這提示接收器接收自上一次上報結束後所產生的所有 事件 和 包,並準備接收下一次的數據和包。

A協議兩點觸摸消息上報:

ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
SYN_MT_REPORT
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_MT_REPORT
SYN_REPORT
B類協議兩點觸摸消息上報舉例:

ABS_MT_SLOT 0
ABS_MT_TRACKING_ID 45
ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
ABS_MT_SLOT 1
ABS_MT_TRACKING_ID 46
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_REPORT


消息含義

ABS_MT_TOUCH_MAJOR:
觸摸點橢圓形最長的那個方向的直徑。
這個長度應該是觸摸表面的長度單位,
如果觸摸表面的X是Y的幾倍(矩形),
那麼ABS_MT_TOUCH_MAJOR的長度最長爲 ( x平方 + y平方 )開根號,也就是對角線的長度。

ABS_MT_TOUCH_MINOR:
觸摸點橢圓形短一點的那個方向的直徑,如果是圓形,ABS_MT_TOUCH_MINOR可以省略。

ABS_MT_WIDTH_MAJOR:
以觸摸面的長度單位爲單位的觸摸工具,在觸摸面上的最長的長度, 這個長度可以理解爲觸摸工具本身的長度。
觸摸點和觸摸工具的水平方向假設是一致的
ABS_MT_WIDTH_MINOR:
以觸摸面的長度單位爲單位的觸摸工具,在觸摸面上的短一點的長度。如果是圓形可以省略
ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR 的比值用來估計壓力的大小。
這些寬度信息也可以用於識別手指還是手掌。(手掌比手指要寬)
ABS_MT_PRESSURE:
觸摸點的壓力大小,可以是任意衡量單位。對於能夠測量壓力的設備,可以用來替代TOUCH 和 WIDTH
ABS_MT_DISTANCE:
手指頭距離觸摸屏表面的距離,以觸摸面的長度單位爲單位。0意味着已經接觸到觸摸屏。大於0的數是指手指頭在觸摸屏上面的高度
ABS_MT_ORIENTATION:
橢圓形觸摸點的方向(水平還是垂直)。
它的值應該是有符號的、和旋轉方向有關、90度爲一個週期的。
取值範圍是有符號的,取值範圍可以任意定,
但0應該表示爲長軸沿着Y方向,負數表示逆時針旋轉了,正數表示順時針旋轉了。
長軸方向如果完全變成X方向,那麼值就變成最大的了。
如果觸摸點的形狀是圓形,或者得不到形狀信息,可以不上報ABS_MT_ORIENTATION這個消息。
如果設備只能檢測到是水平或者是垂直信息,那麼ABS_MT_ORIENTATION的值就應該是0或者1。
ABS_MT_POSITION_X:
觸摸中心x座標
ABS_MT_POSITION_Y:
觸摸中心y座標
ABS_MT_TOOL_TYPE:
觸摸工具類型,很多內核驅動都不能區分是什麼觸摸工具,比如是手指還是筆。
如果是這樣的內核驅動,那麼應該省略掉這個消息。
目前的多點觸摸協議支持 MT_TOOL_FINGER 和 MT_TOOL_PEN。
對於 type B 類型的設備,這個消息是在 input core 處理的,
因此驅動程序應該調用 input_mt_report_slot_state() 上報觸摸工具的類型。

ABS_MT_BLOB_ID:
將多個座標消息組合成一個BLOB_ID,用於描述觸摸點的形狀。
多個點的信息按照一定順序上報,能夠形成一個代表觸摸點形狀的多邊形。
這個是針對 type A 的更底層的信息打包,不要和 高級的 TRACKING ID 弄混了。
大部分 type A 的設備並不支持這個功能,所以驅動程序忽略掉這個消息也沒有關係
ABS_MT_TRACKING_ID:
TRACKING ID用來追蹤和識別壓下到提起期間的某一個觸摸點。
TRACKING ID的取值範圍應該是足夠大的,用於更方便區分是哪一個觸摸點。
對於 type B 類型的設備,這個消息是 input core 內部處理的,
驅動程序應該調用 input_mt_report_slot_state() 來告訴input core當前slot是否是無效了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章