First Release

Dependencies:   USBDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers In_CyberStick.cpp Source File

In_CyberStick.cpp

00001 #include "In_CyberStick.h"
00002 #include "NiseKabuto.h"
00003 
00004 DigitalOut led11(LED1); 
00005 DigitalOut led22(LED2); 
00006 DigitalOut dbgPin(p8); 
00007 
00008 //
00009 // Constructor
00010 //
00011 In_CyberStick::In_CyberStick(
00012     PinName pn_D0, PinName pn_D1, PinName pn_D2, PinName pn_D3, 
00013     PinName pn_LH, PinName pn_ACK, PinName pn_REQ,
00014     InputStatus *inputStatus
00015 )  : _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)
00016 {
00017     _InputStatus = inputStatus;
00018     _InputStatus->Reset();  // ボタンなどリセット
00019     _InputStatus->InputDeviceType = NiseKabuto::CONFIG_INMODE_CYBERSTICK_ANALOG;    //とりあえずアナログにしておく
00020 
00021     _AnalogReadFailCounter = 0;
00022 
00023     Initialize();
00024 }
00025 
00026 
00027 void In_CyberStick::StartReading(void)
00028 {
00029     //printf("In_CyberStick::StartReading()\r\n");
00030     if(!_ReadEnable)
00031     {
00032         _ReadEnable = 1;
00033         Initialize();
00034     }
00035 }
00036 void In_CyberStick::StopReading(void)
00037 {
00038     //printf("In_CyberStick::StopReading()\r\n");
00039     if(_ReadEnable)
00040     {
00041         _ReadEnable = 0;
00042         DisablePolling();
00043     }
00044 }
00045 
00046 
00047 
00048 //
00049 // Initialize
00050 //
00051 void In_CyberStick::Initialize()
00052 {
00053     // Pin Setting
00054     _IN_D0.mode(PullUp);
00055     _IN_D1.mode(PullUp);
00056     _IN_D2.mode(PullUp);
00057     _IN_D3.mode(PullUp);
00058     _IN_LH.mode(PullUp);
00059     _IN_ACK.mode(PullUp);
00060 
00061     // Class Variable Setting
00062     _ReadEnable = 1;
00063 
00064     // Interrupt Setting
00065     // Initialize pin status
00066     _OUT_REQ = 1;   // output REQ = H
00067 
00068     // Ticker Setting
00069     EnablePolling();
00070 }
00071 
00072 
00073 
00074 //
00075 // Enable polling
00076 //
00077 void In_CyberStick::EnablePolling(void)
00078 {
00079     _PollingTicker.attach_us(this, &In_CyberStick::PollingMethod, REQUESTINTERVAL__MICROSEC);
00080 
00081     // FCAB 入力乱れ対策
00082     _ReadEnable = 1;
00083     _OUT_REQ = 1;  
00084 }
00085 
00086 
00087 //
00088 // Polling method
00089 //
00090 void In_CyberStick::PollingMethod()
00091 {
00092     // デバッグ用:この関数が呼ばれるたび+1される
00093     (_InputStatus->Temp[0])++;
00094 
00095     if(_ReadEnable)
00096     {
00097 
00098         // 割り込み停止しない
00099         //__disable_irq();  
00100         
00101         int waitLoop = 8000; //8000;//11300;//22600;
00102         char state = 1;
00103         char phase = 0;
00104         char cycle = 0;
00105         
00106         // Req下げ
00107         _OUT_REQ = 0;
00108         //wait_us(2);
00109         //_OUT_REQ = 1;
00110 
00111         cycle = 0;
00112         while( cycle<6 )
00113         {
00114             // LH=1の間待つ
00115             if(state)
00116             {
00117                 while( _IN_LH )
00118                 {
00119                     waitLoop--;
00120                     if(!waitLoop)
00121                     {
00122                         // TimeOut !
00123                         state = 0;
00124                         break;
00125                     }
00126                 }
00127             }
00128             
00129             // ACK=1の間待つ
00130             if(state)
00131             {
00132                 while( _IN_ACK )
00133                 {
00134                     waitLoop--;
00135                     if(!waitLoop)
00136                     {
00137                         // TimeOut !
00138                         state = 0;
00139                         break;
00140                     }
00141                 }
00142                 
00143             }
00144             
00145             if(state)
00146             {
00147                 // データ読み出し
00148                 ReadPhase(phase++);
00149             }
00150             
00151             // LH=0の間待つ
00152             if(state)
00153             {
00154                 while( !(_IN_LH) )
00155                 {
00156                     waitLoop--;
00157                     if(!waitLoop)
00158                     {
00159                         // TimeOut !
00160                         state = 0;
00161                         break;
00162                     }
00163                 }
00164             }
00165             
00166             // ACK=1の間待つ
00167             if(state)
00168             {
00169                 // REQ立ち上げ
00170                 // (最速モードのため、2回目のAck立下りまでに行う。このあたり?)
00171                 _OUT_REQ = 1;
00172 
00173                 while( _IN_ACK )
00174                 {
00175                     waitLoop--;
00176                     if(!waitLoop)
00177                     {
00178                         // TimeOut !
00179                         state = 0;
00180                         break;
00181                     }
00182                 }
00183             }
00184 
00185             if(state)
00186             {
00187                 // データ読み出し
00188                 ReadPhase(phase++);
00189             }
00190         
00191             if(!state)
00192             {
00193                 break;
00194             }
00195             cycle++;
00196         }
00197 
00198         // 割り込み禁止しない
00199         //__enable_irq();
00200         
00201         if(state)
00202         {
00203             // ここまでstate==1のままで終わったら、完全にアナログスティックといえる
00204             _InputStatus->InputDeviceType = NiseKabuto::CONFIG_INMODE_CYBERSTICK_ANALOG;
00205             led11 = 1;
00206 
00207             // Analog読み失敗カウンタリセット
00208             _AnalogReadFailCounter = 0;
00209 
00210             //データ確定
00211             CommitAnalogData();
00212         }
00213         else
00214         {
00215         //  printf("_AnalogReadFailCounter: %d\r\n",_AnalogReadFailCounter);
00216             // 数回のAnalog読み失敗を許容
00217             //
00218             // 出力処理側のISRなどに割り込まれ、失敗するケースもある
00219             //
00220             //
00221             _AnalogReadFailCounter++;
00222             
00223             // この値を大きくすると、一時的なデジタルスティック化は避けられるが
00224             // DIGITAL/ANALOG切り替えスイッチへの追従が遅れる
00225             if(_AnalogReadFailCounter > 10)
00226             {
00227                 // この時点でstate==0なら、未接続/デジタルモード
00228                 _InputStatus->InputDeviceType = NiseKabuto::CONFIG_INMODE_CYBERSTICK_DIGITAL;
00229                 led11 = 0;
00230                 DigitalModeReader();
00231                 
00232                 if(_AnalogReadFailCounter>1000)
00233                 {
00234                     _AnalogReadFailCounter = 10;
00235                 }
00236             }
00237         }
00238     }
00239 }
00240 
00241 
00242 //
00243 // Disable polling
00244 //
00245 void In_CyberStick::DisablePolling(void)
00246 {
00247     _PollingTicker.detach();
00248     
00249     //Enable/DisableInput()を頻繁に呼ぶと、デジアナモード判定が乱れる問題対策
00250     if( _ReadEnable )
00251     {
00252     }
00253 }
00254 
00255 
00256 
00257 //
00258 // デジタルモードでの読み取り処理
00259 //
00260 void In_CyberStick::DigitalModeReader(void)
00261 {
00262     int btnData = _InputStatus->Buttons;
00263     
00264     // PC4=“0”
00265     _OUT_REQ = 0;
00266     wait_us(1);
00267 
00268     btnData = 
00269         (_IN_D0?   0x02000 : 0) |   // Up
00270         (_IN_D1?   0x01000 : 0) |   // Down
00271         (_IN_D2?   0x00800 : 0) |   // Left
00272         (_IN_D3?   0x00400 : 0) |   // Right
00273         (_IN_LH?   0x00200 : 0) |   // A
00274         (_IN_ACK?  0x00100 : 0) |   // B
00275         ((_IN_D2==0 && _IN_D3==0)? 0 : 0x02) |  // F(Start)
00276         ((_IN_D0==0 && _IN_D1==0)? 0 : 0x01) ;  // G(Select)
00277 
00278     /*
00279     // デジタルモードのとき、サイバースティックは
00280     // Start,Selectの情報は得られない。
00281     // カブトガニのF(Start),G(Select)については、
00282     // F=LR同時押し、G=UD同時押しとして認識される。
00283     */
00284     
00285     // PC4=“1”
00286     _OUT_REQ = 1;
00287     wait_us(1);
00288 
00289     btnData = btnData           |
00290         (_IN_D0?   0x08000 : 0) |   // Throt Up
00291         (_IN_D1?   0x04000 : 0) |   // Throt Down
00292         (_IN_D2?   0x00020 : 0) |   // C
00293         (_IN_D3?   0x00010 : 0) |   // D
00294         (_IN_LH?   0x00008 : 0) |   // E1
00295         (_IN_ACK?  0x00004 : 0) |   // E2
00296         0xc0;                       //A'B'は常にOFF
00297 
00298     _InputStatus->Buttons = btnData;
00299 }
00300 
00301 //
00302 //ReadPinValue (Pin status -> Class value)
00303 //
00304 int In_CyberStick::ReadPinValue()
00305 {
00306     return ( _IN_D0 | (_IN_D1<<1) | (_IN_D2<<2) | (_IN_D3<<3) );
00307 }
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 //
00316 // あるデータフェーズのデータを読み取り、格納
00317 //
00318 void In_CyberStick::ReadPhase(char phase)
00319 {
00320     int readVal = ReadPinValue();
00321     
00322     switch(phase)
00323     {
00324         case 0:
00325             // Ack No.1
00326             _Buttons = 
00327                 (_Buttons & 0xfffffccf) |       // mask bit9,8,5,4
00328                 ((readVal & 0x0c)<<6) |         // AB(bit3 & 2)
00329                 ((readVal & 0x03)<<4) ;         // CD(bit1 & 0)
00330             break;
00331 
00332         case 1:
00333             // Ack No.2
00334             _Buttons = 
00335                 (_Buttons & 0xfffffff0) |       // mask bit3,2,1,0
00336                 (readVal & 0x0f)      ;         // E1E2FG(bit3 & 2 & 1 & 0)
00337             break;
00338 
00339         case 2:
00340             // Ack No.3
00341             _Ch0 = 
00342                 (_Ch0 & 0x0f) |                 // mask upper 4 bits
00343                 (readVal & 0x0f)<<4   ;         // 1H(bit3 & 2 & 1 & 0)
00344             break;
00345 
00346         case 3:
00347             // Ack No.4
00348             _Ch1 = 
00349                 (_Ch1 & 0x0f) |                 // mask upper 4 bits
00350                 (readVal & 0x0f)<<4   ;         // 2H(bit3 & 2 & 1 & 0)
00351             break;
00352 
00353         case 4:
00354             // Ack No.5
00355             _Ch2 = 
00356                 (_Ch2 & 0x0f) |                 // mask upper 4 bits
00357                 (readVal & 0x0f)<<4   ;         // 3H(bit3 & 2 & 1 & 0)
00358             break;
00359 
00360         case 5:
00361             // Ack No.6
00362             _Ch3 = 
00363                 (_Ch3 & 0x0f) |                 // mask upper 4 bits
00364                 (readVal & 0x0f)<<4   ;         // 4H(bit3 & 2 & 1 & 0)
00365             break;
00366 
00367         case 6:
00368             // Ack No.7
00369             _Ch0 = 
00370                 (_Ch0 & 0xf0) |                 // mask lower 4 bits
00371                 (readVal & 0x0f)      ;         // 1L(bit3 & 2 & 1 & 0)
00372             break;
00373 
00374         case 7:
00375             // Ack No.8
00376             _Ch1 = 
00377                 (_Ch1 & 0xf0) |                 // mask lower 4 bits
00378                 (readVal & 0x0f)      ;         // 2L(bit3 & 2 & 1 & 0)
00379             break;
00380 
00381         case 8:
00382             // Ack No.9
00383             _Ch2 = 
00384                 (_Ch2 & 0xf0) |                 // mask lower 4 bits
00385                 (readVal & 0x0f)      ;         // 3L(bit3 & 2 & 1 & 0)
00386             break;
00387 
00388         case 9:
00389             // Ack No.10
00390             _Ch3 = 
00391                 (_Ch3 & 0xf0) |                 // mask lower 4 bits
00392                 (readVal & 0x0f)      ;         // 4L(bit3 & 2 & 1 & 0)
00393             break;
00394 
00395         case 10:
00396             // Ack No.11
00397             _Buttons = 
00398                 (_Buttons & 0xffffff3f) |       // mask bit7,6
00399                 ((readVal & 0x03)<<6) ;         // A+A', B+B'(bit1 & 0)
00400             break;
00401 
00402         default:
00403             break;
00404     }
00405 }
00406 
00407 
00408 //
00409 // Analogスティック情報を確定
00410 //
00411 void In_CyberStick::CommitAnalogData(void)
00412 {
00413     //サイバースティックアナログモードで使わないボタンをビット強制ON
00414     // ThrotUp |ThrotDw |   Up   |   Dw   ||   Lf   |   Rg
00415     _Buttons = (_Buttons) | 0x0000fc00;
00416 
00417     _InputStatus->Buttons = _Buttons;
00418     _InputStatus->Ch0 = _Ch0;
00419     _InputStatus->Ch1 = _Ch1;
00420     _InputStatus->Ch2 = _Ch2;
00421     _InputStatus->Ch3 = _Ch3;
00422 }