📄 necdecode.cpp
字号:
/////////////////////////////////////////////////////////////////////////////////////////
//NEC command codes are 32 bits long and consist of and 8-bit address and an 8-bit
// command. It is transmitted as the address, the inverse of the address, the command,
// and the inverse of the command. The address and command bits are transmitted with
// the least significant bit first.
//
// The NEC command code starts out by transmitting a pulse to indicate the start of
// a command. Shortly after, the command starts. 0's are represented by a short
// space, 1's by a long space. The command data is transmitted only once, but, as
// long as the key is held down, the start code followed by a single bit is transmitted
// every few milliseconds.
//
//
#include "common.h"
#include "necdecode.h"
#include "ircommand.h"
const BYTE NEC_Decode::DecodeGroup::_min_long_space = 6;
const BYTE NEC_Decode::DecodeGroup::_max_long_space = 7;
const BYTE NEC_Decode::DecodeGroup::_min_short_space = 1;
const BYTE NEC_Decode::DecodeGroup::_max_short_space = 3;
const BYTE NEC_Decode::DecodeGroup::_min_leader_code = 36;
const BYTE NEC_Decode::DecodeGroup::_max_leader_code = 37;
const BYTE NEC_Decode::DecodeGroup::_min_short_repeat = 2;
const BYTE NEC_Decode::DecodeGroup::_max_short_repeat = 3;
const BYTE NEC_Decode::DecodeGroup::_min_repeat_space = 8;
const BYTE NEC_Decode::DecodeGroup::_max_repeat_space = 9;
NEC_Decode::NEC_Decode(DWORD ir_command_table):
_bit_count(0),
_current_bit(0),
_bit_index(0),
_address(0),
_inverse_address(0),
_command(0),
_inverse_command(0),
_found_leader_code(FALSE),
_command_is_valid(FALSE),
_nec_command((BYTE)ir_command_table)
{
}
ULONG NEC_Decode::submitSample(DWORD sample)
{
ULONG command = 0xFFFFFFFF;
//Search for groups of bits in the sample
for(LONG i = 31; i >= 0; i--)
{
BYTE current_bit = getBit(sample, (BYTE)i);
if(current_bit == _current_bit)
{
//Another bit in the current group.
_bit_count++;
}
else
{
dbgLogTrace(("Found group of %d, %d's\n", _bit_count, _current_bit));
//We've just switched to a different group.
if(_decode_group.isLongSpace(_current_bit, _bit_count))
{
dbgLogTrace(("Found a one!\n"));
processLongSpace();
//If we hit the end of a command, this will retreive it.
command = getCommand();
}
else if(_decode_group.isShortSpace(_current_bit, _bit_count))
{
dbgLogTrace(("Found a zero!\n"));
processShortSpace();
//If we hit the end of a command, this will retreive it.
command = getCommand();
}
else if(_decode_group.isShortRepeat(_current_bit, _bit_count))
{
dbgLogTrace(("Found a short repeat pulse!\n"));
if(_found_repeat_space && _command_is_valid)
{
//It's a repeat command
dbgLogTrace(("Found Repeat command %x\n", _command))
command = DECODE_REPEAT_COMMAND;
}
}
if(_decode_group.isRepeatSpace(_current_bit, _bit_count))
{
dbgLogTrace(("Found a repeat space!\n"));
if(_found_leader_code)
{
_found_repeat_space = TRUE;
}
}
else
{
_found_repeat_space = FALSE;
}
if(_decode_group.isLeaderCode(_current_bit, _bit_count))
{
dbgLogTrace(("Found a leader code!\n"));
_found_leader_code = TRUE;
//Reset the bit index in case this is leading the new keypress
_bit_index = 0;
}
else
{
_found_leader_code = FALSE;
}
//Switch the bit to check and reset the bit count
_current_bit = current_bit;
_bit_count = 1;
}
}
return command;
}
VOID NEC_Decode::processLongSpace()
{
//Reset if this is the first bit since the command started.
//This initializes all command fields to zero.
if(_bit_index == 0)
{
reset();
}
//Store the bit in the address, inverse address, command, or
// inverse command, depending on the bit index
if(_bit_index < 8)
{
_address |= (1 << _bit_index);
}
else if(_bit_index < 16)
{
_inverse_address |= (1 << (_bit_index - 8));
}
else if(_bit_index < 24)
{
_command |= (1 << (_bit_index - 16));
}
else
{
_inverse_command |= (1 << (_bit_index - 24));
}
_bit_index++;
}
ULONG NEC_Decode::processShortRepeat()
{
ULONG command = 0xFFFFFFFF;
if(_found_repeat_space && _command_is_valid)
{
//It's a repeat command
dbgLogTrace(("Found Repeat command %x\n", _command))
dbgLogTrace(("Address %x\n", _address))
command = DECODE_REPEAT_COMMAND;
}
return command;
}
ULONG NEC_Decode::getCommand()
{
if(_bit_index == 32)
{
//We've just finished a command!
//Reset the index, (Don't destroy the command in case it repeats.)
_bit_index = 0;
//Return the command if it is valid
//NOTE: These are stored in byte variables to get around a compiler bug.
// If ~_inverse_command is in the if statement, it does the ~ operation
// on 32 bits. So if _command is 5 and _inverse_command is 0xFA,
//~inverse_command is 0xFFFFFF05 which will always fail the comparison. :-(
BYTE temp_command = ~_inverse_command;
if(_command == temp_command)
{
dbgLogInfo(("Found NEC command %x\n", _command));
_command_is_valid = TRUE;
//Get the address. There are two types of NEC commands, one
// that uses the entire 16-bit address field as the address and one
// that sends an 8-bit address and 8-bit inverse address.
//We assume it's using the whole address field if the address and
// inverse address aren't complements of each other.
ULONG address = _address;
BYTE temp_address = ~_inverse_address;
if(temp_address != _address)
{
address |= _inverse_address << 8;
}
_nec_command.initialize(_command);
return _command;
}
else
{
dbgLogError(("Error transmitting command %x\n", _command));
}
}
return 0xFFFFFFFF;
}
IR_Command* NEC_Decode::getIrCommand()
{
return &_nec_command;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -