📜 ⬆️ ⬇️

Making homemade accessories for the Nintendo Wii

I own a Nintendo Wii, and recently I wondered how the “expansion port” works on the Wi-Fi port, which is designed to connect various accessories. At the same time, I could not help trying to create my own device for connecting to the Wii.

image


Prehistory


It all started with the fact that in the so-called “star catalog” of Nintendo I saw this:
image
')
This is the Wii controller as a gamepad from the SNES. For those who do not know, I’ll tell you that you can officially buy and play games on the Wii from NES (we are better known as Dandy), SNES (aka Super Nintendo), Nintendo 64 and other classic consoles. In order to fully play such games, you need to additionally buy a “classic controller,” which is a regular gamepad.

So, this gamepad in the form of the original SNES controller can be “bought” in the star catalog only for the stars obtained when buying games. Simply put, it can not be so easy to buy in the store as a regular classic gamepad, because of this, this thing is very much appreciated in narrow circles.

It immediately occurred to me - why not make an adapter that allows you to connect to the Wiimote (the classic controller connects to it, and not directly to the console) a real gamepad from SNES, and also from NES, Nintendo 64 and something else . So the question arose of how the viimout expansion port is arranged.

Theory


After a little googling, it turned out that there is the usual I²C protocol! The connector uses five pins: ground, power, clock, data, and connection detection (there you just need to power up).

image

The connected device must have the address 0x52. Transmitted data is encrypted for some reason. What does it use a 512-bit key that the WiMoot itself transmits. A simple formula is used for decoding:
decrypted_byte = (encrypted_byte ^ table1[address%8]) + table2[address%8] 

Why is there encryption? I can not imagine. Fortunately, it soon became clear that there is a ready-made library for creating your Wii devices:
code.google.com/p/circle-of-current/wiki/WiiExtensionLibrary

It implements work with I²C and encryption-decryption for AVR microcontrollers. Just what I need! It remains only to substitute the device ID and fill the array with the transmitted data. Here is the ID of some devices:

image
(Information from wiibrew.org)

I was interested in the Classic Controller. Next, it was necessary to figure out what format to send the data. And six bytes are transmitted there:

image

LX and LY are left analog stick (0-63), RX and RY are right analog stick (0-31), LT and RT are analog ciphers (0-31), BD {L, R, U, D } - the cross, B {ZR, ZL, A, B, X, Y, +, H, -, LT, RT} - buttons, where 1 is pressed and 0 is pressed.

Everything is somewhat confusing ... It is also worth taking into account that when turned on, the device is calibrated and the first value obtained from analogs is considered central.

Implementation


Thus, in a quiet position of the gamepad, an array of six bytes of data will look like this:
  unsigned char but_dat[6]; // struct containing button data but_dat[0] = 0b01011111; // RX<4:3> LX<5:0> but_dat[1] = 0b11011111; // RX<2:1> LY<5:0> but_dat[2] = 0b10001111; // RX<0> LT<4:3> RY<4:0> but_dat[3] = 0b00000000; // LT<2:0> RT<4:0> but_dat[4] = 0b11111111; // BDR BDD BLT B- BH B+ BRT 1 but_dat[5] = 0b11111111; // BZL BB BY BA BX BZR BDL BDU 

The upper bits of the sticks are zero, everything else is equal to one. This will transfer the data in which the sticks are in the center, and all the buttons are pressed.

It remains only to change these values ​​to the necessary ones and send them when the Wiimuth polls our device. The first thing I decided to try to connect the game controller from the Dandy. Those. read the buttons pressed on it and send them to the viewpoint, imitating clicking on a classic controller.

I will not talk about how to read data from the gamepad from Dandy, this topic is very battered, and it is done very easily. You can read, for example, this article: habrahabr.ru/post/191936 by KurilkaRymin . However, here is the code for this, it is quite small:
 uint8_t get_nes_gamepad() { uint8_t gamepad_data = 0; NES_PORT &= ~(1<<LATCH_PIN); // Latch int b; for (b = 0; b < 8; b++) { NES_PORT &= ~(1<<CLOCK_PIN); // Clock _delay_us(10); gamepad_data |= (((NES_PORT_PIN>>DATA_PIN)&1)<<b); NES_PORT |= 1<<CLOCK_PIN; // Clock _delay_us(10); } NES_PORT |= 1<<LATCH_PIN; // Latch _delay_us(10); return gamepad_data; } 


Everything worked without any delays and problems, except for the fact that the Dendiv controllers did not spare time, I had to actively rub the contacts with alcohol. By the way, oddly enough, they have enough power of 3.3 volts, although they write everywhere that they are powered by five volts. I was already mentally preparing to do a level converter, but I did not have to.

Now I can play Wii games from NES on the controller from Dandy. Or on the native controller from the NES, if you get one. However, they differ only in the presence of turbo cheat buttons.

In the plans:


Project Source Code : github.com/ClusterM/nes2wii
Main source of information : wiibrew.org/wiki/Wiimote/Extension_Controllers

Source: https://habr.com/ru/post/208266/


All Articles