First Release

Dependencies:   USBDevice

InputDeviceDetector.h

Committer:
sankichi
Date:
2013-07-27
Revision:
1:6c392ebcd4d4
Parent:
0:e1265f6b3565

File content as of revision 1:6c392ebcd4d4:

/** Class: InputDeviceDetector
 *
 * Detect input device
 *
 */

#include "mbed.h"
#include "NiseKabuto.h"

class InputDeviceDetector
{
    private:
        // constant
        static const int SELSTATETIME__MICROSEC    = 2;     // Select信号の立ち上げ_立ち下げを行う長さ
                                                            // 短すぎると6Bが反応しない?

        // mbed pins
        DigitalIn   _IN_D0;
        DigitalIn   _IN_D1;
        DigitalIn   _IN_D2;
        DigitalIn   _IN_D3;
        DigitalIn   _IN_D4;
        DigitalIn   _IN_D5;
        DigitalOut  _OUT_SEL;
    
        char        _InputType;
        
    public:
        // Constructor
        InputDeviceDetector(PinName inputPins[])
            :_IN_D0(inputPins[0]), _IN_D1(inputPins[1]), 
             _IN_D2(inputPins[2]), _IN_D3(inputPins[3]), 
             _IN_D4(inputPins[4]), _IN_D5(inputPins[5]), 
             _OUT_SEL(inputPins[6])
        {
            // Pin Setting
            _IN_D0.mode(PullUp);
            _IN_D1.mode(PullUp);
            _IN_D2.mode(PullUp);
            _IN_D3.mode(PullUp);
            _IN_D4.mode(PullUp);
            _IN_D5.mode(PullUp);
            
            // Initialize pin status
            _OUT_SEL = 1;   // output SEL = H
        }

        // public: Return input device type
        char GetInputType()
        {
            char retVal = NiseKabuto::CONFIG_INMODE_CYBERSTICK_ANALOG;
            
            if( Check_MD6B() )
            {
                retVal = NiseKabuto::CONFIG_INMODE_MD6B;
            }
            
            return retVal;
        }

        // Check if MD6B is connected ?
        //  return:
        //      non-0: Connected
        //          0: Not connected
        char Check_MD6B()
        {
            char retVal = 0;
            
            char flag6B = 0;
            int idx = 0;
            char _PhaseData[8];

            // Selを立ち下げ、データ読みを8回
            idx = 0;
            for(int i=0; i<4; i++)
            {
                _OUT_SEL = 0;
                wait_us(SELSTATETIME__MICROSEC);
                
                _PhaseData[idx++] = ReadPinValue();
                
                _OUT_SEL = 1;
                wait_us(SELSTATETIME__MICROSEC);

                _PhaseData[idx++] = ReadPinValue();
            }
            
            idx = 0;
            while(1)
            {
                // D0-D3がLなものを探す
                if( (_PhaseData[idx]&0x0f)==0 )
                {
                    // idx+2をチェック
                    // ただし6を超えた場合はidx-6の位置をチェック
                    if(idx < 6)
                    {
                        if( (_PhaseData[idx+2]&0x0f)==0x0f )
                        {
                            flag6B = 1;
                            break;
                        }
                    }
                    else
                    {
                        if( (_PhaseData[idx-6]&0x0f)==0x0f )
                        {
                            flag6B = 1;
                            break;
                        }
                    }
                }
                
                // このidxではなかった
                idx++;
                // 全部チェックしてしまった
                if( idx == 8 )
                {
                    break;
                }
            }
            
            // この時点でflag6B==0の場合、6Bではない
            if( flag6B != 1 )
            {
                retVal = 0;
            }
            else
            {
                retVal = 1;
            }
            
            return retVal;
        }
        
        // ReadPinValue
        char ReadPinValue()
        {
            return ( 
                (_IN_D5<<5) | (_IN_D4<<4) |
                (_IN_D3<<3) | (_IN_D2<<2) | (_IN_D1<<1) |  _IN_D0
            );
        }

        
};