Rhys

Energia Tiva USB support

37 posts in this topic

I know Energia does not currently support USB host/device on the Tiva chips due to TI's ridiculous licensing on the library code.  I was wondering if anyone would be interested in collaborating on writing a USB stack for the Tiva chips for Energia.  I was actually thinking of porting LUFA over to the Tiva, as it might be easier than starting from scratch.  The idea being to do an end-run around TI's stupid Clickwrap license on all the useful parts of TivaWare beyond barebones support of the chips hardware.

 

While I don't mind developing USB device code in CCS, USB support in Energia would make the Launchpad boards far more attractive to the average Arduino hacker as a less expensive and more feature reach platform.  The new Tiva Connected Launchpad can physically do just about anything an Arduino Due can (and then some) at half the price, but the development environment just isn't up to snuff compared to Arduino.  I would like to help remedy that if anyone else is interested in helping.

Share this post


Link to post
Share on other sites

@Rhys  It might not be a bad idea to cross post this over at 43oh since it seems more folks follow that board than this one.  I am not a good enough coder to help but I think it is a great idea.

Share this post


Link to post
Share on other sites

I'll second, the licensing of the USB subsystem in TivaWare seems like a colossal mistake to me.

It does look like some portion of the USB hardware I/O is in driverlib, but the usblib ties it all together...

Share this post


Link to post
Share on other sites

Tying this back to a sub-discussion at 43oh: CMSIS defines an API for USB host and peripheral devices. Implement that for TM4C, then bridge from that to LUFA (if necessary), and you'd have something that could work across the entire Cortex-M ecosystem.

Share this post


Link to post
Share on other sites

@@bluehash - I'm good on hardware at the moment.  I have a TM4C123 sitting on my desk, and a TM4C1294 that should be here in a day or two. 

 

@@dubnet - I'm not sure if I'm up to the task or not.  I'm still relatively new to writing code myself....  I have written a few USB device firmware sets using the TivaWare USB library though, including some modifications to the USB library code itself.

 

@@pabigot - I will look into that, it's definitely an idea that may save starting completely from the usb hardware driver in the driverlib (which is under a BSD license).

Share this post


Link to post
Share on other sites

I should clarify: the CMSIS Peripheral Driver Interface which includes the USB interface in was added in CMSIS 4.0, which was only released a month ago. There's no implementation of it from TI or (AFAICT) anybody else; it's just the specification for an API which, if you implement to it, means you'd be able to re-use code that depends on it on any other Cortex-M device that also implements it. (Maybe; I'm a long way from looking at USB support on these things.)

Share this post


Link to post
Share on other sites

I think one BIG issue is USB devices have a Vendor ID as well as Product ID, so there are some proprietary things going on regardless of the code source license, and those tend to be tied to hardware exclusivity, from what I can tell. TI provides for people to use their lib and a block of VID/PID combos. And even though TI does permit certain VID/PID combinations, there's no guarantee that any one of us won't inadvertently duplicate things and cause potential conflicts should something get out into the wild. I.e. say I get the Hercules ECU out with USB boot-loader and such with some VID/PID combo and provide a driver and then RobG releases a DMX LED controller and uses the same VID/PID... and someone happens to want to use both?

 

My opinion is that the only logical thing TI, or any vendor providing product for maker / hobby use for that matter, can do is restrict the license.

 

I'm probably babbling so I'll shut up now.

Share this post


Link to post
Share on other sites

VID/PID isn't really an issue.  A properly implemented USB library would require the end user to configure a VID/PID combo in their code at time of use.  That could be TI's, V-USB's, or your companie's, or whatever one you want to use.

 

Implementing a CMSIS driver library might be a little beyond my skill level.  That's more of a silicon vendor sort of thing.  TI already has a low level USB hardware library in the driverlib that has a BSD license, I don't really want to reinvent the wheel.  I just want to get a stack for the rest of it setup for Energia so the USB can be used there.

Share this post


Link to post
Share on other sites

Have you tried asking Texas Instruments about the licensing on those libraries?  They have been gradually opening the license on various of the files.

