controller protocols

Started by Splynncryth, January 19, 2004, 07:43:58 PM

Previous topic - Next topic

Splynncryth

I would like to know where I can get information about the protocol some of the more oddball controller out there. For my senior project, I'll be trying to design and build an interface to handle various console controllers and interface then to a PC through USB. Most of the base controllers for the systems haven't been too much trouble to find, but it is the extra controllers that are more difficult, and I *really* want to support some of the oddballs. Here is my running list:
NES zapper
NES powerglove
SNES mouse
SNES superscope
PSX negcon compatable
PSX jogcon
PS2 dualshock 2
DC light gun
DC keyboard
DC mouse

These are what I can think of right now. With the interface logic feeding the microcontroller, making this stuff work should basically be adding code to the microcontroller to put the data in a USB packet, or some basic reencoding for mouse and keyboard stuff  to be reconized as HID input devices.

Tom61

NES zapper is fairly easy, it's basically two buttons, one is the trigger, the other is the photometer (when it sees light, it triggers the equivilent of a button press). I lost the info on how to build the decoder, but 10 minutes and an oscilloscope and you should have it figured out.

NES powerglove registers as a NES controller, and you can change the modes manually. Now if you want to tell it what modes to be in through the interface, that's gonna be difficult.

SNES mouse is probably discreet too, so it shouldn't take long to figure out.

SNES superscope is going to be much more difficult, I'm pretty sure it measures decay rate of the pixels to determine where it's looking at on screen. Going to be very difficult to get working.

DC light gun, DC keyboard, and DC mouse protocols could be reverse engineered from the KOS library. (once you get maplebus running of course, which if you ahve regular controllers running should be no trouble)

hemphacker

DC protocal: link

All the various NES and SNES controllers use a parallel to serial protocal that is easily decoded. This website has protocal information, except I'm told that the clock line is actually the inverse of what is pictured in his diagrams. Data can be on 3 different pins and they all use the same protocal. NES can send 8 bits, while SNES sends 16. I can't remember where the info is on what bit is what for the mouse, etc, but it isn't too hard to figure out if you can get one. Just create the proper pulses and watch a scope as you play with the controllers.

This is all the info I have on the Power Glove so far. link

