V-USB on an ATmega328! - V-USB and HID Explained

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in my last USB video I told you how the USB protocol worked and how you could use a special at Mega 16u2 microcontroller to communicate over USB to act as a keyboard and while perhaps this is one of the better ways to utilize USB since the small details are taken care of by the hardware there's another way that involves no special Hardware whatsoever but rather uses firmware to run the USB protocol and that method is known as the vusb library you may decide to use a library like this on devices such as the atmega 328p or more famously known as an Arduino Uno since they don't have the necessary USB Hardware to communicate there are a few limitations with it though which I'll talk about more during the video I will also be showing you how the hid protocol works this is just the protocol on top of USB that we'll use to run the keyboard well without any further introduction let's start the video as I've just told you in the introduction vusb is not a hardware controlled implementation instead it is one that is run inside of the firmware this does mean that any old AVR can use USB but it does come with a cost if you watched the first video you will know just how involved the USB protocol is and there are a lot of steps in abstraction layers luckily V USB handles this for you but keep in mind it comes at the cost of a massive CPU load this means that there isn't much time for any processing other than USB it is possible to circumvent this by perhaps having another microcontroller handle most of the processing and then send it over to the USB microcontroller but that's beyond the scope of this video but what is in the scope of this video though is the hid protocol how it works and how we can implement it using the USB if you were inspired by my Hardware USB video you can still learn about the hid protocol here the ideas are the exact same anyways let's set up the circuit that we will need to create this hid keyboard I decided to skip the breadboard and solder most of the circuit together this time what you will need is a few buttons three LEDs a few resistors a 12 megahertz Crystal and most importantly your microcontroller the crystal is used by the V USB library to correctly time the USB data transfer you can pick another value Crystal but keep in mind that the clock options are rather strict you can only use 12 12.8 15 16.5 18 and finally 20 megahertz clock sources all of which are crystals except for the 12.8 and 16.5 options the strictness is due to the need for the clock to be precise enough to operate on the USB protocol you will also need a 3.3 volt regulator since while the USB voltage line is 5 volts the data lines are instead run on 3.3 volts simply make it easy on yourself and just power the entire circuit with 3.3 volts to begin with because the microcontroller is capable of running in 3.3 volts anyways I use an ams-1117 linear regulator to do the job but you can use any old linear regulator that fits the specs here this little IC was tricky to solder on since it is meant to be an SMD component but I still managed to decide right in the end anyways here's the full schematic for the circuit it is also in the description if you would prefer to see it in that way anyways that out of the way let's dive into the hid protocol this is a protocol that is typically implemented over USB but it has also proved to be protocol agnostic with it also being used in places like Bluetooth but we will be covering hid in a USB context anyways hid communication is done using two distinct forms of information report descriptors and reports from a top-down perspective report descriptors simply describe how the data will look inside of the reports themselves this idea of a descriptor is carried down from the USB protocol here's a hierarchy of the scriptures in a USB device the device descriptor and the configuration descriptor both describe exactly the device is and the interface descriptor describes what a certain subset of the device will do and how many endpoints it will need in our case the interface descriptor will describe this interface as an HID device beyond that point we will get into hid specific territory the hid descriptor tells us how many report descriptors and how many fiscal descriptors we will have this video will focus on report descriptors since physical descriptors are optional and only describe which parts of the human body will interact with which parts of the device report descriptors really make up the bulk of the work when using the hid protocol since there are a lot of options there are three types of reports described by the descriptors and they are input output and future reports input reports are the ones in which data is being sent to the host such as the keyboard data inversely outward rewards are where data is being sent to the device such as toggling the caps lock LED future reports are not intended for user interaction but more for internal communication if you have noticed these interactions seem familiar and that's because they can be somewhat represented by USB transfers which I talked about in the previous video in fact the hid specification even classes this as being synonymous to each other let's take a moment to talk about the methods in which data can be transferred by using USB hid device can have bi-directional communication over endpoint0 and while this might be enough for a few applications there's also another required USB endpoint which is an interrupt in endpoint this will provide more bandwidth than just the control transfers by themselves and if your device requires it you can set up the optional interrupt out endpoint as well great but how can we determine what the data means not just which direction well for that let's go back to the report descriptors like I said they describe reports similar to device and endpoint descriptors there's a key difference in the layout of the data though in device and endpoint descriptors the data is a fixed size table conversely report descriptors are made up of what are called items these items have no predefined structure meaning that you can completely customize how the reports will look at the cost of a little more complexity let's say that we have an input report planned and we need to send over all the control keys on the keyboard those would be the control alt GUI and shift keys first we will need to tell the computer that we're sending those keys and to do that we can use what is called a usage item a usage describes what a particular set of data represents so in our case those control keys we can then add a few more items to format the data we can use the logical Min and logical Max items to tell what the range of our data will be so since there are buttons they will either be a one or a zero the report size tag means how many bits each usage will be and again since they are one bit button presses we'll just use one bit each and since we have eight control keys we will need to describe that too so we'll use the report count item and give it an 8. so we have just described eight bits of data that'll represent our control keys but this is just one small portion of the entire descriptor so let me show you the one that I have created this chunky here is the one that we have just looked at anyways let's go from the top down starting at the top we have a uses page call this is distinct from the user's tag since it basically dictates what the usage means there is a rather large document which I will link below that basically guides you in this if we select the general usage we can select from this table of usages and that shows the keyboard usage within that the next item is the collection this basically groups up different reports under one idea which is our keyboard usage going inside the collection we will find another uses page but this time it's the keyboard table this essentially allows us to select the keys on the keyboard as like described earlier we're here to cover this section so let's go to the next section it's very similar but with a few differences we select the user's minimum to be the first key on the keyboard and the maximum to be the last key that we will use we will also set The Logical Min and Maxis to the minimum and maximum key codes this time the keys will be arranged as one by each with a maximum of six being reported at once we will use an array type input to return a maximum of six keys back to the computer finally we have the output section which is similar to the first one we will use the LED page to select our num lock caps lock and scroll lock LED outputs and finally we end the collection well now that we have the human readable version we need to convert it to the one that's used by the protocol and for that I've manually compiled mine you can simply copy mine if you would want but if you want to make your own like I did simply cross reference which each item's hex code is for example the usage minimum is a hex 19. there's also a useful website that you can use to double check your work and make sure that your hex values match what you're intending and that is basically it for the hid protocol it isn't too bad the hard part for us will be translating our V USB code into the hid protocol so let me tell you how to set up your own vusb project the first thing that you should do is download the V USB library from the USB website I'll provide a download link to that in the description from there you should make a new folder and place and extract the V USB Library into that inside the vusb library look for a folder named USB drv this is what you will need to compile the V USB Library into your project move this folder into your project folder and inside the V USB drv folder you will also find a file called USB config prototype.h copy this and place it into the project folder and also rename it to USB config.h now let's edit this USB config.h file the first things that you will need to do is edit the placements of the USB data lines I put mine on Port D on pin 0 and 2. going further down look for this line and change it to a 1. it basically will activate our required interrupt in the next endpoint next you will have to jump further down to the device descriptor section if you have your own vendor ID replace it here otherwise leave it as is since obdev has kindly provided a free vendor ID that we can use you should change the device ID as necessary though and that's changed mine to the one defined as a keyboard next change the vendor and device names if you have one change the vendor name to your name I changed mine to sign lab.net for example the device name is up to you but I changed it to keyboard next up are the device and interface classes since we don't want to Define behavior at the device class level we will put a zero to indicate that we will be using an interface descriptor instead then change the interface class to a hex 3 which stands for our hid class finally put in the size of bytes of your HIV descriptor and now we are done with the USB config.h edits let's get to the fun part and write our code the first thing that you will need to do is include a few header files include the USB drive.h if you are io.h if you are interrupt.h if you are program space.h and AVR watchdogtimer.h headers here's the bare minimum code flow that you need to include in your program first enable the Watchdog timer this is basically used to reset the microcontroller in case there's ever a time where a bug occurs and the device can't recover from there you should do any specific device setup such as pulling up your buttons for example then you need to initialize the vusb library with the USB init function immediately after enable interrupts from there you should re-enumerate the USB device since the USB getting the computer may not have the same address to do that simply disconnect the USB device and then reconnect it after a short delay now you can get into the main Loop the two functions that you need to do in the Watchdog reset in the USB pull functions this is the basic structure of the program but we are aiming to add keyboard functionality to do that we need a few more methods remember our USB interrupt in endpoint well we can use that to send our reports and for that we will use the USB interrupt is ready function to check that we are able to send data over the endpoint we can then we will send our data buffer using the USB set interrupt function the other code that I added around this was simply adding an ilorate that will either slow down or speed up the rate of our key presses being sent we have some other required methods that we will need to use to define ourselves first we need to give the microcontroller our hid descriptor simply put it in as an array called usb hid report descriptor we also need to define a method called USB function setup this is basically what is called when our control endpoint needs attention the main things we'll do here are sending reports just like the USB interrupt and endpoint and setting the idle rate we can also reject the output requests to another function by returning to the USB no message when it is brought up and to handle those output requests you will Define the USB function write function to toggle our LEDs when something like caps lock is activated and that is basically it as far as it goes for the explanation of the code it is complicated at first but you can definitely get used to this if you got lost anywhere in my explanation feel free to check out the link in the description it contains the entire project from the schematic all the way to the code after this project I have another small USB keyboard to play with anyways if you enjoyed this video and found it helpful please consider subscribing so that you can see my other videos have a good one and good luck with the USB projects
Info
Channel: Sine Lab
Views: 44,957
Rating: undefined out of 5
Keywords: microcontroller, AVR, PORT, AVR-GCC, Arduino, Atmega328p, how to, registers, 8 bit, IO, I/O, explained, easy, quick, hands on, timer, CPU, hardware, clock, counter, 256, USB, serial, keyboard, LED, ATmega16u2, V-USB, VUSB
Id: 6U_bHTnFu-g
Channel Id: undefined
Length: 14min 8sec (848 seconds)
Published: Thu Feb 23 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.