ReSwitched Wiki

Documenting the Nintendo Switch hardware, software, and development.

User Tools

Site Tools


hardware:joycon

Joy-Con Hardware Information

  • Runs at 1.8v
  • Key Prompts are read using the built-in keypad scanner inside the BCM20734 with a 128KHz clock for reading the buttons.
    • This in return makes it harder to do TAS/Twitch-Plays with the Joy-Cons, and the Pro Controller could be a better avenue to emulating the controls on a Switch.

SPI Peripherals

  • 2 SPI Devices
  • 4Mb MX25U4033E Flash Mem
  • LSM6DS3 6-axis MEMS accelerometer, and gyroscope.

Sample capture of SPI lines when the Joy-Con battery is connected, and attached to the console.


Accelerometer and gyroscope

Upon connection the microcontroller initializes a software reset of the MEMS chip, then set up the accelerometer and gyroscope as follows:

AccelerometerGyroscope
ODR 1.66KHz, full-scale ±8gODR 208Hz, full-scale 2000dps

The accelerometer also has AA filter at 100Hz bandwidth, low-pass filter enabled, slope filter enabled with cut-off frequency at 416Hz.

The Joy-Con then polls LSM6DS3 every 1.35ms(740Hz) for both accelerometer and gyroscope data in all axises, totaling 12 bytes(6 axises, each axis 2 bytes).

Since the Joy-Con polls MEMS data every 1.35ms but only send out controller update every 15ms, there might be some internal averaging to smooth out the data, needs to go through the numbers to find out.

Flash Memory

Not documented yet. SPI sample will have all the data, and addresses that the Joy-Con is reading from flash memory so take a look at it for that information.


Joy-Con to Console Communication

When the Joy-Con is attached to the, Joy-Con switches to a physical connection to talk to the Switch instead of Bluetooth. There is 10 pins on the connector.

In the picture above the rumble motor has been removed, and a whole made through the back cover, and wires routed through that.

Capture of Left Joy-Con docking with the Switch.

Joy-Con Connector Pinout

Logic analyzer channelJoy-Con Connector PinFunctionRemark
- 1 GND -
- 2 GND -
0 3 BT status? Only high when connected to console via bluetooth, low when unpaired, sleeping, or attached to the console directly
1 4 5V Joy-Con power and charging
2 5 Serial data, console to Joy-Con Inverted level (idle at GND)
3 6 Attach status? GND only when directly attached to console and not sleeping, 1.8V.
- 7 GND -
4 8 Serial data, Joy-Con to console Standard level (idle at 1.8V)
5 9 ? Always at GND
6 10 Flow control Looks like RTS line, Joy-Con will only send data when this line is high.

When first connected the baud rate is at 1000000bps(!), after the initial handshake the speed is then switched to 3125000bps(!!). The handshake probably exchanges information about the side of the Joy-Con, the color, and bluetooth address etc.

Handshake

Console to Joy-ConGRAY Joy-Con responseRED Joy-Con responseDifferent?Remarks
A1 A2 A3 A4 19 01 03 07 00 A5 02 01 7E 00 00 00 19 81 03 07 00 A5 02 02 7D 00 00 64 19 81 03 07 00 A5 02 02 7D 00 00 64 Same Handshake start; 1000000bps
19 01 03 07 00 91 01 00 00 00 00 24 19 81 03 0F 00 94 01 08 00 00 FA E8 01 31 67 9C 8A BB 7C 00 19 81 03 0F 00 94 01 08 00 00 8F 87 01 E6 4C 5F B9 E6 98 00 Different Joy-Con info; possibly color; side; battery level; BT info; etc
19 01 03 0F 00 91 20 08 00 00 BD B1 C0 C6 2D 00 00 00 00 00 19 81 03 07 00 94 20 00 00 00 00 A8 19 81 03 07 00 94 20 00 00 00 00 A8 Same Command to switch to 3125000bps
19 01 03 07 00 91 11 00 00 00 00 0E 19 81 03 07 00 94 11 00 00 0F 00 33 19 81 03 07 00 94 11 00 00 0F 00 33 Same ?; 3125000 bps from now on
19 01 03 07 00 91 10 00 00 00 00 3D 19 81 03 07 00 94 10 00 00 00 00 D6 19 81 03 07 00 94 10 00 00 00 00 D6 Same ?
19 01 03 0B 00 91 12 04 00 00 12 A6 0F 00 00 00 19 81 03 07 00 94 12 00 00 00 00 B0 19 81 03 07 00 94 12 00 00 00 00 B0 Same ?
19 01 03 08 00 92 00 01 00 00 69 2D 1F 61B Controller status 61B Controller status Different Handshake done. Console sends this controller status request command every 15ms from now on.
  • Pin 5 (Serial data, console to Joy-Con) is normally pulled high on the console side when nothing is connected. Since this line is inverted on the Joy-Con side, it will be pulled down when a Joy-Con is attached to the console, thus initializing a handshake.
  • Pin 5 needs to be pulled down for a while for the handshake to take place, around 500ms works.
  • Handshake starts at 1000000bps, and the console will send a 4-byte start sequence of A1 A2 A3 A4, around 46us later followed by 12 byte command of 19 01 03 07 00 A5 02 01 7E 00 00 00. It will send those commands repeatedly every 100ms (10Hz) for 3 seconds. Joy-Con respond with 19 81 03 07 00 A5 02 02 7D 00 00 64. If no response is received it gives up and wait for another event on the line.
  • The console then sends 19 01 03 07 00 91 01 00 00 00 00 24, to which Joy-Con respond with a 20-byte response that's different on each Joy-Con. That response definitely contains the color information of the Joy-Con, and also possibly contains the serial number, BT info, battery level, etc. After the response is received the little Joy-Con insertion animation starts on the screen.
  • They console also sends 19 01 03 0F 00 91 20 08 00 00 BD B1 C0 C6 2D 00 00 00 00 00, a command that switches baud rate from 1000000 to 3125000. Joy-Con respond with 19 81 03 07 00 94 20 00 00 00 00 A8. Note that the faster baud rate takes effect from the next command.
  • Now serial comm is at 3125000bps. Console sends 19 01 03 07 00 91 11 00 00 00 00 0E, Joy-Con responds with 19 81 03 07 00 94 11 00 00 0F 00 33.
  • Console sends 19 01 03 07 00 91 10 00 00 00 00 3D, Joy-Con responds with 19 81 03 07 00 94 10 00 00 00 00 D6.
  • Now the pairing is seemingly done, the console will now send 19 01 03 08 00 92 00 01 00 00 69 2D 1F every 15ms to ask for a controller status update. See “Protocol” section below for details.

