プレステ1アナログコントローラ用ライブラリのサンプル
pspad.cpp
- Committer:
- kurt
- Date:
- 2013-09-09
- Revision:
- 1:38674ebae5dc
- Parent:
- 0:ab4722670dd8
- Child:
- 3:3a33f8294a84
File content as of revision 1:38674ebae5dc:
/* * pspad.c * * Created on: 2012/12/21 * Author: KORA */ #include "mbed.h" #include "pspad.h" //---------------------------------------------------------- // PS PAD //---------------------------------------------------------- #define PS_DAT datpin //400Ωほどのプルアップ必要 #define PS_CMD_H cmdpin = 1 #define PS_CMD_L cmdpin = 0 #define PS_SEL_H selpin = 1 #define PS_SEL_L selpin = 0 #define PS_CLK_H clkpin = 1 #define PS_CLK_L clkpin = 0 //---------------------------------------------------------- // 動作周波数 //---------------------------------------------------------- #define PS_FREQ 250//125 // パッドの動作周波数 (kHz) // タイマはこの2倍の周波数で動かす // 本来250kHzだが変更しても問題ない #define TM_PERI (500/PS_FREQ) // タイマの1クロックに要する時間(us) // タイマの2クロックをパッドの1クロックとしている //---------------------------------------------------------- // constructor //---------------------------------------------------------- Pspad::Pspad(PinName dat, PinName cmd, PinName sel, PinName clk) : datpin(dat), cmdpin(cmd), selpin(sel), clkpin(clk) { // GPIOの出力値を設定する PS_CMD_H; // CMD を1に PS_CLK_H; // CLK を1に PS_SEL_H; // SEL を1に // タイマの設定 tm.reset(); } //---------------------------------------------------------- // プレステ用ゲームパッドとの1バイトの通信 // 引数 // int send : 送信データ(0~255) // 戻り値 // int 受信データ(0~255) //---------------------------------------------------------- uint8_t Pspad::PsComm( uint8_t send_data ) { uint8_t i; uint8_t recv_data = 0; // カウント開始 tm.start(); for(i=0; i<8; i++) { // 送信データ if(send_data & 0x01){ PS_CMD_H; }else{ PS_CMD_L; } // クロックをLOWに PS_CLK_L; // 待機 while(tm.read_us()/TM_PERI <= 2*i); // クロックをHIGHに PS_CLK_H; // 受信データ recv_data |= (PS_DAT<<i); // 待機 while(tm.read_us()/TM_PERI <= 2*i+1); // 送信データを1ビットずらす send_data >>= 1; } // CMDをHIGHに戻す PS_CMD_H; // 5クロックほど待機 while(tm.read_us()/TM_PERI <= 2*8+2*5); // カウント停止 及び リセット tm.stop(); tm.reset(); return recv_data; } //---------------------------------------------------------- // プレステ用ゲームパッドからのデータの取得 // 変数 // uint32_t key ボタンの押下状態をbitmapで返す。 // int8_t right_x -128~127 の値を返す。アナログスティック中立時は0 // int8_t right_y -128~127 の値を返す。アナログスティック中立時は0 // int8_t left_x -128~127 の値を返す。アナログスティック中立時は0 // int8_t left_y -128~127 の値を返す。アナログスティック中立時は0 //---------------------------------------------------------- void Pspad::PsRead(void) { uint8_t i, len; uint8_t rcv[20]; //BUTTON.WORD = 0; right_x = 0; // アナログスティック中立 right_y = 0; // アナログスティック中立 left_x = 0; // アナログスティック中立 left_y = 0; // アナログスティック中立 // SELをLOWに PS_SEL_L; // 少し待機 tm.start(); while(tm.read_us() <= 40); // 40usでも動く模様 tm.stop(); tm.reset(); // 通信開始 rcv[0] = PsComm(0x01); // PADはコマンド'01h'を検出して動作を開始する rcv[1] = PsComm(0x42); // 受信データの下位4ビットが転送バイト数の半分の数を表す len = (rcv[1] & 0x03) * 2; // 転送バイト数を求める unsigned char data = 0x00; if(VIBRATE)data = 0x41; for(i=0;i<len+1;i++){ rcv[i+2] = PsComm(data);//PsComm(0x00); // PADの状態を受信 } // SELをHIGHに PS_SEL_H; // PADの状態を返す PREV.BUTTON.WORD = BUTTON.WORD; BUTTON.WORD = ((rcv[3]<<8) | rcv[4]) ^ 0xFFFF; PREV.right_x = right_x; PREV.right_y = right_y; PREV.left_x = left_x; PREV.left_y = left_y; if(len >= 6){ //Convert range to -128~127 ANALOG_MODE = 1; right_x = rcv[5] - 128; right_y = -(rcv[6] - 128 +1); left_x = rcv[7] - 128; left_y = -(rcv[8] - 128 +1); }else{ ANALOG_MODE = 0; right_x = 0; right_y = 0; left_x = 0; left_y = 0; } }