diff options
20 files changed, 1505 insertions, 14 deletions
diff --git a/indieweb-micro/content/indie/follows.md b/indieweb-micro/content/indie/follows.md index 333e173..a62725d 100644 --- a/indieweb-micro/content/indie/follows.md +++ b/indieweb-micro/content/indie/follows.md @@ -15,6 +15,11 @@ This is mostly here for pages that can receive [Webmentions](https://indieweb.or {{< follow "https://floss.social/@kde" "2025-12-03" >}} {{< follow "https://mastodon.social/@gamingonlinux" "2025-12-03" >}} {{< follow "https://threads.net/@nintendeal" "2025-12-03" >}} +{{< follow "https://mastodon.social/@Mastodon" "2025-12-04" >}} +{{< follow "https://jvns.ca/@b0rk" "2025-12-04" >}} +{{< follow "https://tippy.rabbithouse.garden/@serebii" "2025-12-04" >}} +{{< follow "https://retro.pizza/@outofprintarchive" "2025-12-04" >}} +{{< follow "https://peoplemaking.games/@nindiespotlight" "2025-12-04" >}} ## Bluesky {{< follow "https://bsky.app/profile/anew.social" "2025-12-03" >}} diff --git a/indieweb-micro/content/posts/05-procon2-hid-tool.md b/indieweb-micro/content/posts/05-procon2-hid-tool.md new file mode 100644 index 0000000..65cc948 --- /dev/null +++ b/indieweb-micro/content/posts/05-procon2-hid-tool.md @@ -0,0 +1,162 @@ +--- +title: "Enable HID Mode on Nintendo Pro Controller 2" +date: 2025-12-04T23:19:29-08:00 +slug: 2025-12-04-procon2-hid-tool +type: posts +draft: false +categories: + - tools +tags: + - code + - nintendo +--- +Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn't work out of box on PC (Linux) for me like it's predacessor. Until there's actual better driver support for this thing in the kernel (or Valve does something), here's a hacky Python script to initialize HID-mode on the controller + +```python +# I only tested this script on Linux w/ Steam but in theory it shoud work on Windows? +import usb.core # install pyusb first: pip install pyusb +import usb.util +import time +import sys + +VENDOR_ID = 0x057E +PRODUCT_IDS = { + 0x2066: "Joy-Con (L)", + 0x2067: "Joy-Con (R)", + 0x2069: "Pro Controller", + 0x2073: "GCN Controller" +} + +USB_INTERFACE_NUMBER = 1 + +INIT_COMMAND_0x03 = bytes([0x03, 0x91, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) +UNKNOWN_COMMAND_0x07 = bytes([0x07, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]) +UNKNOWN_COMMAND_0x16 = bytes([0x16, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]) +REQUEST_CONTROLLER_MAC = bytes([0x15, 0x91, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) +LTK_REQUEST = bytes([0x15, 0x91, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) +UNKNOWN_COMMAND_0x15_ARG_0x03 = bytes([0x15, 0x91, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00]) +UNKNOWN_COMMAND_0x09 = bytes([0x09, 0x91, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) +IMU_COMMAND_0x02 = bytes([0x0c, 0x91, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00]) +OUT_UNKNOWN_COMMAND_0x11 = bytes([0x11, 0x91, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00]) +UNKNOWN_COMMAND_0x0A = bytes([0x0a, 0x91, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x35, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) +IMU_COMMAND_0x04 = bytes([0x0c, 0x91, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00]) +ENABLE_HAPTICS = bytes([0x03, 0x91, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00]) +OUT_UNKNOWN_COMMAND_0x10 = bytes([0x10, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]) +OUT_UNKNOWN_COMMAND_0x01 = bytes([0x01, 0x91, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00]) +OUT_UNKNOWN_COMMAND_0x03 = bytes([0x03, 0x91, 0x00, 0x01, 0x00, 0x00, 0x00]) +OUT_UNKNOWN_COMMAND_0x0A_ALT = bytes([0x0a, 0x91, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00]) + +def send_usb_data(ep_out, ep_in, data, description=""): + try: + ep_out.write(data) + time.sleep(0.01) + try: + response = ep_in.read(32, timeout=100) + hex_resp = " ".join([f"{x:02x}" for x in response]) + print(f"[{description}] Response: {hex_resp}") + except usb.core.USBError as e: + if e.errno == 110: + print(f"[{description}] No response (Timeout)") + else: + print(f"[{description}] Read Error: {e}") + + except usb.core.USBError as e: + print(f"[{description}] Write Error: {e}") + raise + +def set_player_leds(ep_out, ep_in, led_mask): + command = [ + 0x09, 0x91, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, + led_mask, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ] + send_usb_data(ep_out, ep_in, bytes(command), f"Set LED Mask: 0x{led_mask:02x}") + +def connect_usb(): + print("Searching for Nintendo Switch Controllers...") + def match_device(dev): + return dev.idVendor == VENDOR_ID and dev.idProduct in PRODUCT_IDS + dev = usb.core.find(custom_match=match_device) + if dev is None: + raise ValueError("Device not found") + + product_name = PRODUCT_IDS.get(dev.idProduct, "Unknown Device") + print(f"Found {product_name} (ID: {dev.idProduct:04x})") + if dev.is_kernel_driver_active(USB_INTERFACE_NUMBER): + try: + print("Detaching kernel driver...") + dev.detach_kernel_driver(USB_INTERFACE_NUMBER) + except usb.core.USBError as e: + sys.exit(f"Could not detach kernel driver: {e}") + try: + dev.set_configuration() + print("Configuration set.") + except usb.core.USBError as e: + print(f"Error setting configuration: {e}") + try: + usb.util.claim_interface(dev, USB_INTERFACE_NUMBER) + print(f"Interface {USB_INTERFACE_NUMBER} claimed.") + except usb.core.USBError as e: + sys.exit(f"Could not claim interface: {e}") + cfg = dev.get_active_configuration() + intf = cfg[(USB_INTERFACE_NUMBER,0)] + ep_out = usb.util.find_descriptor( + intf, + custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT) + + ep_in = usb.util.find_descriptor( + intf, + custom_match = + lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN + ) + + if not ep_out: + sys.exit("Could not find OUT endpoint") + + print(f"Found Endpoint OUT: 0x{ep_out.bEndpointAddress:02x}") + print("Starting Initialization Sequence...") + + try: + send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, "Init 0x03") + send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, "Unknown 0x07") + send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, "Unknown 0x16") + send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, "Req MAC") + send_usb_data(ep_out, ep_in, LTK_REQUEST, "Req LTK") + send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, "Unknown 0x15") + send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, "Unknown 0x09") + send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, "IMU 0x02") + send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, "OUT Unknown 0x11") + send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, "Unknown 0x0A") + send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, "IMU 0x04") + send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, "Enable Haptics") + send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, "OUT Unknown 0x10") + send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, "OUT Unknown 0x01") + send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, "OUT Unknown 0x03") + send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, "OUT Unknown 0x0A Alt") + set_player_leds(ep_out, ep_in, 0x0F) + + print("Controller initialization sequence complete! All LEDs should be on.") + + except Exception as e: + print(f"Error during sequence: {e}") + +if __name__ == "__main__": + try: + connect_usb() + except ValueError as e: + print(e) + except Exception as e: + print(f"Unexpected error: {e}") +``` +**Steps** + +0. (Optional) First Create a virtual environment +1. Install pyusb via `pip install pyusb` +2. Plug your Pro Controller 2 in via USB +3. Run the script + +If all 4 of the player indicator LEDs light up (the square ones near the charging port), then that means you should be good to go! + +You'll need to re-run this script each time you plug/unplug or restart your machine. + +This is pretty much a copy of the [online Procon 2 Enabler Tool](https://handheldlegend.github.io/procon2tool/) but WebHID is dodgy on the Firefox fork I'm using, plus its annoying having to open this page each time. diff --git a/micro.pinapelz.moe/categories/index.html b/micro.pinapelz.moe/categories/index.html index 2df2185..8c3b840 100644 --- a/micro.pinapelz.moe/categories/index.html +++ b/micro.pinapelz.moe/categories/index.html @@ -75,6 +75,8 @@ <li><a href="/categories/life/">Life</a></li> + <li><a href="/categories/tools/">Tools</a></li> + </ul> </div> </main> diff --git a/micro.pinapelz.moe/categories/index.xml b/micro.pinapelz.moe/categories/index.xml index e8c7974..596c38d 100644 --- a/micro.pinapelz.moe/categories/index.xml +++ b/micro.pinapelz.moe/categories/index.xml @@ -8,9 +8,16 @@ <language>en-us</language> <managingEditor>yukais@pinapelz.com (Pinapelz)</managingEditor> <webMaster>yukais@pinapelz.com (Pinapelz)</webMaster> - <lastBuildDate>Wed, 03 Dec 2025 19:38:52 -0800</lastBuildDate> + <lastBuildDate>Thu, 04 Dec 2025 23:19:29 -0800</lastBuildDate> <atom:link href="https://micro.pinapelz.moe/categories/index.xml" rel="self" type="application/rss+xml" /> <item> + <title>Tools</title> + <link>https://micro.pinapelz.moe/categories/tools/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/categories/tools/</guid> + <description></description> + </item> + <item> <title>Default</title> <link>https://micro.pinapelz.moe/categories/default/</link> <pubDate>Wed, 03 Dec 2025 19:38:52 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> diff --git a/micro.pinapelz.moe/categories/tools/index.html b/micro.pinapelz.moe/categories/tools/index.html new file mode 100644 index 0000000..b3d0968 --- /dev/null +++ b/micro.pinapelz.moe/categories/tools/index.html @@ -0,0 +1,106 @@ +<!DOCTYPE html> +<html lang="en-us"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <style type=text/css>body{font-family:monospace;}</style> + <title>Tools | micro.pinapelz.moe</title> + + <meta name="author" content="map[avatar:https://files.catbox.moe/5r1pue.jpg banner:https://files.pinapelz.com/pso2ngs-2232-collab.png bio:yo! and he's more than a cover he's a quilt<br/> + General arcade rhythm game enjoyer (SDVX, IIDX, CHUNITHM)<br/> + Mostly play MMOs (FFXIV, OSRS), JRPGs, and VNs (anything with a good story)<br/> + I Watch only slice of life (and Bandori)<br/> + Arch Linux + Hyprland user (btw)<br/> + Hi from the <a href="https://indieweb.org/">indieweb</a>, if you are seeing me bridged elsewhere! email:yukais@pinapelz.com name:Pinapelz]"> + <link rel="stylesheet" href="/css/style.css"> + <link rel="alternate" type="application/rss+xml" href="/categories/tools/index.xml" title="micro.pinapelz.moe"> + + + <link rel="me" href="https://github.com/pinapelz" /> + <link rel="me" href="mailto:yukais@pinapelz.com" /> + <link rel="me" href="https://sakurajima.social/@pinapelz" /> + <link rel="me" href="https://bsky.app/profile/pinapelz.moe" /><link rel="pgpkey" href="https://pinapelz.com/Yukai_Shan.asc"> + <link + rel="authorization_endpoint" + href="https://indieauth.com/auth" + /> + <link + rel="token_endpoint" + href="https://tokens.indieauth.com/token" + /> + <link rel="webmention" href="https://webmention.io/micro.pinapelz.moe/webmention" /> + + + +</head> +<body> + <header> + <div style="display:flex;flex-flow:row wrap;justify-content:space-between"> + <div style="align-self:flex-start;"> + ==============<br> + == <a href="https://micro.pinapelz.moe/">Pinapelz</a> ==<br> + ============== + </div> + <div style="align-self:center;">check it out. I'm in the house like carpet</div> + </div> + <nav style="margin: 1rem auto;"> + + + <a href="/posts/"><b>Posts</b></a>. + + <a href="/categories/"><b>Categories</b></a>. + + <a href="/tags/"><b>Tags</b></a>. + + + </nav> +</header> + + + +<main> + <div> + <h1> + Tools + <a href="https://micro.pinapelz.moe/categories/tools/index.xml"> + <img style="height:1.5rem; display: inline;" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='RSS' role='img' viewBox='0 0 512 512'%3E%3Cpath d='M0 0h512v512H0' fill='%23f80'/%3E%3Cpath d='M109 271A132 133 0 0 1 241 403h60A192 193 0 0 0 109 211v-54A246 247 0 0 1 355 403h60A306 307 0 0 0 109 97m35 235a35 35 0 1 0 2 0' fill='%23fff'/%3E%3C/svg%3E" alt="RSS icon" /> + </a> + </h1> + <div> + + </div><p>Content linked to the taxonomy term « TOOLS »:</p> + + + + + <div> + <h3>Posts</h3> + <ul> + + <li> + <time class="date dt-published" datetime="2025-12-04T23:19:29-08:00">2025-12-04</time> + <a href="/posts/2025-12-04-procon2-hid-tool/">Enable HID Mode on Nintendo Pro Controller 2</a> + </li> + + + </ul> + </div></div> +</main> + + <hr /> +<footer> + <p> + <a href="https://github.com/pinapelz"><b>Github</b></a>. + <a href="https://pinapelz.moe"><b>pinapelz.moe</b></a>. + </p> + + + + <p style="text-align: center" class="copyright"> + © <a href="https://micro.pinapelz.moe/"><b>micro.pinapelz.moe</b></a>. + </p> +</footer> + +</body> +</html> diff --git a/micro.pinapelz.moe/categories/tools/index.xml b/micro.pinapelz.moe/categories/tools/index.xml new file mode 100644 index 0000000..0c4c761 --- /dev/null +++ b/micro.pinapelz.moe/categories/tools/index.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> + <channel> + <title>Tools on micro.pinapelz.moe</title> + <link>https://micro.pinapelz.moe/categories/tools/</link> + <description>Recent content in Tools on micro.pinapelz.moe</description> + <generator>Hugo</generator> + <language>en-us</language> + <managingEditor>yukais@pinapelz.com (Pinapelz)</managingEditor> + <webMaster>yukais@pinapelz.com (Pinapelz)</webMaster> + <lastBuildDate>Thu, 04 Dec 2025 23:19:29 -0800</lastBuildDate> + <atom:link href="https://micro.pinapelz.moe/categories/tools/index.xml" rel="self" type="application/rss+xml" /> + <item> + <title>Enable HID Mode on Nintendo Pro Controller 2</title> + <link>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</guid> + <description><p>Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn&rsquo;t work out of box on PC (Linux) for me like it&rsquo;s predacessor. Until there&rsquo;s actual better driver support for this thing in the kernel (or Valve does something), here&rsquo;s a hacky Python script to initialize HID-mode on the controller</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># I only tested this script on Linux w/ Steam but in theory it shoud work on Windows?</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.core <span style="color:#75715e"># install pyusb first: pip install pyusb</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.util
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> time
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>VENDOR_ID <span style="color:#f92672">=</span> <span style="color:#ae81ff">0x057E</span>
</span></span><span style="display:flex;"><span>PRODUCT_IDS <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2066</span>: <span style="color:#e6db74">&#34;Joy-Con (L)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2067</span>: <span style="color:#e6db74">&#34;Joy-Con (R)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2069</span>: <span style="color:#e6db74">&#34;Pro Controller&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2073</span>: <span style="color:#e6db74">&#34;GCN Controller&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>USB_INTERFACE_NUMBER <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>INIT_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0d</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x07 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x16 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x16</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>REQUEST_CONTROLLER_MAC <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0e</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>LTK_REQUEST <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x15_ARG_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x09 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x02 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x11 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x0A <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x14</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0x35</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x46</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x04 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>ENABLE_HAPTICS <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x10 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x10</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x01 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x0A_ALT <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_usb_data</span>(ep_out, ep_in, data, description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> ep_out<span style="color:#f92672">.</span>write(data)
</span></span><span style="display:flex;"><span> time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">0.01</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> response <span style="color:#f92672">=</span> ep_in<span style="color:#f92672">.</span>read(<span style="color:#ae81ff">32</span>, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">100</span>)
</span></span><span style="display:flex;"><span> hex_resp <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34; &#34;</span><span style="color:#f92672">.</span>join([<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>x<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#66d9ef">for</span> x <span style="color:#f92672">in</span> response])
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Response: </span><span style="color:#e6db74">{</span>hex_resp<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> e<span style="color:#f92672">.</span>errno <span style="color:#f92672">==</span> <span style="color:#ae81ff">110</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] No response (Timeout)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Read Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Write Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">set_player_leds</span>(ep_out, ep_in, led_mask):
</span></span><span style="display:flex;"><span> command <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>,
</span></span><span style="display:flex;"><span> led_mask,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, bytes(command), <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Set LED Mask: 0x</span><span style="color:#e6db74">{</span>led_mask<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">connect_usb</span>():
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Searching for Nintendo Switch Controllers...&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">match_device</span>(dev):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> dev<span style="color:#f92672">.</span>idVendor <span style="color:#f92672">==</span> VENDOR_ID <span style="color:#f92672">and</span> dev<span style="color:#f92672">.</span>idProduct <span style="color:#f92672">in</span> PRODUCT_IDS
</span></span><span style="display:flex;"><span> dev <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>find(custom_match<span style="color:#f92672">=</span>match_device)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">&#34;Device not found&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> product_name <span style="color:#f92672">=</span> PRODUCT_IDS<span style="color:#f92672">.</span>get(dev<span style="color:#f92672">.</span>idProduct, <span style="color:#e6db74">&#34;Unknown Device&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found </span><span style="color:#e6db74">{</span>product_name<span style="color:#e6db74">}</span><span style="color:#e6db74"> (ID: </span><span style="color:#e6db74">{</span>dev<span style="color:#f92672">.</span>idProduct<span style="color:#e6db74">:</span><span style="color:#e6db74">04x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev<span style="color:#f92672">.</span>is_kernel_driver_active(USB_INTERFACE_NUMBER):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Detaching kernel driver...&#34;</span>)
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>detach_kernel_driver(USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not detach kernel driver: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>set_configuration()
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Configuration set.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error setting configuration: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>claim_interface(dev, USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Interface </span><span style="color:#e6db74">{</span>USB_INTERFACE_NUMBER<span style="color:#e6db74">}</span><span style="color:#e6db74"> claimed.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not claim interface: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> cfg <span style="color:#f92672">=</span> dev<span style="color:#f92672">.</span>get_active_configuration()
</span></span><span style="display:flex;"><span> intf <span style="color:#f92672">=</span> cfg[(USB_INTERFACE_NUMBER,<span style="color:#ae81ff">0</span>)]
</span></span><span style="display:flex;"><span> ep_out <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_OUT)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> ep_in <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_IN
</span></span><span style="display:flex;"><span> )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> ep_out:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">&#34;Could not find OUT endpoint&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found Endpoint OUT: 0x</span><span style="color:#e6db74">{</span>ep_out<span style="color:#f92672">.</span>bEndpointAddress<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Starting Initialization Sequence...&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, <span style="color:#e6db74">&#34;Init 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, <span style="color:#e6db74">&#34;Unknown 0x07&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, <span style="color:#e6db74">&#34;Unknown 0x16&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, <span style="color:#e6db74">&#34;Req MAC&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, LTK_REQUEST, <span style="color:#e6db74">&#34;Req LTK&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, <span style="color:#e6db74">&#34;Unknown 0x15&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, <span style="color:#e6db74">&#34;Unknown 0x09&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, <span style="color:#e6db74">&#34;IMU 0x02&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, <span style="color:#e6db74">&#34;OUT Unknown 0x11&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, <span style="color:#e6db74">&#34;Unknown 0x0A&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, <span style="color:#e6db74">&#34;IMU 0x04&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, <span style="color:#e6db74">&#34;Enable Haptics&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, <span style="color:#e6db74">&#34;OUT Unknown 0x10&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, <span style="color:#e6db74">&#34;OUT Unknown 0x01&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, <span style="color:#e6db74">&#34;OUT Unknown 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, <span style="color:#e6db74">&#34;OUT Unknown 0x0A Alt&#34;</span>)
</span></span><span style="display:flex;"><span> set_player_leds(ep_out, ep_in, <span style="color:#ae81ff">0x0F</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Controller initialization sequence complete! All LEDs should be on.&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error during sequence: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> connect_usb()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">ValueError</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(e)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Unexpected error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></div><p><strong>Steps</strong></p></description> + </item> + </channel> +</rss> diff --git a/micro.pinapelz.moe/index.html b/micro.pinapelz.moe/index.html index 016eee4..9ed9ecc 100644 --- a/micro.pinapelz.moe/index.html +++ b/micro.pinapelz.moe/index.html @@ -82,6 +82,158 @@ <article> + <h1><a href="https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/">Enable HID Mode on Nintendo Pro Controller 2</a></h1> + <b><time>Thursday, December 4, 2025</time></b> + + <a href="/tags/code">code</a> + + <a href="/tags/nintendo">nintendo</a> + + <div> + <p>Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn’t work out of box on PC (Linux) for me like it’s predacessor. Until there’s actual better driver support for this thing in the kernel (or Valve does something), here’s a hacky Python script to initialize HID-mode on the controller</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># I only tested this script on Linux w/ Steam but in theory it shoud work on Windows?</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.core <span style="color:#75715e"># install pyusb first: pip install pyusb</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.util +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> time +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span>VENDOR_ID <span style="color:#f92672">=</span> <span style="color:#ae81ff">0x057E</span> +</span></span><span style="display:flex;"><span>PRODUCT_IDS <span style="color:#f92672">=</span> { +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2066</span>: <span style="color:#e6db74">"Joy-Con (L)"</span>, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2067</span>: <span style="color:#e6db74">"Joy-Con (R)"</span>, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2069</span>: <span style="color:#e6db74">"Pro Controller"</span>, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2073</span>: <span style="color:#e6db74">"GCN Controller"</span> +</span></span><span style="display:flex;"><span>} +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span>USB_INTERFACE_NUMBER <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span>INIT_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0d</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x07 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x16 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x16</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>REQUEST_CONTROLLER_MAC <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0e</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>]) +</span></span><span style="display:flex;"><span>LTK_REQUEST <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x15_ARG_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x09 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>IMU_COMMAND_0x02 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x11 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x0A <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x14</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0x35</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x46</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>IMU_COMMAND_0x04 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>ENABLE_HAPTICS <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x10 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x10</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x01 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x0A_ALT <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_usb_data</span>(ep_out, ep_in, data, description<span style="color:#f92672">=</span><span style="color:#e6db74">""</span>): +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> ep_out<span style="color:#f92672">.</span>write(data) +</span></span><span style="display:flex;"><span> time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">0.01</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> response <span style="color:#f92672">=</span> ep_in<span style="color:#f92672">.</span>read(<span style="color:#ae81ff">32</span>, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">100</span>) +</span></span><span style="display:flex;"><span> hex_resp <span style="color:#f92672">=</span> <span style="color:#e6db74">" "</span><span style="color:#f92672">.</span>join([<span style="color:#e6db74">f</span><span style="color:#e6db74">"</span><span style="color:#e6db74">{</span>x<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">"</span> <span style="color:#66d9ef">for</span> x <span style="color:#f92672">in</span> response]) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Response: </span><span style="color:#e6db74">{</span>hex_resp<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> e<span style="color:#f92672">.</span>errno <span style="color:#f92672">==</span> <span style="color:#ae81ff">110</span>: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] No response (Timeout)"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span>: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Read Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Write Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">set_player_leds</span>(ep_out, ep_in, led_mask): +</span></span><span style="display:flex;"><span> command <span style="color:#f92672">=</span> [ +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, +</span></span><span style="display:flex;"><span> led_mask, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span> +</span></span><span style="display:flex;"><span> ] +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, bytes(command), <span style="color:#e6db74">f</span><span style="color:#e6db74">"Set LED Mask: 0x</span><span style="color:#e6db74">{</span>led_mask<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">connect_usb</span>(): +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Searching for Nintendo Switch Controllers..."</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">match_device</span>(dev): +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> dev<span style="color:#f92672">.</span>idVendor <span style="color:#f92672">==</span> VENDOR_ID <span style="color:#f92672">and</span> dev<span style="color:#f92672">.</span>idProduct <span style="color:#f92672">in</span> PRODUCT_IDS +</span></span><span style="display:flex;"><span> dev <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>find(custom_match<span style="color:#f92672">=</span>match_device) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span>: +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">"Device not found"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> product_name <span style="color:#f92672">=</span> PRODUCT_IDS<span style="color:#f92672">.</span>get(dev<span style="color:#f92672">.</span>idProduct, <span style="color:#e6db74">"Unknown Device"</span>) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Found </span><span style="color:#e6db74">{</span>product_name<span style="color:#e6db74">}</span><span style="color:#e6db74"> (ID: </span><span style="color:#e6db74">{</span>dev<span style="color:#f92672">.</span>idProduct<span style="color:#e6db74">:</span><span style="color:#e6db74">04x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">)"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev<span style="color:#f92672">.</span>is_kernel_driver_active(USB_INTERFACE_NUMBER): +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Detaching kernel driver..."</span>) +</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>detach_kernel_driver(USB_INTERFACE_NUMBER) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Could not detach kernel driver: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>set_configuration() +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Configuration set."</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Error setting configuration: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>claim_interface(dev, USB_INTERFACE_NUMBER) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Interface </span><span style="color:#e6db74">{</span>USB_INTERFACE_NUMBER<span style="color:#e6db74">}</span><span style="color:#e6db74"> claimed."</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Could not claim interface: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> cfg <span style="color:#f92672">=</span> dev<span style="color:#f92672">.</span>get_active_configuration() +</span></span><span style="display:flex;"><span> intf <span style="color:#f92672">=</span> cfg[(USB_INTERFACE_NUMBER,<span style="color:#ae81ff">0</span>)] +</span></span><span style="display:flex;"><span> ep_out <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor( +</span></span><span style="display:flex;"><span> intf, +</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_OUT) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> ep_in <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor( +</span></span><span style="display:flex;"><span> intf, +</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_IN +</span></span><span style="display:flex;"><span> ) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> ep_out: +</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">"Could not find OUT endpoint"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Found Endpoint OUT: 0x</span><span style="color:#e6db74">{</span>ep_out<span style="color:#f92672">.</span>bEndpointAddress<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Starting Initialization Sequence..."</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, <span style="color:#e6db74">"Init 0x03"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, <span style="color:#e6db74">"Unknown 0x07"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, <span style="color:#e6db74">"Unknown 0x16"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, <span style="color:#e6db74">"Req MAC"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, LTK_REQUEST, <span style="color:#e6db74">"Req LTK"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, <span style="color:#e6db74">"Unknown 0x15"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, <span style="color:#e6db74">"Unknown 0x09"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, <span style="color:#e6db74">"IMU 0x02"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, <span style="color:#e6db74">"OUT Unknown 0x11"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, <span style="color:#e6db74">"Unknown 0x0A"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, <span style="color:#e6db74">"IMU 0x04"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, <span style="color:#e6db74">"Enable Haptics"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, <span style="color:#e6db74">"OUT Unknown 0x10"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, <span style="color:#e6db74">"OUT Unknown 0x01"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, <span style="color:#e6db74">"OUT Unknown 0x03"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, <span style="color:#e6db74">"OUT Unknown 0x0A Alt"</span>) +</span></span><span style="display:flex;"><span> set_player_leds(ep_out, ep_in, <span style="color:#ae81ff">0x0F</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Controller initialization sequence complete! All LEDs should be on."</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Error during sequence: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">"__main__"</span>: +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> connect_usb() +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">ValueError</span> <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(e) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Unexpected error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span></code></pre></div><p><strong>Steps</strong></p> + + <a href="https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/">Read more...</a> + + </div> +</article> + + + <article> <h1><a href="https://micro.pinapelz.moe/posts/2025-12-03-04-yt-music-rewind/">YouTube Music Recap 2025</a></h1> <b><time>Wednesday, December 3, 2025</time></b> diff --git a/micro.pinapelz.moe/index.xml b/micro.pinapelz.moe/index.xml index 9c2994b..72e4836 100644 --- a/micro.pinapelz.moe/index.xml +++ b/micro.pinapelz.moe/index.xml @@ -8,9 +8,16 @@ <language>en-us</language> <managingEditor>yukais@pinapelz.com (Pinapelz)</managingEditor> <webMaster>yukais@pinapelz.com (Pinapelz)</webMaster> - <lastBuildDate>Wed, 03 Dec 2025 19:38:52 -0800</lastBuildDate> + <lastBuildDate>Thu, 04 Dec 2025 23:19:29 -0800</lastBuildDate> <atom:link href="https://micro.pinapelz.moe/index.xml" rel="self" type="application/rss+xml" /> <item> + <title>Enable HID Mode on Nintendo Pro Controller 2</title> + <link>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</guid> + <description><p>Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn&rsquo;t work out of box on PC (Linux) for me like it&rsquo;s predacessor. Until there&rsquo;s actual better driver support for this thing in the kernel (or Valve does something), here&rsquo;s a hacky Python script to initialize HID-mode on the controller</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># I only tested this script on Linux w/ Steam but in theory it shoud work on Windows?</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.core <span style="color:#75715e"># install pyusb first: pip install pyusb</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.util
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> time
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>VENDOR_ID <span style="color:#f92672">=</span> <span style="color:#ae81ff">0x057E</span>
</span></span><span style="display:flex;"><span>PRODUCT_IDS <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2066</span>: <span style="color:#e6db74">&#34;Joy-Con (L)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2067</span>: <span style="color:#e6db74">&#34;Joy-Con (R)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2069</span>: <span style="color:#e6db74">&#34;Pro Controller&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2073</span>: <span style="color:#e6db74">&#34;GCN Controller&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>USB_INTERFACE_NUMBER <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>INIT_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0d</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x07 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x16 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x16</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>REQUEST_CONTROLLER_MAC <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0e</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>LTK_REQUEST <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x15_ARG_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x09 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x02 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x11 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x0A <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x14</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0x35</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x46</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x04 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>ENABLE_HAPTICS <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x10 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x10</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x01 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x0A_ALT <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_usb_data</span>(ep_out, ep_in, data, description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> ep_out<span style="color:#f92672">.</span>write(data)
</span></span><span style="display:flex;"><span> time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">0.01</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> response <span style="color:#f92672">=</span> ep_in<span style="color:#f92672">.</span>read(<span style="color:#ae81ff">32</span>, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">100</span>)
</span></span><span style="display:flex;"><span> hex_resp <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34; &#34;</span><span style="color:#f92672">.</span>join([<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>x<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#66d9ef">for</span> x <span style="color:#f92672">in</span> response])
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Response: </span><span style="color:#e6db74">{</span>hex_resp<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> e<span style="color:#f92672">.</span>errno <span style="color:#f92672">==</span> <span style="color:#ae81ff">110</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] No response (Timeout)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Read Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Write Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">set_player_leds</span>(ep_out, ep_in, led_mask):
</span></span><span style="display:flex;"><span> command <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>,
</span></span><span style="display:flex;"><span> led_mask,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, bytes(command), <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Set LED Mask: 0x</span><span style="color:#e6db74">{</span>led_mask<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">connect_usb</span>():
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Searching for Nintendo Switch Controllers...&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">match_device</span>(dev):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> dev<span style="color:#f92672">.</span>idVendor <span style="color:#f92672">==</span> VENDOR_ID <span style="color:#f92672">and</span> dev<span style="color:#f92672">.</span>idProduct <span style="color:#f92672">in</span> PRODUCT_IDS
</span></span><span style="display:flex;"><span> dev <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>find(custom_match<span style="color:#f92672">=</span>match_device)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">&#34;Device not found&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> product_name <span style="color:#f92672">=</span> PRODUCT_IDS<span style="color:#f92672">.</span>get(dev<span style="color:#f92672">.</span>idProduct, <span style="color:#e6db74">&#34;Unknown Device&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found </span><span style="color:#e6db74">{</span>product_name<span style="color:#e6db74">}</span><span style="color:#e6db74"> (ID: </span><span style="color:#e6db74">{</span>dev<span style="color:#f92672">.</span>idProduct<span style="color:#e6db74">:</span><span style="color:#e6db74">04x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev<span style="color:#f92672">.</span>is_kernel_driver_active(USB_INTERFACE_NUMBER):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Detaching kernel driver...&#34;</span>)
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>detach_kernel_driver(USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not detach kernel driver: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>set_configuration()
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Configuration set.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error setting configuration: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>claim_interface(dev, USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Interface </span><span style="color:#e6db74">{</span>USB_INTERFACE_NUMBER<span style="color:#e6db74">}</span><span style="color:#e6db74"> claimed.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not claim interface: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> cfg <span style="color:#f92672">=</span> dev<span style="color:#f92672">.</span>get_active_configuration()
</span></span><span style="display:flex;"><span> intf <span style="color:#f92672">=</span> cfg[(USB_INTERFACE_NUMBER,<span style="color:#ae81ff">0</span>)]
</span></span><span style="display:flex;"><span> ep_out <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_OUT)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> ep_in <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_IN
</span></span><span style="display:flex;"><span> )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> ep_out:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">&#34;Could not find OUT endpoint&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found Endpoint OUT: 0x</span><span style="color:#e6db74">{</span>ep_out<span style="color:#f92672">.</span>bEndpointAddress<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Starting Initialization Sequence...&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, <span style="color:#e6db74">&#34;Init 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, <span style="color:#e6db74">&#34;Unknown 0x07&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, <span style="color:#e6db74">&#34;Unknown 0x16&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, <span style="color:#e6db74">&#34;Req MAC&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, LTK_REQUEST, <span style="color:#e6db74">&#34;Req LTK&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, <span style="color:#e6db74">&#34;Unknown 0x15&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, <span style="color:#e6db74">&#34;Unknown 0x09&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, <span style="color:#e6db74">&#34;IMU 0x02&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, <span style="color:#e6db74">&#34;OUT Unknown 0x11&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, <span style="color:#e6db74">&#34;Unknown 0x0A&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, <span style="color:#e6db74">&#34;IMU 0x04&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, <span style="color:#e6db74">&#34;Enable Haptics&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, <span style="color:#e6db74">&#34;OUT Unknown 0x10&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, <span style="color:#e6db74">&#34;OUT Unknown 0x01&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, <span style="color:#e6db74">&#34;OUT Unknown 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, <span style="color:#e6db74">&#34;OUT Unknown 0x0A Alt&#34;</span>)
</span></span><span style="display:flex;"><span> set_player_leds(ep_out, ep_in, <span style="color:#ae81ff">0x0F</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Controller initialization sequence complete! All LEDs should be on.&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error during sequence: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> connect_usb()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">ValueError</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(e)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Unexpected error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></div><p><strong>Steps</strong></p></description> + </item> + <item> <title>YouTube Music Recap 2025</title> <link>https://micro.pinapelz.moe/posts/2025-12-03-04-yt-music-rewind/</link> <pubDate>Wed, 03 Dec 2025 19:38:52 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> @@ -22,7 +29,7 @@ <link>https://micro.pinapelz.moe/indie/follows/</link> <pubDate>Wed, 03 Dec 2025 01:17:39 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> <guid>https://micro.pinapelz.moe/indie/follows/</guid> - <description><p>Here are all the pages/accounts I follow.</p>
<p>This is mostly here for pages that can receive <a href="https://indieweb.org/webmention">Webmentions</a> and the <a href="https://fed.brid.gy">Bridgy Fed</a> service.</p>
<h2 id="fediverse">Fediverse</h2>
<p>


<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@Mofumatic">
 https://sakurajima.moe/@Mofumatic
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mathstodon.xyz/@tao">
 https://mathstodon.xyz/@tao
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@chikorita157">
 https://sakurajima.moe/@chikorita157
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@sakurajima">
 https://sakurajima.moe/@sakurajima
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://floss.social/@kde">
 https://floss.social/@kde
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mastodon.social/@gamingonlinux">
 https://mastodon.social/@gamingonlinux
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://threads.net/@nintendeal">
 https://threads.net/@nintendeal
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>
</p>
<h2 id="bluesky">Bluesky</h2>



<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://bsky.app/profile/anew.social">
 https://bsky.app/profile/anew.social
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>

<blockquote>
<p>Learn more about the <a href="https://indieweb.org">Indieweb</a></p>
</blockquote></description> + <description><p>Here are all the pages/accounts I follow.</p>
<p>This is mostly here for pages that can receive <a href="https://indieweb.org/webmention">Webmentions</a> and the <a href="https://fed.brid.gy">Bridgy Fed</a> service.</p>
<h2 id="fediverse">Fediverse</h2>
<p>


<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@Mofumatic">
 https://sakurajima.moe/@Mofumatic
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mathstodon.xyz/@tao">
 https://mathstodon.xyz/@tao
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@chikorita157">
 https://sakurajima.moe/@chikorita157
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@sakurajima">
 https://sakurajima.moe/@sakurajima
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://floss.social/@kde">
 https://floss.social/@kde
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mastodon.social/@gamingonlinux">
 https://mastodon.social/@gamingonlinux
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://threads.net/@nintendeal">
 https://threads.net/@nintendeal
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mastodon.social/@Mastodon">
 https://mastodon.social/@Mastodon
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://jvns.ca/@b0rk">
 https://jvns.ca/@b0rk
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://tippy.rabbithouse.garden/@serebii">
 https://tippy.rabbithouse.garden/@serebii
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://retro.pizza/@outofprintarchive">
 https://retro.pizza/@outofprintarchive
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://peoplemaking.games/@nindiespotlight">
 https://peoplemaking.games/@nindiespotlight
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>
</p>
<h2 id="bluesky">Bluesky</h2>



<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://bsky.app/profile/anew.social">
 https://bsky.app/profile/anew.social
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>

<blockquote>
<p>Learn more about the <a href="https://indieweb.org">Indieweb</a></p></description> </item> <item> <title>INIU Power Bank Gets Recall</title> diff --git a/micro.pinapelz.moe/indie/follows/index.html b/micro.pinapelz.moe/indie/follows/index.html index f580f1e..a2d2502 100644 --- a/micro.pinapelz.moe/indie/follows/index.html +++ b/micro.pinapelz.moe/indie/follows/index.html @@ -175,6 +175,71 @@ 2025-12-03 </time> </div> + + + + +<div class="follow-card"> + <a class="follow-target u-follow-of" href="https://mastodon.social/@Mastodon"> + https://mastodon.social/@Mastodon + </a> + + <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z"> + 2025-12-04 + </time> +</div> + + + + +<div class="follow-card"> + <a class="follow-target u-follow-of" href="https://jvns.ca/@b0rk"> + https://jvns.ca/@b0rk + </a> + + <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z"> + 2025-12-04 + </time> +</div> + + + + +<div class="follow-card"> + <a class="follow-target u-follow-of" href="https://tippy.rabbithouse.garden/@serebii"> + https://tippy.rabbithouse.garden/@serebii + </a> + + <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z"> + 2025-12-04 + </time> +</div> + + + + +<div class="follow-card"> + <a class="follow-target u-follow-of" href="https://retro.pizza/@outofprintarchive"> + https://retro.pizza/@outofprintarchive + </a> + + <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z"> + 2025-12-04 + </time> +</div> + + + + +<div class="follow-card"> + <a class="follow-target u-follow-of" href="https://peoplemaking.games/@nindiespotlight"> + https://peoplemaking.games/@nindiespotlight + </a> + + <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z"> + 2025-12-04 + </time> +</div> </p> <h2 id="bluesky">Bluesky</h2> diff --git a/micro.pinapelz.moe/indie/index.xml b/micro.pinapelz.moe/indie/index.xml index 26167bf..e338b2d 100644 --- a/micro.pinapelz.moe/indie/index.xml +++ b/micro.pinapelz.moe/indie/index.xml @@ -15,7 +15,7 @@ <link>https://micro.pinapelz.moe/indie/follows/</link> <pubDate>Wed, 03 Dec 2025 01:17:39 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> <guid>https://micro.pinapelz.moe/indie/follows/</guid> - <description><p>Here are all the pages/accounts I follow.</p>
<p>This is mostly here for pages that can receive <a href="https://indieweb.org/webmention">Webmentions</a> and the <a href="https://fed.brid.gy">Bridgy Fed</a> service.</p>
<h2 id="fediverse">Fediverse</h2>
<p>


<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@Mofumatic">
 https://sakurajima.moe/@Mofumatic
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mathstodon.xyz/@tao">
 https://mathstodon.xyz/@tao
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@chikorita157">
 https://sakurajima.moe/@chikorita157
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@sakurajima">
 https://sakurajima.moe/@sakurajima
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://floss.social/@kde">
 https://floss.social/@kde
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mastodon.social/@gamingonlinux">
 https://mastodon.social/@gamingonlinux
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://threads.net/@nintendeal">
 https://threads.net/@nintendeal
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>
</p>
<h2 id="bluesky">Bluesky</h2>



<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://bsky.app/profile/anew.social">
 https://bsky.app/profile/anew.social
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>

<blockquote>
<p>Learn more about the <a href="https://indieweb.org">Indieweb</a></p>
</blockquote></description> + <description><p>Here are all the pages/accounts I follow.</p>
<p>This is mostly here for pages that can receive <a href="https://indieweb.org/webmention">Webmentions</a> and the <a href="https://fed.brid.gy">Bridgy Fed</a> service.</p>
<h2 id="fediverse">Fediverse</h2>
<p>


<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@Mofumatic">
 https://sakurajima.moe/@Mofumatic
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mathstodon.xyz/@tao">
 https://mathstodon.xyz/@tao
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@chikorita157">
 https://sakurajima.moe/@chikorita157
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://sakurajima.moe/@sakurajima">
 https://sakurajima.moe/@sakurajima
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://floss.social/@kde">
 https://floss.social/@kde
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mastodon.social/@gamingonlinux">
 https://mastodon.social/@gamingonlinux
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://threads.net/@nintendeal">
 https://threads.net/@nintendeal
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://mastodon.social/@Mastodon">
 https://mastodon.social/@Mastodon
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://jvns.ca/@b0rk">
 https://jvns.ca/@b0rk
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://tippy.rabbithouse.garden/@serebii">
 https://tippy.rabbithouse.garden/@serebii
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://retro.pizza/@outofprintarchive">
 https://retro.pizza/@outofprintarchive
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>




<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://peoplemaking.games/@nindiespotlight">
 https://peoplemaking.games/@nindiespotlight
 </a>

 <time class="follow-date dt-published" datetime="2025-12-04T00:00:00Z">
 2025-12-04
 </time>
</div>
</p>
<h2 id="bluesky">Bluesky</h2>



<div class="follow-card">
 <a class="follow-target u-follow-of" href="https://bsky.app/profile/anew.social">
 https://bsky.app/profile/anew.social
 </a>

 <time class="follow-date dt-published" datetime="2025-12-03T00:00:00Z">
 2025-12-03
 </time>
</div>

<blockquote>
<p>Learn more about the <a href="https://indieweb.org">Indieweb</a></p></description> </item> </channel> </rss> diff --git a/micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/index.html b/micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/index.html new file mode 100644 index 0000000..137cf9a --- /dev/null +++ b/micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/index.html @@ -0,0 +1,634 @@ +<!DOCTYPE html> +<html lang="en-us"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <style type=text/css>body{font-family:monospace;}</style> + <title>Enable HID Mode on Nintendo Pro Controller 2 | micro.pinapelz.moe</title> + + <meta name="author" content="map[avatar:https://files.catbox.moe/5r1pue.jpg banner:https://files.pinapelz.com/pso2ngs-2232-collab.png bio:yo! and he's more than a cover he's a quilt<br/> + General arcade rhythm game enjoyer (SDVX, IIDX, CHUNITHM)<br/> + Mostly play MMOs (FFXIV, OSRS), JRPGs, and VNs (anything with a good story)<br/> + I Watch only slice of life (and Bandori)<br/> + Arch Linux + Hyprland user (btw)<br/> + Hi from the <a href="https://indieweb.org/">indieweb</a>, if you are seeing me bridged elsewhere! email:yukais@pinapelz.com name:Pinapelz]"> + <link rel="stylesheet" href="/css/style.css"> + + + + <link rel="me" href="https://github.com/pinapelz" /> + <link rel="me" href="mailto:yukais@pinapelz.com" /> + <link rel="me" href="https://sakurajima.social/@pinapelz" /> + <link rel="me" href="https://bsky.app/profile/pinapelz.moe" /><link rel="pgpkey" href="https://pinapelz.com/Yukai_Shan.asc"> + <link + rel="authorization_endpoint" + href="https://indieauth.com/auth" + /> + <link + rel="token_endpoint" + href="https://tokens.indieauth.com/token" + /> + <link rel="webmention" href="https://webmention.io/micro.pinapelz.moe/webmention" /> + + + +</head> +<body> + <header> + <div style="display:flex;flex-flow:row wrap;justify-content:space-between"> + <div style="align-self:flex-start;"> + ==============<br> + == <a href="https://micro.pinapelz.moe/">Pinapelz</a> ==<br> + ============== + </div> + <div style="align-self:center;">check it out. I'm in the house like carpet</div> + </div> + <nav style="margin: 1rem auto;"> + + + <a href="/posts/"><b>Posts</b></a>. + + <a href="/categories/"><b>Categories</b></a>. + + <a href="/tags/"><b>Tags</b></a>. + + + </nav> +</header> + + + + <main> + <article class="h-entry"> + <a class="u-bridgy-fed" href="https://fed.brid.gy/" hidden="from-humans"></a> + <h1 class="p-name">Enable HID Mode on Nintendo Pro Controller 2</h1> + <div hidden><div class="h-card p-author bio-card" style="text-align:center;"> + + <div class="banner" style="margin-bottom: 1rem; position: relative;"> + <img class="u-featured" src="https://files.pinapelz.com/pso2ngs-2232-collab.png" alt="Banner" style="width: 100%; max-width: 400px; height: auto; border-radius: 8px; opacity: 0.6;"> + <img class="u-photo avatar" src="https://files.catbox.moe/5r1pue.jpg" alt="Pinapelz's avatar" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);"> + </div> + + <div class="bio"> + <p class="p-note">yo! and he's more than a cover he's a quilt<br/> + General arcade rhythm game enjoyer (SDVX, IIDX, CHUNITHM)<br/> + Mostly play MMOs (FFXIV, OSRS), JRPGs, and VNs (anything with a good story)<br/> + I Watch only slice of life (and Bandori)<br/> + Arch Linux + Hyprland user (btw)<br/> + Hi from the <a href="https://indieweb.org/">indieweb</a>, if you are seeing me bridged elsewhere!</p> + </div> + <p class="bio-name"><a href="https://micro.pinapelz.moe/" rel="me" class="p-nickname p-name u-url">Pinapelz</a></p> +</div> +<hr/> +</div> + + + <div><b> + <time class="dt-published" datetime="2025-12-04T23:19:29-08:00"> + Thursday, December 4, 2025 + </time> + - <a href="https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/" class="u-url u-uid" >Permalink</a> + </b></div> + <div class="article-meta"><span class="categories"> + Categories: + + <a href="/categories/tools">tools</a> + + </span>--<span class="tags"> + Tags: + + #<a href="/tags/code" class="p-category">code</a> + + #<a href="/tags/nintendo" class="p-category">nintendo</a> + + </span></div><div class="e-content"> + <p>Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn’t work out of box on PC (Linux) for me like it’s predacessor. Until there’s actual better driver support for this thing in the kernel (or Valve does something), here’s a hacky Python script to initialize HID-mode on the controller</p> +<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># I only tested this script on Linux w/ Steam but in theory it shoud work on Windows?</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.core <span style="color:#75715e"># install pyusb first: pip install pyusb</span> +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.util +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> time +</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span>VENDOR_ID <span style="color:#f92672">=</span> <span style="color:#ae81ff">0x057E</span> +</span></span><span style="display:flex;"><span>PRODUCT_IDS <span style="color:#f92672">=</span> { +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2066</span>: <span style="color:#e6db74">"Joy-Con (L)"</span>, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2067</span>: <span style="color:#e6db74">"Joy-Con (R)"</span>, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2069</span>: <span style="color:#e6db74">"Pro Controller"</span>, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2073</span>: <span style="color:#e6db74">"GCN Controller"</span> +</span></span><span style="display:flex;"><span>} +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span>USB_INTERFACE_NUMBER <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span>INIT_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0d</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x07 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x16 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x16</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>REQUEST_CONTROLLER_MAC <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0e</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>]) +</span></span><span style="display:flex;"><span>LTK_REQUEST <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x15_ARG_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x09 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>IMU_COMMAND_0x02 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x11 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x0A <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x14</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0x35</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x46</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>IMU_COMMAND_0x04 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>ENABLE_HAPTICS <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x10 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x10</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x01 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x0A_ALT <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>]) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_usb_data</span>(ep_out, ep_in, data, description<span style="color:#f92672">=</span><span style="color:#e6db74">""</span>): +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> ep_out<span style="color:#f92672">.</span>write(data) +</span></span><span style="display:flex;"><span> time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">0.01</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> response <span style="color:#f92672">=</span> ep_in<span style="color:#f92672">.</span>read(<span style="color:#ae81ff">32</span>, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">100</span>) +</span></span><span style="display:flex;"><span> hex_resp <span style="color:#f92672">=</span> <span style="color:#e6db74">" "</span><span style="color:#f92672">.</span>join([<span style="color:#e6db74">f</span><span style="color:#e6db74">"</span><span style="color:#e6db74">{</span>x<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">"</span> <span style="color:#66d9ef">for</span> x <span style="color:#f92672">in</span> response]) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Response: </span><span style="color:#e6db74">{</span>hex_resp<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> e<span style="color:#f92672">.</span>errno <span style="color:#f92672">==</span> <span style="color:#ae81ff">110</span>: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] No response (Timeout)"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span>: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Read Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Write Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">set_player_leds</span>(ep_out, ep_in, led_mask): +</span></span><span style="display:flex;"><span> command <span style="color:#f92672">=</span> [ +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, +</span></span><span style="display:flex;"><span> led_mask, +</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span> +</span></span><span style="display:flex;"><span> ] +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, bytes(command), <span style="color:#e6db74">f</span><span style="color:#e6db74">"Set LED Mask: 0x</span><span style="color:#e6db74">{</span>led_mask<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">connect_usb</span>(): +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Searching for Nintendo Switch Controllers..."</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">match_device</span>(dev): +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> dev<span style="color:#f92672">.</span>idVendor <span style="color:#f92672">==</span> VENDOR_ID <span style="color:#f92672">and</span> dev<span style="color:#f92672">.</span>idProduct <span style="color:#f92672">in</span> PRODUCT_IDS +</span></span><span style="display:flex;"><span> dev <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>find(custom_match<span style="color:#f92672">=</span>match_device) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span>: +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">"Device not found"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> product_name <span style="color:#f92672">=</span> PRODUCT_IDS<span style="color:#f92672">.</span>get(dev<span style="color:#f92672">.</span>idProduct, <span style="color:#e6db74">"Unknown Device"</span>) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Found </span><span style="color:#e6db74">{</span>product_name<span style="color:#e6db74">}</span><span style="color:#e6db74"> (ID: </span><span style="color:#e6db74">{</span>dev<span style="color:#f92672">.</span>idProduct<span style="color:#e6db74">:</span><span style="color:#e6db74">04x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">)"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev<span style="color:#f92672">.</span>is_kernel_driver_active(USB_INTERFACE_NUMBER): +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Detaching kernel driver..."</span>) +</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>detach_kernel_driver(USB_INTERFACE_NUMBER) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Could not detach kernel driver: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>set_configuration() +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Configuration set."</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Error setting configuration: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>claim_interface(dev, USB_INTERFACE_NUMBER) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Interface </span><span style="color:#e6db74">{</span>USB_INTERFACE_NUMBER<span style="color:#e6db74">}</span><span style="color:#e6db74"> claimed."</span>) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Could not claim interface: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> cfg <span style="color:#f92672">=</span> dev<span style="color:#f92672">.</span>get_active_configuration() +</span></span><span style="display:flex;"><span> intf <span style="color:#f92672">=</span> cfg[(USB_INTERFACE_NUMBER,<span style="color:#ae81ff">0</span>)] +</span></span><span style="display:flex;"><span> ep_out <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor( +</span></span><span style="display:flex;"><span> intf, +</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_OUT) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> ep_in <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor( +</span></span><span style="display:flex;"><span> intf, +</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_IN +</span></span><span style="display:flex;"><span> ) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> ep_out: +</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">"Could not find OUT endpoint"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Found Endpoint OUT: 0x</span><span style="color:#e6db74">{</span>ep_out<span style="color:#f92672">.</span>bEndpointAddress<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Starting Initialization Sequence..."</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, <span style="color:#e6db74">"Init 0x03"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, <span style="color:#e6db74">"Unknown 0x07"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, <span style="color:#e6db74">"Unknown 0x16"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, <span style="color:#e6db74">"Req MAC"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, LTK_REQUEST, <span style="color:#e6db74">"Req LTK"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, <span style="color:#e6db74">"Unknown 0x15"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, <span style="color:#e6db74">"Unknown 0x09"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, <span style="color:#e6db74">"IMU 0x02"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, <span style="color:#e6db74">"OUT Unknown 0x11"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, <span style="color:#e6db74">"Unknown 0x0A"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, <span style="color:#e6db74">"IMU 0x04"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, <span style="color:#e6db74">"Enable Haptics"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, <span style="color:#e6db74">"OUT Unknown 0x10"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, <span style="color:#e6db74">"OUT Unknown 0x01"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, <span style="color:#e6db74">"OUT Unknown 0x03"</span>) +</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, <span style="color:#e6db74">"OUT Unknown 0x0A Alt"</span>) +</span></span><span style="display:flex;"><span> set_player_leds(ep_out, ep_in, <span style="color:#ae81ff">0x0F</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">"Controller initialization sequence complete! All LEDs should be on."</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Error during sequence: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">"__main__"</span>: +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>: +</span></span><span style="display:flex;"><span> connect_usb() +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">ValueError</span> <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(e) +</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e: +</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">"Unexpected error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">"</span>) +</span></span></code></pre></div><p><strong>Steps</strong></p> +<ol start="0"> +<li>(Optional) First Create a virtual environment</li> +<li>Install pyusb via <code>pip install pyusb</code></li> +<li>Plug your Pro Controller 2 in via USB</li> +<li>Run the script</li> +</ol> +<p>If all 4 of the player indicator LEDs light up (the square ones near the charging port), then that means you should be good to go!</p> +<p>You’ll need to re-run this script each time you plug/unplug or restart your machine.</p> +<p>This is pretty much a copy of the <a href="https://handheldlegend.github.io/procon2tool/">online Procon 2 Enabler Tool</a> but WebHID is dodgy on the Firefox fork I’m using, plus its annoying having to open this page each time.</p> + + </div> + + + + + + + <section id="comments" class="webmentions"> + <h2 class="wm-title">Webmentions</h2> + <div id="mentions" class="wm-list">Loading…</div> +</section> + +<style> +.webmentions { + margin-top: 2.5rem; + padding-top: 1rem; + border-top: 2px dashed var(--hrcolor); +} + +.webmentions .wm-title { + color: var(--titlecolor); + margin-bottom: 1rem; +} + +.wm-list { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + + +.wm-reactions { + margin-bottom: 1.5rem; +} + +.wm-reaction-group { + margin-bottom: 1rem; +} + +.wm-reaction-title { + font-size: 1.1rem; + font-weight: 600; + color: var(--titlecolor); + margin-bottom: 0.5rem; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.wm-avatar-grid { + display: flex; + flex-wrap: wrap; + gap: 4px; + align-items: center; +} + +.wm-avatar { + position: relative; + display: inline-block; +} + +.wm-avatar img { + width: 40px; + height: 40px; + border-radius: 50%; + border: 2px solid var(--hrcolor); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.wm-avatar:hover img { + transform: scale(1.1); + box-shadow: 0 4px 12px rgba(255, 140, 200, 0.4); +} + +.wm-avatar-tooltip { + position: absolute; + bottom: 120%; + left: 50%; + transform: translateX(-50%); + background: var(--blockquotecolor); + color: var(--titlecolor); + padding: 4px 8px; + border-radius: 4px; + font-size: 0.8rem; + white-space: nowrap; + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease; + z-index: 10; + border: 1px solid var(--hrcolor); +} + +.wm-avatar:hover .wm-avatar-tooltip { + opacity: 1; +} + + +.wm-comments-header { + font-size: 1.1rem; + font-weight: 600; + color: var(--titlecolor); + margin-bottom: 0.5rem; + margin-top: 1rem; + text-transform: uppercase; + letter-spacing: 0.5px; +} + + +.wm-regular { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.wm { + display: flex; + gap: 0.6rem; + padding: 0.6rem 0.75rem; + border-radius: 10px; + background: var(--alertbgcolor); + border: 1px solid var(--hrcolor); + box-shadow: 0 0 6px rgba(255, 180, 220, 0.22); +} + +.wm-author img { + width: 32px; + height: 32px; + border-radius: 50%; + box-shadow: 0 0 4px rgba(255, 140, 200, 0.35); +} + +.wm-body { + flex: 1; + font-size: 0.9rem; +} + +.wm-author-name a { + font-weight: 600; + color: var(--linkcolor); +} + +.wm-type { + font-size: 0.8rem; + margin-top: 2px; + color: var(--titlecolor); +} + +.wm-content { + margin-top: 4px; + padding: 6px 8px; + font-size: 0.9rem; + background: var(--blockquotecolor); + border-left: 3px solid var(--hrcolor); + border-radius: 6px; +} + +.wm-meta { + margin-top: 3px; + font-size: 0.75rem; + opacity: 0.7; +} + +.wm-meta a { + color: var(--linkcolor); +} + + +@media (max-width: 600px) { + .wm-avatar img { + width: 32px; + height: 32px; + } + + .wm-avatar-grid { + gap: 3px; + } + + .wm-reaction-title { + font-size: 1rem; + } + + .wm-comments-header { + font-size: 1rem; + } +} +</style> + +<script> +const PAGE_URL = "https:\/\/micro.pinapelz.moe\/posts\/2025-12-04-procon2-hid-tool\/"; + +async function loadMentions() { + const url = + "https://webmention.io/api/mentions.jf2?domain=micro.pinapelz.moe&token=hdjQAqlZwgJmSuPSiU8h8w"; + + const res = await fetch(url); + const data = await res.json(); + + const container = document.getElementById("mentions"); + container.innerHTML = ""; + + + const mentions = data.children.filter(m => { + const t = m["wm-target"]; + const inReply = m["in-reply-to"]; + const likeOf = m["like-of"]; + const repostOf = m["repost-of"]; + const mentionOf = m["mention-of"]; + + return ( + t === PAGE_URL || + inReply === PAGE_URL || + likeOf === PAGE_URL || + repostOf === PAGE_URL || + mentionOf === PAGE_URL + ); + }); + + if (!mentions.length) { + container.innerHTML = "<p>No webmentions yet.</p>"; + return; + } + + + const likes = mentions.filter(m => m["wm-property"] === "like-of"); + const reposts = mentions.filter(m => m["wm-property"] === "repost-of"); + const replies = mentions.filter(m => m["wm-property"] === "in-reply-to"); + const regularMentions = mentions.filter(m => + !["like-of", "repost-of", "in-reply-to"].includes(m["wm-property"]) + ); + + + const reactionsDiv = document.createElement("div"); + reactionsDiv.className = "wm-reactions"; + + + if (reposts.length > 0) { + const repostGroup = document.createElement("div"); + repostGroup.className = "wm-reaction-group"; + + const repostTitle = document.createElement("div"); + repostTitle.className = "wm-reaction-title"; + repostTitle.textContent = `${reposts.length} Repost${reposts.length !== 1 ? 's' : ''}`; + + const repostGrid = document.createElement("div"); + repostGrid.className = "wm-avatar-grid"; + + reposts.forEach(mention => { + const author = mention.author || {}; + const avatarDiv = document.createElement("div"); + avatarDiv.className = "wm-avatar"; + + avatarDiv.innerHTML = ` + <a href="${author.url || "#"}" target="_blank"> + <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" /> + </a> + <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div> + `; + + repostGrid.appendChild(avatarDiv); + }); + + repostGroup.appendChild(repostTitle); + repostGroup.appendChild(repostGrid); + reactionsDiv.appendChild(repostGroup); + } + + + if (likes.length > 0) { + const likeGroup = document.createElement("div"); + likeGroup.className = "wm-reaction-group"; + + const likeTitle = document.createElement("div"); + likeTitle.className = "wm-reaction-title"; + likeTitle.textContent = `${likes.length} Like${likes.length !== 1 ? 's' : ''}`; + + const likeGrid = document.createElement("div"); + likeGrid.className = "wm-avatar-grid"; + + likes.forEach(mention => { + const author = mention.author || {}; + const avatarDiv = document.createElement("div"); + avatarDiv.className = "wm-avatar"; + + avatarDiv.innerHTML = ` + <a href="${author.url || "#"}" target="_blank"> + <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}" /> + </a> + <div class="wm-avatar-tooltip">${author.name || 'Unknown'}</div> + `; + + likeGrid.appendChild(avatarDiv); + }); + + likeGroup.appendChild(likeTitle); + likeGroup.appendChild(likeGrid); + reactionsDiv.appendChild(likeGroup); + } + + + if (reactionsDiv.children.length > 0) { + container.appendChild(reactionsDiv); + } + + + const regularMentionsToShow = [...replies, ...regularMentions]; + + if (regularMentionsToShow.length > 0) { + + const commentsHeader = document.createElement("div"); + commentsHeader.className = "wm-comments-header"; + commentsHeader.textContent = "Comments"; + container.appendChild(commentsHeader); + + const regularDiv = document.createElement("div"); + regularDiv.className = "wm-regular"; + + regularMentionsToShow.forEach(m => { + const div = document.createElement("div"); + div.className = "wm"; + + const author = m.author || {}; + const content = m.content || {}; + const type = + m["wm-property"] === "in-reply-to" ? "replied 💬" : + "mentioned this"; + + div.innerHTML = ` + <div class="wm-author"> + <img src="${author.photo || ""}" alt="${author.name || 'Unknown'}"> + </div> + + <div class="wm-body"> + <div class="wm-author-name"> + <a href="${author.url || "#"}" target="_blank"> + ${author.name || "Unknown"} + </a> + </div> + + <div class="wm-type">${type}</div> + + ${content.text ? `<div class="wm-content">${content.text}</div>` : ""} + + <div class="wm-meta"> + <a href="${m.url}" target="_blank">source</a> • + ${m["wm-received"] + ? new Date(m["wm-received"]).toLocaleString() + : ""} + </div> + </div> + `; + regularDiv.appendChild(div); + }); + + container.appendChild(regularDiv); + } + + + if (container.children.length === 0) { + container.innerHTML = "<p>No webmentions yet.</p>"; + } +} + +loadMentions(); +</script> + + </article> + </main> + + <hr /> +<footer> + <p> + <a href="https://github.com/pinapelz"><b>Github</b></a>. + <a href="https://pinapelz.moe"><b>pinapelz.moe</b></a>. + </p> + + + + <p style="text-align: center" class="copyright"> + © <a href="https://micro.pinapelz.moe/"><b>micro.pinapelz.moe</b></a>. + </p> +</footer> + +</body> +</html> diff --git a/micro.pinapelz.moe/posts/index.html b/micro.pinapelz.moe/posts/index.html index 17cf9fc..08cea4c 100644 --- a/micro.pinapelz.moe/posts/index.html +++ b/micro.pinapelz.moe/posts/index.html @@ -117,6 +117,45 @@ </div> <div class="post-title"> + <time class="date dt-published" datetime="2025-12-04T23:19:29-08:00">04</time>: + + <a href="https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/" class="u-url p-name title"> + Enable HID Mode on Nintendo Pro Controller 2 + </a> + </div> + </li> + + + + + + + + + + <li class="h-entry"> + <div hidden> + <div class="h-card p-author bio-card" style="text-align:center;"> + + <div class="banner" style="margin-bottom: 1rem; position: relative;"> + <img class="u-featured" src="https://files.pinapelz.com/pso2ngs-2232-collab.png" alt="Banner" style="width: 100%; max-width: 400px; height: auto; border-radius: 8px; opacity: 0.6;"> + <img class="u-photo avatar" src="https://files.catbox.moe/5r1pue.jpg" alt="Pinapelz's avatar" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);"> + </div> + + <div class="bio"> + <p class="p-note">yo! and he's more than a cover he's a quilt<br/> + General arcade rhythm game enjoyer (SDVX, IIDX, CHUNITHM)<br/> + Mostly play MMOs (FFXIV, OSRS), JRPGs, and VNs (anything with a good story)<br/> + I Watch only slice of life (and Bandori)<br/> + Arch Linux + Hyprland user (btw)<br/> + Hi from the <a href="https://indieweb.org/">indieweb</a>, if you are seeing me bridged elsewhere!</p> + </div> + <p class="bio-name"><a href="https://micro.pinapelz.moe/" rel="me" class="p-nickname p-name u-url">Pinapelz</a></p> +</div> +<hr/> + + </div> + <div class="post-title"> <time class="date dt-published" datetime="2025-12-03T19:38:52-08:00">03</time>: <a href="https://micro.pinapelz.moe/posts/2025-12-03-04-yt-music-rewind/" class="u-url p-name title"> diff --git a/micro.pinapelz.moe/posts/index.xml b/micro.pinapelz.moe/posts/index.xml index d830e70..372ca51 100644 --- a/micro.pinapelz.moe/posts/index.xml +++ b/micro.pinapelz.moe/posts/index.xml @@ -8,9 +8,16 @@ <language>en-us</language> <managingEditor>yukais@pinapelz.com (Pinapelz)</managingEditor> <webMaster>yukais@pinapelz.com (Pinapelz)</webMaster> - <lastBuildDate>Wed, 03 Dec 2025 19:38:52 -0800</lastBuildDate> + <lastBuildDate>Thu, 04 Dec 2025 23:19:29 -0800</lastBuildDate> <atom:link href="https://micro.pinapelz.moe/posts/index.xml" rel="self" type="application/rss+xml" /> <item> + <title>Enable HID Mode on Nintendo Pro Controller 2</title> + <link>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</guid> + <description><p>Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn&rsquo;t work out of box on PC (Linux) for me like it&rsquo;s predacessor. Until there&rsquo;s actual better driver support for this thing in the kernel (or Valve does something), here&rsquo;s a hacky Python script to initialize HID-mode on the controller</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># I only tested this script on Linux w/ Steam but in theory it shoud work on Windows?</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.core <span style="color:#75715e"># install pyusb first: pip install pyusb</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.util
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> time
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>VENDOR_ID <span style="color:#f92672">=</span> <span style="color:#ae81ff">0x057E</span>
</span></span><span style="display:flex;"><span>PRODUCT_IDS <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2066</span>: <span style="color:#e6db74">&#34;Joy-Con (L)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2067</span>: <span style="color:#e6db74">&#34;Joy-Con (R)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2069</span>: <span style="color:#e6db74">&#34;Pro Controller&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2073</span>: <span style="color:#e6db74">&#34;GCN Controller&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>USB_INTERFACE_NUMBER <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>INIT_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0d</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x07 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x16 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x16</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>REQUEST_CONTROLLER_MAC <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0e</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>LTK_REQUEST <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x15_ARG_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x09 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x02 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x11 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x0A <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x14</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0x35</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x46</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x04 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>ENABLE_HAPTICS <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x10 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x10</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x01 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x0A_ALT <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_usb_data</span>(ep_out, ep_in, data, description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> ep_out<span style="color:#f92672">.</span>write(data)
</span></span><span style="display:flex;"><span> time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">0.01</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> response <span style="color:#f92672">=</span> ep_in<span style="color:#f92672">.</span>read(<span style="color:#ae81ff">32</span>, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">100</span>)
</span></span><span style="display:flex;"><span> hex_resp <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34; &#34;</span><span style="color:#f92672">.</span>join([<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>x<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#66d9ef">for</span> x <span style="color:#f92672">in</span> response])
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Response: </span><span style="color:#e6db74">{</span>hex_resp<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> e<span style="color:#f92672">.</span>errno <span style="color:#f92672">==</span> <span style="color:#ae81ff">110</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] No response (Timeout)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Read Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Write Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">set_player_leds</span>(ep_out, ep_in, led_mask):
</span></span><span style="display:flex;"><span> command <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>,
</span></span><span style="display:flex;"><span> led_mask,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, bytes(command), <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Set LED Mask: 0x</span><span style="color:#e6db74">{</span>led_mask<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">connect_usb</span>():
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Searching for Nintendo Switch Controllers...&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">match_device</span>(dev):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> dev<span style="color:#f92672">.</span>idVendor <span style="color:#f92672">==</span> VENDOR_ID <span style="color:#f92672">and</span> dev<span style="color:#f92672">.</span>idProduct <span style="color:#f92672">in</span> PRODUCT_IDS
</span></span><span style="display:flex;"><span> dev <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>find(custom_match<span style="color:#f92672">=</span>match_device)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">&#34;Device not found&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> product_name <span style="color:#f92672">=</span> PRODUCT_IDS<span style="color:#f92672">.</span>get(dev<span style="color:#f92672">.</span>idProduct, <span style="color:#e6db74">&#34;Unknown Device&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found </span><span style="color:#e6db74">{</span>product_name<span style="color:#e6db74">}</span><span style="color:#e6db74"> (ID: </span><span style="color:#e6db74">{</span>dev<span style="color:#f92672">.</span>idProduct<span style="color:#e6db74">:</span><span style="color:#e6db74">04x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev<span style="color:#f92672">.</span>is_kernel_driver_active(USB_INTERFACE_NUMBER):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Detaching kernel driver...&#34;</span>)
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>detach_kernel_driver(USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not detach kernel driver: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>set_configuration()
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Configuration set.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error setting configuration: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>claim_interface(dev, USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Interface </span><span style="color:#e6db74">{</span>USB_INTERFACE_NUMBER<span style="color:#e6db74">}</span><span style="color:#e6db74"> claimed.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not claim interface: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> cfg <span style="color:#f92672">=</span> dev<span style="color:#f92672">.</span>get_active_configuration()
</span></span><span style="display:flex;"><span> intf <span style="color:#f92672">=</span> cfg[(USB_INTERFACE_NUMBER,<span style="color:#ae81ff">0</span>)]
</span></span><span style="display:flex;"><span> ep_out <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_OUT)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> ep_in <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_IN
</span></span><span style="display:flex;"><span> )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> ep_out:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">&#34;Could not find OUT endpoint&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found Endpoint OUT: 0x</span><span style="color:#e6db74">{</span>ep_out<span style="color:#f92672">.</span>bEndpointAddress<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Starting Initialization Sequence...&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, <span style="color:#e6db74">&#34;Init 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, <span style="color:#e6db74">&#34;Unknown 0x07&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, <span style="color:#e6db74">&#34;Unknown 0x16&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, <span style="color:#e6db74">&#34;Req MAC&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, LTK_REQUEST, <span style="color:#e6db74">&#34;Req LTK&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, <span style="color:#e6db74">&#34;Unknown 0x15&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, <span style="color:#e6db74">&#34;Unknown 0x09&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, <span style="color:#e6db74">&#34;IMU 0x02&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, <span style="color:#e6db74">&#34;OUT Unknown 0x11&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, <span style="color:#e6db74">&#34;Unknown 0x0A&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, <span style="color:#e6db74">&#34;IMU 0x04&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, <span style="color:#e6db74">&#34;Enable Haptics&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, <span style="color:#e6db74">&#34;OUT Unknown 0x10&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, <span style="color:#e6db74">&#34;OUT Unknown 0x01&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, <span style="color:#e6db74">&#34;OUT Unknown 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, <span style="color:#e6db74">&#34;OUT Unknown 0x0A Alt&#34;</span>)
</span></span><span style="display:flex;"><span> set_player_leds(ep_out, ep_in, <span style="color:#ae81ff">0x0F</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Controller initialization sequence complete! All LEDs should be on.&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error during sequence: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> connect_usb()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">ValueError</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(e)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Unexpected error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></div><p><strong>Steps</strong></p></description> + </item> + <item> <title>YouTube Music Recap 2025</title> <link>https://micro.pinapelz.moe/posts/2025-12-03-04-yt-music-rewind/</link> <pubDate>Wed, 03 Dec 2025 19:38:52 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> diff --git a/micro.pinapelz.moe/sitemap.xml b/micro.pinapelz.moe/sitemap.xml index 3b3a6ee..9a1f9d3 100644 --- a/micro.pinapelz.moe/sitemap.xml +++ b/micro.pinapelz.moe/sitemap.xml @@ -2,22 +2,34 @@ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <url> - <loc>https://micro.pinapelz.moe/tags/anime/</loc> - <lastmod>2025-12-03T19:38:52-08:00</lastmod> - </url><url> <loc>https://micro.pinapelz.moe/categories/</loc> - <lastmod>2025-12-03T19:38:52-08:00</lastmod> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> </url><url> - <loc>https://micro.pinapelz.moe/categories/default/</loc> - <lastmod>2025-12-03T19:38:52-08:00</lastmod> + <loc>https://micro.pinapelz.moe/tags/code/</loc> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> + </url><url> + <loc>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</loc> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> </url><url> <loc>https://micro.pinapelz.moe/</loc> - <lastmod>2025-12-03T19:38:52-08:00</lastmod> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> + </url><url> + <loc>https://micro.pinapelz.moe/tags/nintendo/</loc> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> </url><url> <loc>https://micro.pinapelz.moe/posts/</loc> - <lastmod>2025-12-03T19:38:52-08:00</lastmod> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> </url><url> <loc>https://micro.pinapelz.moe/tags/</loc> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> + </url><url> + <loc>https://micro.pinapelz.moe/categories/tools/</loc> + <lastmod>2025-12-04T23:19:29-08:00</lastmod> + </url><url> + <loc>https://micro.pinapelz.moe/tags/anime/</loc> + <lastmod>2025-12-03T19:38:52-08:00</lastmod> + </url><url> + <loc>https://micro.pinapelz.moe/categories/default/</loc> <lastmod>2025-12-03T19:38:52-08:00</lastmod> </url><url> <loc>https://micro.pinapelz.moe/posts/2025-12-03-04-yt-music-rewind/</loc> diff --git a/micro.pinapelz.moe/tags/code/index.html b/micro.pinapelz.moe/tags/code/index.html new file mode 100644 index 0000000..364c5f4 --- /dev/null +++ b/micro.pinapelz.moe/tags/code/index.html @@ -0,0 +1,106 @@ +<!DOCTYPE html> +<html lang="en-us"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <style type=text/css>body{font-family:monospace;}</style> + <title>Code | micro.pinapelz.moe</title> + + <meta name="author" content="map[avatar:https://files.catbox.moe/5r1pue.jpg banner:https://files.pinapelz.com/pso2ngs-2232-collab.png bio:yo! and he's more than a cover he's a quilt<br/> + General arcade rhythm game enjoyer (SDVX, IIDX, CHUNITHM)<br/> + Mostly play MMOs (FFXIV, OSRS), JRPGs, and VNs (anything with a good story)<br/> + I Watch only slice of life (and Bandori)<br/> + Arch Linux + Hyprland user (btw)<br/> + Hi from the <a href="https://indieweb.org/">indieweb</a>, if you are seeing me bridged elsewhere! email:yukais@pinapelz.com name:Pinapelz]"> + <link rel="stylesheet" href="/css/style.css"> + <link rel="alternate" type="application/rss+xml" href="/tags/code/index.xml" title="micro.pinapelz.moe"> + + + <link rel="me" href="https://github.com/pinapelz" /> + <link rel="me" href="mailto:yukais@pinapelz.com" /> + <link rel="me" href="https://sakurajima.social/@pinapelz" /> + <link rel="me" href="https://bsky.app/profile/pinapelz.moe" /><link rel="pgpkey" href="https://pinapelz.com/Yukai_Shan.asc"> + <link + rel="authorization_endpoint" + href="https://indieauth.com/auth" + /> + <link + rel="token_endpoint" + href="https://tokens.indieauth.com/token" + /> + <link rel="webmention" href="https://webmention.io/micro.pinapelz.moe/webmention" /> + + + +</head> +<body> + <header> + <div style="display:flex;flex-flow:row wrap;justify-content:space-between"> + <div style="align-self:flex-start;"> + ==============<br> + == <a href="https://micro.pinapelz.moe/">Pinapelz</a> ==<br> + ============== + </div> + <div style="align-self:center;">check it out. I'm in the house like carpet</div> + </div> + <nav style="margin: 1rem auto;"> + + + <a href="/posts/"><b>Posts</b></a>. + + <a href="/categories/"><b>Categories</b></a>. + + <a href="/tags/"><b>Tags</b></a>. + + + </nav> +</header> + + + +<main> + <div> + <h1> + Code + <a href="https://micro.pinapelz.moe/tags/code/index.xml"> + <img style="height:1.5rem; display: inline;" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='RSS' role='img' viewBox='0 0 512 512'%3E%3Cpath d='M0 0h512v512H0' fill='%23f80'/%3E%3Cpath d='M109 271A132 133 0 0 1 241 403h60A192 193 0 0 0 109 211v-54A246 247 0 0 1 355 403h60A306 307 0 0 0 109 97m35 235a35 35 0 1 0 2 0' fill='%23fff'/%3E%3C/svg%3E" alt="RSS icon" /> + </a> + </h1> + <div> + + </div><p>Content linked to the taxonomy term « CODE »:</p> + + + + + <div> + <h3>Posts</h3> + <ul> + + <li> + <time class="date dt-published" datetime="2025-12-04T23:19:29-08:00">2025-12-04</time> + <a href="/posts/2025-12-04-procon2-hid-tool/">Enable HID Mode on Nintendo Pro Controller 2</a> + </li> + + + </ul> + </div></div> +</main> + + <hr /> +<footer> + <p> + <a href="https://github.com/pinapelz"><b>Github</b></a>. + <a href="https://pinapelz.moe"><b>pinapelz.moe</b></a>. + </p> + + + + <p style="text-align: center" class="copyright"> + © <a href="https://micro.pinapelz.moe/"><b>micro.pinapelz.moe</b></a>. + </p> +</footer> + +</body> +</html> diff --git a/micro.pinapelz.moe/tags/code/index.xml b/micro.pinapelz.moe/tags/code/index.xml new file mode 100644 index 0000000..a8b7d04 --- /dev/null +++ b/micro.pinapelz.moe/tags/code/index.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> + <channel> + <title>Code on micro.pinapelz.moe</title> + <link>https://micro.pinapelz.moe/tags/code/</link> + <description>Recent content in Code on micro.pinapelz.moe</description> + <generator>Hugo</generator> + <language>en-us</language> + <managingEditor>yukais@pinapelz.com (Pinapelz)</managingEditor> + <webMaster>yukais@pinapelz.com (Pinapelz)</webMaster> + <lastBuildDate>Thu, 04 Dec 2025 23:19:29 -0800</lastBuildDate> + <atom:link href="https://micro.pinapelz.moe/tags/code/index.xml" rel="self" type="application/rss+xml" /> + <item> + <title>Enable HID Mode on Nintendo Pro Controller 2</title> + <link>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</guid> + <description><p>Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn&rsquo;t work out of box on PC (Linux) for me like it&rsquo;s predacessor. Until there&rsquo;s actual better driver support for this thing in the kernel (or Valve does something), here&rsquo;s a hacky Python script to initialize HID-mode on the controller</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># I only tested this script on Linux w/ Steam but in theory it shoud work on Windows?</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.core <span style="color:#75715e"># install pyusb first: pip install pyusb</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.util
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> time
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>VENDOR_ID <span style="color:#f92672">=</span> <span style="color:#ae81ff">0x057E</span>
</span></span><span style="display:flex;"><span>PRODUCT_IDS <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2066</span>: <span style="color:#e6db74">&#34;Joy-Con (L)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2067</span>: <span style="color:#e6db74">&#34;Joy-Con (R)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2069</span>: <span style="color:#e6db74">&#34;Pro Controller&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2073</span>: <span style="color:#e6db74">&#34;GCN Controller&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>USB_INTERFACE_NUMBER <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>INIT_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0d</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x07 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x16 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x16</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>REQUEST_CONTROLLER_MAC <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0e</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>LTK_REQUEST <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x15_ARG_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x09 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x02 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x11 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x0A <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x14</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0x35</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x46</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x04 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>ENABLE_HAPTICS <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x10 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x10</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x01 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x0A_ALT <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_usb_data</span>(ep_out, ep_in, data, description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> ep_out<span style="color:#f92672">.</span>write(data)
</span></span><span style="display:flex;"><span> time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">0.01</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> response <span style="color:#f92672">=</span> ep_in<span style="color:#f92672">.</span>read(<span style="color:#ae81ff">32</span>, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">100</span>)
</span></span><span style="display:flex;"><span> hex_resp <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34; &#34;</span><span style="color:#f92672">.</span>join([<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>x<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#66d9ef">for</span> x <span style="color:#f92672">in</span> response])
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Response: </span><span style="color:#e6db74">{</span>hex_resp<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> e<span style="color:#f92672">.</span>errno <span style="color:#f92672">==</span> <span style="color:#ae81ff">110</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] No response (Timeout)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Read Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Write Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">set_player_leds</span>(ep_out, ep_in, led_mask):
</span></span><span style="display:flex;"><span> command <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>,
</span></span><span style="display:flex;"><span> led_mask,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, bytes(command), <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Set LED Mask: 0x</span><span style="color:#e6db74">{</span>led_mask<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">connect_usb</span>():
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Searching for Nintendo Switch Controllers...&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">match_device</span>(dev):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> dev<span style="color:#f92672">.</span>idVendor <span style="color:#f92672">==</span> VENDOR_ID <span style="color:#f92672">and</span> dev<span style="color:#f92672">.</span>idProduct <span style="color:#f92672">in</span> PRODUCT_IDS
</span></span><span style="display:flex;"><span> dev <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>find(custom_match<span style="color:#f92672">=</span>match_device)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">&#34;Device not found&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> product_name <span style="color:#f92672">=</span> PRODUCT_IDS<span style="color:#f92672">.</span>get(dev<span style="color:#f92672">.</span>idProduct, <span style="color:#e6db74">&#34;Unknown Device&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found </span><span style="color:#e6db74">{</span>product_name<span style="color:#e6db74">}</span><span style="color:#e6db74"> (ID: </span><span style="color:#e6db74">{</span>dev<span style="color:#f92672">.</span>idProduct<span style="color:#e6db74">:</span><span style="color:#e6db74">04x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev<span style="color:#f92672">.</span>is_kernel_driver_active(USB_INTERFACE_NUMBER):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Detaching kernel driver...&#34;</span>)
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>detach_kernel_driver(USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not detach kernel driver: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>set_configuration()
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Configuration set.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error setting configuration: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>claim_interface(dev, USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Interface </span><span style="color:#e6db74">{</span>USB_INTERFACE_NUMBER<span style="color:#e6db74">}</span><span style="color:#e6db74"> claimed.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not claim interface: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> cfg <span style="color:#f92672">=</span> dev<span style="color:#f92672">.</span>get_active_configuration()
</span></span><span style="display:flex;"><span> intf <span style="color:#f92672">=</span> cfg[(USB_INTERFACE_NUMBER,<span style="color:#ae81ff">0</span>)]
</span></span><span style="display:flex;"><span> ep_out <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_OUT)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> ep_in <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_IN
</span></span><span style="display:flex;"><span> )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> ep_out:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">&#34;Could not find OUT endpoint&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found Endpoint OUT: 0x</span><span style="color:#e6db74">{</span>ep_out<span style="color:#f92672">.</span>bEndpointAddress<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Starting Initialization Sequence...&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, <span style="color:#e6db74">&#34;Init 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, <span style="color:#e6db74">&#34;Unknown 0x07&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, <span style="color:#e6db74">&#34;Unknown 0x16&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, <span style="color:#e6db74">&#34;Req MAC&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, LTK_REQUEST, <span style="color:#e6db74">&#34;Req LTK&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, <span style="color:#e6db74">&#34;Unknown 0x15&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, <span style="color:#e6db74">&#34;Unknown 0x09&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, <span style="color:#e6db74">&#34;IMU 0x02&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, <span style="color:#e6db74">&#34;OUT Unknown 0x11&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, <span style="color:#e6db74">&#34;Unknown 0x0A&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, <span style="color:#e6db74">&#34;IMU 0x04&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, <span style="color:#e6db74">&#34;Enable Haptics&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, <span style="color:#e6db74">&#34;OUT Unknown 0x10&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, <span style="color:#e6db74">&#34;OUT Unknown 0x01&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, <span style="color:#e6db74">&#34;OUT Unknown 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, <span style="color:#e6db74">&#34;OUT Unknown 0x0A Alt&#34;</span>)
</span></span><span style="display:flex;"><span> set_player_leds(ep_out, ep_in, <span style="color:#ae81ff">0x0F</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Controller initialization sequence complete! All LEDs should be on.&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error during sequence: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> connect_usb()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">ValueError</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(e)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Unexpected error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></div><p><strong>Steps</strong></p></description> + </item> + </channel> +</rss> diff --git a/micro.pinapelz.moe/tags/index.html b/micro.pinapelz.moe/tags/index.html index b93480a..334960f 100644 --- a/micro.pinapelz.moe/tags/index.html +++ b/micro.pinapelz.moe/tags/index.html @@ -75,8 +75,12 @@ <li><a href="/tags/arcade/">Arcade</a></li> + <li><a href="/tags/code/">Code</a></li> + <li><a href="/tags/default/">Default</a></li> + <li><a href="/tags/nintendo/">Nintendo</a></li> + </ul> </div> </main> diff --git a/micro.pinapelz.moe/tags/index.xml b/micro.pinapelz.moe/tags/index.xml index 18a2584..a8fb41c 100644 --- a/micro.pinapelz.moe/tags/index.xml +++ b/micro.pinapelz.moe/tags/index.xml @@ -8,9 +8,23 @@ <language>en-us</language> <managingEditor>yukais@pinapelz.com (Pinapelz)</managingEditor> <webMaster>yukais@pinapelz.com (Pinapelz)</webMaster> - <lastBuildDate>Wed, 03 Dec 2025 19:38:52 -0800</lastBuildDate> + <lastBuildDate>Thu, 04 Dec 2025 23:19:29 -0800</lastBuildDate> <atom:link href="https://micro.pinapelz.moe/tags/index.xml" rel="self" type="application/rss+xml" /> <item> + <title>Code</title> + <link>https://micro.pinapelz.moe/tags/code/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/tags/code/</guid> + <description></description> + </item> + <item> + <title>Nintendo</title> + <link>https://micro.pinapelz.moe/tags/nintendo/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/tags/nintendo/</guid> + <description></description> + </item> + <item> <title>Anime</title> <link>https://micro.pinapelz.moe/tags/anime/</link> <pubDate>Wed, 03 Dec 2025 19:38:52 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> diff --git a/micro.pinapelz.moe/tags/nintendo/index.html b/micro.pinapelz.moe/tags/nintendo/index.html new file mode 100644 index 0000000..3680dcf --- /dev/null +++ b/micro.pinapelz.moe/tags/nintendo/index.html @@ -0,0 +1,106 @@ +<!DOCTYPE html> +<html lang="en-us"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <style type=text/css>body{font-family:monospace;}</style> + <title>Nintendo | micro.pinapelz.moe</title> + + <meta name="author" content="map[avatar:https://files.catbox.moe/5r1pue.jpg banner:https://files.pinapelz.com/pso2ngs-2232-collab.png bio:yo! and he's more than a cover he's a quilt<br/> + General arcade rhythm game enjoyer (SDVX, IIDX, CHUNITHM)<br/> + Mostly play MMOs (FFXIV, OSRS), JRPGs, and VNs (anything with a good story)<br/> + I Watch only slice of life (and Bandori)<br/> + Arch Linux + Hyprland user (btw)<br/> + Hi from the <a href="https://indieweb.org/">indieweb</a>, if you are seeing me bridged elsewhere! email:yukais@pinapelz.com name:Pinapelz]"> + <link rel="stylesheet" href="/css/style.css"> + <link rel="alternate" type="application/rss+xml" href="/tags/nintendo/index.xml" title="micro.pinapelz.moe"> + + + <link rel="me" href="https://github.com/pinapelz" /> + <link rel="me" href="mailto:yukais@pinapelz.com" /> + <link rel="me" href="https://sakurajima.social/@pinapelz" /> + <link rel="me" href="https://bsky.app/profile/pinapelz.moe" /><link rel="pgpkey" href="https://pinapelz.com/Yukai_Shan.asc"> + <link + rel="authorization_endpoint" + href="https://indieauth.com/auth" + /> + <link + rel="token_endpoint" + href="https://tokens.indieauth.com/token" + /> + <link rel="webmention" href="https://webmention.io/micro.pinapelz.moe/webmention" /> + + + +</head> +<body> + <header> + <div style="display:flex;flex-flow:row wrap;justify-content:space-between"> + <div style="align-self:flex-start;"> + ==============<br> + == <a href="https://micro.pinapelz.moe/">Pinapelz</a> ==<br> + ============== + </div> + <div style="align-self:center;">check it out. I'm in the house like carpet</div> + </div> + <nav style="margin: 1rem auto;"> + + + <a href="/posts/"><b>Posts</b></a>. + + <a href="/categories/"><b>Categories</b></a>. + + <a href="/tags/"><b>Tags</b></a>. + + + </nav> +</header> + + + +<main> + <div> + <h1> + Nintendo + <a href="https://micro.pinapelz.moe/tags/nintendo/index.xml"> + <img style="height:1.5rem; display: inline;" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-label='RSS' role='img' viewBox='0 0 512 512'%3E%3Cpath d='M0 0h512v512H0' fill='%23f80'/%3E%3Cpath d='M109 271A132 133 0 0 1 241 403h60A192 193 0 0 0 109 211v-54A246 247 0 0 1 355 403h60A306 307 0 0 0 109 97m35 235a35 35 0 1 0 2 0' fill='%23fff'/%3E%3C/svg%3E" alt="RSS icon" /> + </a> + </h1> + <div> + + </div><p>Content linked to the taxonomy term « NINTENDO »:</p> + + + + + <div> + <h3>Posts</h3> + <ul> + + <li> + <time class="date dt-published" datetime="2025-12-04T23:19:29-08:00">2025-12-04</time> + <a href="/posts/2025-12-04-procon2-hid-tool/">Enable HID Mode on Nintendo Pro Controller 2</a> + </li> + + + </ul> + </div></div> +</main> + + <hr /> +<footer> + <p> + <a href="https://github.com/pinapelz"><b>Github</b></a>. + <a href="https://pinapelz.moe"><b>pinapelz.moe</b></a>. + </p> + + + + <p style="text-align: center" class="copyright"> + © <a href="https://micro.pinapelz.moe/"><b>micro.pinapelz.moe</b></a>. + </p> +</footer> + +</body> +</html> diff --git a/micro.pinapelz.moe/tags/nintendo/index.xml b/micro.pinapelz.moe/tags/nintendo/index.xml new file mode 100644 index 0000000..75a6acd --- /dev/null +++ b/micro.pinapelz.moe/tags/nintendo/index.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> + <channel> + <title>Nintendo on micro.pinapelz.moe</title> + <link>https://micro.pinapelz.moe/tags/nintendo/</link> + <description>Recent content in Nintendo on micro.pinapelz.moe</description> + <generator>Hugo</generator> + <language>en-us</language> + <managingEditor>yukais@pinapelz.com (Pinapelz)</managingEditor> + <webMaster>yukais@pinapelz.com (Pinapelz)</webMaster> + <lastBuildDate>Thu, 04 Dec 2025 23:19:29 -0800</lastBuildDate> + <atom:link href="https://micro.pinapelz.moe/tags/nintendo/index.xml" rel="self" type="application/rss+xml" /> + <item> + <title>Enable HID Mode on Nintendo Pro Controller 2</title> + <link>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</link> + <pubDate>Thu, 04 Dec 2025 23:19:29 -0800</pubDate><author>yukais@pinapelz.com (Pinapelz)</author> + <guid>https://micro.pinapelz.moe/posts/2025-12-04-procon2-hid-tool/</guid> + <description><p>Switch 2 Pro Controller is very comfy in my hands, but unfortunately it didn&rsquo;t work out of box on PC (Linux) for me like it&rsquo;s predacessor. Until there&rsquo;s actual better driver support for this thing in the kernel (or Valve does something), here&rsquo;s a hacky Python script to initialize HID-mode on the controller</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># I only tested this script on Linux w/ Steam but in theory it shoud work on Windows?</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.core <span style="color:#75715e"># install pyusb first: pip install pyusb</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> usb.util
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> time
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> sys
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>VENDOR_ID <span style="color:#f92672">=</span> <span style="color:#ae81ff">0x057E</span>
</span></span><span style="display:flex;"><span>PRODUCT_IDS <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2066</span>: <span style="color:#e6db74">&#34;Joy-Con (L)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2067</span>: <span style="color:#e6db74">&#34;Joy-Con (R)&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2069</span>: <span style="color:#e6db74">&#34;Pro Controller&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x2073</span>: <span style="color:#e6db74">&#34;GCN Controller&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>USB_INTERFACE_NUMBER <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>INIT_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0d</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x07 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x16 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x16</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>REQUEST_CONTROLLER_MAC <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0e</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>LTK_REQUEST <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>, <span style="color:#ae81ff">0xFF</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x15_ARG_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x15</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x09 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x02 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x11 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x11</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>UNKNOWN_COMMAND_0x0A <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x14</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0xff</span>, <span style="color:#ae81ff">0x35</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x46</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>IMU_COMMAND_0x04 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x27</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>ENABLE_HAPTICS <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x10 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x10</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x01 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x0c</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x03 <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x01</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>OUT_UNKNOWN_COMMAND_0x0A_ALT <span style="color:#f92672">=</span> bytes([<span style="color:#ae81ff">0x0a</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x02</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x04</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x03</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_usb_data</span>(ep_out, ep_in, data, description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;&#34;</span>):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> ep_out<span style="color:#f92672">.</span>write(data)
</span></span><span style="display:flex;"><span> time<span style="color:#f92672">.</span>sleep(<span style="color:#ae81ff">0.01</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> response <span style="color:#f92672">=</span> ep_in<span style="color:#f92672">.</span>read(<span style="color:#ae81ff">32</span>, timeout<span style="color:#f92672">=</span><span style="color:#ae81ff">100</span>)
</span></span><span style="display:flex;"><span> hex_resp <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34; &#34;</span><span style="color:#f92672">.</span>join([<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{</span>x<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#66d9ef">for</span> x <span style="color:#f92672">in</span> response])
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Response: </span><span style="color:#e6db74">{</span>hex_resp<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> e<span style="color:#f92672">.</span>errno <span style="color:#f92672">==</span> <span style="color:#ae81ff">110</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] No response (Timeout)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Read Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;[</span><span style="color:#e6db74">{</span>description<span style="color:#e6db74">}</span><span style="color:#e6db74">] Write Error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">set_player_leds</span>(ep_out, ep_in, led_mask):
</span></span><span style="display:flex;"><span> command <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x09</span>, <span style="color:#ae81ff">0x91</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x07</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x08</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>,
</span></span><span style="display:flex;"><span> led_mask,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>, <span style="color:#ae81ff">0x00</span>
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, bytes(command), <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Set LED Mask: 0x</span><span style="color:#e6db74">{</span>led_mask<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">connect_usb</span>():
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Searching for Nintendo Switch Controllers...&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">match_device</span>(dev):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> dev<span style="color:#f92672">.</span>idVendor <span style="color:#f92672">==</span> VENDOR_ID <span style="color:#f92672">and</span> dev<span style="color:#f92672">.</span>idProduct <span style="color:#f92672">in</span> PRODUCT_IDS
</span></span><span style="display:flex;"><span> dev <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>find(custom_match<span style="color:#f92672">=</span>match_device)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">raise</span> <span style="color:#a6e22e">ValueError</span>(<span style="color:#e6db74">&#34;Device not found&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> product_name <span style="color:#f92672">=</span> PRODUCT_IDS<span style="color:#f92672">.</span>get(dev<span style="color:#f92672">.</span>idProduct, <span style="color:#e6db74">&#34;Unknown Device&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found </span><span style="color:#e6db74">{</span>product_name<span style="color:#e6db74">}</span><span style="color:#e6db74"> (ID: </span><span style="color:#e6db74">{</span>dev<span style="color:#f92672">.</span>idProduct<span style="color:#e6db74">:</span><span style="color:#e6db74">04x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">)&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> dev<span style="color:#f92672">.</span>is_kernel_driver_active(USB_INTERFACE_NUMBER):
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Detaching kernel driver...&#34;</span>)
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>detach_kernel_driver(USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not detach kernel driver: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> dev<span style="color:#f92672">.</span>set_configuration()
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Configuration set.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error setting configuration: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>claim_interface(dev, USB_INTERFACE_NUMBER)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Interface </span><span style="color:#e6db74">{</span>USB_INTERFACE_NUMBER<span style="color:#e6db74">}</span><span style="color:#e6db74"> claimed.&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> usb<span style="color:#f92672">.</span>core<span style="color:#f92672">.</span>USBError <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Could not claim interface: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> cfg <span style="color:#f92672">=</span> dev<span style="color:#f92672">.</span>get_active_configuration()
</span></span><span style="display:flex;"><span> intf <span style="color:#f92672">=</span> cfg[(USB_INTERFACE_NUMBER,<span style="color:#ae81ff">0</span>)]
</span></span><span style="display:flex;"><span> ep_out <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_OUT)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> ep_in <span style="color:#f92672">=</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>find_descriptor(
</span></span><span style="display:flex;"><span> intf,
</span></span><span style="display:flex;"><span> custom_match <span style="color:#f92672">=</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">lambda</span> e: usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>endpoint_direction(e<span style="color:#f92672">.</span>bEndpointAddress) <span style="color:#f92672">==</span> usb<span style="color:#f92672">.</span>util<span style="color:#f92672">.</span>ENDPOINT_IN
</span></span><span style="display:flex;"><span> )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">not</span> ep_out:
</span></span><span style="display:flex;"><span> sys<span style="color:#f92672">.</span>exit(<span style="color:#e6db74">&#34;Could not find OUT endpoint&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Found Endpoint OUT: 0x</span><span style="color:#e6db74">{</span>ep_out<span style="color:#f92672">.</span>bEndpointAddress<span style="color:#e6db74">:</span><span style="color:#e6db74">02x</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Starting Initialization Sequence...&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, INIT_COMMAND_0x03, <span style="color:#e6db74">&#34;Init 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x07, <span style="color:#e6db74">&#34;Unknown 0x07&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x16, <span style="color:#e6db74">&#34;Unknown 0x16&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, REQUEST_CONTROLLER_MAC, <span style="color:#e6db74">&#34;Req MAC&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, LTK_REQUEST, <span style="color:#e6db74">&#34;Req LTK&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x15_ARG_0x03, <span style="color:#e6db74">&#34;Unknown 0x15&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x09, <span style="color:#e6db74">&#34;Unknown 0x09&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x02, <span style="color:#e6db74">&#34;IMU 0x02&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x11, <span style="color:#e6db74">&#34;OUT Unknown 0x11&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, UNKNOWN_COMMAND_0x0A, <span style="color:#e6db74">&#34;Unknown 0x0A&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, IMU_COMMAND_0x04, <span style="color:#e6db74">&#34;IMU 0x04&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, ENABLE_HAPTICS, <span style="color:#e6db74">&#34;Enable Haptics&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x10, <span style="color:#e6db74">&#34;OUT Unknown 0x10&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x01, <span style="color:#e6db74">&#34;OUT Unknown 0x01&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x03, <span style="color:#e6db74">&#34;OUT Unknown 0x03&#34;</span>)
</span></span><span style="display:flex;"><span> send_usb_data(ep_out, ep_in, OUT_UNKNOWN_COMMAND_0x0A_ALT, <span style="color:#e6db74">&#34;OUT Unknown 0x0A Alt&#34;</span>)
</span></span><span style="display:flex;"><span> set_player_leds(ep_out, ep_in, <span style="color:#ae81ff">0x0F</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">&#34;Controller initialization sequence complete! All LEDs should be on.&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Error during sequence: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span> connect_usb()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">ValueError</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(e)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span> print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Unexpected error: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span></code></pre></div><p><strong>Steps</strong></p></description> + </item> + </channel> +</rss> |
