First Release

Dependencies:   USBDevice

NiseKabuto.cpp

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

File content as of revision 1:6c392ebcd4d4:

#include "NiseKabuto.h"
#include "InputDeviceDetector.h"

// _InputTypeとInputStatus.InputDeviceTypeの違いは????

/**
--------------------------------------------------

 Constructor

--------------------------------------------------
**/
NiseKabuto::NiseKabuto(PinName inputPins[], PinName outputPins[], PinName configurePins[])
 : 
    _ConfigSwitch(
        configurePins[0],configurePins[1],configurePins[2],configurePins[3],
        configurePins[4],configurePins[5],configurePins[6],configurePins[7]
    )
{
    InitInterruptPriority();
//  InitTimer0();
    
    // Pin Setting
    _ConfigSwitch.mode(PullUp);
    
    // Detect Input device
    InputDeviceDetector myDetector = InputDeviceDetector(inputPins);
    _InputType = myDetector.GetInputType();
    //printf("_InputType: %d\n",_InputType & 0xff);
    

    // Initialize  input instance
    switch(_InputType)
    {
        case CONFIG_INMODE_CYBERSTICK_ANALOG:
        case CONFIG_INMODE_CYBERSTICK_DIGITAL:
            // Initialize Input: CyberStick
            InitInput_CyberStick(inputPins);
            break;
            
        case CONFIG_INMODE_MD6B:
            // Initialize Input: MD6B
            InitInput_MD6B(inputPins);
            break;

        default:
            InitInput_MD6B(inputPins);
            break;
    }

    /*
    wait_ms(5000);
    printf("_ConfigSwitch: %d\n",_ConfigSwitch & 0xff);
    */
    
    // Save output mode
    //printf("CS:%02x\n\r",~_ConfigSwitch);
    _OutputType = (~_ConfigSwitch) & 0x0ff;

    // Initialize output instance
    switch(_OutputType)
    {
        case CONFIGPIN_OUTMODE_SSMULCON:
            // Initialize Output: SS Multi Controller
            InitOutput_SSMulCon(outputPins);
            break;
            
        case CONFIGPIN_OUTMODE_PCE:
            // Initialize Output: PCE Analog/Digital Controller
            InitOutput_PCE(outputPins);
            break;

        case CONFIGPIN_OUTMODE_FC:
            // Initialize Output: Famicom Controller
            InitOutput_FC(outputPins);
            break;
        case CONFIGPIN_OUTMODE_MD:
            // Initialize Output: Megadrive analog joystick
            InitOutput_MD(outputPins);
            break;
        default:
            // Initialize Output: PlayStation3 USB Joystick
            InitOutput_PS3USB();
            break;
    }
}


/**
--------------------------------------------------

 Initialize Input Device: CyberStick

--------------------------------------------------
**/
void NiseKabuto::InitInput_CyberStick(PinName inputPins[])
{
    // Create In_CyberStick instance
    _In_CyberStick = new In_CyberStick(
                    inputPins[0],inputPins[1],inputPins[2],inputPins[3],
                    inputPins[4],inputPins[5],inputPins[6],&_InputStatus);
}



/**
--------------------------------------------------

 Initialize Input Device: Fighting Pad 6B

--------------------------------------------------
**/
void NiseKabuto::InitInput_MD6B(PinName inputPins[])
{
    // Create In_CyberStick instance
    _In_MD6B= new In_MD6B(
                    inputPins[0],inputPins[1],inputPins[2],inputPins[3],
                    inputPins[4],inputPins[5],inputPins[6],&_InputStatus);
}



/**
--------------------------------------------------

 Initialize Output Device: Megadrive analog/digital joystick

--------------------------------------------------
**/
void NiseKabuto::InitOutput_MD(PinName outputPins[])
{
    // Create Out_MD instance
    _Out_MD = new Out_MD(
                    outputPins[0],outputPins[1],outputPins[2],outputPins[3],
                    outputPins[4],outputPins[5],outputPins[6],
                    &_InputStatus
                );
    
    if( _InputType == CONFIG_INMODE_CYBERSTICK_ANALOG || _InputType == CONFIG_INMODE_CYBERSTICK_DIGITAL) 
    {
        _Out_MD->SetupInputControll(_In_CyberStick, &In_CyberStick::StartReading, &In_CyberStick::StopReading);
    }
    else if( _InputType == CONFIG_INMODE_MD6B )
    {
        _Out_MD->SetupInputControll(_In_MD6B, &In_MD6B::StartReading, &In_MD6B::StopReading);
    }
}

