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

Dependencies:   mbed-src

Committer:
kurt
Date:
Fri Apr 04 05:23:04 2014 +0000
Revision:
3:3a33f8294a84
Parent:
0:ab4722670dd8
fix PsComm

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kurt 0:ab4722670dd8 1 #include "mbed.h"
kurt 0:ab4722670dd8 2 #include "pspad.h"
kurt 0:ab4722670dd8 3
kurt 0:ab4722670dd8 4 //----------------------------------------------------------
kurt 0:ab4722670dd8 5 // PS PAD
kurt 0:ab4722670dd8 6 //----------------------------------------------------------
kurt 0:ab4722670dd8 7 #define PS_DAT datpin //400Ωほどのプルアップ必要
kurt 0:ab4722670dd8 8 #define PS_CMD_H cmdpin = 1
kurt 0:ab4722670dd8 9 #define PS_CMD_L cmdpin = 0
kurt 0:ab4722670dd8 10 #define PS_SEL_H selpin = 1
kurt 0:ab4722670dd8 11 #define PS_SEL_L selpin = 0
kurt 0:ab4722670dd8 12 #define PS_CLK_H clkpin = 1
kurt 0:ab4722670dd8 13 #define PS_CLK_L clkpin = 0
kurt 0:ab4722670dd8 14
kurt 0:ab4722670dd8 15 //----------------------------------------------------------
kurt 0:ab4722670dd8 16 // 動作周波数
kurt 0:ab4722670dd8 17 //----------------------------------------------------------
kurt 0:ab4722670dd8 18 #define PS_FREQ 250//125 // パッドの動作周波数 (kHz)
kurt 0:ab4722670dd8 19 // タイマはこの2倍の周波数で動かす
kurt 0:ab4722670dd8 20 // 本来250kHzだが変更しても問題ない
kurt 3:3a33f8294a84 21 // DAT線のプルアップ抵抗が高すぎる場合は速度を落とすこと
kurt 0:ab4722670dd8 22
kurt 0:ab4722670dd8 23 #define TM_PERI (500/PS_FREQ) // タイマの1クロックに要する時間(us)
kurt 0:ab4722670dd8 24 // タイマの2クロックをパッドの1クロックとしている
kurt 0:ab4722670dd8 25
kurt 0:ab4722670dd8 26 //----------------------------------------------------------
kurt 0:ab4722670dd8 27 // constructor
kurt 0:ab4722670dd8 28 //----------------------------------------------------------
kurt 0:ab4722670dd8 29 Pspad::Pspad(PinName dat, PinName cmd, PinName sel, PinName clk) : datpin(dat), cmdpin(cmd), selpin(sel), clkpin(clk)
kurt 0:ab4722670dd8 30 {
kurt 3:3a33f8294a84 31 datpin.mode(PullUp);
kurt 0:ab4722670dd8 32 // GPIOの出力値を設定する
kurt 0:ab4722670dd8 33 PS_CMD_H; // CMD を1に
kurt 0:ab4722670dd8 34 PS_CLK_H; // CLK を1に
kurt 0:ab4722670dd8 35 PS_SEL_H; // SEL を1に
kurt 0:ab4722670dd8 36
kurt 0:ab4722670dd8 37 // タイマの設定
kurt 0:ab4722670dd8 38 tm.reset();
kurt 0:ab4722670dd8 39 }
kurt 0:ab4722670dd8 40
kurt 0:ab4722670dd8 41 //----------------------------------------------------------
kurt 0:ab4722670dd8 42 // プレステ用ゲームパッドとの1バイトの通信
kurt 0:ab4722670dd8 43 // 引数
kurt 0:ab4722670dd8 44 // int send : 送信データ(0~255)
kurt 0:ab4722670dd8 45 // 戻り値
kurt 0:ab4722670dd8 46 // int 受信データ(0~255)
kurt 0:ab4722670dd8 47 //----------------------------------------------------------
kurt 0:ab4722670dd8 48 uint8_t Pspad::PsComm( uint8_t send_data )
kurt 0:ab4722670dd8 49 {
kurt 0:ab4722670dd8 50 uint8_t i;
kurt 0:ab4722670dd8 51 uint8_t recv_data = 0;
kurt 0:ab4722670dd8 52
kurt 0:ab4722670dd8 53 // カウント開始
kurt 0:ab4722670dd8 54 tm.start();
kurt 0:ab4722670dd8 55
kurt 0:ab4722670dd8 56 for(i=0; i<8; i++)
kurt 0:ab4722670dd8 57 {
kurt 0:ab4722670dd8 58
kurt 0:ab4722670dd8 59 // 送信データ
kurt 0:ab4722670dd8 60 if(send_data & 0x01){
kurt 0:ab4722670dd8 61 PS_CMD_H;
kurt 0:ab4722670dd8 62 }else{
kurt 0:ab4722670dd8 63 PS_CMD_L;
kurt 0:ab4722670dd8 64 }
kurt 0:ab4722670dd8 65 // クロックをLOWに
kurt 0:ab4722670dd8 66 PS_CLK_L;
kurt 0:ab4722670dd8 67 // 待機
kurt 0:ab4722670dd8 68 while(tm.read_us()/TM_PERI <= 2*i);
kurt 0:ab4722670dd8 69
kurt 0:ab4722670dd8 70 // クロックをHIGHに
kurt 0:ab4722670dd8 71 PS_CLK_H;
kurt 3:3a33f8294a84 72 // 待機
kurt 3:3a33f8294a84 73 while(tm.read_us()/TM_PERI <= 2*i+1);
kurt 0:ab4722670dd8 74 // 受信データ
kurt 0:ab4722670dd8 75 recv_data |= (PS_DAT<<i);
kurt 0:ab4722670dd8 76
kurt 0:ab4722670dd8 77 // 送信データを1ビットずらす
kurt 0:ab4722670dd8 78 send_data >>= 1;
kurt 0:ab4722670dd8 79 }
kurt 0:ab4722670dd8 80
kurt 0:ab4722670dd8 81 // CMDをHIGHに戻す
kurt 0:ab4722670dd8 82 PS_CMD_H;
kurt 0:ab4722670dd8 83
kurt 0:ab4722670dd8 84 // 5クロックほど待機
kurt 0:ab4722670dd8 85 while(tm.read_us()/TM_PERI <= 2*8+2*5);
kurt 0:ab4722670dd8 86
kurt 0:ab4722670dd8 87 // カウント停止 及び リセット
kurt 0:ab4722670dd8 88 tm.stop();
kurt 0:ab4722670dd8 89 tm.reset();
kurt 0:ab4722670dd8 90
kurt 0:ab4722670dd8 91 return recv_data;
kurt 0:ab4722670dd8 92 }
kurt 0:ab4722670dd8 93
kurt 0:ab4722670dd8 94 //----------------------------------------------------------
kurt 0:ab4722670dd8 95 // プレステ用ゲームパッドからのデータの取得
kurt 0:ab4722670dd8 96 // 変数
kurt 0:ab4722670dd8 97 // uint32_t key ボタンの押下状態をbitmapで返す。
kurt 0:ab4722670dd8 98 // int8_t right_x -128~127 の値を返す。アナログスティック中立時は0
kurt 0:ab4722670dd8 99 // int8_t right_y -128~127 の値を返す。アナログスティック中立時は0
kurt 0:ab4722670dd8 100 // int8_t left_x -128~127 の値を返す。アナログスティック中立時は0
kurt 0:ab4722670dd8 101 // int8_t left_y -128~127 の値を返す。アナログスティック中立時は0
kurt 0:ab4722670dd8 102 //----------------------------------------------------------
kurt 0:ab4722670dd8 103 void Pspad::PsRead(void)
kurt 0:ab4722670dd8 104 {
kurt 0:ab4722670dd8 105 uint8_t i, len;
kurt 0:ab4722670dd8 106 uint8_t rcv[20];
kurt 0:ab4722670dd8 107
kurt 0:ab4722670dd8 108 //BUTTON.WORD = 0;
kurt 0:ab4722670dd8 109 right_x = 0; // アナログスティック中立
kurt 0:ab4722670dd8 110 right_y = 0; // アナログスティック中立
kurt 0:ab4722670dd8 111 left_x = 0; // アナログスティック中立
kurt 0:ab4722670dd8 112 left_y = 0; // アナログスティック中立
kurt 0:ab4722670dd8 113
kurt 0:ab4722670dd8 114 // SELをLOWに
kurt 0:ab4722670dd8 115 PS_SEL_L;
kurt 0:ab4722670dd8 116
kurt 0:ab4722670dd8 117 // 少し待機
kurt 0:ab4722670dd8 118 tm.start();
kurt 0:ab4722670dd8 119 while(tm.read_us() <= 40); // 40usでも動く模様
kurt 0:ab4722670dd8 120 tm.stop();
kurt 0:ab4722670dd8 121 tm.reset();
kurt 0:ab4722670dd8 122
kurt 0:ab4722670dd8 123 // 通信開始
kurt 0:ab4722670dd8 124 rcv[0] = PsComm(0x01); // PADはコマンド'01h'を検出して動作を開始する
kurt 0:ab4722670dd8 125 rcv[1] = PsComm(0x42); // 受信データの下位4ビットが転送バイト数の半分の数を表す
kurt 0:ab4722670dd8 126 len = (rcv[1] & 0x03) * 2; // 転送バイト数を求める
kurt 0:ab4722670dd8 127 unsigned char data = 0x00;
kurt 0:ab4722670dd8 128 if(VIBRATE)data = 0x41;
kurt 0:ab4722670dd8 129 for(i=0;i<len+1;i++){
kurt 0:ab4722670dd8 130 rcv[i+2] = PsComm(data);//PsComm(0x00); // PADの状態を受信
kurt 0:ab4722670dd8 131 }
kurt 0:ab4722670dd8 132
kurt 0:ab4722670dd8 133 // SELをHIGHに
kurt 0:ab4722670dd8 134 PS_SEL_H;
kurt 0:ab4722670dd8 135
kurt 0:ab4722670dd8 136 // PADの状態を返す
kurt 0:ab4722670dd8 137 PREV.BUTTON.WORD = BUTTON.WORD;
kurt 0:ab4722670dd8 138 BUTTON.WORD = ((rcv[3]<<8) | rcv[4]) ^ 0xFFFF;
kurt 0:ab4722670dd8 139
kurt 0:ab4722670dd8 140 PREV.right_x = right_x;
kurt 0:ab4722670dd8 141 PREV.right_y = right_y;
kurt 0:ab4722670dd8 142 PREV.left_x = left_x;
kurt 0:ab4722670dd8 143 PREV.left_y = left_y;
kurt 0:ab4722670dd8 144 if(len >= 6){ //Convert range to -128~127
kurt 0:ab4722670dd8 145 ANALOG_MODE = 1;
kurt 0:ab4722670dd8 146 right_x = rcv[5] - 128;
kurt 0:ab4722670dd8 147 right_y = -(rcv[6] - 128 +1);
kurt 0:ab4722670dd8 148 left_x = rcv[7] - 128;
kurt 0:ab4722670dd8 149 left_y = -(rcv[8] - 128 +1);
kurt 0:ab4722670dd8 150 }else{
kurt 0:ab4722670dd8 151 ANALOG_MODE = 0;
kurt 0:ab4722670dd8 152 right_x = 0;
kurt 0:ab4722670dd8 153 right_y = 0;
kurt 0:ab4722670dd8 154 left_x = 0;
kurt 0:ab4722670dd8 155 left_y = 0;
kurt 0:ab4722670dd8 156 }
kurt 0:ab4722670dd8 157 }