Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 模擬IR(續一)---內核

android 模擬IR(續一)---內核

編輯:關於Android編程

在http://blog.csdn.net/cuityanxi/article/details/18413725 中我有給出IR模擬的示例代碼,但是只能作為參考;
若要在android中使用還有諸多問題,比如:android平台中有較多的中斷會導致延時的誤差很大,因此我有做改進,通過實驗證實是很可靠的。

思路:用戶空間:獲取GPIO驅動設備句柄,將要發送的IR CODE write到dev中;

內核空間:利用內核中現有的GPIO驅動輸出高低電平,使用內核軟中斷防止模擬時序時被中斷導致延時誤差大;GPIO設備讀取數據後引發軟中斷產生模擬IR。

代碼:

1. .h文件中的數據結構以及宏定義

struct IR_CODE
{
    U16 uHead;
    U8 uScancode;
	U8 bOutreverse;
};

typedef struct GPIO_Reg GPIO_Reg_t;
typedef struct IR_CODE IR_CODE_t;

//add by yanxi for  ir out start  140117
#define IR_HEAD0 0
#define IR_HEAD1 1
#define IR_TIME_BASE 2
#define IR_CODE_0  3
#define IR_CODE_1  4
#define IR_CODE_END  5

//38k = 26.315us
#define TIMER_9000US  342
#define TIMER_4500US  171
#define TIMER_560US   21
#define TIMER_1680US  63
//add by yanxi for  ir out end 140117

2.當用戶空間寫數據到設備節點時, _MDrv_GPIO_Write被執行,通過copy_from_user 獲取IR數據,並使用_MDrv_GPIO_SendIR發送IR

static ssize_t _MDrv_GPIO_Write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	IR_CODE_t mIR_CODE_t; 
	GPIO_PRINT("%s is invoked\n", __FUNCTION__);
	copy_from_user(&mIR_CODE_t, (IR_CODE_t __user *) buf, sizeof(IR_CODE_t));
	printk("\n yanxidebug uHead:%x  uScancode:%x  bOutreverse:%d",mIR_CODE_t.uHead,mIR_CODE_t.uScancode,mIR_CODE_t.bOutreverse);
	_MDrv_GPIO_SendIR((unsigned int)mIR_CODE_t.uHead,(unsigned int)mIR_CODE_t.uScancode,(BOOL)mIR_CODE_t.bOutreverse);
 	return 0;
}

3、主要是通過raise_softirq使能軟中斷

static void _MDrv_GPIO_SendIR(unsigned int Head, int scancode, BOOL bOutreverse)
{
	GPIO_PRINT("\n %s  Head:%d  scancode:%d bOutreverse:%d\n", __FUNCTION__,Head,scancode,bOutreverse);
	mHead = Head;
	mscancode = scancode;
	mbOutreverse = bOutreverse;

	raise_softirq(SENDIR_SOFTIRQ);
}

4、中斷處理函數,依據mscancode發送IR

  int irq_handle_function(int irq, void *device_id)  
{  
	  GPIO_PRINT("\n %s  \n", __FUNCTION__);
	  S8 TranselateBitPos;
	  U8 Ir_trans_sta;
	  int mcount = 0;
	  unsigned int head = 0x007f;
	  U8 head0 = head >> 8;
	  U8 head1 = head &0x00ff;
	  U16 mkeycode = mscancode;
	  BOOL outreverse = true;
	  //init state
	  Ir_trans_sta=IR_HEAD0;
	  TranselateBitPos=32;
	  //send ir code
	  while(TranselateBitPos>=0)
	  {
	  	mcount = 0;
	 	switch(Ir_trans_sta)
	 	{
		 case IR_HEAD0:	
			  Ir_trans_sta= IR_HEAD1; 
			  if(outreverse)
			  {
				  mcount = TIMER_9000US;
			  }	
			  else
			  {
			  	  MHal_GPIO_Set_Low(0);
				  mdelay(9);			  
			  }
			  break;
		 case IR_HEAD1:		 			
			  Ir_trans_sta= IR_TIME_BASE; 
			  if(!outreverse)//outreverse true
			  {
				  mcount = TIMER_4500US;//output high ;38k
			  }
			  else
			  {
			  	  MHal_GPIO_Set_High(0);//outreverse false,low vol
			  	  mdelay(4);
				  udelay(500);
			  }			 
			  break;
		 case IR_TIME_BASE:	
		 		if(TranselateBitPos>24)
				{
					 if( ((head0>>(32-TranselateBitPos)) & 0x1) == 0x1 )
					 	Ir_trans_sta= IR_CODE_1; 
					 else 
					 	Ir_trans_sta= IR_CODE_0; 						 
				}
				else if(TranselateBitPos>16)
				{
					 if( ((head1>>(24-TranselateBitPos)) & 0x1) == 0x1 )
					 	Ir_trans_sta= IR_CODE_1; 
					 else 
					 	Ir_trans_sta= IR_CODE_0; 						 
				}
				else if(TranselateBitPos>8)
				{
					 if( ((mkeycode>>(16-TranselateBitPos))&0x1) == 0x1 ){
					 	Ir_trans_sta= IR_CODE_1; 											 	


					 	}
					 else {
					 	Ir_trans_sta= IR_CODE_0; 	


					 	}
				}
				else if(TranselateBitPos>0)
				{
					 if( ((mkeycode>>(8-TranselateBitPos))&0x1) == 0x1 )
					 	Ir_trans_sta= IR_CODE_0; 
					 else 
					 	Ir_trans_sta= IR_CODE_1; 						 
				}
				else
				{
					 Ir_trans_sta= IR_CODE_END; 	
				}
				
			  if(!outreverse)	
			  {
			  	  MHal_GPIO_Set_Low(0);
				  udelay(560);		
			  }
			  else
			  {
				  mcount = TIMER_560US;
			  }				
			  break;
		 case IR_CODE_0:		
		 		Ir_trans_sta= IR_TIME_BASE; 
			  	if(outreverse)	
			  	{
			   	 	MHal_GPIO_Set_Low(0);
				  	udelay(500);	
			  	}
				else
				{
				  	mcount = TIMER_560US;
				}				
			  	TranselateBitPos--;
				break;
		 case IR_CODE_1:		
				Ir_trans_sta= IR_TIME_BASE; 
			  	if(outreverse)	
			  	{
			   	 	MHal_GPIO_Set_Low(0);
				  	udelay(1680);	
			  	}
				else
				{
				  	mcount = TIMER_1680US;
				}					
				TranselateBitPos--;
				break;
	 	 case IR_CODE_END:
				Ir_trans_sta= IR_HEAD0; 
				MHal_GPIO_Set_High(0);
				TranselateBitPos=-1;//force to exit.
				break;
		 default:break;
		}


		//38k generate
		while(mcount-- > 0){
			MHal_GPIO_Set_High(0);
			MHal_GPIO_Set_High(0);
			MHal_GPIO_Set_High(0);
			MHal_GPIO_Set_High(0);		
			udelay(11);
			MHal_GPIO_Set_Low(0);
			MHal_GPIO_Set_Low(0);
			MHal_GPIO_Set_Low(0);
			MHal_GPIO_Set_Low(0);		
			udelay(11);
		}
	}




	
    return IRQ_NONE;  
} 


  完...       


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved