USB Host Shield 2.0
SwitchProUSB.h
Go to the documentation of this file.
1 /* Copyright (C) 2021 Kristian Sloth Lauszus. All rights reserved.
2 
3  This software may be distributed and modified under the terms of the GNU
4  General Public License version 2 (GPL2) as published by the Free Software
5  Foundation and appearing in the file GPL2.TXT included in the packaging of
6  this file. Please note that GPL2 Section 2[b] requires that all works based
7  on this software must also be made publicly available under the terms of
8  the GPL2 ("Copyleft").
9 
10  Contact information
11  -------------------
12 
13  Kristian Sloth Lauszus
14  Web : https://lauszus.com
15  e-mail : lauszus@gmail.com
16  */
17 
18 #ifndef _switch_pro_usb_h_
19 #define _switch_pro_usb_h_
20 
21 #include "hiduniversal.h"
22 #include "SwitchProParser.h"
23 
24 #define SWITCH_PRO_VID 0x057E // Nintendo Corporation
25 #define SWITCH_PRO_PID 0x2009 // Switch Pro Controller
26 
31 class SwitchProUSB : public HIDUniversal, public SwitchProParser {
32 public:
38  HIDUniversal(p) {
40  };
41 
46  bool connected() {
48  };
49 
54  void attachOnInit(void (*funcOnInit)(void)) {
55  pFuncOnInit = funcOnInit;
56  };
57 
58 protected:
67  virtual void ParseHIDData(USBHID *hid __attribute__((unused)), bool is_rpt_id __attribute__((unused)), uint8_t len, uint8_t *buf) {
69  SwitchProParser::Parse(len, buf);
70  };
71 
77  virtual uint8_t OnInitSuccessful() {
80 
81  // We need to send a handshake and disable the timeout or the Pro controller will stop sending data via USB
82  // We can not send the commands quickly after each other, so we simply send out the commands at the same
83  // rate as the controller is sending data
85 
86  if (pFuncOnInit)
87  pFuncOnInit(); // Call the user function
88  else {
89  setLedOn(LED1); // Turn on the LED1
90  setLedHomeOn(); // Turn on the home LED
91  }
92  }
93  return 0;
94  };
98  virtual void sendOutputReport(uint8_t *data, uint8_t len) {
99  // Based on: https://github.com/Dan611/hid-procon
100  // The first 8 bytes are always the same. The actual report follows
101  uint8_t buf[8 + len];
102  buf[0] = 0x80; // PROCON_REPORT_SEND_USB
103  buf[1] = 0x92; // PROCON_USB_DO_CMD
104  buf[2] = 0x00;
105  buf[3] = 0x31;
106  buf[4] = 0x00;
107  buf[5] = 0x00;
108  buf[6] = 0x00;
109  buf[7] = 0x00;
110 
111  // Cope over the report
112  memcpy(buf + 8, data, len);
113 
114  // Endpoint (control endpoint), Interface (0x00), Report Type (Output 0x02), Report ID (0x80), nbytes, data
115  SetReport(epInfo[0].epAddr, 0, 0x02, buf[0], sizeof(buf), buf);
116  };
117 
118  virtual void sendHandshake() {
120 
121  // See: https://github.com/Dan611/hid-procon/blob/master/hid-procon.c
122  // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/USB-HID-Notes.md
123  uint8_t buf[2] = { 0x80 /* PROCON_REPORT_SEND_USB */, 0x02 /* PROCON_USB_HANDSHAKE */ };
124 
125  // Endpoint (control endpoint), Interface (0x00), Report Type (Output 0x02), Report ID (0x80), nbytes, data
126  SetReport(epInfo[0].epAddr, 0, 0x02, buf[0], sizeof(buf), buf);
127  };
128 
129  virtual void disableTimeout() {
131 
132  // See: https://github.com/Dan611/hid-procon/blob/master/hid-procon.c
133  // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/USB-HID-Notes.md
134  uint8_t buf[2] = { 0x80 /* PROCON_REPORT_SEND_USB */, 0x04 /* PROCON_USB_ENABLE */ };
135 
136  // Endpoint (control endpoint), Interface (0x00), Report Type (Output 0x02), Report ID (0x80), nbytes, data
137  SetReport(epInfo[0].epAddr, 0, 0x02, buf[0], sizeof(buf), buf);
138  };
148  virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
149  return (vid == SWITCH_PRO_VID && pid == SWITCH_PRO_PID);
150  };
153 private:
154  void (*pFuncOnInit)(void); // Pointer to function called in onInit()
155 };
156 #endif
#define SWITCH_PRO_PID
Definition: SwitchProUSB.h:25
#define SWITCH_PRO_VID
Definition: SwitchProUSB.h:24
uint16_t PID
Definition: hidcomposite.h:71
virtual bool isReady()
Definition: hidcomposite.h:99
EpInfo epInfo[totalEndpoints]
Definition: hidcomposite.h:63
uint16_t VID
Definition: hidcomposite.h:71
void setLedOn(LEDEnum a)
void Parse(uint8_t len, uint8_t *buf)
SwitchProOutput switchProOutput
void attachOnInit(void(*funcOnInit)(void))
Definition: SwitchProUSB.h:54
virtual void disableTimeout()
Definition: SwitchProUSB.h:129
virtual void sendOutputReport(uint8_t *data, uint8_t len)
Definition: SwitchProUSB.h:98
virtual bool VIDPIDOK(uint16_t vid, uint16_t pid)
Definition: SwitchProUSB.h:148
virtual uint8_t OnInitSuccessful()
Definition: SwitchProUSB.h:77
bool connected()
Definition: SwitchProUSB.h:46
virtual void sendHandshake()
Definition: SwitchProUSB.h:118
SwitchProUSB(USB *p)
Definition: SwitchProUSB.h:37
virtual void ParseHIDData(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
Definition: SwitchProUSB.h:67
Definition: usbhid.h:143
uint8_t SetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t *dataptr)
Definition: usbhid.cpp:50
Definition: UsbCore.h:212
@ LED1