# Analog Stick Calibration Data

Calibration data is stored on the SPI flash onboard the Joy-Con or Pro Controller as a series of 22 bytes at *address 0x00008010*.

For these examples, the byte numbers correspond to the 11 bytes corresponding to each stick axis. There are two 'Magic Bytes' followed by 9 byte segments. The first segment is for the left stick.

To obtain data for the right stick, increase the index by 11.

This section is based on real calibration data read from a real Pro Controller after it has been calibrated through the Nintendo Switch OS. Processing requires that these bytes be cast to 16 bit unsigned integers. This is basically a way for Nintendo to compress 32 bytes into just 22* bytes*.

The data captured for left stick calibration data:

*0xB2 0xA1 0x04 0xF6 0x6A 0xD7 0x77 0x75 0x13 0x06 0x60*

If the Magic bytes equals 0xA1B2, it means data is stored by the calibration process and can be read. Otherwise, this is ignored.

Byte Number | Description | Data Example |

0 | Magic byte lower byte. | 0xB2 |

1 | Magic byte upper byte. | 0xA1 |

The byte is read as *big endian* as *0xA1B2 *altogether.

Byte Number | Description | Data Example |

6 | Lower 4 bits. Shift left 8 bits. | 0x7 |

5 | The entire 8 bits. | 0xD7 |

Bytes get OR'd and the result is the X axis center.

*Example result: 0x7D7.*

This value is a *distance. *I.E. it's the amount of units away from the center point that the minimum value is. Math must be done to determine the exact minimum value.

Byte Number | Description | Data Example |

9 | Get shifted lower 4 bits. Upper bits ignored. | 0x0 |

8 | The entire 8 bits. | 0x13 |

- Bytes get OR'd. 0x600 |= 0x013 -->
*0x613.* - Formula is applied (X Center - Result) = Minimum Value (0x7D7 - 0x613)

*Example result: 0x1C4.*

This value is a *distance. *I.E. it's the amount of units away from the center point that the maximum value is. Math must be done to determine the exact maximum value.

Byte Number | Description | Data Example |

3 | Get shifted lower 4 bits. Upper bits ignored. | 0xF |

2 | The entire 8 bits. | 0x04 |

- Bytes get OR'd. 0x600 |= 0x004 -->
*0x604.* - Formula is applied (X Center + Result) = Maximum Value (0x7D7 + 0x604)

*Example result: 0xDDB.*

Byte Number | Description | Data Example |

7 | Shift left 4 bits. | 0x |

6 | The upper 4 bits of byte 4. Lower bits ignored. | 0x |

Bytes get OR'd and the result is the Y axis center.

*Example result: 0x756.*

This value is a *distance. *I.E. it's the amount of units away from the center point that the minimum value is. Math must be done to determine the exact minimum value.

Byte Number | Description | Data Example |

10 | Shift left 4 bits. | 0x |

9 | The upper 4 bits of byte 4. Lower bits ignored. | 0x |

- Bytes get OR'd. 0x600 |= 0x000 -->
*0x600.* - Formula is applied (Y Center - Result) = Minimum Value (0x756 - 0x600)

*Example result: 0x156.*

This value is a *distance. *I.E. it's the amount of units away from the center point that the maximum value is. Math must be done to determine the exact maximum value.

Byte Number | Description | Data Example |

4 | Shift left 4 bits. | 0x |

3 | The upper 4 bits of byte 4. Lower bits ignored. | 0x |

- Bytes get OR'd. 0x6A0 |= 0x00F -->
*0x6AF.* - Formula is applied (Y Center + Result) = Maximum Value (0x756 + 0x6AF)

*Example result: 0xE05.*

For this example, we will use the following calibration values. The index should be adjusted to match the proper address locations.

Name | Hex | Decimal |

X axis minimum value | 0x1C4 | 452 |

X axis center value | 0x7D7 | 2007 |

X axis maximum value | 0xDDB | 3547 |

Y axis minimum value | 0x157 | 343 |

Y axis center value | 0x757 | 1879 |

Y axis maximum value | 0xE06 | 3590 |

๏ปฟ