Perhaps they might open those if asked?

 

 

Thoughts on a couple of other library models/resources

 

libOpenCM3 

http://libopencm3.org/wiki/Main_Page

 

USB support is one of the areas that are planned to be covered.  They even list USB device as being one of the (few) sections that is written for the TM4C.

 

USBHost on Arduino

http://arduino.cc/en/Reference/USBHost

 

USB Host Shield

http://www.circuitsathome.com/arduino_usb_host_shield_projects

Share this post


Link to post
Share on other sites

I posted on the e2e forum regarding the usblib license and have received no response to date.

Share this post


Link to post
Share on other sites

I know Energia does not currently support USB host/device on the Tiva chips due to TI's ridiculous licensing on the library code.  I was wondering if anyone would be interested in collaborating on writing a USB stack for the Tiva chips for Energia.  I was actually thinking of porting LUFA over to the Tiva, as it might be easier than starting from scratch.  The idea being to do an end-run around TI's stupid Clickwrap license on all the useful parts of TivaWare beyond barebones support of the chips hardware.

 

While I don't mind developing USB device code in CCS, USB support in Energia would make the Launchpad boards far more attractive to the average Arduino hacker as a less expensive and more feature reach platform.  The new Tiva Connected Launchpad can physically do just about anything an Arduino Due can (and then some) at half the price, but the development environment just isn't up to snuff compared to Arduino.  I would like to help remedy that if anyone else is interested in helping.

Hello friend were you able to find some solution? I need to support Energia a USB device, so can you help me out?

Share this post


Link to post
Share on other sites