/**
--------------------------------------------------

 Initialize Output Device: SS Multi Controller

--------------------------------------------------
**/
void NiseKabuto::InitOutput_SSMulCon(PinName outputPins[])
{
    // Create Out_SSMulCon instance
    _Out_SSMulCon = new Out_SSMulCon(
                    outputPins[0],outputPins[1],outputPins[2],outputPins[3],
                    outputPins[4],outputPins[5],outputPins[6],
                    &_InputStatus
                );

    if( _InputType == CONFIG_INMODE_CYBERSTICK_ANALOG || _InputType == CONFIG_INMODE_CYBERSTICK_DIGITAL) 
    {
        _Out_SSMulCon->SetupInputControll(_In_CyberStick, &In_CyberStick::StartReading, &In_CyberStick::StopReading);
    }
    else if( _InputType == CONFIG_INMODE_MD6B )
    {
        _Out_SSMulCon->SetupInputControll(_In_MD6B, &In_MD6B::StartReading, &In_MD6B::StopReading);
    }
}

/**
--------------------------------------------------

 Initialize Output Device: PCE Analog/Digital Controller

--------------------------------------------------
**/
void NiseKabuto::InitOutput_PCE(PinName outputPins[])
{
    // Create Out_PCEAnalog instance
    _Out_PCE = new Out_PCE(
                    outputPins[0],outputPins[1],outputPins[2],outputPins[3],
                    outputPins[4],outputPins[5],outputPins[6],
                    &_InputStatus
                );

    if( _InputType == CONFIG_INMODE_CYBERSTICK_ANALOG || _InputType == CONFIG_INMODE_CYBERSTICK_DIGITAL) 
    {
        _Out_PCE->SetupInputControll(_In_CyberStick, &In_CyberStick::StartReading, &In_CyberStick::StopReading);
    }
    else if( _InputType == CONFIG_INMODE_MD6B )
    {
        _Out_PCE->SetupInputControll(_In_MD6B, &In_MD6B::StartReading, &In_MD6B::StopReading);
    }
}


/**
--------------------------------------------------

 Initialize Output Device: Famicom Controller

--------------------------------------------------
**/
void NiseKabuto::InitOutput_FC(PinName outputPins[])
{
    // Create Out_FC instance
    _Out_FC = new Out_FC(
                    outputPins[0],outputPins[1],outputPins[2],outputPins[3],
                    &_InputStatus
                );

    if( _InputType == CONFIG_INMODE_CYBERSTICK_ANALOG || _InputType == CONFIG_INMODE_CYBERSTICK_DIGITAL) 
    {
        _Out_FC->SetupInputControll(_In_CyberStick, &In_CyberStick::StartReading, &In_CyberStick::StopReading);
    }
    else if( _InputType == CONFIG_INMODE_MD6B )
    {
        _Out_FC->SetupInputControll(_In_MD6B, &In_MD6B::StartReading, &In_MD6B::StopReading);
    }
}

/**
--------------------------------------------------

 Initialize Output Device: PlayStation3 USB Joystick

--------------------------------------------------
**/
void NiseKabuto::InitOutput_PS3USB(void)
{
    // Create Out_PS3USB instance
    _Out_PS3USB = new Out_PS3USB(
                    &_InputStatus
                );

    if( _InputType == CONFIG_INMODE_CYBERSTICK_ANALOG || _InputType == CONFIG_INMODE_CYBERSTICK_DIGITAL) 
    {
        _Out_PS3USB->SetupInputControll(_In_CyberStick, &In_CyberStick::StartReading, &In_CyberStick::StopReading);
    }
    else if( _InputType == CONFIG_INMODE_MD6B )
    {
        _Out_PS3USB->SetupInputControll(_In_MD6B, &In_MD6B::StartReading, &In_MD6B::StopReading);
    }
}


/**
--------------------------------------------------

 Show (for test)

--------------------------------------------------
**/

