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

📄 rc5decode.cpp

📁 pci 底层驱动
💻 CPP
字号:
//
//  File:   rc5decode.cpp
//  Description: implementation of class RC5Decode
//
//  Created:  Wed. Jan 15, 2003
//
//
// Copyright and Disclaimer:
//
//   ---------------------------------------------------------------
//   THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
//   EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//   PARTICULAR PURPOSE.
//
//   IN NO EVENT SHALL CONEXANT BE LIABLE TO ANY PARTY FOR DIRECT,
//   INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
//   INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE
//   AND ITS DOCUMENTATION, EVEN IF CONEXANT HAS BEEN ADVISED OF THE
//   POSSIBILITY OF SUCH DAMAGE.
//
//   Copyright (c) 2000-2001 Conexant Systems, Inc.
//
//   All Rights Reserved.
//   ---------------------------------------------------------------
//
// Module Revision Id:
//
//

#include "common.h"
#include "rc5decode.h"

/////////////////////////////////////////////////////////////////////////////////////////
// RC5 commands are 14 bits in length.  Two start bits, one toggle bit, 5 address bits,
// and 6 command bits.  The first start bit is always 1.  The second start bit could 
// be zero if the remote wants to address a very high-numbered device.  The toggle bit
// changes state every time a button is pressed on the remote so that it is possible to
// tell when a single button was pressed multiple times.  The address is usually 0, and
// represents the device the command is directed to.  
//
// When a button is pressed on the remote, the command for that button is sent over and
// over again until the user stops pressing the button.
//
// Each bit of a command takes the same amount of time to send and changes state, from 
// zero to one, or from one to zero, at the midpoint of the command.  Therefore, a one
// would be several zeros followed by several ones.
//
// Our device inverts these bits, however. We get a long string of ones when the remote 
// is not active.  There are also long strings of ones between key presses which mark the
// end of a command.
//
// The class works by searching for groups of zeros and groups of ones.  It can also handle
// double groups of each type.  Double groups occur whenever a 1 follows a 0 or a 0 follows
// a 1. The group size is defined by the constant members 
// _min_bits_in_group and _max_bits_in_group.  These numbers could be changed to support
// remotes that might send longer or shorter pulses.
//
// The class closes a group or double group when the next bit in the incoming stream is 
// of a different value.  If there is a long stream of ones, it is acknowledged as such
// as soon as it becomes larger than the largest double group.  When a large string of
// ones is recognized, the class attempts to complete the previous command and reset the
// class to receive the next command.
//
/////////////////////////////////////////////////////////////////////////////////////////


//_min_bits_in_group and _max_bits_in_group define the size of 
// groups of 0's and 1's.  These values may need to be adjusted for
// remote controls that take longer or shorter to transmit each bit.
//
// A group is valid if the number of 0's or 1's in the group falls
// between these values.
//
// A double group is between _max_bits_in_group+1 and 2*_max_bits_in_group.
//
const BYTE RC5Decode::_min_bits_in_group = 2;
const BYTE RC5Decode::_max_bits_in_group = 4;

/////////////////////////////////////////////////////////////////////////////////////////
//RC5Decode::RC5Decode
//
// Constructor
//

RC5Decode::RC5Decode(DWORD ir_command_table):
_group_index(0),
_bit_count(0),
_current_bit(0),
_last_command(0),
_rc5_command((BYTE)ir_command_table)
{
}

/////////////////////////////////////////////////////////////////////////////////////////
//RC5Decode::submitSample
//
// This is the main entry point, called when there is a DWORD sample available. The 
// function resolves the sample into groups of 0's or 1's, and calls foundGroup() for 
// each group of a valid size that it finds.
//
// foundEndOfCommand() is called when a long string of 1's is recognized, marking the 
// boundary between commands.
//
// The samples can cross DWORD boundaries, so this function saves the current bit it is 
// looking at and the number of bits found in the group in _bit_count and _current_bit.
//
// Returns the command if it finds the end of a command in the current DWORD.  Otherwise, 
// it returns 0xFFFFFFFF.
//

