First Release
Diff: Out_SSMulCon/Out_SSMulCon.cpp
- Revision:
- 0:e1265f6b3565
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Out_SSMulCon/Out_SSMulCon.cpp Sat Jul 27 14:05:47 2013 +0000 @@ -0,0 +1,577 @@ +#include "NiseKabuto.h" + +DigitalOut led1(LED1); + +// +// Constructor +// +Out_SSMulCon::Out_SSMulCon( + PinName pn_D0, PinName pn_D1, PinName pn_D2, PinName pn_D3, + PinName pn_TL, PinName pn_TR, PinName pn_TH, + InputStatus *inputStatus) + : _OUT_D0(pn_D0), _OUT_D1(pn_D1), _OUT_D2(pn_D2), _OUT_D3(pn_D3), + _INTR_TL(pn_TL), _INTR_TR(pn_TR), _OUT_TH(pn_TH) +{ + _InputStatus = inputStatus; + Initialize(); +} + +// +// Initialize +// +void Out_SSMulCon::Initialize() +{ + + // Pin Setting + _INTR_TL.mode(PullUp); + _INTR_TR.mode(PullUp); + + // Class Variable Setting + RenewOutputMode();//_OutputMode = 0; + _PhaseCounter = 0; + _NowWriting = 0; + _RapidFireValue = 1; + + // Interrupt Setting + _INTR_TL.fall(this, &Out_SSMulCon::StrobeFallISR); + _INTR_TL.rise(this, &Out_SSMulCon::StrobeRiseISR); + _INTR_TR.fall(this, &Out_SSMulCon::ClockFallISR); + _INTR_TR.rise(this, &Out_SSMulCon::ClockRiseISR); + + // Initialize pin status + InitializePinStatus(); + +} + +// +// Initialize pin status +// +void Out_SSMulCon::InitializePinStatus() +{ + SetD3D2D1D0(0,0,0,1); + + _OUT_TH = 1; + +} + +// +// ISR for S0/Strobe=L +// +void Out_SSMulCon::StrobeFallISR(void) +{ + if( _NowWriting != 1 ) + { + /* + // デジタル出力・アナログ出力を_IN_CONFIGによって決める + _OutputMode = _IN_CONFIG; + led1 = _OutputMode; + */ + + // データフェーズカウンタ初期化 + _PhaseCounter = 0; + + // ピン状態の設定(phase0向けデータ) + //SetPinStatus(); + InitializePinStatus(); + SetPinStatus(); + + // データ出力中 + _NowWriting = 1; + + DisableInput(); + } + + RenewOutputMode(); +} + +// +// ISR for S0/Strobe=H +// +void Out_SSMulCon::StrobeRiseISR(void) +{ + led1 = 0; + + // データフェーズカウンタ初期化 + _PhaseCounter = 0; + + // データ出力終了 + _NowWriting = 0; + + // ピン状態戻す + InitializePinStatus(); + + EnableInput(); + + RenewOutputMode(); + + _RapidFireValue=!_RapidFireValue; +} + +// +// ISR for S1/Clock=L +// +void Out_SSMulCon::ClockFallISR(void) +{ + // データ出力中の場合のみ処理する + if(_NowWriting==1) + { + // アナログ出力モード + if( _OutputMode==OUTPUTMODE_ANALOG ) + { + switch(_PhaseCounter) + { + case 0: + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + _PhaseCounter++; + break; + } + } + // デジタル出力モード + else + { + switch(_PhaseCounter) + { + case 0: + case 2: + case 4: + case 6: + _PhaseCounter++; + break; + } + } + SetPinStatus(); + _OUT_TH = 0; + } +} + +// +// ISR for S1/Clock=H +// +void Out_SSMulCon::ClockRiseISR(void) +{ + // データ出力中の場合のみ処理する + if(_NowWriting==1) + { + // アナログ出力モード + if( _OutputMode==OUTPUTMODE_ANALOG ) + { + switch(_PhaseCounter) + { + case 1: + case 3: + case 5: + case 7: + case 9: + case 11: + case 13: + _PhaseCounter++; + break; + case 15: + _PhaseCounter=0; + break; + } + } + // デジタル出力モード + else + { + switch(_PhaseCounter) + { + case 1: + case 3: + case 5: + _PhaseCounter++; + break; + case 7: + _PhaseCounter=0; + break; + } + } + + SetPinStatus(); + _OUT_TH = 1; + } +} + + +// +// Set Pin D3,D2,D1,D0 Status +// +void Out_SSMulCon::SetD3D2D1D0(char d3, char d2, char d1, char d0) +{ + _OUT_D0 = d0; + _OUT_D1 = d1; + _OUT_D2 = d2; + _OUT_D3 = d3; +} + +// +// Set Pin D3,D2,D1,D0 Status (bus) +// +void Out_SSMulCon::SetBus(char data) +{ + _OUT_D0 = data & 0x01; + _OUT_D1 = (data>>1) & 0x01; + _OUT_D2 = (data>>2) & 0x01; + _OUT_D3 = (data>>3) & 0x01; +} + + + +// +// Set Pin Status +// +void Out_SSMulCon::SetPinStatus(void) +{ + // データ出力中の場合のみ処理する + if(_NowWriting==1) + { + // Get InputStatus + InputStatus *inp = _InputStatus; + char chDat = 0; + + int buttons = _InputStatus->Buttons; + char ch0 = _InputStatus->Ch0; + char ch1 = _InputStatus->Ch1; + char ch2 = _InputStatus->Ch2; + char ch3 = _InputStatus->Ch3; + + char trigR; + char trigL; + + // サイバースティック アナログ出力モード + if( _OutputMode==OUTPUTMODE_ANALOG ) + { + switch(_PhaseCounter) + { + case 0: + case 1: + SetD3D2D1D0(0,0,0,1); + break; + + case 2: + SetD3D2D1D0(0,1,1,0); + break; + + case 3: + if(!(buttons & 0x01)) // G(SELECT)ボタンが押されてたら、アナログスティックで十字キー操作 + { + SetD3D2D1D0 + ( + ch1>0xf0? 0:1, + ch1<0x0f? 0:1, + ch0>0xf0? 0:1, + ch0<0x0f? 0:1 + ); + } + else + { + SetD3D2D1D0(1,1,1,1); + } + break; + + case 4: + SetD3D2D1D0( + ((inp->Buttons) & 0x0002)?1:0, // Start + ((inp->Buttons) & 0x0200)?1:0, // A + ((inp->Buttons) & 0x0020)?1:0, // C + ((inp->Buttons) & 0x0100)?1:0 // B + ); + break; + + case 5: + trigR = 1; + if(!(buttons & 0x01)) // G(SELECT)ボタンが押されてたら、スロットルでRキー操作 + { + trigR = ch2<0x0f? 0:1; //スロットル引く + } + + SetD3D2D1D0( + trigR, // R-Trigger + ((inp->Buttons) & 0x0010)?1:0, // D is X + ((inp->Buttons) & 0x0008)?1:0, // E1 is Y + ((inp->Buttons) & 0x0004)?1:0 // E2 is Z + ); + break; + + case 6: + trigL = 1; + if(!(buttons & 0x01)) // G(SELECT)ボタンが押されてたら、スロットルでLキー操作 + { + trigL = ch2>0xf0? 0:1; //スロットル押す + } + + SetD3D2D1D0( + trigL, // L-Trigger + 1, // (H) + 1, // (H) + 1 // (H) + ); + break; + + case 7: + chDat = inp->Ch1; // Upper4bits of axis-X + SetBus(chDat>>4); + break; + + case 8: + chDat = inp->Ch1; // Lower4bits of axis-X + SetBus(chDat); + break; + + case 9: + chDat = inp->Ch0; // Upper4bits of axis-Y + SetBus(chDat>>4); + break; + + case 10: + chDat = inp->Ch0; // Lower4bits of axis-Y + SetBus(chDat); + break; + + case 11: + chDat = inp->Ch2; // Upper4bits of throttle + SetBus(chDat>>4); + break; + + case 12: + chDat = inp->Ch2; // Lower4bits of throttle + SetBus(chDat); + break; + + case 13: + SetD3D2D1D0(0,0,0,0); // L Trigger Upper 4bits + break; + + case 14: + SetD3D2D1D0(0,0,0,0); // L Trigger Lower 4bits + break; + + case 15: + SetD3D2D1D0(0,0,0,0); // final phase + break; + + } + } + // サイバースティック デジタル出力モード + else if( _OutputMode==OUTPUTMODE_DIGITAL ) + { + switch(_PhaseCounter) + { + case 0: + SetD3D2D1D0(0,0,0,1); + break; + + case 1: + SetD3D2D1D0(0,0,0,0); + break; + + case 2: + SetD3D2D1D0(0,0,1,0); + break; + + case 3: + SetD3D2D1D0( + ((inp->Buttons) & 0x0400)? 1 : 0, // Right + ((inp->Buttons) & 0x0800)? 1 : 0, // Left + ((inp->Buttons) & 0x1000)? 1 : 0, // Down + ((inp->Buttons) & 0x2000)? 1 : 0 // Up + ); + + break; + + case 4: + // サイバースティックはStartボタンが無い縺ョで、Dで代用 + SetD3D2D1D0( + (((inp->Buttons) & 0x0002)?1:0) & (((inp->Buttons) & 0x0010)?1:0), // Start & D + ((inp->Buttons) & 0x0200)?1:0, // A + ((inp->Buttons) & 0x0020)?1:0, // C + ((inp->Buttons) & 0x0100)?1:0 // B + ); + break; + + case 5: + SetD3D2D1D0( + ((inp->Buttons) & 0x8000)?1:0, // R-Trigger(=ThrotUp) + ((inp->Buttons) & 0x0010)?1:0, // X + ((inp->Buttons) & 0x0008)?1:0, // Y + ((inp->Buttons) & 0x0004)?1:0 // Z + ); + break; + + case 6: + SetD3D2D1D0( + ((inp->Buttons) & 0x4000)?1:0, // L-Trigger + 1, // (H) + 1, // (H) + 1 // (H) + ); + break; + + case 7: + SetD3D2D1D0(0,0,0,0); + break; + } + } + // 6B + else if( _OutputMode==OUTPUTMODE_6B ) + { + switch(_PhaseCounter) + { + case 0: + SetD3D2D1D0(0,0,0,1); + break; + + case 1: + SetD3D2D1D0(0,0,0,0); + break; + + case 2: + SetD3D2D1D0(0,0,1,0); + break; + + case 3: + SetD3D2D1D0( + ((inp->Buttons) & 0x0400)? 1 : 0, // Right + ((inp->Buttons) & 0x0800)? 1 : 0, // Left + ((inp->Buttons) & 0x1000)? 1 : 0, // Down + ((inp->Buttons) & 0x2000)? 1 : 0 // Up + ); + + break; + + case 4: + // modeキーが押されてたら、_RapidFireValue値を有効に + if( !((inp->Buttons) & 0x0001) ) + { + SetD3D2D1D0( + ((inp->Buttons) & 0x0002)?1:0, // Start + ((inp->Buttons) & 0x0200)?1:_RapidFireValue, // A + ((inp->Buttons) & 0x0020)?1:_RapidFireValue, // C + ((inp->Buttons) & 0x0100)?1:_RapidFireValue // B + ); + } + else + { + SetD3D2D1D0( + ((inp->Buttons) & 0x0002)?1:0, // Start + ((inp->Buttons) & 0x0200)?1:0, // A + ((inp->Buttons) & 0x0020)?1:0, // C + ((inp->Buttons) & 0x0100)?1:0 // B + ); + } + break; + + case 5: + // modeキーが押されてたら、_RapidFireValue値を有効に + if( !((inp->Buttons) & 0x0001) ) + { + // Rトリガはmode+右 + SetD3D2D1D0( + ((inp->Buttons) & 0x0401)?1:0, // R-Trigger + ((inp->Buttons) & 0x0010)?1:_RapidFireValue, // X + ((inp->Buttons) & 0x0008)?1:_RapidFireValue, // Y + ((inp->Buttons) & 0x0004)?1:_RapidFireValue // Z + ); + } + else + { + // Rトリガはmode+右 <-おかしい? + SetD3D2D1D0( + ((inp->Buttons) & 0x0401)?1:0, // R-Trigger + ((inp->Buttons) & 0x0010)?1:0, // X + ((inp->Buttons) & 0x0008)?1:0, // Y + ((inp->Buttons) & 0x0004)?1:0 // Z + ); + } + break; + + case 6: + // Lトリガはmode+左 + SetD3D2D1D0( + ((inp->Buttons) & 0x0801)?1:0, // L-Trigger + 1, // (H) + 1, // (H) + 1 // (H) + ); + break; + + case 7: + SetD3D2D1D0(0,0,0,0); + break; + } + } + + } +} + + +// +// Set output mode +// +void Out_SSMulCon::RenewOutputMode(void) +{ + switch(_InputStatus->InputDeviceType) + { + // + // Input: CyberStick ANALOG mode + // + case NiseKabuto::CONFIG_INMODE_CYBERSTICK_ANALOG: + _OutputMode = OUTPUTMODE_ANALOG; + break; + + // + // Input: CyberStick DIGITAL mode + // 6B + // + case NiseKabuto::CONFIG_INMODE_CYBERSTICK_DIGITAL: + _OutputMode = OUTPUTMODE_DIGITAL; + break; + + case NiseKabuto::CONFIG_INMODE_MD6B: + _OutputMode = OUTPUTMODE_6B; + break; + + default: + _OutputMode = OUTPUTMODE_ANALOG; + break; + } +} + + +void Out_SSMulCon::SetupInputControll(void (*startInputFunction)(void), void (*stopInputFunction)(void)) +{ + StartInputFunction = startInputFunction; + StopInputFunction = stopInputFunction; +} + +void Out_SSMulCon::EnableInput(void) +{ + if(_InputInstance && StartInputMethod) + { + (_InputInstance->*StartInputMethod)(); + } + else if(StartInputFunction) + { + StartInputFunction(); + } +} + +void Out_SSMulCon::DisableInput(void) +{ + if(_InputInstance && StopInputMethod) + { + (_InputInstance->*StopInputMethod)(); + } + else if(StopInputFunction) + { + StopInputFunction(); + } +} + +