Checksums

The first 4 bytes are a header, with the 4th byte being the length of the remaining packet (not counting the checksum). The next 7 bytes are a type of data, with the 8th byte being the CRC of that data. The CRC used is CRC-8 with a polynomial of 0x8D, and a initial value of 0x00.

Here's some example code for calculating the CRC using a lookup table.

Below is a example of some commands that will be sent from the Joy-Con.

19 01 03 07 00 91 10 00 00 00 00 3D
19 01 03 07 00 91 01 00 00 00 00 24
19 01 03 07 00 91 11 00 00 00 00 0E
19 81 03 07 00 94 10 00 00 00 00 D6
19 81 03 07 00 94 11 00 00 0F 00 33

Joy-Con status data packet

In normal use the switch will ask the Joy-Con to update every 15ms (66.6fps), the command sent for requesting is below.

19 01 03 08 00 92 00 01 00 00 69 2d 1f

4ms later the Joy-Con will respond with a 61 byte answer, an example is provided.

19 81 03 38 
00 92 00 31 
00 00 e9 2e 
30 7f 40 00 
00 00 65 f7 
81 00 00 00 
c0 23 01 e2 
ff 3e 10 0a 
00 d6 ff d0 
ff 23 01 e1 
ff 37 10 0a 
00 d6 ff cf 
ff 29 01 dd 
ff 34 10 0a 
00 d7 ff ce 
ff 
Byte #Sample ValueRemarks
0 to 8 19 81 03 38 00 92 00 31 Header, fixed
16 to 17 00 02 Button status, see section below
19 f7 Joystick X value, reversed nibble?
20 81 Joystick Y value
31 and 32 4e 05 Gyroscope X value
33 and 34 cc fb Gyroscope Y value
35 and 36 eb ff Gyroscope Z value
37 and 38 41 00 Accelerometer X Value
39 and 40 1b 03 Accelerometer Y Value
41 and 42 82 f0 Accelerometer Z Value

Each accelerometer and gyroscope axis data is 2 bytes long and forms a int16_t, last byte is the higher byte.

Button status

The 16th and 17th byte (on line 5, before 65 f7) are the button status, when a button is pressed the corresponding bit is set to 1.

Byte16th Byte
Bit Position 7 6 5 4 3 2 1 0
Button ? ? CAPTURE STICK BUTTON ? ? ? MINUS
Byte17th Byte
Bit Position 7 6 5 4 3 2 1 0
Button ZL L ? ? LEFT RIGHT UP DOWN

Joystick Value

  • Byte 19 = f7 (X)
  • Byte 20 = 81 (Y)

Are the joystick values, most likely being raw 8-bit ADC data. Weirdly, the X value is reversed as in (f7 = 7f). It's 127 at neutral position. The Y value wasn't reversed thought (0x81 is 129).

Left Joy-Con PCB

Credits

  • dekuNukem for publishing his findings on GitHub.
hardware/joycon.txt · Last modified: 2017/03/31 20:00 by shinyquagsire