User Tools

Site Tools


uic

UIC

The UIC is the gamepad's auxiliary microcontroller. It is connected to the CPU over the SPI bus.

Given the characteristics, the UIC could be a STM8L151R8. It has 4KB of RAM, 2KB of EEPROM and 64KB of FLASH.

Pinout

Pin Name Function
1 PA0 SWIM pin
2 PA1/NRST Reset
3 PA2 DPAD right
4 PA3 DPAD left
5 PA4 DPAD down
6 PA5 Left joystick Y
7 PA6 Left joystick X
8 PA7 Right joystick button
9 GNDA/Vref- Analog ground and ADC negative reference
10 GND1 Ground
11 Vcc1 Supply voltage
12 VccA Analog supply voltage
13 Vref+ ADC positive reference
14 PG0 DPAD up
15 PG1 xx
16 PG2 xx
17 PG3 xx
18 (res.) xx
19 PE0 xx
20 PE1 xx
21 PE2 Red LED
22 PE3 Button ZL
23 PE4 Button L
24 PE5 Sync button
25 PD0 Button ZR
26 PD1 Button R
27 PD2 xx
28 PD3 xx
29 Vcc3 Supply voltage
30 GND3 Ground
31 PB0 xx
32 PB1 xx
33 PB2 Amber LED
34 PB3 xx
35 PB4 SPI - UIC chipselect
36 PB5 SPI - clock
37 PB6 SPI - MOSI
38 PB7 SPI - MISO
39 PF0 xx
40 PF1 xx
41 PF4 xx
42 PF5 xx
43 PF6 Button A
44 PF7 Button B
45 PD4 Button X
46 PD5 Button Y
47 PD6 Right joystick X
48 PD7 Right joystick Y
49 PG4 xx
50 PG5 xx
51 PG6 xx
52 PG7 xx
53 PC0 UIC I2C - SDA
54 PC1 UIC I2C - SCL
55 Vcc2 Supply voltage
56 GND2 Ground
57 PC2 Button +
58 PC3 Button -
59 PC4 HOME button
60 PC5 TV button
61 PC6 Left joystick button
62 PC7 xx
63 PE6 Blue LED (?)
64 PE7 Power button (active low)

Pins 1 and 2 are connected to test points TP233 and TP234 respectively. Pin 1 doesn't seem to be connected to anything else. Pin 2 is connected to a simple reset circuit.

Pin 1 would be the SWIM debug pin, but as far as I've seen, SWIM seems to be entirely disabled on the UIC.

Bootloader command list

Bootloader commands must be sent in two bytes, where the second byte is the first byte negated. Additionally, the read/write commands have basic integrity checks on the input data.

The only exception is command 0x7F.

Bootloader commands only apply when the UIC is in firmware upload mode (ie when no firmware is installed). In this mode, it is required to send command 0x7F before the other commands become available.

Command Parameters Response bytes Description
0x00 0xFF 0 1 Get version and supported commands
0x11 0xEE 5+1 1+1+N+1 Read memory
0x21 0xDE 0 1 Finalize firmware upload
0x31 0xCE 5+1+N 1+1+1 Write memory
0x7F 0 1 Get firmware type

The command set is based on the official STM8 bootloader command set, with a few differences:

  • The data returned by command 00 FF is wrong
  • Command 21 DE does not take an address
  • Command 11 EE is limited to 128 bytes
  • There is no memory erase command

Command 00 FF

Get bootloader version and supported commands.

Response is 8 bytes: 0x79, 0x05, 0x10, 0x00, 0x11, 0x21, 0x31, 0x43.

The first byte is the bootloader's standard 'OK' code. The latter 7 bytes are hardcoded.

The second byte is the number of command bytes. The third byte is the bootloader version. The subsequent bytes theoretically list the supported commands. In practice, the list advertises command 0x43, but it isn't supported.

This command doesn't seem to do much beyond returning a fixed response, so it probably just serves to ensure the UIC is ready for a firmware upload. On the gamepad, the host ignores the response bytes.

Command 11 EE

Read memory.

First set of parameters: 5 bytes, AA BB CC DD EE

  • AA = address bit 24-31
  • BB = address bit 16-23
  • CC = address bit 8-15
  • DD = address bit 0-7
  • EE = AA^BB^CC^DD

A response is sent after the first set of parameters: 0x79 = OK, 0x1F = error (incorrect parameters).

Second parameter: one byte, length of data to read. Maximum length allowed is 128.

A second response is sent after this second parameter byte, with same values as the first response.

If the second response is 0x79, it is followed by the requested data.

Command 21 DE

Finalize firmware upload.

Response is one byte: 0x51.

This command writes the bytes 0xA5 0x5A at address 0x1010, to indicate that a firmware is installed. Then the UIC is reset.

Command 31 CE

Write memory.

First set of parameters: 5 bytes, AA BB CC DD EE

  • AA = address bit 24-31
  • BB = address bit 16-23
  • CC = address bit 8-15
  • DD = address bit 0-7
  • EE = AA^BB^CC^DD

