太郎 九大 / pspad
Committer:
kurt
Date:
Fri Sep 13 23:07:34 2013 +0000
Revision:
3:626a7462e184
Parent:
2:af93372182bf
Child:
4:64efd8803fa9
correct mode(PullUp)

Who changed what in which revision?

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