Sunday, June 13, 2010

Communication dumps between wiimote+motionplus with and without extension and wii

Just a quick post from me, presenting you some motionplus communication dumps:

Redsteel2_motionplus_and_nunchuk_raw_communication_dump.txt
http://www.mediafire.com/download.php?2zkmmweeteq

Wii_Sports_Resort_motionplus_raw_communication_dump.txt:
http://www.mediafire.com/download.php?djtzraqhojw

Dynamic MotionPlus (WMP,WM+) Calibration - Part 2: Reversing calibration data at a40050h

I'm not completely done with it, but this is what I got so far. This was reverse engineered by me and megazig. Megazig even reverse engineered the checksum algo, but I won't publish it, since it is of no practical use to us. I will just add that the mechanism involves summing up bytes with constant table lookups and following xor'ing, which gets done a couple of times. Apart from that a big thanks to crediar for helping us out with the necessary input.

4x16 Bytes within the active motion plus register starting at 0xA40050. Data is interleaved,
starting with a 28 byte long structure for fast motion and following 28 bytes for slow motion.
8 Byte orientation blocks consist of 2 single-precision floats, former represent zero- and later scale-values.
The yellow block represents a 32bit signed integer, which is not fully understood yet.

This is how the game splits the data at 50h into a data structure, which is 28 bytes long. After the game has copied those values to the corresponding structure/datatype, a few floatpoint calculations which I haven't completely reversed yet, will be applied on those values. The data itself most likely just represents a simple orientation matrix. Note: I don't think yaw has to be set to an exact value at the beginning, since we only want to move relative to a fixpoint. So it's possible to just set it to a pseudo-random value, and move relative to it, as soon we have visual contact to the sensorbar to adjust the yaw. More later.

Tuesday, June 8, 2010

Dynamic MotionPlus (WMP,WM+) Calibration - Part 1: Shaking some hands.....

You might have wondered yourself how to toggle MotionPlus dynamic calibration. Well, here we go.
Part 1 will be about the handshake and part 2 will be dedicated to the 64bytes long data structure at register 0xA40050. If you would like to know anything else, just drop a comment.



As soon as a game has verified that a MP is active, which was done by reading from the active extension register at 0xA400F0-FF, hardcoded calibration data will be read from register 0xA40020-3f. Afterwards a controlflag at 0xA400F7 will be checked. This flag can contain values like 02,06,08,0A,0C,0E or 1A.
Every value represents a different initiation state of the MP extension. For instance if the flag is below a certain state, data reports will contain invalid or 0xFF'ed MP extension data or certain actions are not able to be done. The default(inactive) is 0x10. When the MP gets activated, the flag will be reseted to 0x02 (maybe even to zero but you wont be able to read this value since it would just change too fast to catch it) and will be gradually increased until it reaches 0x1A, which represents an activate state with accomplished dynamic recalibration(doesn't matter if the recalibration was successful or not).
When there is an extension connected to the MP, the game will read 3 more bytes by reading 4 bytes from 0xA400F6. Those 3 bytes will be always 0xx00 when there's an extension connected to the MP, else they are defaultwise 0xFF. There is no direct need to read them. At this point our controlflag usually will be already 0x0C/0x0E. For the next step however its important to be at least in state 0x08.
The next step toggles dynamic calibration. It is done by writing 0x00 to 0xA400F2. Data at 0x50-0x8f will now start to change until a second 0x00 write to 0xA400F2 is issued to stop the calibration. So it would be smart to  keep track of extension data reports to make sure to trigger the routine not too early, since it might be still moving. The game will read out the initiation state flag again and verify that it's at least 0x0E. Then the calibration data will be read out twice to make sure the routine wasn't still running in between. After this is done the game will check if the data is reasonable, and write either 0x00 or 0x01 to register  0xA400F1. A write to this register will change the calibration data again, which seems to me is just some sort of correction or update. As soon as the game verified that the calibration was accomplished by simply checking the initiation state, which should read 0x1a now, it will read out the calibration data twice again from  0xA40050-8f. This data represents a rotation matrix
Stay tuned for part 2.

I hope this was of any help to ya chaps. If you like it, link it.

Best regards
Sanchez

Thursday, May 27, 2010

Calibration data

