Jump to content
IGNORED

USB is coming to the Inty


JohnPCAE

Recommended Posts

This project is only in its infancy, but it's happening. What you see here is an experimental board that's talking to the Inty about connected USB devices. So far I only have it telling the Intellivision how many devices are connected, but it's only been 24 hours of work. This is nowhere near the final version of the board's layout, but as you can see it's going to be very simple: only three level-shifter ICs, a power MOSFET, and a Pi Pico (and a few passives for a nice clean power rail). The plan is to support (at the very least) keyboards, mice, and gamepads, and if I'm very lucky, mass-storage devices. It's theoretically possible to also add Wifi with a Pi Pico W, and a real-time clock using spare I2C pins.

 

In this picture, it's not my Logitech mouse that's plugged in, but a 4-port USB hub (yes, you can use a hub). And I was testing with a USB gamepad. I've already tested the software with an earlier standalone unit so I already know it can handle a mouse and keyboard plugged in at the same time.

 

In terms of the Inty's memory map, it takes over addresses $007C and $007D, and like the ACC uses a register array. $007C is where you set the register index and $007D is where you read or write the register value. Also like the ACC, one of the registers is a read-only signature register where a magic value tells you if the unit is plugged in.

 

IMG_2204.JPG

Edited by JohnPCAE
  • Like 12
Link to comment
Share on other sites

Making progress. I have mouse and keyboard events making it to the Inty. There's also a keyboard event buffer that is set to 16 events for now. You can connect multiple keyboards and mice if you really want (I allow a maximum of 16 devices). Next I'll look into gamepads.

Edited by JohnPCAE
Link to comment
Share on other sites

A little more progress. I have data from a Microsoft Sidewinder and an N64 controller (using USB adapters) getting to the Inty. Both are classified as USB HID Joysticks (as opposed to HID gamepads which sends different data). So theoretically, anything classified as a HID joystick should work. I have a couple of other controllers I can test tomorrow, one of which is an MS flight stick. I put in code to process data from HID gamepads as well, but I might not have anything to test it.

Edited by JohnPCAE
Link to comment
Share on other sites

My Logitech Wingman and Microsoft flightstick work (both are also classified as HID joysticks). That only leaves a custom arcade stick I bought a long time ago that's based on an old XBox 360 controller. That doesn't show up at all, so I'll investigate it. It would be cool if it supported original XBox 360 controllers.

 

It's worth pointing out that all USB joysticks require calibration, so any Inty games that support them will have to provide people with a calibration screen. It would be cool if they also saved calibration info to cart storage. One thing I'll look into is supplying the Inty with the USB VID (vendor ID) and PID (product ID) for any controllers to make looking up precalibrated data possible.

Edited by JohnPCAE
Link to comment
Share on other sites

I don't know what protocol XBox 360 controllers use, but the original XBox controllers used a proprietary Microsoft protocol called XID.  However, it is easy to create a driver for it since XID uses fixed-format packets that are HID-like.  To support them, either 1) parse the raw packets yourself or 2) create a fake HID descriptor that describes the fixed-format packet and feed it into the existing HID joystick driver.

 

I recommend adding support for the original XBox controller only if it is easy for you to implement.

 

https://xboxdevwiki.net/Xbox_Input_Devices

Link to comment
Share on other sites

That explains why TinyUSB isn't even seeing it mounted. It's not even calling the HID mount callback routine. I think I'll just skip that controller then and move on to diagnosing detecting devices that are already plugged in. It detects a device if you plug it in after the Inty is powered up, but it's not seeing devices that were already plugged in. I could have sworn that was working earlier.

 

I'm also wondering if I can store calibration data in the Pi Pico's flash memory. I don't know if it's feasible but that would mean that calibration could be persistent across game sessions and even from one game to another.

 

Edit...Aha. It's the hub. If it's already plugged into the hub then the software in the Pico gets confused. But if it's already plugged in directly without a hub it works fine. So that's something else to investigate. That might be a TinyUSB issue.

Edited by JohnPCAE
Link to comment
Share on other sites

This is untested, but I've added code to load/save 4k (2k words) of calibration data to the Pi Pico's flash memory. So theoretically a game could read the VID and PID of a controller, load the calibration data, and if there isn't a block for that controller somewhere in the data, let players calibrate their controller and save it to flash (or let them recalibrate whenever they want). The nice thing is that the calibration data would be persistent across sessions and even games. We would all have to agree on a memory layout standard for calibration data though. The memory area is large enough that it could store calibration data for many controllers at once. It's probably enough to store data for as many controllers as any of us could ever own.

Edited by JohnPCAE
Link to comment
Share on other sites

I've figured out how to set the LED's on a keyboard and I've added some initial code for mass-storage devices (you can get some basic info like block size and number of blocks). I've also started looking at MIDI device support, but this might be difficult since I don't have any.

 