Light guns rely on the video interface and software used, ie... the Light gun software needs to accept the proper type of information. Some use timing, while others do not. Also, light guns are designed to work on TV's or monitors, and they can't be mixed (a TV light gun won't work on a monitor, and vice versa). There's some info on the NES and SNES light guns floating around the net, but I can't remember where they are.

Oh, and I've already gotten regular SNES and NES controllers working on USB, and I'm planning on adding as many other controllers as possible. I should have Virtual Boy done soon, as it uses the same protocal as the others. I'd like to discuss sharing our work sometime.

Splynncryth

That ould be welcomed. I haven't settles on a microcontroller yet, so I haven't done anything with repacking the data of the controllers, but I have looked at the interface logic for a few of the simpler controllers. NES and SNES should be quite simple for the basic controllers. Its all the extra gizmos, and third part controllers that are hard to get info on. I would like to use the scope method as a last resort, as I could foul up the interpretation. Right now, I'm 99% sure I can make this thing work with the base (originally sold with the system) controllers for the NES, SNES, Genesis, SMS, and PSX. The Saturn shouldn't be any worse than the Genesis, but I don't have any hardware to test with (yet). I'll worry about other 8 and 16 bit era consoles later if I get time, but in my experience, it can be hard comming across some of the older hardware.
Supporting the base model DC controller could be easy or difficult depending on how I implement it. A lot depends on the software and of things. I'm trying to finish an EE degree, not a CS degree so while I can make the hardware work, and write ASM for a microcontroller, drivers are way beyond me. If do have a family member in CS who wants one of these very badly, so maybe I can suck him into to writing the drivers for me :)
Playstation controller will be far more interesting though. There are NO standards here, the data structures look to have been made up as Sony and Namco thought them up. The digital and dualshock communication protocols are well documented, but I want to support the negcon protocol quite badly, and the jogcon almost as bad. I also want to handle dualshock 2 controllers. I'll look into others if there is time.
I'm still debating N64 support. I'm not sure as to the best approach to dealing with its encoding.If I beat that problem, the rest is simply software on the microcontroller.
Saturn should be easy too as it works similarly to the Genesis. But I have no idea about the nights contoller. Does it do serial over some of the pins?
I'll look into the other modern consoles to be fair too. But I mainly want to focus on out of production consoles.

The main thing I want to achieve with this is to eventually support as many of the controller based gizmos as I can so they can be used either by programmers writing custom apps, or by emulation authors who want to preserve as much of the older gamming eras as they can. There are no new NES or Genesis systems being manufactured anymore. Every dead or discarded system loweres the total number of consoles in the world. Som are already rare enough that the only way most people will be able to play them is emulation. I'd like to make that experience as close to the original as I can by letting the original control harware to be used.

hemphacker

Just a quick note about drivers... If you use HID, then there's no reason to write drivers. I'm a hardware guy also, so the microcontroller & interfacing is in my area, but drivers are out of reach for me at this time. Stick to HID. What's the point of re-inventing what's already there?

Guest_Splynncryth

I'm not dead yet, nor is my project, it was just delayed.
I just got the USB dev kit I think will be the best thing for this project. It's based on the FX2 family from Cypress. My brother is a programmer and wants this project done 'right' so badly he's offered to deal with the driver ^_^. So, I'm trying to focus on thge hardware and firmware right now. This shouldn't be *too* bad, the microcontroller uses a systrem they have dubbed the GPIF. It seems like at least supporting the base controllers shouldn't be too bad, and because of a very nice feature this family uses, the microcontroller can be reprogrammed in circuit, assunming the electrical connections aren't too whackey. For example, if I'm following the power glove info, it looks like the clock signal does not follow the standard cock definition that the NES and SNES controllers use (I was going to tie their clocks togeter to same on pins used).
Now I'm trying to get solid PSX protocol data, like what range of clocks the PSX can use. Again, I'm hoping to combine lines even if I need to use some dividers for the NES and SNES clock to slow it down from the PSX's clock. Between al the lines the PSX uses, and support for Sega controllers, I'll be pressed for GPIF pins and if I need to rely on GPIO pins instead, it means I can't get away with using the very nice app Cypress has provided for configuring the GPIO.

If anyone is curious about what I'm using, here is the link: http://www.cypress.com/support/dev_kit.cfm...28715F47620AEE8

It's based on a 8051 microcontroller.
If you're curious, check out renumeration and GPIF in the technical reference. These are two big features I like this family for. I would like to have a final circuit that is single IC and uses the internal RAM for the firmware so the circuit will be easy for most people to build. Then, because of the renumeration, more controllers can be supported in the future through a driver update.

Aidan

You don't need, or really want a driver. Using HID instead makes far more sense, as this is exactly the type of device that HID is designed to operate with. As an additional bonus, if you make it HID complient, then it'll work on any OS that understands HID. That's most OSes that understand USB!

That includes Windows, Linux, Playstation 2 and just about anything else with a USB controller in it.
[ Not an authoritive source of information. ]

Guest_Splynncryth

The problem with the HID class is that I haven't sen support for some features these controllers have, such as analog buttons for example (present on the NegCon, Dualshock 2, and arguably dreamcast controllers). Then there is support for other oddball devices like the original NES zapper (I think it will work pretty well), the power glove, and maybe even some of the better light guns. I haven't dealt with the HID calss, but from what I've seen, I think what I want to do may be outside the class definition.
Then there is vibration and force feedback. I know force feedback is an advertised feature of the HID class, but I'm not sure how this works. I have yet to see anything on vibration feedback.
Then there is the issue of endpoints. I don't have as many endpoints as I have devices, so I was looking at a sort of 'megapacket' that gets split off into the appropriate controllers at the other end. Force feedback would probally end up being done similarly, the data preformatted on the PC end, then sent to the endpoint buffer set up as an output to run the controllers. Different controllers that use the same interface would be handled by selectring what is connected throught the driver. Trying to autodetect what is connected is not exactly easy, so I'm avoiding it :)