A response is sent after the first set of parameters: 0x79 = OK, 0x1F = error (incorrect parameters).

Second parameter: one byte, length of data to write. Maximum length allowed is 128.

A second response is sent after this second parameter byte, with same values as the first response.

Then the data to be written is sent, followed by one checksum byte. The checksum is the data length XORed to each data byte.

A third response byte is sent: if the integrity check passes and the data is successfully written, the response is 0x79, otherwise it is 0x1F.

This command is used to upload firmware data to the UIC's FLASH memory.

Command 7F

In firmware upload mode, command 0x7F returns 0x79.

Command list

Command Parameters Response bytes Description
0x01 1 0 set UIC state
0x02 3+N 0 write UIC memory
0x03 3 N read UIC memory
0x04 0 0 EEPROM write disable
0x05 0 1 query UIC state
0x06 0 0 EEPROM write enable
0x07 0 128 query input data
0x08 2 0 ?
0x09 1 0 begin firmware update
0x0A 0 6 ?
0x0B 0 4 get UIC firmware version
0x0C 102 0 ?
0x0D 1 0 ?
0x0E 1 0 ?
0x0F 0 2 ?
0x10 0 1 ?
0x11 1 0 ?
0x12 1 0 toggle backlight
0x13 0 1 ?
0x14 0 0 ?
0x15 0 0 reboot
0x16 ? ? ?
0x17 1 0 ?
0x18 0 1 ?
0x19 255 0 ?
0x1A 0 255 ?
0x1B 4 0 ?
0x1C 0 4 ?
0x7F 0 1 get UIC firmware ID/type

Command 01

Set UIC state.

Parameter: one byte, the UIC state to switch to.

There are restrictions on which state you can switch to based on the current state, see UIC states to see which transitions are possible.

Command 02

Write UIC memory. Used to write to the EEPROM.

Parameters: AA BB CC

  • AA = address bit8-15
  • BB = address bit0-7
  • CC = length

Followed by CC bytes of data.

After sending the parameter bytes, the host should wait atleast 60 microseconds before sending the data. Sending the data too early can cause the UIC-side DMA to malfunction.

Address must be within range 0x1100..0x17FF.

Before using this command, the EEPROM must be unlocked for writing via command 0x06. After all data is written, command 0x04 must be used to commit the changes to EEPROM. Command 0x02 may be invoked multiple times in a row.

Internally, this command redirects the provided address to RAM at 0x01B7. Command 0x04 does write back RAM data to EEPROM.

Command 03

Read UIC memory. Used to read the EEPROM.

Parameters: AA BB CC

  • AA = address bit8-15
  • BB = address bit0-7
  • CC = length

Response is CC bytes of data.

Address must be within range 0x1100..0x17FF.

Internally, this command redirects the provided address to RAM at 0x01B7, where a copy of the EEPROM data is kept.

Command 04

EEPROM write disable. Commits EEPROM writes. Should be invoked after writing to EEPROM.

After invoking this command, the host should wait atleast 140 milliseconds before sending further UIC commands.

Command 05

Query the current UIC state.

Response is one byte: the current UIC state.

The UIC starts in state 11.

Command 06

EEPROM write enable. Should be invoked before writing to EEPROM.

Command 07

Query input data.

Response:

Offset Length Desc.
0x00 2 Sequence ID?
0x02 2 Button bitmask
0x04 1 Power status
0x05 1 Battery charge
0x06 2 Left stick X
0x08 2 Left stick Y
0x0A 2 Right stick X
0x0C 2 Right stick Y
0x0E 1 Audio volume
0x0F 2 Accelerometer X (signed)
0x11 2 Accelerometer Y (signed)
0x13 2 Accelerometer Z (signed)
0x15 3 Gyroscope roll (signed)
0x18 3 Gyroscope yaw (signed)
0x1B 3 Gyroscope pitch (signed)
0x1E 6 Magnet data (unknown)
0x24 40 Touchscreen data (10 samples)
0x4C 4 ???
0x50 1 Extra button bitmask
0x51 46 ???
0x7F 1 Firmware version negated

Button bitmask:

Bit Desc.
0 Down
1 Up
2 Right
3 Left
4 Y
5 X
6 B
7 A
8 Sync
9 Home
10 Minus
11 Plus
12 R
13 L
14 ZR
15 ZL

Power status:

Bit Desc.
0 AC plugged in
1 Power button pressed
6 Charging
7 “POWER_USB” - presumably, expansion device present

Extra button bitmask:

Bit Desc.
5 TV
6 R3
7 L3

Touchscreen data:

Each sample is 4 bytes long: 2 bytes for the X coordinate, 2 bytes for the Y coordinate. The X and Y coordinates take up 12 bits.

The remaining bits are used to store a touchscreen pressure reading. See the libdrc page on input data for more information.

Command 09

Begin firmware update. After this command is sent, command 0x7F will return 0x79, and the UIC will be ready to accept a firmware upload.

WARNING: the UIC remembers the 'waiting for firmware update' state even after a full power-off.

