Page 1 of 1

Implementing a USB Driver

Posted: Sun Dec 30, 2012 8:02 pm
by mark3094
Hi,

I've recently been working with the Raspberry Pi. I can draw on the screen and print characters now, so the next step would seem to be to get some keyboard input.
For those not familiar with the RPi, the keyboard uses USB only, so therefore I will have to implement a USB driver (or subset thereof).

I've been looking on the USB Wiki page, and I have found it particularly daunting, as it's quite detailed (I can only imagine what the official documentation must be like). I have found the source for a small driver here:
https://github.com/Chadderz121/csud
Unfortunately, there is not much documentation on how it works yet.

For starters, I would just like to be able to have a simple host controller driver that can detect that something has been plugged in or disconnected. I think this is a reasonable goal to start with, and if I can figure this out the rest will be much easier.

I will keep reading with USB Wiki page, but does anyone know if there's a simple tutorial to explain where to begin practiacally?

I've also been looking at the standards (OHCI, UHCI and EHCI). Is it correct that I would only need to look at EHCI to support a USB device? At least to start with (I am aware that all specifications must be supported to be compliant)...


Thank you for any tips or pointers you may be able to provide.

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 11:07 am
by Jonatan44
Hi there,
you will first need to know what is the USB Host Controller version embedded to your board, then, understand the way it is enumerated to a physical address (on x86 the is usually done by the PCI).
beside the controller enumeration phase, there are several sheets you'll need to read about, the first one is the Host Controller spec which define the controller initialization, the scheduler setup, and the transactions stages.
in addition you'll need to read about the USB Core spec, which define the USB Device Framework, Hub setup, Split transactions (For low-seepd devices with no UHCI, if needed).
there could be a Keyboard (maybe also called as HID) spec you should be read which define the exact behavior of your device.

most of the information you'll be needing can be found here:
http://www.usb.org/developers/docs/

furthermore you could use as a reference some of the open source drivers others develop here in osdev.

best of luck.

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 12:40 pm
by shikhin
Hi,
Jonatan44 wrote:you will first need to know what is the USB Host Controller version embedded to your board, then, understand the way it is enumerated to a physical address (on x86 the is usually done by the PCI).
I lack knowledge on USB too, and have been looking into that area. Now, I've been trying to figure out how you access the host controller on the RPi. From the link the OP provided, the "HCD_DESIGNWARE_BASE" for the DesignWare OTG Core is mapped to 0x20980000. Now, I've tried the Broadcom SoC datasheets which link to synopsys, the manufacturers website. However, the datasheets on their website seem to be too sparse.

I've tried my luck at Google, and dug deep in documents, but can't find how "0x20980000" comes up? Any clues?

Regards,
Shikhin

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 1:13 pm
by Owen
Likely from the SoC Peripheral manual, found here

Note that the core has a phsical-to-device address "MMU" which may complicate matters

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 5:19 pm
by mark3094
Shikhin wrote:I lack knowledge on USB too, and have been looking into that area. Now, I've been trying to figure out how you access the host controller on the RPi. From the link the OP provided, the "HCD_DESIGNWARE_BASE" for the DesignWare OTG Core is mapped to 0x20980000. Now, I've tried the Broadcom SoC datasheets which link to synopsys, the manufacturers website. However, the datasheets on their website seem to be too sparse.

I've tried my luck at Google, and dug deep in documents, but can't find how "0x20980000" comes up? Any clues?

I have found that the Synopsis data sheet isn't available to the public. Unfortunately this makes it difficult to develop for.

I'm currently working through some reverse engineering of the code that I linked to in the first post. I'm not sure if I have the skills to get anything useful, but I will give it a shot.
I will share anything I can get here.

Something else to look into is Plan 9. They have a basic USB driver for the RPi as well.
Richard (from Plan 9) worked on the USB code, and sent me this link:
http://plan9.bell-labs.com/sources/cont ... m/usbdwc.c
He also suggested looking at "ralink 3050" and "cavium cn50xx" as they're similar.


Unfortunately, I've read a few posts about the RPi USB controller around the place, and a lot of people are saying it's buggy and hard to write for...


If I get any further, I will post an update here.

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 5:23 pm
by mark3094
PS
Shikhin wrote: From the link the OP provided, the "HCD_DESIGNWARE_BASE" for the DesignWare OTG Core is mapped to 0x20980000.
Yes, this is definitely the base address for USB MMIO. So far I can see that there are a series of single word 'registers' there (remembering that a word is 32-bit on RPi).

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 8:24 pm
by shikhin
Hi,
Owen wrote:Likely from the SoC Peripheral manual, found here

Note that the core has a phsical-to-device address "MMU" which may complicate matters
Yes, that one links to Synopsys' website, and I found out that the databook there isn't freely available.
mark3094 wrote:I have found that the Synopsis data sheet isn't available to the public. Unfortunately this makes it difficult to develop for.

I'm currently working through some reverse engineering of the code that I linked to in the first post. I'm not sure if I have the skills to get anything useful, but I will give it a shot.
I will share anything I can get here.

Something else to look into is Plan 9. They have a basic USB driver for the RPi as well.
Richard (from Plan 9) worked on the USB code, and sent me this link:
http://plan9.bell-labs.com/sources/cont ... m/usbdwc.c
He also suggested looking at "ralink 3050" and "cavium cn50xx" as they're similar.


Unfortunately, I've read a few posts about the RPi USB controller around the place, and a lot of people are saying it's buggy and hard to write for...


If I get any further, I will post an update here.
Aha, please keep on updating your progress here.

Regards,
Shikhin

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 8:30 pm
by shikhin
Hi,

On a quick look through that driver, it seems to use 0x7E980000 as the base address, which is what the Broadcom datasheet suggests. I *think* that driver may be out of date.

Regards,
Shikhin

Re: Implementing a USB Driver

Posted: Wed Jan 02, 2013 10:16 pm
by mark3094
The Broadcom manual does start all base addresses with 0x7E, and the driver uses 0x20...

Have a look on page 5 of the manual. It shows the memory mapping scheme.

It maps physical memory to 4 virtual locations, which correspond to caching 'aliases' (0, 4, 8 and C). 0x7E... refers to '4', which 0x20... refers to cache '0'.

Most things I have seen so far use 0x20, but some of the addresses relating to the GPU seem to work better with 0x7E


Hope that helps

Re: Implementing a USB Driver

Posted: Thu Jan 03, 2013 2:10 am
by mark3094
Shikhin wrote:Aha, please keep on updating your progress here.
Here is my work in progress for the RPi's USB Memory Mapped IO.
There's still a lot to go into this, but you may be able to use this to get started.

I will post another when it's more complete.

Re: Implementing a USB Driver

Posted: Sat Jan 05, 2013 3:37 am
by mark3094
I have finished my documentation for now.
You can find it here:
http://networkdirection.net/index.php?o ... &Itemid=54

There is still more work to go into it of course, but this should (hopefully) help a few people out.