In the http://blog.csdn.net/cuityanxi/article/details/18413725 I have sample code that gives IR simulation, but it can only be used as a reference;
There are still many problems to be used in android. For example, there are many interruptions on the android platform, which may lead to a large delay error. Therefore, I have made some improvements and proved to be reliable through experiments.
Idea: user space: Get the GPIO driver device handle and write the ir code to be sent to dev;
Kernel space: use the existing GPIO driver output level in the kernel, and use soft interrupt in the kernel to prevent large delay errors caused by Interruption During simulation timing; when the GPIO device reads data, Soft Interrupt is triggered to generate analog IR.
Code:
1. Data Structure and macro definition in the H file
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. When the user space writes data to the device node, _ MDrv_GPIO_Write is executed, the data is obtained through copy_from_user, And the IR is sent using _ MDrv_GPIO_SendIR.
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. It mainly enables soft interruption through 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. Interrupt Processing Function, send IR Based on mscancode
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; 2010mkeycode = 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 {hour (0); mdelay (9);} break; case IR_HEAD1: ir_trans_sta = IR_TIME_BASE; if (! Outreverse) // outreverse true {mcount = TIMER_4500US; // output high; 38 k} 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_t Rans_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) {response (0); udelay (560) ;}else {mcount = TIMER_560US;} break; case IR_CODE_0: Ir_trans_sta = IR_TIME_BASE; if (outreverse) {response (0 ); udelay (500);} else {mcount = TIMER_560US;} TranselateBitPos --; break; case IR_CODE_1: Ir_trans_sta = IR_TIME_BASE; if (outreverse) {limit (0 ); udelay (1680);} else {mcount = TIMER_1680US;} TranselateBitPos --; break; case IR_CODE_END: Ir_trans_sta = IR_HEAD0; hour (0); TranselateBitPos =-1; // force to exit. break; default: break;} // 38 k generatewhile (mcount --> 0) {random (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); random (0); udelay (11) ;}} return IRQ_NONE ;}Complete...