First Release
Embed:
(wiki syntax)
Show/hide line numbers
Out_PCE.cpp
00001 #include "NiseKabuto.h" 00002 #include "Cfunc_PCEDigital.h" 00003 00004 volatile char test = 0; 00005 00006 //extern "C" void mbed_reset(); 00007 00008 // 00009 // Constructor 00010 // 00011 Out_PCE::Out_PCE( 00012 PinName pn_1Y, PinName pn_2Y, PinName pn_3Y, PinName pn_4Y, 00013 PinName pn_DSEL, PinName pn_ST, PinName pn_POWDETECT, 00014 InputStatus *inputStatus) 00015 : _OUT_1Y(pn_1Y), _OUT_2Y(pn_2Y), _OUT_3Y(pn_3Y), _OUT_4Y(pn_4Y), 00016 _INTR_DSEL(pn_DSEL), _INTR_ST(pn_ST), _INTR_POWDETECT(pn_POWDETECT) 00017 { 00018 _InputStatus = inputStatus; 00019 00020 // OutputMode Initialize 00021 _OutputMode = _InputStatus->InputDeviceType; 00022 00023 //printf("_OutputMode: %d(constructor)\r\n",_OutputMode); 00024 00025 // InitInterruptPriority(); 00026 Initialize(); 00027 00028 } 00029 00030 // 00031 // Initialize 00032 // 00033 void Out_PCE::Initialize() 00034 { 00035 00036 // Pin Setting 00037 _INTR_ST.mode(PullUp); 00038 _INTR_DSEL.mode(PullUp); 00039 _INTR_POWDETECT.mode(PullUp); 00040 00041 // Class Variable Setting 00042 _PhaseCounter = 0; 00043 _NowWriting = 0; 00044 _DataSelectStatus = 1; 00045 _TransferSpeed = TRANSFERSPEED_MAX__MICROSEC; 00046 _RapidFireValue = 1; 00047 00048 // Reset Interrupt Settings 00049 _INTR_ST.fall(NULL); 00050 _INTR_ST.rise(NULL); 00051 _INTR_DSEL.fall(NULL); 00052 _INTR_DSEL.rise(NULL); 00053 _PhaseChangeTicker.detach(); 00054 _DigitalPadPhase0SetTicker.detach(); 00055 _ModeCheckTicker.detach(); 00056 00057 // 入力デバイスにより場合わけ 00058 _OutputMode = _InputStatus->InputDeviceType; 00059 //printf("_OutputMode: %d(init)\r\n",_OutputMode); 00060 00061 // ModeCheckTicker Setting 00062 _ModeCheckTicker.attach_us(this, &Out_PCE::ModeChecker, MODECHECKPERIOD__MICROSEC); 00063 00064 switch(_OutputMode) 00065 { 00066 // 00067 // Input: CyberStick DIGITAL mode 00068 // Input: FightingPad 6B 00069 // 00070 case NiseKabuto::CONFIG_INMODE_CYBERSTICK_DIGITAL: 00071 case NiseKabuto::CONFIG_INMODE_MD6B: 00072 Cfunc_PCEDigital_Initialize( 00073 &_OUT_1Y, 00074 &_OUT_2Y, 00075 &_OUT_3Y, 00076 &_OUT_4Y, 00077 &_INTR_DSEL, 00078 &_INTR_ST, 00079 _PhaseData, 00080 &_RapidFireValue, 00081 &(_InputStatus->Temp[4]) 00082 ); 00083 00084 00085 // Ticker Setting 00086 _DigitalPadPhase0SetTicker.attach_us( 00087 this, 00088 &Out_PCE::Digital_TickerMethod, 00089 DIGITALPAD_STATERENEWINTERVAL__MICROSEC 00090 ); 00091 00092 EnableInput(); 00093 00094 SetOutputPinsValue(0x00); 00095 wait_us(5000); // PCエンジンに気づかせる 00096 break; 00097 00098 // 00099 // Input: CyberStick ANALOG mode 00100 // 00101 default: 00102 case NiseKabuto::CONFIG_INMODE_CYBERSTICK_ANALOG: 00103 00104 // Interrupt Setting 00105 _INTR_ST.fall(this, &Out_PCE::StrobeFallISR); 00106 00107 // Initialize pin status 00108 //SetOutputPinsValue(0x0f); // AfterBurner Boot時にRUN押されちゃう 00109 SetOutputPinsValue(0x02); // 00110 break; 00111 00112 } 00113 } 00114 00115 00116 // 00117 // Set Pins 00118 // 00119 void Out_PCE::SetOutputPinsValue(char dat) 00120 { 00121 _OUT_1Y = dat & 1; 00122 _OUT_2Y = (dat & 2) >> 1; 00123 _OUT_3Y = (dat & 4) >> 2; 00124 _OUT_4Y = (dat & 8) >> 3; 00125 } 00126 00127 // 00128 // Set Pins2 00129 // 00130 void Out_PCE::SetOutputPinsValue2(char dat) 00131 { 00132 // D0 00133 _OUT_1Y = dat & 1; // D0 00134 // D1 00135 _OUT_2Y = (dat & 8) >> 3; // D3 00136 // D2 00137 _OUT_3Y = (dat & 2) >> 1; // D1 00138 // D3 00139 _OUT_4Y = (dat & 4) >> 2; // D2 00140 } 00141 00142 // 00143 // ISR for Strobe=L 00144 // 00145 void Out_PCE::StrobeFallISR(void) 00146 { 00147 //_PCEActiveCounter++; 00148 00149 if( _NowWriting == 0) 00150 { 00151 _INTR_ST.fall(NULL); 00152 00153 00154 00155 // Disableしないと、入力にまれにノイズがのる 00156 // Disable/Enable有る場合も無い場合も、しばらくすると入力が受け付けられなくなる 00157 // EnableInput()時にInitialize()を実行させるように修正 00158 00159 //wait_us(_TransferSpeed>>1); //AfterBurnerはこれで良かった.OutRun動かないかも? 00160 //wait_us(10); //Outrun対策 00161 00162 _NowWriting = 1; 00163 00164 // データフェーズごとのデータ用意 00165 int buttons = _InputStatus->Buttons; 00166 char ch0 = _InputStatus->Ch0; 00167 char ch1 = _InputStatus->Ch1; 00168 char ch2 = _InputStatus->Ch2; 00169 char ch3 = _InputStatus->Ch3; 00170 00171 // DisableInput(); 00172 00173 // |A|B|C|D 00174 _PhaseData[0] = 00175 ( 00176 (((buttons) & 0x0200)?1:0)<<3 | // A 00177 (((buttons) & 0x0100)?1:0)<<2 | // B 00178 (((buttons) & 0x0020)?1:0)<<1 | // C 00179 (((buttons) & 0x0010)?1:0) // D 00180 ); 00181 00182 // |E1|E2|F|G 00183 _PhaseData[1] = 00184 ( 00185 (((buttons) & 0x0008)?1:0)<<3 | // E1 00186 (((buttons) & 0x0004)?1:0)<<2 | // E2 00187 (((buttons) & 0x0002)?1:0)<<1 | // F 00188 (((buttons) & 0x0001)?1:0) // G 00189 ); 00190 00191 // 1H 00192 _PhaseData[2] = 00193 ( ((ch0)>>4) & 0x0f ); 00194 00195 // 2H 00196 _PhaseData[3] = 00197 ( ((ch1)>>4) & 0x0f ); 00198 00199 // 3H 00200 _PhaseData[4] = 00201 ( ((ch2)>>4) & 0x0f ); 00202 00203 // 4H 00204 _PhaseData[5] = 00205 ( 0x010 ); 00206 00207 // 1L 00208 _PhaseData[6] = 00209 ( ch0 ); 00210 00211 // 2L 00212 _PhaseData[7] = 00213 ( ch1 ); 00214 00215 // 3L 00216 _PhaseData[8] = 00217 ( ch2 ); 00218 00219 // 4L 00220 _PhaseData[9] = 00221 ( 0 ); 00222 00223 _PhaseData[10] = 00224 // |A|B|A'|B'| 00225 ( 00226 (((buttons) & 0x0200)?1:0)<<3 | // A 00227 (((buttons) & 0x0100)?1:0)<<2 | // B 00228 (((buttons) & 0x0080)?1:0)<<1 | // A' 00229 (((buttons) & 0x0040)?1:0) // B' 00230 ); 00231 00232 _PhaseData[11] = (0x0f); 00233 00234 // DisableInput(); 00235 _PhaseChangeTicker.attach_us(this, &Out_PCE::ChangePhase, _TransferSpeed>>1); 00236 } 00237 } 00238 00239 00240 // 00241 // Tickerにより呼ばれる処理 00242 // PhaseCounterを変化 00243 // 00244 void Out_PCE::ChangePhase(void) 00245 { 00246 int loopCounter=0; 00247 char state=1; 00248 00249 // 一瞬だけ2Yを下げて 00250 SetOutputPinsValue( _PhaseCounter&1 ); 00251 wait_us(2); //PCEがアナログモードになるwait_us値:10, 5, 3, 2 00252 00253 // すぐデータ変更 00254 SetOutputPinsValue2( _PhaseData[_PhaseCounter] ); 00255 00256 // DSELがHになるまで待つ 00257 loopCounter=100; 00258 while(!(_INTR_DSEL)) 00259 { 00260 loopCounter--; 00261 if(loopCounter<0) 00262 { 00263 state=0; 00264 break; 00265 } 00266 } 00267 00268 if(state) 00269 { 00270 // DSELがLになるまで待つ 00271 loopCounter=100; 00272 while(_INTR_DSEL) 00273 { 00274 loopCounter--; 00275 if(loopCounter<0) 00276 { 00277 state=0; 00278 break; 00279 } 00280 } 00281 } 00282 00283 if(state) 00284 { 00285 00286 // その後、Ack出力に戻す 00287 SetOutputPinsValue( _PhaseCounter&1 | 0x02); 00288 00289 _PhaseCounter++; 00290 00291 //if(_PhaseCounter==12) 00292 if(_PhaseCounter>=11) 00293 { 00294 _PhaseCounter = 0; 00295 _PhaseChangeTicker.detach(); 00296 SetOutputPinsValue(0x02); 00297 _NowWriting = 0; 00298 // EnableInput(); 00299 _INTR_ST.fall(this, &Out_PCE::StrobeFallISR); 00300 } 00301 } 00302 else 00303 { 00304 _PhaseCounter = 0; 00305 _PhaseChangeTicker.detach(); 00306 SetOutputPinsValue(0x02); 00307 _NowWriting = 0; 00308 // EnableInput(); 00309 _INTR_ST.fall(this, &Out_PCE::StrobeFallISR); 00310 } 00311 00312 } 00313 00314 00315 00316 // 00317 // Ticker method for digital pad output 00318 // 00319 // 1. 全phase用のデータを集め、クラス変数に保存 00320 // 2. Phase0データを出力する 00321 void Out_PCE::Digital_TickerMethod(void) 00322 { 00323 // デバッグ用:この関数が呼ばれるたび+1される 00324 (_InputStatus->Temp[2])++; 00325 00326 //printf("I\r\n"); // これがあるとhungup起きない?(1) 00327 // _InputStatus->Temp[0] = 1; 00328 // wait_us(14000); 00329 00330 volatile int idx; 00331 00332 // データフェーズごとのデータ用意 00333 __disable_irq(); 00334 volatile int buttons = _InputStatus->Buttons; 00335 volatile char type = _InputStatus->InputDeviceType; 00336 __enable_irq(); 00337 00338 volatile int val_1a=0x0f; 00339 volatile int val_1b=0x0f; 00340 volatile int trgState_I = 1; 00341 volatile int trgState_II = 1; 00342 00343 if( type == NiseKabuto::CONFIG_INMODE_CYBERSTICK_DIGITAL) 00344 { 00345 // 入力デバイス=サイバースティック/カブトガニ デジタルモード 00346 00347 // 4Y 3Y 2Y 1Y 00348 // L D R U 00349 val_1a = 00350 ( 00351 ((buttons & 0x0800) ? 0x08 : 0) | // L 00352 ((buttons & 0x1000) ? 0x04 : 0) | // D 00353 ((buttons & 0x0400) ? 0x02 : 0) | // R 00354 ((buttons & 0x2000) ? 0x01 : 0) // U 00355 ); 00356 00357 // 4Y 3Y 2Y 1Y 00358 // |Run|Sel|II|I 00359 val_1b = 00360 ( 00361 ((buttons & 0x0002) ? 0x08 : 0)&((buttons & 0x0010) ? 0x08 : 0) | // F(Start) & D 00362 ((buttons & 0x0001) ? 0x04 : 0)&((buttons & 0x0020) ? 0x04 : 0) | // G(Sel,Mode) & C 00363 ((buttons & 0x0100) ? 0x02 : 0) | // B 00364 ((buttons & 0x0200) ? 0x01 : 0) // A 00365 ); 00366 00367 } 00368 else if (type == NiseKabuto::CONFIG_INMODE_MD6B) 00369 { 00370 // 入力デバイス=6B 00371 00372 if( !(buttons & 0x020000) ) //Y 00373 { 00374 trgState_II = ((_RapidFireValue) ? 0x02 : 0); 00375 } 00376 else 00377 { 00378 trgState_II = ((buttons & 0x0100) ? 0x02 : 0); // B 00379 } 00380 if( !(buttons & 0x010000) ) //Z 00381 { 00382 trgState_I = ((_RapidFireValue) ? 0x01 : 0); 00383 } 00384 else 00385 { 00386 trgState_I = ((buttons & 0x0020) ? 0x01 : 0); // C 00387 } 00388 00389 // 4Y 3Y 2Y 1Y 00390 // L D R U 00391 val_1a = 00392 ( 00393 ((buttons & 0x0800) ? 0x08 : 0) | // L 00394 ((buttons & 0x1000) ? 0x04 : 0) | // D 00395 ((buttons & 0x0400) ? 0x02 : 0) | // R 00396 ((buttons & 0x2000) ? 0x01 : 0) // U 00397 ); 00398 00399 // 4Y 3Y 2Y 1Y 00400 // |Run|Sel|II|I 00401 val_1b = 00402 ( 00403 ((buttons & 0x0002) ? 0x08 : 0) | // F(Start) 00404 ((buttons & 0x0001) ? 0x04 : 0) | // G(Sel,Mode) 00405 trgState_II | 00406 trgState_I 00407 ); 00408 00409 00410 } 00411 00412 __disable_irq(); 00413 for(idx=0; idx<12; idx+=2) 00414 { 00415 //printf("idx:%d\r\n",idx); 00416 _PhaseData[idx ] = val_1a; 00417 _PhaseData[idx+1] = val_1b; 00418 } 00419 __enable_irq(); 00420 00421 00422 // //phase0データをset 00423 // Digital_SetDataOfPhase(0); 00424 00425 00426 //printf("O\r\n"); // これがあるとhungup起きない?(2) 00427 // _InputStatus->Temp[0] = 0; 00428 // wait_us(14000); 00429 00430 } 00431 00432 00433 void Out_PCE::Digital_SetDataOfPhase(char phaseCounter) 00434 { 00435 if( phaseCounter < 10 ) 00436 { 00437 SetOutputPinsValue(_PhaseData[phaseCounter]); 00438 } 00439 else 00440 { 00441 SetOutputPinsValue(0x0f); 00442 } 00443 00444 } 00445 00446 void Out_PCE::ModeChecker(void) 00447 { 00448 // デバッグ用:この関数が呼ばれるたび+1される 00449 (_InputStatus->Temp[5])++; 00450 00451 __disable_irq(); 00452 char curOutMode = _InputStatus->InputDeviceType; 00453 __enable_irq(); 00454 00455 // Analog/Digital切り替え判定 00456 if(_OutputMode != curOutMode) 00457 { 00458 _OutputMode = curOutMode; 00459 // printf("InputDeviceType changed. Calling Initialize().\r\n"); 00460 Initialize(); 00461 } 00462 } 00463 00464 00465 00466 void Out_PCE::SetupInputControll(void (*startInputFunction)(void), void (*stopInputFunction)(void)) 00467 { 00468 StartInputFunction = startInputFunction; 00469 StopInputFunction = stopInputFunction; 00470 } 00471 00472 void Out_PCE::EnableInput(void) 00473 { 00474 //printf("Out_PCE::EnableInput() called!!"); 00475 if(_InputInstance && StartInputMethod) 00476 { 00477 (_InputInstance->*StartInputMethod)(); 00478 } 00479 else if(StartInputFunction) 00480 { 00481 StartInputFunction(); 00482 } 00483 } 00484 00485 void Out_PCE::DisableInput(void) 00486 { 00487 //printf("Out_PCE::DisableInput() called!!"); 00488 00489 if(_InputInstance && StopInputMethod) 00490 { 00491 (_InputInstance->*StopInputMethod)(); 00492 } 00493 else if(StopInputFunction) 00494 { 00495 StopInputFunction(); 00496 } 00497 } 00498 00499 00500
Generated on Thu Jul 14 2022 14:49:55 by 1.7.2