As for mass-storage devices, dealing with device format (FAT16, FAT32, NTFS, etc.) will be outside the scope of this project. I plan to let the Inty read or write raw data but interpreting the format will be up to Inty software. I'm providing an 8k shared memory area that can be used for anything requiring a buffer (controller calibration, mass storage data, etc.). You access it via a couple of registers: data pointer and data value. Reading or writing to the data value register auto-increments the data pointer.

Edited by JohnPCAE
Link to comment
Share on other sites

On 11/11/2022 at 3:03 AM, JohnPCAE said:

This is untested, but I've added code to load/save 4k (2k words) of calibration data to the Pi Pico's flash memory. So theoretically a game could read the VID and PID of a controller, load the calibration data, and if there isn't a block for that controller somewhere in the data, let players calibrate their controller and save it to flash (or let them recalibrate whenever they want). The nice thing is that the calibration data would be persistent across sessions and even games. We would all have to agree on a memory layout standard for calibration data though. The memory area is large enough that it could store calibration data for many controllers at once. It's probably enough to store data for as many controllers as any of us could ever own.

If you have access to the device's serial number (not all USB devices include this), that would be the best way to know what calibration data goes with which device.  Falling back to using VID/PID is so-so since it is likely the user only owns 1 of that particular make/model and a production run of a make/model would likely have similar calibration offsets.

Link to comment
Share on other sites

13 minutes ago, JohnPCAE said:

Hmm. TinyUSB doesn't yet have a host-mode driver for USB audio devices, so MIDI won't be happening for now. But at least HID devices are working and I've completed putting in code for mass-storage devices, though that's still untested.

Check for a MIDI-specific driver since that protocol is audio-related but not audio itself.  By itself, MIDI just transmits sheet music (i.e. what notes to play when on which instrument) but not the audio itself.  This is why the pre-USB MIDI cable just transmits at 31Kbps.  The USB version of the MIDI protocol is fairly simple.

Link to comment
Share on other sites

11 minutes ago, Lathe26 said:

If you have access to the device's serial number (not all USB devices include this), that would be the best way to know what calibration data goes with which device.  Falling back to using VID/PID is so-so since it is likely the user only owns 1 of that particular make/model and a production run of a make/model would likely have similar calibration offsets.

I'm not suggesting that we would supply calibration data but only that when people calibrated their controllers the VID and PID would be stored along with the calibration data in flash. That way it could be retrieved at a later time by either the same or a different game and matched with the controller. The idea is that if a person has multiple USB controllers of different types it could match the correct calibration data with the correct controller.

Link to comment
Share on other sites

35 minutes ago, JohnPCAE said:

I'm not suggesting that we would supply calibration data but only that when people calibrated their controllers the VID and PID would be stored along with the calibration data in flash. That way it could be retrieved at a later time by either the same or a different game and matched with the controller. The idea is that if a person has multiple USB controllers of different types it could match the correct calibration data with the correct controller.

I think @Lathe26 is saying, what if you have two controllers that need different calibrations, but they have the same VID/PID?  This is an issue with RetroPi when you want different controller mapping due to the controllers being different but they have the same PID.

  • Like 1
Link to comment
Share on other sites

3 hours ago, JohnPCAE said:

I'm not suggesting that we would supply calibration data but only that when people calibrated their controllers the VID and PID would be stored along with the calibration data in flash. That way it could be retrieved at a later time by either the same or a different game and matched with the controller. The idea is that if a person has multiple USB controllers of different types it could match the correct calibration data with the correct controller.

I wasn't suggesting supplying the calibration data either.  The idea is when people calibrate their controllers the VID and PID USB serial number would be stored along with the calibration data in flash.  Only use the VID/PID as a backup alternative if the USB serial number isn't available for that particular device.

  • Like 1
Link to comment
Share on other sites

19 hours ago, JohnPCAE said:

I see. It looks like the serial number is a single byte. I can add a routine to TinyUSB to retrieve it and store that as well as the VID and PID.

It is a variable length string that can be a max of 253 bytes long (limit set by USB descriptor length max).  It should be UTF-16-LE string encoded (i.e. each character is 16-bits wide, little-endian).  You can either store it as string or as a byte array, whichever is easier.

Link to comment
Share on other sites

I had to add some code to TinyUSB but I have it properly mounting my 4GB USB stick now. It doesn't like my 8GB stick, though. I'm not sure why. I'm getting DEVICE_ATTACH and DEVICE_REMOVE events but no other events from it. I'm specifically looking for a XFER_COMPLETE event but not getting any.

Edited by JohnPCAE
Link to comment
Share on other sites

Well, well. Someone has added a MIDI host driver to a fork of TinyUSB:

 

https://github.com/rppicomidi/tinyusb/tree/pio-midihost

 

I've integrated it into my TinyUSB library, which means I could conceivably support plugging in a single MIDI device (a single MIDI device is all his driver supports). I'll start looking into adding support tomorrow, but I don't have any MIDI devices to test (a musician I am not). Short of someone with a MIDI device building one of my USB boards and having me send them the microcontroller software (and then they'd have to write something for the Inty to actually use it) I'm not sure how to test it.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...