Rhys

Energia Tiva USB support

37 posts in this topic

I know nothing about MTP, and I don't believe I've seen any reference to it in the TI usblib (may have just missed it).  Not really something I'm looking to do at this time.  I'm not entirely positive if I am even going to bother with Mass Storage mode at this point anyways.  Not something I need for any projects I'm working on.  If someone else wants to add it, they are welcome to do so.  I'm putting the prototype in place as a placeholder at this point.  All I'm looking to do is USB HID and CDC.  This is just a start on the header file for a library wrapper to get some semblance of USB support for the Tiva chips, and being to distribute it included with Energia will be dependent on TI opening up the usblib to a BSD license anyways.  I came to the conclusion I have neither the time nor the skill to write the whole USB stack from scratch....

spirilis likes this

Share this post


Link to post
Share on other sites

I know nothing about MTP, and I don't believe I've seen any reference to it in the TI usblib (may have just missed it).  Not really something I'm looking to do at this time.  I'm not entirely positive if I am even going to bother with Mass Storage mode at this point anyways.  Not something I need for any projects I'm working on.  If someone else wants to add it, they are welcome to do so.  I'm putting the prototype in place as a placeholder at this point.  All I'm looking to do is USB HID and CDC.  This is just a start on the header file for a library wrapper to get some semblance of USB support for the Tiva chips, and being to distribute it included with Energia will be dependent on TI opening up the usblib to a BSD license anyways.  I came to the conclusion I have neither the time nor the skill to write the whole USB stack from scratch....

Yeah it sounds like several months worth of work to just get up to speed on the necessary intricacies of USB to make a stack, as it stands now I bet this will take a little less...

Share this post


Link to post
Share on other sites

I should be able to knock out the wrapper in a few weeks (if I get time to work on it) along with instructions for how to integrate it and usblib into Energia until such time as TI decides to move the usblib to a BSD license.  TI's usblib is relatively feature complete as far as I'm concerned.  It's not even all that terribly difficult to use if you want pretty decent controls over your device.  However, definitely not friendly to use for the Arduino type crowd.  I just didn't see the point in reinventing the entire wheel when I could just put training wheels on it lol....  I have a reasonable understanding of the USB HID portion of usblib, and a couple of new examples in the latest Tivaware release helped fill in a few gaps.  CDC I haven't used yet, but looks pretty straight forward.  I should be able to cherry pick the bits I need out of the USB_CDC example code.  Mass Storage is a shot in the dark if I decide to even look at it.  I may leave that for some other enterprising individual who has use for it to implement.

 

The partial header file I posted was all I've had time for yet lol....  Although that does allow me solicit comments and suggestions on the user end of the library and adjust things before starting on actual code.  I find it best if I start at the top and work my way down :)

 

BTW, I like the current library call names I decided on, but the internal variable names are simply place holders for readabilities sake and are by no means what I plan on using....  Once I get the header a little more polished, I'll start a new github repo for it and anyone else who cares to chime in and help can submit pulls requests to the repo.

spirilis likes this

Share this post


Link to post
Share on other sites

Few thoughts on the interface 

extern void joy1_DIG(bool x, bool y); 

How is this going to work?  As far as I know typical digital joystick has 4 buttons (right, left, up, down) - which gives 9 possible states.  

The function prototype given can only take 4 possible inputs.