void NiseKabuto::Show()
{
    char    strBuf[100];

    __disable_irq();
    int val = _InputStatus.Buttons;
    int ch0 = _InputStatus.Ch0;
    int ch1 = _InputStatus.Ch1;
    int ch2 = _InputStatus.Ch2;
    int ch3 = _InputStatus.Ch3;
    char mode = _InputStatus.InputDeviceType;
    char temp0 = _InputStatus.Temp[0];
    char temp1 = _InputStatus.Temp[1];
    char temp2 = _InputStatus.Temp[2];
    char temp3 = _InputStatus.Temp[3];
    char temp4 = _InputStatus.Temp[4];
    char temp5 = _InputStatus.Temp[5];
    __enable_irq();
    
    strBuf[0]=0;

    switch(mode)
    {
        case CONFIG_INMODE_CYBERSTICK_ANALOG:
        case CONFIG_INMODE_CYBERSTICK_DIGITAL:
            strcat(strBuf, "CS");
            if( mode==CONFIG_INMODE_CYBERSTICK_ANALOG )
            {
                strcat(strBuf, "AN");
            }
            else
            {
                strcat(strBuf, "DG");
            }
            break;
            
        case CONFIG_INMODE_MD6B:
            strcat(strBuf, "6B");
            break;
    }

    switch(_OutputType)
    {
        case CONFIGPIN_OUTMODE_SSMULCON:
            strcat(strBuf, "->SSMC ");
            break;
            
        case CONFIGPIN_OUTMODE_PCE:
            strcat(strBuf, "->PCE ");
            break;

        case CONFIGPIN_OUTMODE_FC:
            strcat(strBuf, "->Famicom ");
            break;

        case CONFIGPIN_OUTMODE_MD:
            strcat(strBuf, "->MD ");
            break;      

        default:
            strcat(strBuf, "->PS3USB ");
            break;      
    }
    
    switch(mode)
    {
        case CONFIG_INMODE_CYBERSTICK_ANALOG:
        case CONFIG_INMODE_CYBERSTICK_DIGITAL:
            strcat(strBuf, val & 0x8000? "---" : "Tup");
            strcat(strBuf, val & 0x4000? "---" : "Tdw");
            strcat(strBuf, val & 0x2000? "-" : "U");
            strcat(strBuf, val & 0x1000? "-" : "D");
            strcat(strBuf, val & 0x0800? "-" : "L");
            strcat(strBuf, val & 0x0400? "-" : "R");
            strcat(strBuf, val & 0x0200? "-" : "A");
            strcat(strBuf, val & 0x0100? "-" : "B");
            strcat(strBuf, val & 0x0020? "-" : "C");
            strcat(strBuf, val & 0x0010? "-" : "D");
            strcat(strBuf, val & 0x0008? "--" : "E1");
            strcat(strBuf, val & 0x0004? "--" : "E2");
            strcat(strBuf, val & 0x0002? "---" : "Fst");
            strcat(strBuf, val & 0x0001? "---" : "Gsl");
            strcat(strBuf, val & 0x0080? "--" : "A'");
            strcat(strBuf, val & 0x0040? "--" : "B'");
            printf("%s ",strBuf);

            printf("CH0:%02X ",   ch0);
            printf("CH1:%02X ",   ch1);
            printf("CH2:%02X ",   ch2);
            printf("CH3:%02X ",   ch3);
            /*
            printf("\r\ni:%02x o:%02x %02x %02x ", temp0, temp2, temp5, temp4); // debug(in, out functions)
            printf("tc(%u) mr0(%u) ", LPC_TIM3->TC, LPC_TIM3->MR0);             // debug(TIMER3)
            */
            printf("\r\n");

            break;

        case CONFIG_INMODE_MD6B:
            strcat(strBuf, val & 0x002000? "-" : "U");
            strcat(strBuf, val & 0x001000? "-" : "D");
            strcat(strBuf, val & 0x000800? "-" : "L");
            strcat(strBuf, val & 0x000400? "-" : "R");
            strcat(strBuf, val & 0x000200? "-" : "A");
            strcat(strBuf, val & 0x000100? "-" : "B");
            strcat(strBuf, val & 0x000020? "-" : "C");
            strcat(strBuf, val & 0x040000? "-" : "X");
            strcat(strBuf, val & 0x020000? "-" : "Y");
            strcat(strBuf, val & 0x010000? "-" : "Z");
            strcat(strBuf, val & 0x000002? "-" : "S");
            strcat(strBuf, val & 0x000001? "-" : "M");
            printf("%s ",strBuf);
            //printf("%02x %02x %02x %02x %02x %02x", temp0, temp1, temp2, temp3, temp4, temp5);
            /*
            printf("i:%02x o:%02x %02x %02x ", temp0, temp2, temp5, temp4);
            printf("TIM3 tc(%u) mr0(%u) diff(%d)", 
                LPC_TIM3->TC, 
                LPC_TIM3->MR0, 
                int(LPC_TIM3->MR0) - int(LPC_TIM3->TC) );
            */
            printf("\r\n");
            /*
            printf("\r\nIR:%08x,TCR:%08x,PR:%08x,PC:%08x,MCR:%08x,EMR:%08x,CTCR:%08x tc(%u) mr0(%u) diff(%d) pending:%u ", 
            //  NVIC_GetActive(TIMER3_IRQn),
                LPC_TIM3->IR, 
                LPC_TIM3->TCR, 
                LPC_TIM3->PR, 
                LPC_TIM3->PC, 
                LPC_TIM3->MCR, 
                LPC_TIM3->EMR, 
                LPC_TIM3->CTCR, 
                LPC_TIM3->TC, 
                LPC_TIM3->MR0, 
                int(LPC_TIM3->MR0) - int(LPC_TIM3->TC), 
                ( NVIC->ISPR[0] & ( 1<<4 ) ) );
            printf("\r\n");
            */
            break;
    }

    //
    // ここで実行させるのはおかしいが、暫定的に
    //
    if( (int(LPC_TIM3->MR0) - int(LPC_TIM3->TC)) <0 )
    {
        printf("=================================================\r\n");
        printf("                   Resetting MR0 !!!!            \r\n");
        printf("=================================================\r\n");
        LPC_TIM3->MR0 = LPC_TIM3->TC + 1000;
    }

}