Aidan

#8
There's several ways you could attempt to do this... The problem with moving outside the HID class is that you will have to do the mapping into DirectInput. From what I understand of DirectInput, you don't gain anything by moving outside the HID class, as DirectInput only supports a subset of the features that HID supports! Ultimately DirectInput is the limiting factor, not the HID class, so the custom driver would suffer the same restrictions that the HID class does.

The HID class supports seven different analog axes, covering X, Y, Z, Rudder, Rx, Ry, Rz, as well as slider, dial, wheel, throttle, hat switch and button.

DirectInput supports six different analog axes,  X, Y, Z, Rx, Ry, Rz as well as Slider, POV and button.

However, both HID and DirectInput support analog buttons. It's up to the application running to decide if it wants to know anything about analog buttons or just treat them as digital.

There is no vibration support in either DirectInput or HID as far as I'm aware. Even if your driver implements vibration support, there is no API for a program to use for vibration! There is force feedback support however, and a number of driver writers have tried to map force feedback onto vibration. Generally this works, but it's highly dependant on the program that's running.

The powerglove could probably make use of the physical descriptors, which allow you to map axes onto body parts. Yes, it even includes definitions for each finger, as well as eyelids, big toes, upper lips, head... ;) I don't know if DirectInput bothers to pay any attention to physical descriptors however!


The biggest problem will be any of the lightguns. LCDs are out, as the gun cannot pick up any beam position on a LCD. CRTs with a high refresh rate may cause difficulties as they may exceed the bandwidth of the lightgun!

The lightguns can be mapped onto a pointer device, but you will need to do some video sync processing on your microcontroller, depending how smart the lightgun is. The initial processing can't be done on the host PC, as there's going to be at least a mS worth of latency. At TV resolutions, in that one mS, the beam would have moved 66 lines on from where it was originally.
[ Not an authoritive source of information. ]

Splynncryth

haha, remembered my PW finally :)

I have seen a driver that does basically all of what I'm asking about, but it was created for the x-box controller. The 'company' was cherry on top productions IIRC, I need to dig, but I think I still have it. They had implemented analog button support and had some vibration feedback working. I'm assuming that the controller could not be detected as a standard HID device, presumably because MS couldn't make it conform to the HID class when they designed the features of the controller (HID compliant console controllers would be grat though, use any controller with any game on the system).
I'll look at the light gun issue later, I'm not super concerned with them at the moment. The solution may be to have the video mode set so the monitor acts like a TV. I am aware that LCDs can't be made to work due to the way they operate. I was originally thinking about using them in conjuction with a video card using TV outputs though.

