android平臺應用GPIO模擬IR控制車載DTV

    數字電視—DTV對我們來說早已不是一個新東西,在車載電子上DTV大多是以模塊的形式獨立存在的,是可配的。在車載的市場上,客戶的需求是多種多樣的,如果把DTV也做到車載導航主PCB上去,還是不靈活,不要DTV的就得是不同的PCB板,這對於售後維護、開發都不是一個好辦法。

        DTV在家裏,大家一般都是通過遙控器來操作,當然現在有些android的電視盒子可以通過手機來控制,有個泰捷遙控器的apk,通過同一個wifi熱點的電視盒,可以用手機來操作也挺方便。但是在車上,怎麼去操作DTV呢?在小車上,一般空間都是比較狹窄的,使用遙控器是很不方便的,因此我們需要把控制做到導航主控上去。在遙控器的協議中,NEC協議是使用得最普遍的,下面就以NEC協議爲例學習一下使用GPIO模擬IR按鍵消息的方法。

        NEC的一條按鍵信息由數據頭、客戶碼、客戶碼反碼、鍵值、鍵值反碼、停止位組成,在此不介紹重複碼。數據頭是一個9ms + 4.5ms的高低組合,後面就是緊跟4個字節的數值,也就是32bit01組合。IR口的gpio口一般是默認是高電平的,解碼驅動大多都是採用下降沿觸發中斷。在此我們主要是要編出一串IR脈衝。組合這一串脈衝的代碼如下:

[plain] view plaincopy
  1. gpio_write_one_pin_value(simulate_ir_gpio_hdle, 0, "simulate_ir_gpio");       
  2.  Delay10us(900);// 9ms  
  3. gpio_write_one_pin_value(simulate_ir_gpio_hdle, 1, "simulate_ir_gpio");       
  4.  Delay10us(450);// 4.5ms  
  5.   
  6. //IR Customer Code: 0x807f ,  NEC IR protocol    
  7. SendByteData(0x80);  // DVB HEADER_CODE0   
  8. SendByteData(0x7F);  // DVB HEADER_CODE1   
  9.   
  10. SendByteData(IRData);  
  11. SendByteData(~IRData);   
  12. gpio_write_one_pin_value(simulate_ir_gpio_hdle, 0, "simulate_ir_gpio");       
  13. Delay10us(56);   
  14. gpio_write_one_pin_value(simulate_ir_gpio_hdle, 1, "simulate_ir_gpio");       


        在此有一個問題,就是編這一段脈衝需要50ms以上,標準的一個完整的消息大概是108ms-110ms。這就要求我們在發送4字節數據以及停止碼中間不能被任務調度,因爲任務一調度的話編的碼的寬度就會有很大出入,接收端解析就會認爲是一個錯誤的遙控值。那我們怎麼去盡力保證呢?在linux中有一個spinlock,也就是自旋鎖,一旦獲得這個鎖就可以保證當然執行的進程不被調度搶佔。因此在上面的這段代碼前後加上鎖以及取消鎖操作,筆者在實際操作中,在近百次的操作中,發送IR鍵值的成功率是百分之百。加鎖的相關代碼如下:

[plain] view plaincopy
  1. #include <linux/spinlock.h>  
  2. spinlock_t      lock;  
  3.   
  4.   spin_lock_init(&lock);  
  5.   
  6.    spin_lock(&lock);  
  7.  ////////////////for your process//////////////////  
  8.    spin_unlock(&lock);  


       在android上層,可以通過ioctl來控制,向上層可以封裝在service裏面供上層應用使用。

       以上僅供參考。

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