void NiseKabuto::InitInterruptPriority(void)
{
    // http://mbed.org/users/earlz/code/MbedConsole/file/370b9e559f92/main.cpp
    
    NVIC_SetPriority(NonMaskableInt_IRQn, 100 ); 
    NVIC_SetPriority(MemoryManagement_IRQn, 100);
    
    NVIC_SetPriority(BusFault_IRQn, 100);
    NVIC_SetPriority(UsageFault_IRQn, 100);
    NVIC_SetPriority(SVCall_IRQn, 100);
    NVIC_SetPriority(DebugMonitor_IRQn, 100);
    NVIC_SetPriority(PendSV_IRQn, 100);
    NVIC_SetPriority(SysTick_IRQn, 50);
    NVIC_SetPriority(WDT_IRQn, 100);
    NVIC_SetPriority(TIMER0_IRQn, 85);
    NVIC_SetPriority(TIMER1_IRQn, 85);
    NVIC_SetPriority(TIMER2_IRQn, 85);
    NVIC_SetPriority(TIMER3_IRQn, 85);
    NVIC_SetPriority(UART0_IRQn, 75);
    NVIC_SetPriority(UART1_IRQn, 100);
    NVIC_SetPriority(UART2_IRQn, 100);
    NVIC_SetPriority(UART3_IRQn, 100);
    
    NVIC_SetPriority(PWM1_IRQn, 100);
    NVIC_SetPriority(I2C0_IRQn, 100);
    NVIC_SetPriority(I2C1_IRQn, 100);
    NVIC_SetPriority(I2C2_IRQn, 100);
    NVIC_SetPriority(SPI_IRQn, 100);
    NVIC_SetPriority(SSP0_IRQn, 100);
    NVIC_SetPriority(SSP1_IRQn, 100);
    NVIC_SetPriority(PLL0_IRQn, 100);
    NVIC_SetPriority(RTC_IRQn, 100);
    NVIC_SetPriority(EINT0_IRQn, 100);
    NVIC_SetPriority(EINT1_IRQn, 100);
    
    NVIC_SetPriority(EINT2_IRQn, 100);
    NVIC_SetPriority(EINT3_IRQn, 20);    // 最高
    NVIC_SetPriority(ADC_IRQn, 100);
    NVIC_SetPriority(BOD_IRQn, 100);
    NVIC_SetPriority(USB_IRQn, 100);
    NVIC_SetPriority(CAN_IRQn, 100);
    NVIC_SetPriority(DMA_IRQn, 100);
    
    NVIC_SetPriority(I2S_IRQn, 100);
    NVIC_SetPriority(ENET_IRQn, 100);
    NVIC_SetPriority(RIT_IRQn, 100);
    NVIC_SetPriority(MCPWM_IRQn, 100);
    NVIC_SetPriority(QEI_IRQn, 100);
    NVIC_SetPriority(PLL1_IRQn, 100);
    
}


void NiseKabuto::WaitUs(uint32_t nus)
{
    uint32_t countNop, countNopMAX;
    countNopMAX = 24;   // 96MHz動作のmbedで、1usになるような値にする
    
    for(uint32_t i=0; i<nus; i++)
    {
        countNop = countNopMAX;
        while(countNop--)
        {
            __nop();
        }
    }

}