The Wii Remote includes a 6-pin expansion port that allows external peripherals to be connected to it. Communications are bidirectional synchronous serial I2C, and the devices provide a virtual register block of length 0x100 that is mapped at 0xa40000 in the Wii Remote's address space (The 7-bit I2C address is 0x52). Communications are encrypted, as detailed in below. Nintendo has currently released two extensions, the Nunchuk and the Classic Controller. In addition, Guitar Hero guitars and drums also act as extension controllers, although the Rock Band guitars and drums connect using their own system. The balance board acts like a dummy Wiimote with its own type of extension controller. There are also many third party versions of classic controllers and nunchuks.
The Wii Motion Plus is a small expansion which itself has an expansion port, allowing people to plug the Nunchuk into the Wii Motion Plus and the Wii Motion Plus into the Wii Remote.
Peripheral Protocol is 400kHz "fast" I2C, with slave address 0x52. It is easy to make homebrew peripherals; see the Tenkey numberpad project(japanese), gyro project(japanese), the Twiidler project, the DIY Wii drum controller, the OpenChord Guitar,or the DIY Wii guitar proof of concept demo video.
Registers / Initialization
Wii Motion Plus is mapped at register 0xa60000.
Other extension Controllers are mapped at register address 0xa40000. The data is 0x100 bytes long, and it is mirrored across the entire 16-bit address space up to 0xa4FFFF. These registers are readable and writable. Communications are optionally encrypted, and explicit initialization is required to disable encryption (see below).
In encrypted mode, bytes can be decrypted using the following transformation:
decrypted_byte = (encrypted_byte XOR table1[address%8]) + table2[address%8]
Where table1 and table2 are 8-byte tables calculated based on the 16-byte key sent by the host, and address is the address of the byte being read (only the bottom 3 bits matter). If the host key is 16 zero bytes, table1[x] and table2[x] are all 0x97. The value 0x17 was used previously, which is equivalent. Proof of why any two pairs of table entries a,b and x,y are equivalent if (a^b^x^y)&0x80 == 0 is left as an exercise to the reader.
The calculations should be performed mod 256, that is, truncated to 8 bits (in languages such as C and Python, use &0xFF or work directly with 8-bit datatypes).
If the Wii Remote is initialized using the new method listed below, then the encryption of the extension bytes is disabled and they need not be decrypted using the transform listed above.
The Wii Remote will stream data bytes from the Extension Controller starting at offset 0x08, and continuing for however many bytes the current Data Reporting Mode requires. Data streamed through the Input Reports must also be decrypted using the above transformation if encryption is enabled.
Once initialized, the last six bytes of the register block identify the connected Extension Controller. A six-byte read of register 0xa400fa will return these bytes. The Extension Controller must have been initialized prior to this. There are two ways of initializing the extension.
The Old Way
The old way to initialize the extension was by writing the single encryption byte 0x00 to 0x(4)A40040, but that only works on Nintendo's own brand extensions and the GH3 Guitar, and will fail on 3rd party wireless nunchuks and GHWT extensions. If it fails, the 6 bytes will be FFFF FFFF FFFF. With this method you must decrypt the extension bytes to read them.
The New Way
The new way to initialize the extension is by writing 0x55 to 0x(4)A400F0, then writing 0x00 to 0x(4)A400FB. It works on all extensions, and makes the extension type bytes unencrypted. This means that you no longer have to decrypt the extension bytes using the transform listed above.
|0000 0000 0000*||0x2E2E||BladeFX adapter that has been initialised old way, unplugged then replugged|
|FFFF FFFF FFFF*||0xFFFF||GHWT Guitar or Drums or synced BladeFX or other wireless nunchuk initialised the old way|
|0xFEFE||0000 A420 0000||Nunchuk|
|0xFDFD||0000 A420 0101||Classic Controller|
|0xFDFD||0100 A420 0101||Classic Controller Pro & NES/SNES controller from the NES/SNES mini|
|0xFEEB||FF00 A420 0013||Drawsome Graphics Tablet|
|0xFDFB||0000 A420 0103||GH3 or GHWT Guitar|
|0xFDFB||0100 A420 0103||Guitar Hero World Tour Drums|
|0300 A420 0103*||DJ Hero Turntable|
|0000 A420 0111*||Taiko no Tatsujin TaTaCon (Drum controller)|
|FF00 A420 0112*||uDraw GameTablet (Graphics tablet)|
|0000 A420 0310*||Densha de GO! Shinkansen Controller|
|0000 A420 0402*||0x2A2C||Wii Balance Board|
|0000 A420 0005*||Inactive Wii Motion Plus (Built-in)|
|0000 A420 0405*||Activated Wii Motion Plus|
|0000 A420 0505*||Activated Wii Motion Plus in Nunchuck passthrough mode|
|0000 A420 0705*||Activated Wii Motion Plus in Classic Controller passthrough mode|
|0000 A620 0005*||Inactive Wii Motion Plus|
|0000 A620 0405*||No-longer active Wii Motion Plus|
|0000 A620 0505*||No-longer nunchuk-passthrough Wii Motion Plus|
|0000 A620 0705*||No-longer classic-passthrough Wii Motion Plus|
The values marked with a * are actually already unencrypted, and should not be decrypted. They are given here along with unencrypted version for those wanting to use simplified detection code. You can easily tell whether a value should be decrypted or not by looking at the other values in the 0xa400fa to 0xa400fd region.
The "Partially inserted" condition allegedly occurs when the connector is loose or has a bad connection. Usually, this will correct itself upon full insertion. However, it has been known to "stick" in the partially inserted state rarely. This is a hardware glitch, the fix is to simply disconnect and reconnect the Extension Controller. Third party controllers such as wireless nunchuks also return this value if initialized with the old method, in which case the whole last 16 bytes will be FF.
Contrary to previous documentation, the 0000 0000 0000 value does NOT occur when nothing is inserted. Instead you get error 7 when you try to read the expansion type. A successful 0000 0000 0000 only occurs when a BladeFX wireless nunchuk is synced, initialized with the old method, then the adapter is unplugged, then the adapter is replugged.
A Wii Balance Board extension is only found in a Wii Balance Board. Although it exposes functionality as an Extension Controller, they are not separable and this controller is documented separately.
Data format code
After some research of NES/SNES Classic Mini's Classic Controller driver source code, it turned out that the penultimate byte of the register block identify (e.g. the byte at offset 0x(4)A400FE) is data format code. So 0x00 is the Nunchuck data format and 0x01 is the default Classic Controller data format. Actually, this byte is writable for some controllers. So, official Classic Controller supports data formats 0x01, 0x02 and 0x03. Most old third party Classic Controllers supports only 0x01, NES/SNES Classic Mini tries to set the data format byte to 0x03, that's why most of them don't work. Guitar Hero controller uses mode 0x03 by default, so it shares the data format with Classic Controller, that's why guitar can be used in Wii's main menu.
After the identification is read, the encryption can be set up if required. This is done by enabling encryption by writing 0xAA to extension register 0xF0, and then writing the 16-byte key to register 0x40. The key is written in 3 blocks of 6, 6, and 4 bytes. (Writing a single encryption byte to register 0x40 will work on genuine Nintendo controllers, but not on others). After this the extension can be operated in full encryption mode.