プレステ1アナログコントローラ用ライブラリのサンプル

Dependencies:   mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pspad.cpp Source File

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 }