Connect to a Wii Motion Plus (compatible) unit with no pass through or other controllers connected. The Motion Plus is a 3-axis gyroscope add-on w/Invensense IDG655 & IXZ650 MEMS gyros communicating via I2C @ 100KHz clock (some may do 400KHz)
WiiMP.c@0:506079387c48, 2011-03-14 (annotated)
- Committer:
- gbrush
- Date:
- Mon Mar 14 22:39:59 2011 +0000
- Revision:
- 0:506079387c48
- Child:
- 1:727906cb5051
Initial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gbrush | 0:506079387c48 | 1 | #include "WiiMP.h" |
gbrush | 0:506079387c48 | 2 | |
gbrush | 0:506079387c48 | 3 | |
gbrush | 0:506079387c48 | 4 | |
gbrush | 0:506079387c48 | 5 | WiiMP::WiiMP(PinName data, PinName clk):_i2c(data, clk) { |
gbrush | 0:506079387c48 | 6 | _i2c.frequency(100000); // Some report success at 400000, but 100000 should be guaranteed |
gbrush | 0:506079387c48 | 7 | Error = true; |
gbrush | 0:506079387c48 | 8 | |
gbrush | 0:506079387c48 | 9 | //initialize whatever is at 0xA4 (if anything) -- will turn off MP+ if it's already on |
gbrush | 0:506079387c48 | 10 | unsigned char cmd[] = {0xF0, 0x55}; |
gbrush | 0:506079387c48 | 11 | _i2c.write(WIIEXT_ADDR, (const char*)cmd, sizeof(cmd)); |
gbrush | 0:506079387c48 | 12 | wait_ms(I2C_READ_DELAY); |
gbrush | 0:506079387c48 | 13 | |
gbrush | 0:506079387c48 | 14 | // Instruct WiiMP to change address from 0xA6 to 0xA4 and initialize |
gbrush | 0:506079387c48 | 15 | cmd[0] = 0xfe; cmd[1]= 0x04; |
gbrush | 0:506079387c48 | 16 | if (_i2c.write(WMP_ADDR, (const char*)cmd, sizeof(cmd)) == I2C_ACK) { |
gbrush | 0:506079387c48 | 17 | Error = false; |
gbrush | 0:506079387c48 | 18 | } |
gbrush | 0:506079387c48 | 19 | |
gbrush | 0:506079387c48 | 20 | } |
gbrush | 0:506079387c48 | 21 | |
gbrush | 0:506079387c48 | 22 | bool WiiMP::Read(int* Yaw,int* Roll,int* Pitch) { |
gbrush | 0:506079387c48 | 23 | |
gbrush | 0:506079387c48 | 24 | int i; |
gbrush | 0:506079387c48 | 25 | char readBuf[WIIMP_READLEN]; |
gbrush | 0:506079387c48 | 26 | |
gbrush | 0:506079387c48 | 27 | if (Error) { |
gbrush | 0:506079387c48 | 28 | return false; |
gbrush | 0:506079387c48 | 29 | } |
gbrush | 0:506079387c48 | 30 | |
gbrush | 0:506079387c48 | 31 | const unsigned char cmd[] = {0x00}; |
gbrush | 0:506079387c48 | 32 | if (_i2c.write(WIIEXT_ADDR, (const char*)cmd, sizeof(cmd)) == I2C_ACK) { |
gbrush | 0:506079387c48 | 33 | wait_ms(I2C_READ_DELAY); |
gbrush | 0:506079387c48 | 34 | if (_i2c.read(WIIEXT_ADDR, readBuf, sizeof(readBuf)) == I2C_ACK) { |
gbrush | 0:506079387c48 | 35 | //init values |
gbrush | 0:506079387c48 | 36 | *Yaw = 0; *Roll = 0; *Pitch = 0; |
gbrush | 0:506079387c48 | 37 | |
gbrush | 0:506079387c48 | 38 | for (i = 0; i < WIIMP_READLEN; ++i) { |
gbrush | 0:506079387c48 | 39 | readBuf[i] = (readBuf[i] ^ 0x17) + 0x17; |
gbrush | 0:506079387c48 | 40 | } |
gbrush | 0:506079387c48 | 41 | *Yaw = ((readBuf[YawH] >> 2) << 8) + readBuf[YawL]; |
gbrush | 0:506079387c48 | 42 | *Roll = ((readBuf[RollH] >> 2) << 8) + readBuf[RollL]; |
gbrush | 0:506079387c48 | 43 | *Pitch = ((readBuf[PitchH] >> 2) << 8) + readBuf[PitchL]; |
gbrush | 0:506079387c48 | 44 | |
gbrush | 0:506079387c48 | 45 | } |
gbrush | 0:506079387c48 | 46 | else |
gbrush | 0:506079387c48 | 47 | { |
gbrush | 0:506079387c48 | 48 | return false; |
gbrush | 0:506079387c48 | 49 | } |
gbrush | 0:506079387c48 | 50 | } else { |
gbrush | 0:506079387c48 | 51 | return false; |
gbrush | 0:506079387c48 | 52 | } |
gbrush | 0:506079387c48 | 53 | return true; |
gbrush | 0:506079387c48 | 54 | } |