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

📄 necdecode.cpp

📁 pci 底层驱动
💻 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 + -