Hola hombres,
this time I'm presenting you guys a handful of nunchuk and motion plus calibration data samples found at register 0x20-3f of different nunchuks/motionplus devices. And last but not least, I added motion plus sync/calibration data found at register 50h on different orientations.
Check out the google spreadsheet below if your interested to take a look into the data or even analyze it. Feedback is always welcome and appreciated.

spreadsheet


Saturday, May 22, 2010

MP Initiaton - with and without extension hooked up

Last time I did a post on calibration data. This time I'll talk about the general initiation scheme of the MotionPlus(MP) Extension. There are two possible cases which are handled in my scheme below - either there's an extension connected or none connected to the motion plus pass-through port. Parts that are marked blue are specific for the MP, yellows parts are done additionally when an extension was connected to the MP.

Games will usually start with requesting a status report. When the MP already  has been active, it will be deactivated by the following Init() (write 0x55 to 0xA400F0  and 0x00 to 0xA400FB) and a corresponding status report 0x20 will be scheduled. Afterwards the game will usually try to read out the extensions ID  within the active extension register located at 0x(A400)FA. If there was an extension hooked up to the Wiimote besides the MP, we'll find  its corresponding ID at that place and the game starts encryption( the so called "old way", but it's the way games do it). It's done by writing a 16bytes long key splitted in three chunks (6bytes,6bytes,4bytes) at 0x(A400)40. Extension data wil be encrypted from now on (calibration data, active extension register data). When the encryption was set, the game will read out the calibration data encrypted from the extension device connected to the MP.
As soon that is done, the game will check if there's a MP available by attempting to read from A600FE. It will return the corresponding MP extension ID. If the MP has already been activated earlier and has not been deactivated somehow - which shouldn't be the case, since the game was clever enough to do an Init() at the beginning of the whole handshake, which disables the MP and activates the regular extension- it will throw out a readerror. The readerror would mean at this place, there was no MP present at all. You could check that, by simply comparing the active extension ID or resp. do another Init() and do the whole cycle other again. If the extension ID was found at register 0xA600FE, the game will issue a MP Init(2) .The Init2() consists of a 0x55 single byte write to 0xA600F0 and a 0x05 single byte write to 0xA600FE. The byte written to 0xA600FE varies, depending on what extension the game still might want to use or what it already has found. When only the MP is needed, it would just write 0x04 to 0xA600FE instead, if it does need the nunchuk for instance as well, it would write 0x05 to passthrough the extension data from the nunchuk.
Apart from that, you could also just write 0x05 even if u only have a MP. The written single byte to 0xA600FE, will initiate a registerswap(0xA4xxxx and 0xA6xxxx) and a status report about a new connected extension will be sent out by all means. If there was a passthrough extension connected, there will be first a  status report send out, informing you of a disconnection of the current active extension, and then the regular one noticing you of a connection, will be sent out. Now, since the extension registers got swapped, readerrors will occur on readattempts to the former MP extension ID at 0xA600FE. The game will expect those read errors since it just activated the MP. It will read as long there was no status report (extension connected) issued, which usually takes a period of 2-3 read attempts. When no report gets issued, the game will just issue another Init() to play the whole cycle over again after some time. When the report got issued, the game will write a 0x00 single byte to 0xA400FB, to ready up the device and refresh the data reporting, due an "unrequested (connection) status reports.

The game will try to verify a last time whether it's the right extension(MP), and will read out its extension ID at 0xA400FA. Which should read 00 00 A4(instead of A6, gets changed because of the page mapping) 20 05(depending on what you wrote to 0xA600FE earlier) 05. When this all is settled, the game will request calibration data from the active extension register at 0x20-0x3f just like for regular extensions . If there was an extension hooked up to the MP extension port, calibration data will be requested, which resides noncrypted at 0xA40040. Motionplus supporting games will usually validate the extensions calibration data checksum (last 2 bytes of it). If it's incorrect it will issue a 0x01 write to 0xA400F3h. The game will explicitly disable the MP and try to do the whole Init() over again. If the validation was passed, the game will now request syncdata at 0x50-0x8f, to sync up MP data with Wiimote accel data which is needed to get "6DOF". This is needed to correlate regular accel velocities and angular accel for absolute orientation.

I hope this was some clear and any helpful. Be fair and don't forgot to link if your passing stuff.

