⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ir_control.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        _pipe,
        _interface,
        p_buffer->p_buffer,
        IR_BUFFER_SIZE,
        NULL,
        &(p_buffer->read_context)); 

        p_buffer->buffer_dirty = TRUE;
        addBuffer(p_buffer,&_data_queue);

    if(NT_SUCCESS(status))
    {
        return;
    }
 
}

////////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::sendFreeBuffer(PBUFFER_ENTRY_MINI p_buffer)
{

    RtlZeroMemory(p_buffer->p_buffer,IR_BUFFER_SIZE); 
    addBuffer(p_buffer,&_free_queue);
    p_buffer->buffer_dirty = FALSE;

}

////////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::freeBuffer(PBUFFER_ENTRY_MINI p_buffer)
{
    if(p_buffer->p_irp) IoFreeIrp(p_buffer->p_irp);
    delete [] p_buffer->p_urb;
    delete [] p_buffer->p_buffer;
    delete p_buffer;
    
    InterlockedDecrement(&_buffer_count);
}

////////////////////////////////////////////////////////////////////////////////////////////
PBUFFER_ENTRY_MINI IR_Control::getBuffer(PQUEUE_HEAD p_queue)
{
	
    PBUFFER_ENTRY_MINI p_buffer = NULL;
    KIRQL old_irql = lock(p_queue);

    if (!IsListEmpty (&p_queue->queue_head))
    {
        p_buffer = (PBUFFER_ENTRY_MINI) RemoveHeadList(&p_queue->queue_head);
        InterlockedDecrement(&p_queue->count);
    }

    unlock(old_irql,p_queue);
    return p_buffer;
}

/////////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::waitForTimes(DWORD wait_time) //units: ms
{
    sleep(wait_time);
}

/////////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::addBuffer(PBUFFER_ENTRY_MINI p_buffer, PQUEUE_HEAD p_queue)
{
    KIRQL old_irql = lock(p_queue);
 
    InsertTailList(&p_queue->queue_head, (PLIST_ENTRY)p_buffer);
    InterlockedIncrement(&p_queue->count);
    p_buffer->buffer_in_list = TRUE;

    unlock(old_irql,p_queue);
}

/////////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::static_BufferComplete(PBUFFER_ENTRY_MINI            p_context,
                                       NTSTATUS                 status, 
                                       ULONG                    transfer_size,
                                       PVOID                    p_read_context)
{
    if(p_context)
    {
        IR_Control* p_this =(IR_Control*) p_context->p_data_transfer;

        if((status == STATUS_SUCCESS) && (transfer_size > 0))
        {
            p_context->bytes_completed = transfer_size;
            
        }
        else
        {
            p_context->bytes_completed = 0;
        }

    }
}

