傳感器介紹
PAJ7620傳感器是原相科技(Pixart)的一款內部集成光學陣列式傳感器,以使復雜的手勢和光標模式輸出,內部集成了九種手勢的識別:上、下、左、右、向前、向后、順時針、逆時針以及揮動的手勢動作識別、模塊以i2c通信,傳感器功能很強大,更詳細模塊說明的可參考數據手冊。手冊過大無法上傳附件,需要可私信我,我做了pdf目錄標簽,方便定位查看。
手勢傳感器可以用來做大量豐富的應用開發,我在網上找到這樣的應用場景圖片,如下:
還有有些oppo手機的手勢隔空操作,可以翻轉桌面和圖片等操作,估計也是手勢傳感器來實現的。

驅動思路和原理
paj7620的驅動步驟在手冊的programing sequence and function application里有詳細的步驟說明,我在這里就總結一下注意事項。傳感器的讀時序中間有stop信號,因此在封裝讀函數需要調用兩次i2c_transfer,,在下面的代碼會看到。
<ignore_js_op>
設備樹編寫:
講完傳感器的介紹后,我們首先開始在設備樹文件描述手勢傳感器,手勢傳感器是i2c協議通信的,我選擇roc-rk3308的i2c1組進行通信,因此可以如下描述即可。
&i2c1 { clock-frequency = <400000>; status = "okay"; paj7620: paj7620@73 { compatible = "pxi,paj7620"; reg = <0x73>; }; };
從設備的地址可在數據手冊上找到,它是7bit的地址0x73。
設備驅動編寫:
這里我采用輪徇的方式去獲取傳感器的手勢動作狀態,並且將手勢傳感器實現成一個輸入設備,因此可以用一個結構體這樣描述它
struct gesture_sensor{ struct i2c_client *client; //記錄i2c的client struct delayed_work poll_work; //工作隊列 struct input_dev *inputdev; //輸入設備 };
根據傳感器的時序進行封裝paj7620的i2c讀寫函數
//paj7620寫寄存器 static int paj_write_reg(struct i2c_client *client ,unsigned char addr,unsigned char data) { unsigned char buf[2]={addr,data}; return i2c_master_send(client,buf,2); } //paj7620讀寄存器 //paj7620的讀中間是p(停止)信號,因此要將read操作分成兩次transfer static unsigned char paj_read_reg(struct i2c_client *client ,unsigned char addr) { int ret; struct i2c_msg msg[2]; unsigned char data; msg[0].addr=client->addr; msg[0].flags =0;//寫 msg[0].len=1; msg[0].buf=&addr; ret=i2c_transfer(client->adapter,msg,1); if(ret<0) { printk("i2c_transfer read error %d\n",ret); return ret; } msg[1].addr = client->addr; msg[1].flags |= I2C_M_RD;//讀 msg[1].len = 1; msg[1].buf = &data; ret = i2c_transfer(client->adapter,&msg[1], 1); if(ret < 0) { printk("i2c_transfer read error %d\n",ret); return ret; } return data; }
在工作隊列中將數據獲取,並且上報給用戶層。代碼太長,此處將不粘貼,詳細的代碼可參考附件或私信我。
功能測試:
在這里,我做了一個應用層的demo來獲取手勢數據,在串口終端里運行gesturedemo,我們進行手勢動作識別測試,效果如下,可以獲取9種識別的手勢:
# gesturedemo /dev/input/event1 gesture:down gesture:up gesture:left gesture:right gesture:forward gesture:backward gesture:clockwise gesture:count clockwise gesture:wave
進入Firefly開發者社區可下載Demo