extern void joy1_button_on(uint8_t button#);
extern void joy1_button_off(uint8_t button#);
// Consider adding or replacing with 
extern void joy1_button(uint8_t button#, bool state) 

Obviously one can translate back and forth between the above calls, so whichever gives the cleanest interface to underlying code might make most sense, with the others as syntactic sugar.  I would expect the latter might be more readily useful from application perspective - often just read a variable or button and want to pass the state on to the joystick - so bother to have to do a conditional and call separate routines instead of just pass in variable.

 

 

Consider adding an interface to send multiple button presses at one time (button chords on mouse or joystick).  (e.g. buttons as bitmask).

Some programs respond to clicking combination of (e.g.) left and right mouse button simultaneously in special way, would be nice to be able to specify that as one atomic action,

rather than having to make 2 calls and hope that they come in close enough together to be interpreted as a chord.  (i.e. no interrupts, etc. intervene)

If the interface will gather up events and wait for a "Send message now" call, then this would not be strictly necessary, but still could be handy.

 

Calling functions joy1/joy2 seems cumbersome (extending to more joysticks means larger api). - consider taking joystick # as parameter

 

Also, having multiple naming schemes for the joysticks and mice are confusing.

Why call the same device joy1_AN8 (function call) and "5", or device 2 and mouse_REL? Invites confusion and programming errors.  

 

If going to define a mouse device as relative, then the mouse_move will obviously be relative.  Is there reasonable meaning for mouse_ABS on a relative mouse?

(Of course there is reasonable meaning for mouse_REL on an absolute mouse).

 

Assume API will be revised to return error codes from the various functions where there are errors that can be detected.

 

Perhaps providing an example would help clarify how interface is supposed to work.

If I have 1 joystick device (an old Microsoft Sidewinder 3D Pro joystick) with an x/y analog stick, a hat controller (x/y digital), an analog lever on the base, stick rotation switches (left, right), a trigger and 8 buttons, how do I set that up?

I guess I declare it as a combo HID device with device # 4,6 and 8?

Which gives me 16 bit analog main stick (joy1_AN16), digital hat (joy1_DIG), and analog lever as 1 axis of the 8 bit analog stick (joy1_AN8).

Then what about the buttons - do I just get 8 buttons shared between the three joystick 1 sticks?  So I have to forgo some of the buttons or rotation switches (or maybe use rotation switches as second axis of 8 bit analog stick).

For some of the fancier sticks one may have to dip into joystick 2.

 

Need scroll wheel interface for mouse. e.g.

void mouse_z_REL(uint16_t z); // e.g. for rotary encoder
void mouse_z_ABS(uint16_t z); // e.g. for z axis in 3d mouse, or for pressure from a pen

Consider allowing >3 buttons on mouse (e.g. Logitech MX 700 has 7 buttons)

Share this post


Link to post
Share on other sites

Digital Joystick - My bad, that should be a signed int, but the valid range is -1 to 1.  If you look at my earlier arcade control panel code, that is what I used.

 

Button toggle code - Your idea makes more sense and makes toggling a button much simpler.  Thank you!

 

Multiple simultaneous presses - That would be covered by the *****_report() command, you can feed a full HID report for that device in a single variable array.  That is still a work in progress and I may come up with a better solution along the way.

 

multiple device names - I had thought about using a device number rather than joy1/joy2.  I see what you mean about mouse_abs not being usefull for a relative positioned mouse, but the functions are generic, not specific to the type of mouse called, and by explicitly labeling them, it prevents confusion on the part of the end user.

 

error handling - that will be added in as I go.  I will update as I decide what kind of errors could present and how best to report them

 

Your questions at the end make no sense in relation to what I'm working on right now.  This is all device code, I haven't even looked at host yet.  USB host for attaching devices to the Launchpad will be completely different.

 

Any use cases for more complex devices would be covered under the create your own HID device descriptor.  These are simple function prototypes to allow someone who wants basic functionality and doesn't want to learn how USB HID works to setup a quick keyboard/mouse/joystick device.  The DIY descriptor will be my shorthand way of enabling users to make more complex devices without having to learn the underlying usblib functions.

 

I hope that all makes sense, trying to watch TV while I typed this lol...

Share this post


Link to post
Share on other sites

Clarification - the example I gave above of creating a device similar to the MS Sidewinder Pro was not intended as using the micro as a host for that particular joystick.

What I was trying to do was work out how one would use this library in order to create a USB device that would appear to the host computer as a joystick with similar properties.

Writing an example of code that would use the API should help clarify how it is supposed to work, and help turn up difficulties.

For instance, somebody seeing the API might assume that joystick1 can have an analog16, an analog8 and a digital stick (as I did), but somebody else might assume that it can only have one of type of joystick (i.e. joystick 1 can be either analog16 or analog8 or digital).

 

Joysticks with hat sticks, or gamepads with multiple joysticks or joypads seem to be norm, so it makes sense to design the interface to handle typical controllers.

 

 

So here is some pseudo-code of what a use of the API might look like for a launchpad that has analog and digital devices connected on various pins, and uses the API to package it up like a joystick.  

buttons[] = { button1, button2, button3, ... button8 }

setup{
  initializeHIDcomp(4, 6, 8);
}

loop{
  joyxv = analogread(joyx)
  joyyv = analogread(joyy)
  joy1_AN16(joyxv, joyyv);

  throttle = analogread(throttlepin)
  turnl = digitalread(turnleftpin)
  turnr = digitalread(turnrightpin)
  turn = (turnl ? -127 : (turnr ? 127 : 0))  // Digital sensors converted to analog reading

  joy1_AN8(throttle, turn);

  hatleft, hatright, hatup, hatdown = digitalread(bhatleft, bhatright, bhatup, bhatdown)

  joy1_DIG((hatleft ? -1 : hatright ? 1 : 0), (hatup ? 1 : hatdown ? -1 : 0));


  for (i = 0; i < sizeof (buttons); i++)
  {
    butstate = digitalread(buttons[i])
    joy1_button_set(i, butstate);
  }
}

Hope that makes it clearer.

Share this post


Link to post
Share on other sites

Ok, I see where you are going with that.  The prototype functions I setup assume that you pick one of the three options for the joystick, either AN8, AN16, or Digital.  They are meant to allow a simple single x/y axis, 8 button joystick for simple use scenarios.

 

For what you are talking about, that is far more complex than I plan to deal with for simple prototype functions, and is why I will include the ability to build custom HID devices.  I haven't decided yet exactly how I'm going to set that up.  I will probably create an example program to show how to create a custom HID descriptor, how to initialize it as a custom device, and how to send reports.  That allows for more complex devices like what you are describing to be built without having to learn the entire usblib stack like I did.

 

Once I have the wrapper completed, I'll also convert my Mame control panel code over to Energia as an example of both how to create custom composite HID devices and at least one simple method of dealing with debouncing of digital inputs, as well as report structure for USB HID devices.

 

I haven't even started on the code yet, and examples won't come till after the code is close to completion.  There is a LOT of back end work I have to do to support those simple prototype functions for the library to work.  Most of what would normally be in the device code has to be moved into the wrapper library, such as setting up the physical USB port, handling report submission and error trapping, and all of the device configuration.  It's not especially complex, but will be a fair chunk of code.

 

I will continue to post updates as things move along.  Hoping to have the header file created (if not complete or final) and a github repository setup this weekend.  Might even manage to get some code started.

 

Thank you guys for all the comments and suggestions so far.  Keep them coming!

Share this post


Link to post
Share on other sites

Hi Folks,  Hope you don't mind answering some possibly dumb questions from someone with very limited coding experience.  I recently figured out that I could not communicate with my Stellaris / Tiva launchpads the "device" USB connection.  It appears to me that this is the issue that you are working on.  Is that correct?  If you are able to accomplish what you are attempting, will it be possible to communicate with the launchpads without downloading and installing the ICDI drivers?  I would like to use some launchpad based instruments to teach chemistry labs and I foresee installing the drivers on the student computers as a major obstacle.  If this is not what you are  working on and there is a simple answer to my problem, I would be grateful for that info.

Thanks,  Jack

Share this post


Link to post
Share on other sites

While you would not need the ICDI drivers, you still might need drivers, depending on your operating system and what type of communication you are using.

Specifically, Windows often needs to install drivers for a USB_CDC (serial port) device.  

However I believe Linux generally does not need a driver installed for USB_CDC.

For HID devices (joystick, mouse, keyboard), both Windows and Linux have built-in drivers.

I do not know about Macs, although since they have *nix underpinnings I would sort of expect them to act more like Linux in this regard.

 

So, if your device acts like a serial port, then it might need a driver for Windows.  If it looks like one of the other HID types, then probably not.

Share this post


Link to post
Share on other sites

Just curious, has there been any progress on this matter? Has anyone tried packaging a usb_dev_serial.c type application for energia?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now