プレステ1アナログコントローラ用ライブラリのサンプル
Embed:
(wiki syntax)
Show/hide line numbers
pspad.cpp
00001 #include "mbed.h" 00002 #include "pspad.h" 00003 00004 //---------------------------------------------------------- 00005 // PS PAD 00006 //---------------------------------------------------------- 00007 #define PS_DAT datpin //400Ωほどのプルアップ必要 00008 #define PS_CMD_H cmdpin = 1 00009 #define PS_CMD_L cmdpin = 0 00010 #define PS_SEL_H selpin = 1 00011 #define PS_SEL_L selpin = 0 00012 #define PS_CLK_H clkpin = 1 00013 #define PS_CLK_L clkpin = 0 00014 00015 //---------------------------------------------------------- 00016 // 動作周波数 00017 //---------------------------------------------------------- 00018 #define PS_FREQ 250//125 // パッドの動作周波数 (kHz) 00019 // タイマはこの2倍の周波数で動かす 00020 // 本来250kHzだが変更しても問題ない 00021 // DAT線のプルアップ抵抗が高すぎる場合は速度を落とすこと 00022 00023 #define TM_PERI (500/PS_FREQ) // タイマの1クロックに要する時間(us) 00024 // タイマの2クロックをパッドの1クロックとしている 00025 00026 //---------------------------------------------------------- 00027 // constructor 00028 //---------------------------------------------------------- 00029 Pspad::Pspad(PinName dat, PinName cmd, PinName sel, PinName clk) : datpin(dat), cmdpin(cmd), selpin(sel), clkpin(clk) 00030 { 00031 datpin.mode(PullUp); 00032 // GPIOの出力値を設定する 00033 PS_CMD_H; // CMD を1に 00034 PS_CLK_H; // CLK を1に 00035 PS_SEL_H; // SEL を1に 00036 00037 // タイマの設定 00038 tm.reset(); 00039 } 00040 00041 //---------------------------------------------------------- 00042 // プレステ用ゲームパッドとの1バイトの通信 00043 // 引数 00044 // int send : 送信データ(0~255) 00045 // 戻り値 00046 // int 受信データ(0~255) 00047 //---------------------------------------------------------- 00048 uint8_t Pspad::PsComm( uint8_t send_data ) 00049 { 00050 uint8_t i; 00051 uint8_t recv_data = 0; 00052 00053 // カウント開始 00054 tm.start(); 00055 00056 for(i=0; i<8; i++) 00057 { 00058 00059 // 送信データ 00060 if(send_data & 0x01){ 00061 PS_CMD_H; 00062 }else{ 00063 PS_CMD_L; 00064 } 00065 // クロックをLOWに 00066 PS_CLK_L; 00067 // 待機 00068 while(tm.read_us()/TM_PERI <= 2*i); 00069 00070 // クロックをHIGHに 00071 PS_CLK_H; 00072 // 待機 00073 while(tm.read_us()/TM_PERI <= 2*i+1); 00074 // 受信データ 00075 recv_data |= (PS_DAT<<i); 00076 00077 // 送信データを1ビットずらす 00078 send_data >>= 1; 00079 } 00080 00081 // CMDをHIGHに戻す 00082 PS_CMD_H; 00083 00084 // 5クロックほど待機 00085 while(tm.read_us()/TM_PERI <= 2*8+2*5); 00086 00087 // カウント停止 及び リセット 00088 tm.stop(); 00089 tm.reset(); 00090 00091 return recv_data; 00092 } 00093 00094 //---------------------------------------------------------- 00095 // プレステ用ゲームパッドからのデータの取得 00096 // 変数 00097 // uint32_t key ボタンの押下状態をbitmapで返す。 00098 // int8_t right_x -128~127 の値を返す。アナログスティック中立時は0 00099 // int8_t right_y -128~127 の値を返す。アナログスティック中立時は0 00100 // int8_t left_x -128~127 の値を返す。アナログスティック中立時は0 00101 // int8_t left_y -128~127 の値を返す。アナログスティック中立時は0 00102 //---------------------------------------------------------- 00103 void Pspad::PsRead(void) 00104 { 00105 uint8_t i, len; 00106 uint8_t rcv[20]; 00107 00108 //BUTTON.WORD = 0; 00109 right_x = 0; // アナログスティック中立 00110 right_y = 0; // アナログスティック中立 00111 left_x = 0; // アナログスティック中立 00112 left_y = 0; // アナログスティック中立 00113 00114 // SELをLOWに 00115 PS_SEL_L; 00116 00117 // 少し待機 00118 tm.start(); 00119 while(tm.read_us() <= 40); // 40usでも動く模様 00120 tm.stop(); 00121 tm.reset(); 00122 00123 // 通信開始 00124 rcv[0] = PsComm(0x01); // PADはコマンド'01h'を検出して動作を開始する 00125 rcv[1] = PsComm(0x42); // 受信データの下位4ビットが転送バイト数の半分の数を表す 00126 len = (rcv[1] & 0x03) * 2; // 転送バイト数を求める 00127 unsigned char data = 0x00; 00128 if(VIBRATE)data = 0x41; 00129 for(i=0;i<len+1;i++){ 00130 rcv[i+2] = PsComm(data);//PsComm(0x00); // PADの状態を受信 00131 } 00132 00133 // SELをHIGHに 00134 PS_SEL_H; 00135 00136 // PADの状態を返す 00137 PREV.BUTTON.WORD = BUTTON.WORD; 00138 BUTTON.WORD = ((rcv[3]<<8) | rcv[4]) ^ 0xFFFF; 00139 00140 PREV.right_x = right_x; 00141 PREV.right_y = right_y; 00142 PREV.left_x = left_x; 00143 PREV.left_y = left_y; 00144 if(len >= 6){ //Convert range to -128~127 00145 ANALOG_MODE = 1; 00146 right_x = rcv[5] - 128; 00147 right_y = -(rcv[6] - 128 +1); 00148 left_x = rcv[7] - 128; 00149 left_y = -(rcv[8] - 128 +1); 00150 }else{ 00151 ANALOG_MODE = 0; 00152 right_x = 0; 00153 right_y = 0; 00154 left_x = 0; 00155 left_y = 0; 00156 } 00157 }
Generated on Tue Jul 12 2022 19:57:04 by 1.7.2