Parameter: unknown, set to zero.

Command 12

Toggle backlight.

Parameter: 0x00=off, 0x01=on.

Command 13

Returns some status bit.

This commands reads the value at 0x0006 in RAM, and returns bit 1 of that value. Not sure what the value means, but it seems tied to the blue power LED, so it is likely related to the power management system.

The stock gamepad firmware waits for the return value from this command to become 1 before doing wifi initialization, so this is likely related to wifi power too. Not waiting for it to become 1 before doing wifi init will cause the wifi hardware to stop functioning when it becomes 1.

Response: one byte, 0 or 1.

Command 15

Reboot the gamepad.

Command 7F

Query firmware ID/version.

Response: 0x2F or 0x3F when a firmware is installed. 0x79 when a firmware needs to be uploaded.

Firmware upload

WARNING: the following is theoretical and has not yet been successfully replicated so far. A firmware upload gone wrong can and will brick the UIC.

The process to upload a new UIC firmware is as follows:

  1. Send command 0x7F to identify the currently installed firmware
  2. If command 0x7F returned 0x2F or 0x3F: send command 0x09 to switch to firmware update mode. Check with command 0x7F until it is effective.
  3. Send bytes 0x00, 0xFF. Receive 0x79. (1)
  4. Receive 7 bytes.

Then you are ready to upload the firmware data, in chunks of 128 bytes maximum. For each chunk:

  1. Send bytes 0x31, 0xCE. Receive 0x79.
  2. Send bytes AA, BB, CC, DD, EE (where AA=address bits 24-31, BB=address bits 16-23, CC=address bits 8-15, DD=address bits 0-7, EE=AA^BB^CC^DD). Receive 0x79. (2)
  3. Send byte AA (where AA=length of this chunk). Receive 0x79.
  4. Send each data byte, then a trailing byte AA (where AA=length of this chunk XORed to each data byte). Receive 0x79.

When all chunks are uploaded, send a final command:

  1. Send bytes 0x21, 0xDE. Receive 0x51. (3)
  2. Your new UIC firmware is now up and running!

(1): Each “send, receive” line is understood as one single SPI transaction. “Receive 0x79” means to keep receiving bytes until receiving a nonzero value. A value of 0x79 indicates success. In the stock firmware code, under some circumstances, another value will prompt retry attempts, while under other circumstances it will be an outright failure case.

(2): The address is in UIC memory space. The UIC firmware upload starts at address 0x9000.

(3): “Receive 0x51” means to keep receiving bytes until receiving a value that isn't 0x79. A value of 0x51 indicates success.

UIC states

The UIC has 15 possible states. The state determines what it will do, for example, input polling is only done in certain states.

State Internal name Description
0 active Default active state
1 wiiactive vWii mode state
2  background ?
3    Sleep mode
4   Alternate sleep mode (used if EEPROM data is invalid)
5  pairing Pairing to WiiU
6  fwupdate Related to firmware update
7   Debug – causes bootloader to load diagnostics firmware
8   ?
9   ?
10   ?
11  wowlsetting Idle state the gamepad is booted in
12  dksetting ?
13   ?
14  subactive ?

The current UIC state can be retrieved with command 0x05, and changed with command 0x01. The following table shows which state transitions are allowed:

New state → 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
↓ Current state
0 X X X X X X X X X X
1 X X X X X X X
2 X X X X X X X X X X
3 X X X X X X X X
4 X X X X X X X
5 X X X X X X X
6 X X X X X X X
7 X X X X
8 X X
9 X X X X X X X X X X
10 X
11 X X X X X
12 X X X X X X X X X X X X X
13
14 X X X X X X X X X X

An X denotes an allowed state transition. For example, if the UIC is in state 0, you may switch to state 1, but not to state 2.

When powering on the gamepad, the UIC starts in state 11, which is an idle state (where, among other things, no input polling is done). Switching to states 3 or 4 puts the gamepad in sleep mode. Pressing the power button turns the gamepad on again, but this time the UIC is in state 0 and ready to go.

TODO: work out and document what the various states do. Also, maybe different EEPROM parameters start the UIC in a different state?

States 3 and 4 may not work correctly under certain conditions, like if the backlight is on.

Expansion port

The gamepad's expansion port is connected to the UIC's I2C BUS. It hasn't been used by any retail device, however it is used by Nintendo for diagnostics purposes.

The diagnostics firmware contains a test named “CHECK USB JIG PULLED OUT”, which implies that Nintendo's device is a USB adapter of sorts.

To further prove this, the “POWER_USB” bit in the power status bitmask (in the command 0x07 input data structure) is set or cleared after attempting to probe device 0x48 on the I2C bus.

It isn't clear whether the USB jig serves to transfer data to/from the gamepad somehow, or whether its sole purpose is to activate the diagnostics mode. The retail UIC firmware doesn't appear to contain any functions for interacting with an expansion device beyond the aforementioned probing.

uic.txt · Last modified: 2024/11/21 12:25 by arisotura

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki