First Release

Dependencies:   USBDevice

In_MD6B/In_MD6B.cpp

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

File content as of revision 1:6c392ebcd4d4:

#include "In_MD6B.h"
#include "NiseKabuto.h"

//
// Constructor
//
In_MD6B::In_MD6B(
    PinName pn_D0, PinName pn_D1, PinName pn_D2, PinName pn_D3, 
    PinName pn_D4, PinName pn_D5, PinName pn_SEL,
    InputStatus *inputStatus
)  : _IN_D0(pn_D0), _IN_D1(pn_D1), _IN_D2(pn_D2), _IN_D3(pn_D3), 
     _IN_D4(pn_D4), _IN_D5(pn_D5), _OUT_SEL(pn_SEL)
{
    _InputStatus = inputStatus;
    _InputStatus->Reset();  // ボタンなどリセット
    _InputStatus->InputDeviceType = NiseKabuto::CONFIG_INMODE_MD6B;
    
    Initialize();
}


void In_MD6B::StartReading(void)
{
    //printf("In_MD6B::StartReading()!!!\r\n");
    if(!_ReadEnable)
    {
        _ReadEnable = 1;
        Initialize();
    }
}
void In_MD6B::StopReading(void)
{
    //printf("In_MD6B::StopReading()!!!\r\n");
    if(_ReadEnable)
    {
        _ReadEnable = 0;
        DisablePolling();
    }
}



//
// Initialize
//
void In_MD6B::Initialize()
{
    // 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);
    
    // Class Variable Setting
    _ReadEnable = 1;
    
    // Interrupt Setting
    /*
    _INTR_LH.rise(this, &In_MD6B::LHCounter);
    _INTR_ACK.fall(this, &In_MD6B::AckFallISR);
    */
    
    // Initialize pin status
    _OUT_SEL = 1;   // output SEL = H

    // Ticker Setting
    EnablePolling();
}


//
// Enable polling
//
void In_MD6B::EnablePolling(void)
{
    _PollingTicker.attach_us(this, &In_MD6B::PollingMethod, READINGINTERVAL__MICROSEC);
}

//
// Disable polling
//
void In_MD6B::DisablePolling(void)
{
//  printf("In_MD6B::DisablePolling() called!!\r\n");
    _PollingTicker.detach();
}


//
// Polling method
//
void In_MD6B::PollingMethod()
{
    // デバッグ用:この関数が呼ばれるたび+1される
    (_InputStatus->Temp[0])++;
    
    if( _ReadEnable )
    {
        char flag6B = 0;
        int idxPhaseStart = 0;
        int idx = 0;

        // 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)
        {
            (_InputStatus->Temp[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;
                        idxPhaseStart = idx; // 仮の値
                        break;
                    }
                }
                else
                {
                    if( (_PhaseData[idx-6]&0x0f)==0x0f )
                    {
                        flag6B = 1;
                        idxPhaseStart = idx; // 仮の値
                        break;
                    }
                }
            }
            
            // このidxではなかった
            idx++;
            
            // 全部チェックしてしまった
            if( idx >= 8 )  // 2013/05/02
            {
                break;
            }
            
        }
        
        // この時点でflag6B==0の場合、6Bではない
        if( flag6B )
        {
            // ボタン情報が入る予定のビットをoff
            __disable_irq();
            int buttons = (_InputStatus->Buttons) & 0x0f8c0dc;
            //                                             f    8    c    0    d    c
            //                                          1111 1XYZ 11UD LRAB 11C1 11SM
            __enable_irq();

            // idxPhaseStart補正
            if(idx >= 4)
            {
                idxPhaseStart = idxPhaseStart-4;
            }
            else
            {
                idxPhaseStart = idxPhaseStart+4;
            }
            
            // InputStatus
            char data;
            
            //      Phase 0
            data = _PhaseData[idxPhaseStart++];
            if( idxPhaseStart == 8)
            {
                idxPhaseStart = 0;
            }
            buttons = buttons |
                ((data & 0x20) ? 0x000002 : 0) |    // ST
                ((data & 0x10) ? 0x000200 : 0) |    // A
                ((data & 0x02) ? 0x001000 : 0) |    // Dw
                ((data & 0x01) ? 0x002000 : 0) ;    // Up
            
            
            //      Phase 1
            data = _PhaseData[idxPhaseStart++];
            if( idxPhaseStart == 8)
            {
                idxPhaseStart = 0;
            }
            buttons = buttons |
                ((data & 0x20) ? 0x000020 : 0) |    // C
                ((data & 0x10) ? 0x000100 : 0) |    // B
                ((data & 0x08) ? 0x000400 : 0) |    // Rg
                ((data & 0x04) ? 0x000800 : 0) ;    // Lf
            

            //      Phase 2
            //          無視
            data = _PhaseData[idxPhaseStart++];
            if( idxPhaseStart == 8)
            {
                idxPhaseStart = 0;
            }
            //      Phase 3
            //          無視
            data = _PhaseData[idxPhaseStart++];
            if( idxPhaseStart == 8)
            {
                idxPhaseStart = 0;
            }
            //      Phase 4
            //          無視
            data = _PhaseData[idxPhaseStart++];
            if( idxPhaseStart == 8)
            {
                idxPhaseStart = 0;
            }

            //      Phase 5
            data = _PhaseData[idxPhaseStart++];
            if( idxPhaseStart == 8)
            {
                idxPhaseStart = 0;
            }
            buttons = buttons |
                ((data & 0x08) ? 0x000001 : 0) |    // Mode
                ((data & 0x04) ? 0x040000 : 0) |    // X
                ((data & 0x02) ? 0x020000 : 0) |    // Y
                ((data & 0x01) ? 0x010000 : 0) ;    // Z
            
            __disable_irq();
            _InputStatus->Buttons = buttons;
            __enable_irq();
        }

    }
//  printf("E\r\n");
}


//
//ReadPinValue (Pin status -> Class value)
//
int In_MD6B::ReadPinValue()
{
    return ( 
        (_IN_D5<<5) | (_IN_D4<<4) |
        (_IN_D3<<3) | (_IN_D2<<2) | (_IN_D1<<1) |  _IN_D0
    );
}