In my next posting I will hopefully be able to present you chaps a way more complete and corrected calibration data scheme and maybe already a small scheme on issued sync-data since I already know how to make the MP generate new sync data! So knowing how the syncdata is splitted, would be very helpful for a lot of people, since we won't need to do the calibration ourselves anymore - like most fellas are doing it at the moment, esp. those who are working on robotic stuff.;)


Best regards
Sanchez


Wednesday, May 19, 2010

Getting started!

What's the first thing that pops into your head after you initiated a wiimote extension. Bingo, calibration. Wii games will usually try to initiate any extension that is plugged into either the Motionplus or resp. Wiimote by doing a regular extension init() handshake. If there's an active Motionplus device it will be disabled by doing so and a register swap will automatically be issued. The game will try to request encryption and read from 0x20-0x3f, so far so good. Afterwards if the game has everything that was needed or resp. there was no extension at all in the wiimote/passthrough port, it will try to activate the WM+ by writing 0x55 to 0xA600F0 and then 0x04/5/7 to 0xA600Fe, this will issue a register swap if a WM+ was present. Subsequently the game will try to verify if the extension register at 0xA4xxxx was changed by reading the new WM+ extensions ID at 0xA400FA - sometimes games already read data up from 0xA400F0 or only 0xA400FE, depending on it's internal game state and previous inquiries to verify certain flags. If all that is done, the game will request data from 0x20-0x3f just like for regular extensions that are plugged into the Wiimote resp. WM+ passtrough port. We will receive 32 bytes of calibration data.

Calibration Data:
What do we know. We know the Motionplus(wm+) consists of two gyro sensors with a total of 3 sensed axis(14bit vars). Each axis will require a neutral var, and a var for min- and max-ranges. Do not forget, the gyros are able to work in fast motion and slow motion mode to increase accuracy on slow motions, which means we will need 6 vars in the end for each axis to properly calibrate it. This makes a total of 18 vars for all 3 axis, which equals 252 bits. However we receive 256 bits /32 bytes. This means either 4 bits weren't used at all (unlikely tho) within the calibration data resp. just consist of dummy data or represent some kind of checksum similar to nunchuck calibration data, which is most likely.


If you analyze the calibration data, it looks like it got splitted like this:

ata at 0x20 consists of either just fast motion or slow motion related data(I couldn't determine yet which line holds which) and 0x30 the remaining one plus probably 4 unused or checksum-ish bits. The first 6 bytes of each line, consist of neutral values(X,Y,Z) separated by 2 bits, which are probably part of max/min values of the Y/Z Axis. What follows is the calibration data for min and max ranges for each eaxis, however due it's compact packing, quite a lot bits got moved around towards byte 15. I can't say yet which is which. But the calibration data for min/max(X/Y-axis) values seems to be consistent. 0x30 is splitted very similar to 0x20, however the bitsshifting occurs already around byte~12. But again, min/max x and min.y look fine and consistent. I still need to figure out the exact splitting of max.Y and min/max.Z plus the exact location of the remaining 4 bits. For that purpose I will probably need more calibration data,i I you want to help me, drop me a line and post me your motion plus calibration data at 0x20-0x3f.


I hope that was helpful in any way, and be kind to link to this blog when you spread the word. It was quite some work.

Best regards
Sanchez

---------------------------------------------------------
http://invensense.com/mems/gaming.html
http://invensense.com/mems/gyro/documents/whitepapers/Selection-and-integration-of-MEMS-based-motion-processing-in-consumer-apps-070809-EE-Times.pdf
http://invensense.com/mems/gyro/documents/ps-isz-0650b-00-04.pdf
http://invensense.com/mems/gyro/documents/PS-IDG-0650B-00-04.pdf


Monday, May 17, 2010

Hey

I put quite a lot time and effort in this project. This blog will show you some useful stuff around the WM+, which you might not even have known yet. Some data is and was was already available over the internet. Unfortunately however, for the reader most stuff is scattered all over different sites, and at the same time not always complete or even worse, inconsistent. My goal is to bundle all useful data, which was either disclosed by myself or others. That way we can have all the important stuff, programming-wise on one page.

This blog will be updated soon.
Wiimote Motion Plus calibration data schemes, full de/init schemes(passthrough-mode and motionplus-only-mode), and traffic dumps, etc, will follow.
Stay tuned if you care.