ULONG RC5Decode::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++;
        
            if((current_bit == 1) && (_bit_count == 2*_max_bits_in_group + 1))
            {
                //When we have more than a double group of ones, the command
                // has finished transmitting.
                command = foundEndOfCommand();
            }
        }
        else
        {
            dbgLogTrace(("Found group of %d, %d's\n", _bit_count, _current_bit));

            //We've just switched to a new group.  Check if the
            // last group was valid.
            if((_bit_count >= _min_bits_in_group) &&
                (_bit_count <= _max_bits_in_group))
            {
                //Found a valid group
                foundGroup((GROUP_TYPE)_current_bit);
            }
            //Check for a double group: > max bits, but less than 2* max bits
            else if ((_bit_count > _max_bits_in_group) &&
                (_bit_count <= 2*_max_bits_in_group))
            {
                //Found a valid double group 
                foundGroup((GROUP_TYPE)_current_bit);
                foundGroup((GROUP_TYPE)_current_bit);
            }

            //Switch the bit to check and reset the bit count
            _current_bit = current_bit;
            _bit_count = 1;
        }
    }

    return command;
}

/////////////////////////////////////////////////////////////////////////////////////////
//RC5Decode::foundEndOfCommand
//
// The end of a command is detected when a large group of ones is detected.  (More than 
// the maximum for a double group)
//
// If the command ended in a zero, the last group of ones in the last zero is part of 
// the large group of ones detected after the command.  In this case we need to add a last
// group of ones to our array of groups.
//
// This function checks to see if the right number of groups have been stored in the 
// array.  If the number of groups is correct, it attempts to resolve them into a command.
//
// Returns the command found or 0xFFFFFFF if no command was available.
// 

ULONG RC5Decode::foundEndOfCommand()
{
    //If we are short one group, the last group must 
    // have been a group of ones.  Insert it now.
    if(_group_index == (BITS_PER_COMMAND*GROUPS_PER_BIT-1))
    {
        foundGroup(GROUP_OF_ONES);
    }

    //If we have the correct number of groups, resolve them
    // into a command
    ULONG command = 0xFFFFFFFF;
    if(_group_index == BITS_PER_COMMAND*GROUPS_PER_BIT)
    {
        command = getCommand();
        if(command != 0xFFFFFFFF)
        {
            dbgLogTrace(("Found command %x\n", command));
        }
    }

    //Reset the array for the next command
    _group_index = 0;
    //Add an initial group of ones.  RC5 commands always start with a one, which means 
    // that the first group of ones is in the group between commands.
    foundGroup(GROUP_OF_ONES);

    return command;
}

/////////////////////////////////////////////////////////////////////////////////////////
//RC5Decode::getCommand
//
// getCommand is called when the class thinks it has found a valid command.  This function
// resolves the groups of 0's and 1's found, and stored in _group_array into an RC5 command.
//
// It returns the command, or 0xFFFFFFFF if the command is not valid.
//

ULONG RC5Decode::getCommand()
{
    //There must be 28 groups for the command to be valid.
    if(_group_index != (BITS_PER_COMMAND*GROUPS_PER_BIT))
    {
        return 0xFFFFFFF;
    }

    ULONG command = 0;

    for(BYTE index = 0; index < (BITS_PER_COMMAND*GROUPS_PER_BIT); index = index + 2)
    {
        if((_group_array[index] == GROUP_OF_ONES) &&
            (_group_array[index+1] == GROUP_OF_ZEROS))
        {
            //We have a one if there is a group of ones followed by a group of zeros.
            //The bits need to be or'ed into the command in reverse order  
            command |= ( 1 << (BITS_PER_COMMAND - (index/2) - 1));
        }
        else if((_group_array[index] == GROUP_OF_ZEROS) &&
            (_group_array[index+1] == GROUP_OF_ONES))
        {    
            //We have a zero if there is a group of zeros followed by a group of ones.
            //There's no need to or in zero's
        }
        else
        {
            //Invalid command if there are two groups of zero or one for a single bit
            return 0xFFFFFFFF;
        }
    }

    if(command == _last_command)
    {
        command = DECODE_REPEAT_COMMAND;
    }
    else
    {
        _last_command = command;
        _rc5_command.initialize(command);
    }

    return command;
}

IR_Command* RC5Decode::getIrCommand()
{
    return &_rc5_command;
}

⌨️ 快捷键说明

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