Nada, no response on the e2e forum from TI regarding the licensing :(  I've just started to dig into various open source USB stacks.  They all will require significant work to make usable with Energia, and will likely take me months to sift through and start to come up with a workable solution.  I have a full time job and a family, I don't have a lot of time to work on it and it's going to be slow going.  That's why I was hoping to find a few collaborators willing to help with the project.

Share this post


Link to post
Share on other sites

I have brought this up within TI and the good thing is that all whom I talked to are open to converting the stack to the TI modified BSD license just as DriverLib. Give it a bit more time as these things can be a bit tedious legal wise. Once it is BSD I can definitely use some help from the USB experts here to mold this into an Energia library. 

 

With that said, I would definitely welcome an open source alternative!

 

Robert

igor, Thorvard and spirilis like this

Share this post


Link to post
Share on other sites

I would be willing to help.  I have been meaning to learn more about USB, and have a project that could benefit from a more open licensed stack.

Share this post


Link to post
Share on other sites

Well, my thought at this point is to start small and see if I can get a USB CDC Serial device library working to start with, and then move on to HID.  Unfortunately, I don't have tons of free time to work on it right now, so it may be a bit slow going.  Right now I'm working on picking through a handful of OSS USB stacks to see if I can cherry pick out the bits and bobs to put together the CDC library.  I also have to do some serious digging into the low level USB HAL in the driverlib.  I have to reconcile what the TI USB HAL offers against the HAL layer in the open source stacks before I can even begin to tease the rest of it apart.  It may end up being easier to start from scratch, but if I'm going to do that, I'd rather start with the CMSIS USB HAL.  That would in theory make the library portable across all ARM based chips, assuming the chip manufacturers ever decide to support the new spec....

 

And, even if TI does release the usblib under the BSD license, it is so cumbersome to use for the simple tasks that users of Energia would be likely to need, that it will need half rewritten anyways.  So, I guess knowing that there is a good possibility of TI opening up the license of the usblib, I guess I could just start working from that, as I'm already fairly familiar with it, and have it ready to drop in when the legal nimrods get done writing things to death....

Share this post


Link to post
Share on other sites

Ok, so I've come to the conclusion my coding skill is not up to par for writing a USB stack, or even modifying an existing one, for the purpose of getting USB support into Energia.  I on the other hand, should be able to handle writing a wrapper for the TI usblib to act as a wedge to emulate the USB device functions currently in the Arduino environment.  It's not an ideal solution at this point, but if TI is working on opening up the usblib license to BSD, it would be a workable solution.  In the mean time, the wrapper can be made available with instructions on how to add the TI usblib and wrapper to a users local Energia install.  Using the usblib drivers directly is far beyond the skill level of most of the target audience of Energia.

 

I will start working on the wrapper, code will be available on my github if anyone else would like to contribute.  Once the existing Arduino functionality has been implemented, we can work on extending the USB support to allow for more creative uses of the stack.  Assistance from the Energia devs would be helpful for writing up the install docs for usblib and the wrapper until such time as they can be legally distributed as part of Energia.

 

How does that sound to interested parties?

Share this post


Link to post
Share on other sites

In your researches did you find any particularly nice APIs for programming USB (either host or device)?

I did a little browsing of the USB code in Arduino - and a lot of it could be more accessible.

 

Figured there may be some nicer APIs out there, might be worth designing  the warper to improve on the Arduino API (and then provide a compatible API for backward compatibility).  That said, I do not have any particular API in mind as a good one to use.  (After looking at a few USB examples I have seen a lot of difficult to follow code, but not a lot of clarity.)

Share this post


Link to post
Share on other sites

Yeah, I'm not thrilled with the Arduino USB API, it doesn't really accomplish much, and definitely not anything I would want to do.  I haven't found any others I particular like either.  They are all either WAY too basic like Arduino, or way more complex than is appropriate for Energia like the TI usblib.  I will probably end up developing my own API based on things people actually might want to do, and throw in Arduino API compatibility for support of existing Arduino sketches.

 

Here's a rough list of things I want to include.  I haven't even started planning the actual API itself yet.  I will flesh this out more as I have time and continue to log my progress on here.

 

Device:

 

USB HID

 - custom device descriptors

   - simple format for storing custom device descriptors (macros?)

 - composite HID support

   - initialize a composite HID device using standard or custom devices (#define option to enable composite HID)

 - keyboard

   - Arduino API

   - alternative methods of setting keys on/off (faster for alternative keyboard applications - ie. Mame)

 - mouse

   - Arduino API

   - alternative methods of setting mouse buttons on/off (faster)

   - support for hardware QEI for position input

 - joystick

   - simple method to set axis count and type (digital/analog)

   - simple method to set button count

   - simple method to assign ports/pins to buttons/axis

   - Arduino like single button/axis state change commands

   - one shot invert all assigned button ports/pins state to button input command

USB CDC

 - redirect any UART to USB

 - options configuration

USB Mass Storage

 - Access external flash (SD/MMC) as mass storage device

 

Host:

 

USB HID

 - Keyboard

 - Mouse

 - Joystick

USB Mass Storage

 - read/write support

Share this post


Link to post
Share on other sites

Nice list.

A few other things might consider adding (I was toying with a similar list).

 

Device:

Adding HID indicators/outputs as part of joystick, etc.  (Handle LEDs, rumble motors, etc.)

Handle absolute positioning as well as relative (for mouse) - e.g. tablets.

Mouse should also have way to set axis count, number buttons, etc. (3D mice, pressure/tilt sensors on tablets, etc.)

 

Maybe make composite support for other device classes as well.

  (e.g. CDC + HID)

 

Other classes that might consider (or may leave as exercise to the reader):

 

Printer (as device and host).  - nothing fancy, just take basic strings of text

  (e.g. May be simpler alternative if your host software doesn't know how to display things on your neat screen/LED reader board/etc.)

 

Support for simple networking (I assume that would be under CDC) - e.g. there are lots of wireless booster packs, might be handy to have framework for exposing 

  the communications layer to host devices.

 

HID Display (Seems like a natural, with all the little displays on booster packs, text displays, etc.
  However I find very little about implementations of the HID display class - don't know if that indicates there are technical difficulties, or isn't much host software
  to use it, or what)

Share this post


Link to post
Share on other sites

composite devices (ie. CDC & HID) would be a part I forgot to add to the list.

 

custom mouse types would be included in the custom HID descriptor portion of the code.  HID devices are essentially just a descriptor that tells the host how many bytes of data to expect and what to look for in those bytes, and then code to push those packets into the USB FIFO.  Any custom HID descriptor code would therefore allow for the end user to design any HID device they would like.

 

Printer would be a class I wouldn't even touch until I had CDC and HID host/device complete, as I can't really see much use for it.

 

Most wireless booster pack wireless devices uses a uart/spi/i2c type interface to the host MCU, I can't see any reason to deal with any networking related USB code unless someone was wanting the MCU to do USB host for a USB NIC, which seems a little far-fetched.

 

HID display would fall under the category of custom HID device descriptors.  Most graphic LCD displays in their raw state are either RGB or LVDS.  Most smaller displays can be gotten with a built in controller chip that will accept some form of uart/spi/i2c or raw VGA signal.  Larger panels (5" and up) for the most part are raw parallel LVDS (high resolution) or RGB (low resolution) input.  Either way, without specs for the control and timing signals for the display, they are completely useless.  I have a steady supply of 5" 320x240 QVGA full color graphic LCDs that at this point are completely useless because I have neither the skill to disassemble the AT91SAM9 control chip firmware and extract the LCD configuration values, nor have I been able to find the JTAG interface pins on the PCB to connect to the chip while it's running and read them out directly.  They are completely unmarked raw LCD panels, so no way to find out who makes them or get a data sheet. The manufacturer of the device they come out of won't tell me either (already asked nicely).  Laptop LCDs on the other hand are fairly easy to get datasheets for and HDMI/DVI/VGA to LVDS controllers can be had from China on Ebay for under $50.  They will even program them and provide the proper cable for you if you tell them the part# of the LCD when you place the order.  Those are based on purpose built chips that are designed for the sole purpose of converting a standard video signal to LVDS for an LCD.  The other option is to use a stock MCU that has RGB/LVDS LCD support, such as most Cortex A7 or A8 based SBCs, like the Cubieboard.  You can literally attach an LVDS or RGB LCD directly to an AllWinner A10/13/20/31 CPU, create a Linux driver for the LCD, and drive it right off the CPU.  Granted, I'm making that sound entirely simpler than what it actually is, but you get the idea....  For most peoples purposes, HID display would be useless.  Even driving a QVGA display with nothing but static images from the AT91SAM9 CPU requires a decent sized chunk of RAM as an external chip to act as a frame buffer for the display. And the modules I have don't even store the images locally in flash, they are piped to the controller over a USB Bulk connection from a host PC.

Share this post


Link to post
Share on other sites

As far as HID display, I was thinking in terms of the small screens used in booster packs, or text screens ( HD44780, etc. ), VFD (e.g. noritake), e-paper booster pack, OLED, etc.

e.g.

http://forum.stellarisiti.com/topic/643-energia-library-lcd-screen-library-suite/

 

One obvious use for such things might be to connect them up to a computer via software like LCD Smartie http://lcdsmartie.sourceforge.net/, LCD4Linux http://ssl.bulix.org/projects/lcd4linux/, etc.  Windows also had a system for secondary/status displays started (round about Windows Vista or 7).

Or to have a game controller with a small status display.

 

Various of these devices and programs have their own custom protocols, which one could emulate.

In theory, using a standard protocol like HID display might be helpful. Of course that may not play out in practice (e.g. if nobody uses the standard protocol).

Probably something for another topic/separate project.  

Do you have a thread on reverse engineering the devices you mentioned?

Share this post


Link to post
Share on other sites

I see what you mean now.  I can see where that might be useful if you can find host software that supports it.  I do not write windows/Linux software however, so I wouldn't be much help with that.

 

I don't believe I had started a thread on here regarding the LCD/AT91SAM9 combo I would like to reverse engineer.  I do have a project posted on Hackaday regarding it though.  There are pictures and details on the board there.  There is also a link to the firmware and host control software packages hosted on my dropbox.  I would be happy to donate one of these to someone if they are fairly certain they can pull what I need out of the code and find the JTAG pins so it can be reprogramed.

Share this post


Link to post
Share on other sites


//Standard HID devices

//keyboard - Keyboard

//mouse_rel - Mouse - Relative x/y axis

//mouse_abs - Mouse - Absolute x/y axis

//

//Choose only one resolution option each when initializing Joystick 1 and 2

//

//joy1_AN8 - Joystick 1 - x/y axis 8bit resolution (range -127 to 127)

//joy2_AN8 - Joystick 2 - x/y axis 8bit resolution (range -127 to 127)

//

//joy1_AN16 - Joystick 1 - x/y axis 16bit resolution (range -32767 to 32767)

//joy2_AN16 - Joystick 2 - x/y axis 16bit resolution (range -32767 to 32767)

//

//joy1_DIG - Joystick 1 - x/y axis 1bit resolution (range -1 to 1)

//joy2_DIG - Joystick 2 - x/y axis 1bit resolution (range -1 to 1)

//

//custom HID devices can be defined and used as a device type as well - how to define custom device TBD

 

extern bool initializeHID(uint8_t device); //initialize single HID device

extern bool initializeHIDcomp(uint8_t device1, uint8_t device2, uint8_t device3); //Initialize composite HID device

extern bool usb.initializeCDC(uint8_t uart); //Initialize CDC device redirecting UART uart#

extern bool usb.initializeMS; //Initialize Mass Storage device

 

//keyboard commands

extern bool key_change(char key, bool value); //change key state - returns bool success:overrun

extern bool key_press(char key); //press and release key - returns bool success:overrun

extern bool key_modifier_change(char key, bool value); //change modifier key state - returns bool success:overrun

extern void key_report(uint16_t &report); //bypass library processing and send self created HID keyboard report - no return

 

//mouse commands

//

//These defines must be present before initializing an absolute position mouse device

//

//#define mouse_ABS_resX = uint16_t x_res //set X resolution of absolute position mouse device

//#define mouse_ABS_resY = uint16_t y_res //set Y resolution of absolute position mouse device

//

extern void mouse_REL(int16_t x, int16_t y); //update mouse x/y relative coordinates for absolute device

extern void mouse(int16_t x, int16_t y); //update mouse x/y coordinates (relative or absolute depending on initialized mode)

extern void mouse_button_change(uint8_t button, bool value); //change mouse button state (1-3)

extern void mouse_button_press(uint8_tbutton); //press and release mouse button (1-3)

extern void mouse_report(uint16_t &report); //bypass library processing and send self created HID Mouse report

 

//joystick commands

extern void joy1_axis(int16_t x, int16_t y); //update joystick 1 axis positions - use appropriate range for selected device

extern void joy1_button_change(uint8_t button, bool value); //change joystick 1 button state (1-8)

extern void joy1_button_press(uint8_t button); //press and release joystick 1 button (1-8)

extern void joy1_report(uint16_t &report); //bypass library processing and send self created HID Joystick1 report

extern void joy2_AN8(int16_t x, int16_t y); //update joystick 2 axis positions - use appropriate range for selected device

extern void joy2_button_change(uint8_t button, bool value); //change joystick 2 button state (1-8)

extern void joy2_button_press(uint8_t button); //press and release joystick 2 button (1-8)

extern void joy2_report(uint16_t &report); //bypass library processing and send self created HID Joystick2 report

 

//custom HID device commands

extern void device_report(uint8_t device, uint16_t &report); //send device report (uint16_t &report) for custom HID device (uint8_t device)

 

//CDC commands

TBD

 

//Mass Storage commands

TBD

 

Share this post


Link to post
Share on other sites

For the Mass Storage ... would MTP be an option?  I think it would be incredibly useful to produce "files" that are dynamic, think Linux's /proc and /sys filesystems.  Makes for a very easy firmware-to-PC interface.  I'm not too familiar with USB but I think something like MTP is how e.g. Apple and Android devices "share" their filesystem while keeping it mounted internally...

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