📄 ir_control.cpp
字号:
_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 + -