0

Writing Bytes (in Hex) to USB with Pico?
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Writing Bytes (in Hex) to USB with Pico?

by geekinchief on Wed Feb 17, 2021 11:45 am

So my quest to make my Pico emulate a Switch controller continues. So I found the list of hex bytes that a real Switch Pro controller sends via USB and I want to get my Pico, using CP (or MP if nec), to send the same list of hex bytes over USB. I'm not sure what function to use to write directly to the USB port. Is it the UART function in CP or serial.write in MP?

geekinchief
 
Posts: 25
Joined: Wed Dec 28, 2016 2:01 am

Re: Writing Bytes (in Hex) to USB with Pico?

by tannewt on Wed Feb 17, 2021 12:31 pm

How are the bytes being sent via USB? There are CDC and HID interfaces that could be used. Please post to a link to the code you are trying to reimplement.

tannewt
 
Posts: 2189
Joined: Thu Oct 06, 2016 8:48 pm

Re: Writing Bytes (in Hex) to USB with Pico?

by geekinchief on Wed Feb 17, 2021 12:52 pm

Should be done via HID. So I've used the gamepad HID from CP and it works in Windows with no problem, but the Switch doesn't recognize it, even as I've mapped the button numbers to be the same ones that my Switch Pro Controller (wired USB) uses. So I installed a program called Device Monitoring Studio on my PC and logged every signal that my actual wired controller sends. Here's what it shows:

wired-fight.png
wired-fight.png (101.6 KiB) Viewed 84 times


So it sends 8 hex bytes to the computer (or switch) and, for each action, it appears to send twice (presumably one for the press and once for the release). This is hitting the A button:

Code: Select all | TOGGLE FULL SIZE
Pipe Handle: 0xa34bc70 (Endpoint Address: 0x81)
Get 0x8 bytes from the device
04 00 0F 80 80 80 80 00                           ...€€€€.


Now when I use HID gamepad in CP sending the same button, it sends:
Code: Select all | TOGGLE FULL SIZE
Pipe Handle: 0x14615c80 (Endpoint Address: 0x84)
Get 0x7 bytes from the device
04 04 00 00 00 00 00                              .......


So I how do I get my Pico to send the same thing that the actual Switch Pro Controller sends? I have looked at the CP source code and the USB HID descriptor file, but don't see a way to change the codes it sends.

geekinchief
 
Posts: 25
Joined: Wed Dec 28, 2016 2:01 am

Re: Writing Bytes (in Hex) to USB with Pico?

by tannewt on Wed Feb 17, 2021 1:04 pm

It sounds like you want to do the send_report directly from here: https://github.com/adafruit/Adafruit_Ci ... #L127-L145

tannewt
 
Posts: 2189
Joined: Thu Oct 06, 2016 8:48 pm

Re: Writing Bytes (in Hex) to USB with Pico?

by geekinchief on Wed Feb 17, 2021 5:00 pm

Thanks. That link is very helpful. I'm trying to figure one thing out. So in gamepad.py, it creates a byte array called self._report and uses the method send_report to send it to USB. Even though the byte array has six items, my USB detector always gets a first byte that's 04. Is this part of the send_report method and, if so, any idea where I'd find the code for send_report so I could try to remove that first number. I need to end up with 8 hex codes and the first one should not always be 04.

geekinchief
 
Posts: 25
Joined: Wed Dec 28, 2016 2:01 am

Re: Writing Bytes (in Hex) to USB with Pico?

by geekinchief on Wed Feb 17, 2021 11:48 pm

So, since send_report seems like it has to send a device code as a prefix (which Switch doesn't want), I'm wondering if there's a way to just write whatever hex codes I want to USB in CP. In MicroPython, I found a way to do this and it is:

sys.stdout.buffer.write(BYTEBUFFER)

Is there an equivalent in CP? I can't find one.

geekinchief
 
Posts: 25
Joined: Wed Dec 28, 2016 2:01 am

Re: Writing Bytes (in Hex) to USB with Pico?

by tannewt on Thu Feb 18, 2021 3:23 pm

geekinchief wrote:So, since send_report seems like it has to send a device code as a prefix (which Switch doesn't want), I'm wondering if there's a way to just write whatever hex codes I want to USB in CP.


I don't know the details of the HID protocol. Usually the first byte is used as a length or type code. I doubt you actually need control of it. Instead, I suspect you need to change the report bytes after it.

geekinchief wrote:In MicroPython, I found a way to do this and it is:

sys.stdout.buffer.write(BYTEBUFFER)

Is there an equivalent in CP? I can't find one.


I *highly* doubt this is what you need. It will send the exact bytes you want but over the USB CDC protocol, not HID. I'd suggest looking into Wireshark to capture USB traffic too. It should be able to distinguish CDC from HID.


I think send_report is what you need. You can see the native usb_hid API docs here: https://circuitpython.readthedocs.io/en ... index.html You may also need to change the HID report descriptor: https://github.com/adafruit/circuitpyth ... rs.py#L160 You'll need to build CircuitPython to do that now.

tannewt
 
Posts: 2189
Joined: Thu Oct 06, 2016 8:48 pm

Re: Writing Bytes (in Hex) to USB with Pico?

by geekinchief on Thu Feb 18, 2021 3:54 pm

Thanks. Is there more extensive documentation. For send_report or the code for it? I searched the circuitpython source code and the only references I saw to it were in C files not CircuitPythin?

geekinchief
 
Posts: 25
Joined: Wed Dec 28, 2016 2:01 am

Re: Writing Bytes (in Hex) to USB with Pico?

by tannewt on Fri Feb 19, 2021 9:21 pm

What I linked to is what we have for CircuitPython. I'd recommend looking at the USB HID spec to understand report structure. I think it's freely available on usb.org. USB Complete is a good book for understanding USB too.

tannewt
 
Posts: 2189
Joined: Thu Oct 06, 2016 8:48 pm

Please be positive and constructive with your questions and comments.