As for application support, what is probally my strongest reason for this project is to improve the game play experience on emulators. With the systems out of production, every one that breaks is one less in the world. Also, there is the issue of collectors. But controllers seem to out live the consoles (at least anything that isn't the flimsy Atari stick). So I thought that a PC running an emulator on a TV that can use the original controllers would be a good substitute. I was hoping to provide the support on the hardware end, provide detailed info on the driver and data format, and let them decide what they want to support. I'm trying very hard to keep the hardware design as simple as possible, so I can release the plans and have them be simple enough that anyone who can learn to solder can build them.  

Aidan

I beleive that MS made it non HID simply so that you are locked into using MS's controllers. Why else use a propriatary connector for a standard USB connection?
HID can support all the features of the MS controllers.  
[ Not an authoritive source of information. ]

Splynncryth

OK, finally found somthing close to plain english describing MS's support for the HID class. It mentions that 'any usage on any usage page with bit size of unity as a button'. OK, that makes sence, but then it says 'even if it's bit size is greater than one'. Now, this confuses me a bit. What seems to be indicated is that if I map the bit field for an analog button mapped to what would be a button, but having values grreater than one, it can be treated as both a button and an axis. This seems exactly like what I want, but I'm not positive I'm reading it right.  

Aidan

In the HID descriptor, you can set the width of the reporting field for a button. Typically that width would only be a 1, as the button is boolean. However, an analog button can support wider field, so you can set the width to 4 bits, and hence indicate an analog value. The button will still be treated as a button, rather than an axis.
[ Not an authoritive source of information. ]

atom

Also, do you need to support analog buttons? Their are no games that support \ use them, so why have the driver support them? I'd say just register them as digital. The only game I can think of that uses analog buttons are like Metroid Prime and The Wind Waker and use of them is very limited (and not needed).

I do want to encourage you to keep updating use with the info on your project; It looks very interesting I must say. If your gonna burn your own hardware interface, I would follow the advice of others and make it HID. If you are relying only on software, (as in a driver) then do whatever you want. Basically my friend, if you are burning your own hardware interface, there is no point in not going with HID! You otherwise could just do it all software side via LPT1. I wish you the best of luck.

If I can get my hands on an SNES mouse, I will contribute to the project.
forgive my broked english, for I am an AMERICAN

Splynncryth

I've finally made some noteworthy progress. The FX2 is a good system, the documentation is utter crap though. Thank goodness it is so popular for examples though.
I have an NES controller talking to the PC!! My methods for generating the proper signals seems to work fine, at least with a controller that allows for some slop.
I'm using the HID class definitions, though this will go as soon as I can write a driver (I need to get enough done to get a good grade on my project). There is no good way to autodetect what is connected and supress the OS reporting a supported, but disconnected controller. So there isn't any good way to support all the different controllers out there with the standard class definitions :/

Right now I've hit a snag. I was under the impression that it'd be easy to have multiple controllers supported by the built in HID class support. I was under the impression that all I had to do was specify a report ID right after the collection(application) declaration. Then, once I closed it, I add another collection(application), a new report ID, and all the fields for controller #2. Well, I tried it and it broke. For any of the USB buffs, here is a copy of the broken descriptor:
ReportDscr:
       db 05h,  01h                ; USAGE_PAGE (Generic Desktop)
       db 09h,  04h                ; USAGE (Joystick)
       db 0a1h, 01h                ; COLLECTION (Application)
       db 85h,  01h                ;   REPORT_ID (1)
       db 0a1h, 00h                ;   COLLECTION (Physical)
       db 05h,  09h                ;     USAGE_PAGE (Button)
       db 19h,  01h                ;     USAGE_MINIMUM (Button 1)
       db 29h,  04h                ;     USAGE_MAXIMUM (Button 4)
       db 15h,  00h                ;     LOGICAL_MINIMUM (0)
       db 25h,  01h                ;     LOGICAL_MAXIMUM (1)
       db 35h,  00h                ;     PHYSICAL_MINIMUM (0)
       db 45h,  01h                ;     PHYSICAL_MAXIMUM (1)
       db 65h,  00h                ;     UNIT (None)
       db 75h,  01h                ;     REPORT_SIZE (1)
       db 95h,  04h                ;     REPORT_COUNT (4)
       db 81h,  02h                ;     INPUT (Data,Var,Abs)
       db 05h,  01h                ;     USAGE_PAGE (Generic Desktop)
       db 09h,  30h                ;     USAGE (X)
       db 09h,  31h                ;     USAGE (Y)
       db 15h,  00h                ;     LOGICAL_MINIMUM (0)
       db 25h,  02h                ;     LOGICAL_MAXIMUM (2)
       db 35h,  00h                ;     PHYSICAL_MINIMUM (0)
       db 45h,  02h                ;     PHYSICAL_MAXIMUM (2)
       db 65h,  00h                ;     UNIT (None)
       db 75h,  02h                ;     REPORT_SIZE (2)
       db 95h,  02h                ;     REPORT_COUNT (2)
       db 81h,  02h                ;     INPUT (Data,Var,Abs)
       db 0c0h                     ;   END_COLLECTION
       db 09h,  04h                ; USAGE (Joystick)
       db 0a1h, 01h                ; COLLECTION (Application)
       db 85h,  02h                ;   REPORT_ID (2)
       db 0a1h, 00h                ;   COLLECTION (Physical)
       db 05h,  09h                ;     USAGE_PAGE (Button)
       db 19h,  01h                ;     USAGE_MINIMUM (Button 1)
       db 29h,  04h                ;     USAGE_MAXIMUM (Button 4)
       db 15h,  00h                ;     LOGICAL_MINIMUM (0)
       db 25h,  01h                ;     LOGICAL_MAXIMUM (1)
       db 35h,  00h                ;     PHYSICAL_MINIMUM (0)
       db 45h,  01h                ;     PHYSICAL_MAXIMUM (1)
       db 65h,  00h                ;     UNIT (None)
       db 75h,  01h                ;     REPORT_SIZE (1)
       db 95h,  04h                ;     REPORT_COUNT (4)
       db 81h,  02h                ;     INPUT (Data,Var,Abs)
       db 05h,  01h                ;     USAGE_PAGE (Generic Desktop)
       db 09h,  30h                ;     USAGE (X)
       db 09h,  31h                ;     USAGE (Y)
       db 15h,  00h                ;     LOGICAL_MINIMUM (0)
       db 25h,  02h                ;     LOGICAL_MAXIMUM (2)
       db 35h,  00h                ;     PHYSICAL_MINIMUM (0)
       db 45h,  02h                ;     PHYSICAL_MAXIMUM (2)
       db 65h,  00h                ;     UNIT (None)
       db 75h,  02h                ;     REPORT_SIZE (2)
       db 95h,  02h                ;     REPORT_COUNT (2)
       db 81h,  02h                ;     INPUT (Data,Var,Abs)
       db 0c0h                     ;   END_COLLECTION
       db 0c0h                     ; END_COLLECTION
       db 0c0h                     ; END_COLLECTION
ReportDscrEnd:

To 'unbreak' the descriptior, put another end connection right after the first that occurs in the report and delete everything that comes after that. Any ideas?

Splynncryth

I know I haven't said anything here in a while, well, I was able to get both a NES and SNES controller to work simultaneously and be reconized as standard USB gamepads. This was enough to get me a good grade on my final project, but now I'm job hunting, and I haven't worked on the thing in a little while.
The next step is to add N64 or PSX support and see if the extra load chokes the system with my current framework. The microcontroller is much faster than the controllers, so I set latches to fake clock signals with the software, all data is read on transitions after a settling time has been allowed. a couple counters running interrupt service routienes keep everything in sync. It's a purely firmware based system.
If the framework holds with the higher speed controllers, I'll go back and add suppport for some the older stuff. I need to look over the six button genesis controller protocol. I have seen some explinations, but I was hoping that there is somthing in the data from the controller that I could use to detect if a 3 or six button controller is connected.

I donno if I'll get to the dreamcast, making the MCU emulate maple with software simply won't work, there isn't enough power. So that means I'll have to come up with a transceiver. It hurts the low parts count goal, but I'm already planning on using a shift register for atari, SMS, genisis, and saturn support (I'm still debating a consolodated interface that does atari, SMS and Genesis in a single port since Sega designed reverse compatability into the controllers).
I haven't looked at the gamecube's protocol, and I'm having trouble getting the PS2 specific protocol.

I want to use a feature of the FX2 platform (the USB platform I'm developing on) called renumeration to do some fansy stuff. First, new firmware could be handed out in the form of a driver update since it allows a 2 step device install proceedure. First, it installs itself as a default device whose driver says to send data to the unit which contains the firmware. Then the MCU does a soft reset and comes back up with the new firmware. Another neat trick with this is the ability to autodetect. I could have the MCU autodetect what is plugged into it so it only initalizes with devices that are actually plugged in.

atom

Cool, any plans to mass produce these for the grey market?
forgive my broked english, for I am an AMERICAN