Using Teensyduino's USB library

Status
Not open for further replies.

e_l_tang

Member
I'm writing a custom keyboard firmware for the Teensy 2.0 and I'm planning to use Teensyduino's USB library. However, it's embedded deep inside Teensyduino along with a lot of other libraries that I don't need, and I'm not exactly sure what I need to do in order to isolate it. Does anyone have any ideas?

I also have some questions about the library. I'm wondering a) whether it uses interrupt-driven USB communication, and if so, whether there are any precautions I need to take before disabling interrupts, b) whether it would be possible to port this implementation of a NKRO keyboard to it, and c) whether it can tell me when a certain report has been picked up by the host.
 
Last edited:
I've got a similar unanswered question about USB interrupts over in: https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=129759&viewfull=1#post129759

FYI - I did find this: http://www.nxp.com/products/automot...cus/usb-stack:MEDICALUSB?tab=Design_Tools_Tab

USB_STACK_V5.0: ( https://www.nxp.com/webapp/Download...251240750393714284007&Parent_pageType=product )

But since my question has remained unanswered, which included asking if I could "brick" my Teensy's with my thoughts of moving forward on this platform, I've not had a chance to look into it and I've put the Teensy's in the draw for now and started playing with the LPC1768 board I bought at the same time as I bought the Teensy's. I'm actually having more luck with it too, I've got USB working and amazingly, I've managed to mount the boards SD drive in Windows as a drive at the same time! I suspect you can do all this with a Teensy too, but I've not been able to find anyone who's done it yet. But it'll be good when these mysteries are history.
 
Wow, many questions. Look, the basic answer is you can use the open source code according to its very permissive license, but you're mostly on your own to figure out the details of how to do so. But here's some quick answers to your specific questions...

I'm wondering a) whether it uses interrupt-driven USB communication,

Yes, interrupts are used for control transfers. You could pretty easily infer that by the use of "ISR(USB_GEN_vect)" and comments in the code:

https://github.com/PaulStoffregen/cores/blob/master/usb_hid/usb.c#L584

and if so, whether there are any precautions I need to take before disabling interrupts,

Yes. In general, you should follow the example of the existing code. Look for cli() and sei(). Here's one of them:

https://github.com/PaulStoffregen/cores/blob/master/usb_hid/usb_api.cpp#L259

b) whether it would be possible to port this implementation of a NKRO keyboard to it, and

Should be possible. Looks like it just sends a bigger HID report with bitmaps. With all HID stuff, the key is making sure you transmit a packet exactly the same size as your report descriptors says it will be. Windows, Mac and Linux ignore wrong-size packets. It also helps to get the data correct, but as long as the packet size is right, you'll get some results which is a lot easier to troubleshoot than having the driver discard your data.

c) whether it can tell me when a certain report has been picked up by the host.

Generally, the way USB endpoints work is you write a packet into a buffer and give it to the USB to use next time the host requests data (sends an IN token) from that endpoint. On these AVR USB chips, that's done by writing to the UEINTX register, as you can see if you read through the code. From there, the USB hardware takes are of everything. You just compose the packet, give it to the hardware, and don't worry about it anymore.

Perhaps with some work, you could find a way to infer if the host has requested the data and the hardware as responded to the IN token. That all happens automatically under hardware control, so you'd have to infer if it's happened by looking for clues you are able to observe. In these older AVR chips, each endpoint is either single or double buffered. You can't implement more buffers as you can with the newer parts, or get much info. But if you configure the hardware is single buffer mode, whether the hardware tells you a new buffer is available for writing would probably be a pretty good indication it's completed the prior packet transmission. Maybe there are other ways? Honestly, I've never really put any effort into that, at least not on AVR where the hardware manages a 1 or 2 deep packet queue for you.

Like all this stuff, if you want to do these things, you're going to have to dig into the code and figure it out.
 
Many thanks for the answers, Paul. I'm sure they will all be helpful when I get around to implementing the functionalities I asked about, but I think right now I'll have my hands pretty full trying to get the basic functionality working without the help of the Arduino IDE.
 
You could save yourself a lot of time and trouble by just using the Arduino IDE, and then modify the core library code to suit your needs.

But if there's some reason you just have to do it all the hard way, well, suit yourself. It's your time...
 
The problem is that I plan to port my project to many, many more chips, some of which are not supported by the Arduino IDE. If I take the easy way now, I'm going to have to face freeing my entire project from the Arduino IDE sometime down the road.

In the meantime, I've found this library. Would it be at all possible for you to port to it the new features offered by Teensyduino's? I truly believe that it remains a valuable resource for those who want to avoid using the Arduino IDE.
 
Just an observation here, you are asking paul to re-visit code that he has already decided he didn't like, and put hours into it to support hardware he doesn't have (makes testing hard) and that he doesn't sell.

Agree that a robust USB stack open source is a good thing to have, but you are asking for potentially over $1k of manhours that you were not planing to pay for directly. With what you are doing I'd say you could reasonably ask direct questions on why the code does certain things(having read the code and the chip reference first) that can be answered in a minute or two (and preferably with a yes/no) but if you are asking for 20 minutes worth of one on one tuition you need think about how you are asking for this and what you, Paul and the rest of the world gets out of it in the end.

Gratitude is nice, but you can't eat it
 
I don't want to discourage you. I also don't want to speak too harshly here, but from the nature of these questions it's pretty clear you're at only the very beginning of your project.

When/if you dig deeper into the code, you'll discover the USB support in Teensyduino for those 8 bit AVR chips is basically the same as those obsolete stand-alone zip files. The single C file approach was separated into two files, the original C code for the USB control stuff and basically the same C code renamed to C++ functions for the sake of Arduino. On the keyboard stuff, a translation layer for non-US layouts and decoding UTF8 was added, but even that is pretty straightforward C-only code inside C++ functions, and it's just another layer on top, not actual USB device code. The actual USB stuff is pretty much identical.

You're probably also going to discover the concept of "plan to port my project to many, many more chips" may not be very realistic. Or at least starting from my C-only code or my nearly identical C/C++ code in Teensyduino probably isn't a good idea. That code is pretty tightly coupled to the specifics of those chips used on Teensy 2.0 and Teensy++ 2.0. If you look at the USB code inside Teensyduino for Teensy LC & 3.x, you'll see I pretty much started over from scratch. That ought to give you some idea of where you'll be headed...

I'd advise you to take a look at Dean Camera's LUFA library.

http://www.fourwalledcubicle.com/LUFA.php

As you look into the code, you'll see Dean and I have pretty much opposite coding styles! Where I take a minimal, coupled-tightly-to-hardware approach, Dean puts in a lot of work to abstract almost everything. His library was designed to support many chips. I believe it supports all the AVR USB chips, whereas my work only supports the specific chips we used one 4 Teensy models, and 2 of those have been discontinued for nearly 8 years and haven't been supported for a very long time. I believe Dean also did some work for NXP to port his library to some of their LPC chips. Even if you don't use Dean's code, it has a design that's aligned with your many-chips goal. My code has pretty much the opposite design! I personally find all that extra abstraction stuff distracting, but then my focus has always been laser-focused on specific chips. For your project's goal to support a very wide range, you're probably going to need that sort of approach.

You're also going to discover two unpleasant realities of USB. First the obvious: the protocol is very complex, especially when you factor in the huge range of device class specs and quirks of the 3 major operating systems across many older versions still in widespread use. The second reality you'll find is the hardware support in different microcontrollers varies dramatically. That's why I basically re-wrote everything from scratch for the 32 bit boards. It's also why I haven't (yet) supported the 2nd USB port on Teensy 3.6... it's completely different from the 1st USB port, even though they're on the same chip.

Again, I don't want to discourage you. I do hope you can find something useful in Dean's library or even my code. But please understand I'm very focused on just the specific hardware we use on Teensy. As you can see from the still-lacking support of the 2nd USB port on Teensy 3.6, I have a tremendous amount of work to do. Other than pointing you towards LUFA and the general idea of abstractions you'll need to support many chips, I really can't help you any more.
 
Status
Not open for further replies.
Back
Top