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.