//////////////////////////////////////////////////////////////////////////////////////////////
/*
	split buffer to ir data and event data
*/
VOID IR_Control::sliced_data(PBYTE p_buffer, PBYTE p_ir, PBYTE p_event)
{
    BYTE *ir,*buffer,*event;
    BYTE tmp;
    ir = p_ir;
    event = p_event;
    buffer = p_buffer;
    for(int i=0; i<DATA_BLOCK_NUM; i++)
    {
        RtlCopyMemory(ir, buffer, IR_LENGTH-1);
        tmp = buffer[IR_LENGTH-1];
        ir[IR_LENGTH-1] = tmp&0xf;
        event[0] = tmp&0xf0;
        RtlCopyMemory(event+1,buffer+IR_LENGTH,EVENT_LENGTH-1);
        ir+=IR_LENGTH;
        event+=EVENT_LENGTH;
        buffer+=DATA_BLOCK_SIZE;
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////
//to process event, there is two steps:
/*
	1. to kick off the same data, and store most newer data in p_pre_event
	2. to do process, send clear feature command to USB controller
*/
VOID IR_Control::ProcessEvent(PBYTE p_event, PBYTE p_pre_event)
{
    PBYTE tmp;
    SIZE_T  j;
    tmp = p_event;
    for(int i=0; i<DATA_BLOCK_NUM;i++)
    {
        j = RtlCompareMemory(p_pre_event,tmp+i*EVENT_LENGTH,EVENT_LENGTH);
        if(j==EVENT_LENGTH)  //equal, continue
        {
            continue;
        }
        else
        {
            RtlCopyMemory(p_pre_event, tmp+i*EVENT_LENGTH,EVENT_LENGTH);		
            DoEvent(p_pre_event);  //do process
        }
			
    }
}

////////////////////////////////////////////////////////////////////////////////////////////
///this function will be difference between bus-power and self-power
//our implemention, here will be focused on bus-power, there will be 2
//scenario
VOID IR_Control::DoEvent(PBYTE p_pre_event)
{	
    WORD data;
    DWORD  data1;
    data = *((WORD*)p_pre_event);
    data1 = *((DWORD*)(p_pre_event+2));
	
    if(_p_current_pcb->type == USB_SELF_POWER)
    {
        if(_p_current_pcb->speed == 1) //HIGH SPEED
        {
            if((data&BULK_EP3)||(data&ISO_EP3))
            {
                _p_usb->UsbClearFeature(0,_p_current_pcb->hs_config_info[0].interface_info.audio_index);
            }

            if((data&BULK_EP4)||(data&ISO_EP4))
            {
                _p_usb->UsbClearFeature(0, _p_current_pcb->hs_config_info[0].interface_info.video_index);
            }

            if((data&BULK_EP6)||(data&ISO_EP6))
            {
                _p_usb->UsbClearFeature(0,_p_current_pcb->hs_config_info[0].interface_info.hanc_index);
            }

            if(data&BULK_EP5)
            {
                _p_usb->UsbClearFeature(0,_p_current_pcb->hs_config_info[0].interface_info.vanc_index);
            }
        }
        else //full speed
        {
            if((data&BULK_EP3)||(data&ISO_EP3))
            {
                _p_usb->UsbClearFeature(0, _p_current_pcb->fs_config_info[0].interface_info.audio_index);
            }

            if((data&BULK_EP4)||(data&ISO_EP4))
            {
                _p_usb->UsbClearFeature(0,  _p_current_pcb->fs_config_info[0].interface_info.video_index);
            }
        }
    }
    else  // bus-power
    {
        if(_p_current_pcb->speed == 1) //HIGH SPEED
        {
            if((data&BULK_EP3)||(data&ISO_EP3))
            {
                _p_usb->UsbClearFeature(0,_p_current_pcb->hs_config_info[_config_index].interface_info.audio_index);
            }

            if((data&BULK_EP4)||(data&ISO_EP4))
            {
                _p_usb->UsbClearFeature(0, _p_current_pcb->hs_config_info[_config_index].interface_info.video_index);
            }

            if((data&BULK_EP6)||(data&ISO_EP6))
            {
                _p_usb->UsbClearFeature(0,_p_current_pcb->hs_config_info[_config_index].interface_info.hanc_index);
            }

            if(data&BULK_EP5)
            {
                _p_usb->UsbClearFeature(0,_p_current_pcb->hs_config_info[_config_index].interface_info.vanc_index);
            }
        }
        else //full speed
        {
            if((data&BULK_EP3)||(data&ISO_EP3))
            {
                _p_usb->UsbClearFeature(0, _p_current_pcb->fs_config_info[_config_index].interface_info.audio_index);
            }

            if((data&BULK_EP4)||(data&ISO_EP4))
            {
                _p_usb->UsbClearFeature(0, _p_current_pcb->fs_config_info[_config_index].interface_info.video_index);
            }
        }
	
    }
			
}

////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::ProcessIr(PBYTE p_ir)
{
    PBYTE p_ir_data[IR_LENGTH];
    DWORD tmp;
    WORD value;
    int i = 0;

    while(i<IR_LENGTH*DATA_BLOCK_NUM)
    {
        RtlCopyMemory(p_ir_data, p_ir+i, IR_LENGTH);
        tmp = *((DWORD*)p_ir_data);
        value = *((WORD*)p_ir_data);
        if(tmp & IR_RX_REQ)
        {
            while(value != 0)
            {
                if(tmp &0x00010000)
                {
                    value |= 0x8000;
                }
                else
                {
                    value &= ~0x8000;
                }
                //to do , process value
                doProcessIr(value);

                if(tmp& 0x00020000)
                {
                    i+=IR_LENGTH;
                    RtlCopyMemory(p_ir_data, p_ir+i, IR_LENGTH);
                    tmp = *((DWORD*)p_ir_data);
                    value = *((WORD*)p_ir_data);
                }
                else
                {
                    value = 0;
                }
            }
        }

        i+=IR_LENGTH;  //NEXT SAMPLE
    }
	
}

//////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::doProcessIr(WORD value)
{
    if(value != 0)
    {
        //Decode the sample
        DWORD address;
        ULONG command = _decoder.submitSample(value, &address);
                    
        //Handle repeat commands
        if(command == DECODE_REPEAT_COMMAND)
        {
            //Use the last command for repeats
            if(_last_command != 0xFFFFFFFF)
            {
                command = _last_command;
                address = _last_address;
            }
        }

        //If we have a command, add it to the key queue
        if(command != 0xFFFFFFFF)
        {
            _last_command = command;
            _last_address = address;

            KEYSTROKE keystroke;
            keystroke.dwCommand = command;
            keystroke.dwAddress = address;

            _key_queue.Insert(keystroke);
        }
    }	
}

////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::initializeIR()
{
    DWORD ir_control,value;
    BYTE read_buf[4];
    BYTE write_buf[2];
	
    write_buf[0] = IR_CNTRL_REG & 0xff;
    write_buf[1] = IR_CNTRL_REG>>8;
    RtlZeroMemory(read_buf,4);
    _p_i2c_interface->read(MAKO_I2C, 2, write_buf,4, read_buf,0);
    ir_control = *((DWORD*)read_buf);
	
    //Make sure the IR receiver is disabled during initialization
    ir_control &= ~0x00000100;
    BYTE sub_buf2[2];
    BYTE write_buf2[4];
	
    sub_buf2[0]=IR_CNTRL_REG & 0xff;
    sub_buf2[1]=IR_CNTRL_REG>>8;
    write_buf2[0] =(BYTE)(ir_control & 0xff);
    write_buf2[1] =(BYTE)(ir_control>>8);
    write_buf2[2] = (BYTE)(ir_control>>16);
    write_buf2[3] = (BYTE)(ir_control>>24);
    _p_i2c_interface->write(MAKO_I2C, 2, sub_buf2, 4, write_buf2,0);

    //Now set up the IR control register.
    ir_control &= 0xFFFF9FEC; //Clear bits 0,1,4,13,14
    ir_control |= 0x0000044C; //Set bits 2, 3, 6, 10
    sub_buf2[0]=IR_CNTRL_REG & 0xff;
    sub_buf2[1]=IR_CNTRL_REG>>8;
    write_buf2[0] =(BYTE)(ir_control & 0xff);
    write_buf2[1] =(BYTE)(ir_control>>8);
    write_buf2[2] = (BYTE)(ir_control>>16);
    write_buf2[3] = (BYTE)(ir_control>>24);
    _p_i2c_interface->write(MAKO_I2C, 2, sub_buf2, 4, write_buf2,0);


    sub_buf2[0]=IR_RXCLK_REG & 0xff;
    sub_buf2[1]=IR_RXCLK_REG>>8;
    write_buf2[0] =(BYTE)(00 & 0xff);
    write_buf2[1] =(BYTE)(0x800>>8);
    _p_i2c_interface->write(MAKO_I2C, 2, sub_buf2, 2, write_buf2,0);
    //Set up the receive clock


    //Enable interrupts 
    sub_buf2[0]=IR_IRQEN_REG & 0xff;
    sub_buf2[1]=IR_IRQEN_REG>>8;
    write_buf2[0] = 0x23;
    _p_i2c_interface->write(MAKO_I2C, 2, sub_buf2, 1, write_buf2,0);
    //Enble IRQN output on Mako
    write_buf[0] = PIN_CTRL1 & 0xff;
    write_buf[1] = PIN_CTRL1>>8;
    RtlZeroMemory(read_buf,4);
    _p_i2c_interface->read(MAKO_I2C, 2, write_buf,4, read_buf,0);
    value = *((DWORD*)read_buf);

    value |= 0x8;
    sub_buf2[0]=PIN_CTRL1 & 0xff;
    sub_buf2[1]=PIN_CTRL1>>8;
    write_buf2[0] =(BYTE)(value& 0xff);
    write_buf2[1] =(BYTE)(value>>8);
    write_buf2[2] = (BYTE)(value>>16);
    write_buf2[3] = (BYTE)(value>>24);
    _p_i2c_interface->write(MAKO_I2C, 2, sub_buf2,4, write_buf2,0);
		
    //Enable the IR receiver
    ir_control |= 0x100;
    sub_buf2[0]=IR_CNTRL_REG & 0xff;
    sub_buf2[1]=IR_CNTRL_REG>>8;
    write_buf2[0] =(BYTE)(ir_control & 0xff);
    write_buf2[1] =(BYTE)(ir_control>>8);
    write_buf2[2] = (BYTE)(ir_control>>16);
    write_buf2[3] = (BYTE)(ir_control>>24);
    _p_i2c_interface->write(MAKO_I2C, 2, sub_buf2,4,write_buf2,0);
}

/////////////////////////////////////////////////////////////////////////////////////////////
VOID IR_Control::changConfigindex( BYTE index)
{
    _config_index = index;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -