プレステ1アナログコントローラ用ライブラリのサンプル
Revision 0:ab4722670dd8, committed 2013-09-09
- Comitter:
- kurt
- Date:
- Mon Sep 09 06:30:27 2013 +0000
- Child:
- 1:38674ebae5dc
- Commit message:
- for publish
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Sep 09 06:30:27 2013 +0000 @@ -0,0 +1,20 @@ +#include "mbed.h" +#include "pspad.h" + +Serial pc(USBTX, USBRX); +Pspad PS(PTB11,PTB10,PTB9,PTB8); +Timer LapTime; + +int main() { + pc.baud(921600); + while(1) { + PS.PsRead(); + + pc.printf("time:%d",LapTime.read_us()); + LapTime.start(); + + if(PS.BUTTON.BIT.MARU&&(0==PS.PREV.BUTTON.BIT.MARU)) PS.VIBRATE = 1-PS.VIBRATE; + pc.printf("%5d %5d", PS.BUTTON.BIT.MARU, PS.PREV.BUTTON.BIT.MARU); + pc.printf("%5d %5d %5d %5d %5d \r\n", PS.BUTTON.WORD, PS.right_x, PS.right_y, PS.left_x, PS.left_y); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Sep 09 06:30:27 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9c8f0e3462fb \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pspad.cpp Mon Sep 09 06:30:27 2013 +0000 @@ -0,0 +1,162 @@ +/* + * 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; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pspad.h Mon Sep 09 06:30:27 2013 +0000 @@ -0,0 +1,132 @@ +/* + * pspad.h + * + * Created on: 2012/12/21 + * Author: USER + */ + +#ifndef PSPAD_H_ +#define PSPAD_H_ + +/*--------PSPADのアクセスの構造体------- +PS--.PsRead() +|---.right_x +|---.right_y +|---.left_x +|---.left_y; +|---.VIBRATE; +|---.ANALOG_MODE; +|---.BUTTON .WORD +| |---.BIT.L2 +| |-.R2 +| |-.L1 +| |-.R1 +| |-.SANKAKU +| |-.MARU +| |-.BATU +| |-.SIKAKU +| |-.SELECT +| |-.L3 +| |-.R3 +| |-.START +| |-.UP +| |-.RIGHT +| |-.DOWN +| --.LEFT +----.PERV--.right_x + |---.right_y + |---.left_x + |---.left_y; + ----.BUTTON .WORD + |---.BIT.L2 + |-.R2 + |-.L1 + |-.R1 + |-.SANKAKU + |-.MARU + |-.BATU + |-.SIKAKU + |-.SELECT + |-.L3 + |-.R3 + |-.START + |-.UP + |-.RIGHT + |-.DOWN + --.LEFT +---------------------------------------*/ + +//------------------------------------------------------------------------- +// Class +//------------------------------------------------------------------------- +class Pspad +{ +public: + Pspad(PinName dat, PinName cmd, PinName sel, PinName clk); + void PsRead(void); + + union { + uint32_t WORD; + struct { + unsigned char L2 :1; + unsigned char R2 :1; + unsigned char L1 :1; + unsigned char R1 :1; + + unsigned char SANKAKU :1; + unsigned char MARU :1; + unsigned char BATU :1; + unsigned char SIKAKU :1; + + unsigned char SELECT :1; + unsigned char L3 :1; + unsigned char R3 :1; + unsigned char START :1; + + unsigned char UP :1; + unsigned char RIGHT :1; + unsigned char DOWN :1; + unsigned char LEFT :1; + } BIT; + } BUTTON; + int8_t right_x, right_y, left_x, left_y; + unsigned char VIBRATE; + unsigned char ANALOG_MODE; + struct { + union { + uint32_t WORD; + struct { + unsigned char L2 :1; + unsigned char R2 :1; + unsigned char L1 :1; + unsigned char R1 :1; + + unsigned char SANKAKU :1; + unsigned char MARU :1; + unsigned char BATU :1; + unsigned char SIKAKU :1; + + unsigned char SELECT :1; + unsigned char L3 :1; + unsigned char R3 :1; + unsigned char START :1; + + unsigned char UP :1; + unsigned char RIGHT :1; + unsigned char DOWN :1; + unsigned char LEFT :1; + } BIT; + } BUTTON; + int8_t right_x, right_y, left_x, left_y; + } PREV; + +private: + uint8_t PsComm(uint8_t send_data); + Timer tm; + DigitalIn datpin; + DigitalOut cmdpin; + DigitalOut selpin; + DigitalOut clkpin; +}; + +#endif /* PSPAD_H_ */