First Release
In_CyberStick/In_CyberStick.cpp
- Committer:
- sankichi
- Date:
- 2013-07-27
- Revision:
- 0:e1265f6b3565
File content as of revision 0:e1265f6b3565:
#include "In_CyberStick.h" #include "NiseKabuto.h" DigitalOut led11(LED1); DigitalOut led22(LED2); DigitalOut dbgPin(p8); // // Constructor // In_CyberStick::In_CyberStick( PinName pn_D0, PinName pn_D1, PinName pn_D2, PinName pn_D3, PinName pn_LH, PinName pn_ACK, PinName pn_REQ, InputStatus *inputStatus ) : _IN_D0(pn_D0), _IN_D1(pn_D1), _IN_D2(pn_D2), _IN_D3(pn_D3), _IN_LH(pn_LH), _IN_ACK(pn_ACK), _OUT_REQ(pn_REQ) { _InputStatus = inputStatus; _InputStatus->Reset(); // ボタンなどリセット _InputStatus->InputDeviceType = NiseKabuto::CONFIG_INMODE_CYBERSTICK_ANALOG; //とりあえずアナログにしておく _AnalogReadFailCounter = 0; Initialize(); } void In_CyberStick::StartReading(void) { //printf("In_CyberStick::StartReading()\r\n"); if(!_ReadEnable) { _ReadEnable = 1; Initialize(); } } void In_CyberStick::StopReading(void) { //printf("In_CyberStick::StopReading()\r\n"); if(_ReadEnable) { _ReadEnable = 0; DisablePolling(); } } // // Initialize // void In_CyberStick::Initialize() { // Pin Setting _IN_D0.mode(PullUp); _IN_D1.mode(PullUp); _IN_D2.mode(PullUp); _IN_D3.mode(PullUp); _IN_LH.mode(PullUp); _IN_ACK.mode(PullUp); // Class Variable Setting _ReadEnable = 1; // Interrupt Setting // Initialize pin status _OUT_REQ = 1; // output REQ = H // Ticker Setting EnablePolling(); } // // Enable polling // void In_CyberStick::EnablePolling(void) { _PollingTicker.attach_us(this, &In_CyberStick::PollingMethod, REQUESTINTERVAL__MICROSEC); // FCAB 入力乱れ対策 _ReadEnable = 1; _OUT_REQ = 1; } // // Polling method // void In_CyberStick::PollingMethod() { // デバッグ用:この関数が呼ばれるたび+1される (_InputStatus->Temp[0])++; if(_ReadEnable) { // 割り込み停止しない //__disable_irq(); int waitLoop = 8000; //8000;//11300;//22600; char state = 1; char phase = 0; char cycle = 0; // Req下げ _OUT_REQ = 0; //wait_us(2); //_OUT_REQ = 1; cycle = 0; while( cycle<6 ) { // LH=1の間待つ if(state) { while( _IN_LH ) { waitLoop--; if(!waitLoop) { // TimeOut ! state = 0; break; } } } // ACK=1の間待つ if(state) { while( _IN_ACK ) { waitLoop--; if(!waitLoop) { // TimeOut ! state = 0; break; } } } if(state) { // データ読み出し ReadPhase(phase++); } // LH=0の間待つ if(state) { while( !(_IN_LH) ) { waitLoop--; if(!waitLoop) { // TimeOut ! state = 0; break; } } } // ACK=1の間待つ if(state) { // REQ立ち上げ // (最速モードのため、2回目のAck立下りまでに行う。このあたり?) _OUT_REQ = 1; while( _IN_ACK ) { waitLoop--; if(!waitLoop) { // TimeOut ! state = 0; break; } } } if(state) { // データ読み出し ReadPhase(phase++); } if(!state) { break; } cycle++; } // 割り込み禁止しない //__enable_irq(); if(state) { // ここまでstate==1のままで終わったら、完全にアナログスティックといえる _InputStatus->InputDeviceType = NiseKabuto::CONFIG_INMODE_CYBERSTICK_ANALOG; led11 = 1; // Analog読み失敗カウンタリセット _AnalogReadFailCounter = 0; //データ確定 CommitAnalogData(); } else { // printf("_AnalogReadFailCounter: %d\r\n",_AnalogReadFailCounter); // 数回のAnalog読み失敗を許容 // // 出力処理側のISRなどに割り込まれ、失敗するケースもある // // _AnalogReadFailCounter++; // この値を大きくすると、一時的なデジタルスティック化は避けられるが // DIGITAL/ANALOG切り替えスイッチへの追従が遅れる if(_AnalogReadFailCounter > 10) { // この時点でstate==0なら、未接続/デジタルモード _InputStatus->InputDeviceType = NiseKabuto::CONFIG_INMODE_CYBERSTICK_DIGITAL; led11 = 0; DigitalModeReader(); if(_AnalogReadFailCounter>1000) { _AnalogReadFailCounter = 10; } } } } } // // Disable polling // void In_CyberStick::DisablePolling(void) { _PollingTicker.detach(); //Enable/DisableInput()を頻繁に呼ぶと、デジアナモード判定が乱れる問題対策 if( _ReadEnable ) { } } // // デジタルモードでの読み取り処理 // void In_CyberStick::DigitalModeReader(void) { int btnData = _InputStatus->Buttons; // PC4=“0” _OUT_REQ = 0; wait_us(1); btnData = (_IN_D0? 0x02000 : 0) | // Up (_IN_D1? 0x01000 : 0) | // Down (_IN_D2? 0x00800 : 0) | // Left (_IN_D3? 0x00400 : 0) | // Right (_IN_LH? 0x00200 : 0) | // A (_IN_ACK? 0x00100 : 0) | // B ((_IN_D2==0 && _IN_D3==0)? 0 : 0x02) | // F(Start) ((_IN_D0==0 && _IN_D1==0)? 0 : 0x01) ; // G(Select) /* // デジタルモードのとき、サイバースティックは // Start,Selectの情報は得られない。 // カブトガニのF(Start),G(Select)については、 // F=LR同時押し、G=UD同時押しとして認識される。 */ // PC4=“1” _OUT_REQ = 1; wait_us(1); btnData = btnData | (_IN_D0? 0x08000 : 0) | // Throt Up (_IN_D1? 0x04000 : 0) | // Throt Down (_IN_D2? 0x00020 : 0) | // C (_IN_D3? 0x00010 : 0) | // D (_IN_LH? 0x00008 : 0) | // E1 (_IN_ACK? 0x00004 : 0) | // E2 0xc0; //A'B'は常にOFF _InputStatus->Buttons = btnData; } // //ReadPinValue (Pin status -> Class value) // int In_CyberStick::ReadPinValue() { return ( _IN_D0 | (_IN_D1<<1) | (_IN_D2<<2) | (_IN_D3<<3) ); } // // あるデータフェーズのデータを読み取り、格納 // void In_CyberStick::ReadPhase(char phase) { int readVal = ReadPinValue(); switch(phase) { case 0: // Ack No.1 _Buttons = (_Buttons & 0xfffffccf) | // mask bit9,8,5,4 ((readVal & 0x0c)<<6) | // AB(bit3 & 2) ((readVal & 0x03)<<4) ; // CD(bit1 & 0) break; case 1: // Ack No.2 _Buttons = (_Buttons & 0xfffffff0) | // mask bit3,2,1,0 (readVal & 0x0f) ; // E1E2FG(bit3 & 2 & 1 & 0) break; case 2: // Ack No.3 _Ch0 = (_Ch0 & 0x0f) | // mask upper 4 bits (readVal & 0x0f)<<4 ; // 1H(bit3 & 2 & 1 & 0) break; case 3: // Ack No.4 _Ch1 = (_Ch1 & 0x0f) | // mask upper 4 bits (readVal & 0x0f)<<4 ; // 2H(bit3 & 2 & 1 & 0) break; case 4: // Ack No.5 _Ch2 = (_Ch2 & 0x0f) | // mask upper 4 bits (readVal & 0x0f)<<4 ; // 3H(bit3 & 2 & 1 & 0) break; case 5: // Ack No.6 _Ch3 = (_Ch3 & 0x0f) | // mask upper 4 bits (readVal & 0x0f)<<4 ; // 4H(bit3 & 2 & 1 & 0) break; case 6: // Ack No.7 _Ch0 = (_Ch0 & 0xf0) | // mask lower 4 bits (readVal & 0x0f) ; // 1L(bit3 & 2 & 1 & 0) break; case 7: // Ack No.8 _Ch1 = (_Ch1 & 0xf0) | // mask lower 4 bits (readVal & 0x0f) ; // 2L(bit3 & 2 & 1 & 0) break; case 8: // Ack No.9 _Ch2 = (_Ch2 & 0xf0) | // mask lower 4 bits (readVal & 0x0f) ; // 3L(bit3 & 2 & 1 & 0) break; case 9: // Ack No.10 _Ch3 = (_Ch3 & 0xf0) | // mask lower 4 bits (readVal & 0x0f) ; // 4L(bit3 & 2 & 1 & 0) break; case 10: // Ack No.11 _Buttons = (_Buttons & 0xffffff3f) | // mask bit7,6 ((readVal & 0x03)<<6) ; // A+A', B+B'(bit1 & 0) break; default: break; } } // // Analogスティック情報を確定 // void In_CyberStick::CommitAnalogData(void) { //サイバースティックアナログモードで使わないボタンをビット強制ON // ThrotUp |ThrotDw | Up | Dw || Lf | Rg _Buttons = (_Buttons) | 0x0000fc00; _InputStatus->Buttons = _Buttons; _InputStatus->Ch0 = _Ch0; _InputStatus->Ch1 = _Ch1; _InputStatus->Ch2 = _Ch2; _InputStatus->Ch3 = _Ch3; }