THIS TRANSCRIPT IS AUTOMATICALLY GENERATED BY COMPUTER VOICE RECOGNITION. It is good enough to be worth posting, but not perfectly accurate. Do not cite it or take it too seriously; if people do, then I will take it offline. i good afternoon welcome to my schedule stream from may thirty first so in this stream i am planning to first of all unbox a bunch of knobs that i got from i supplier in taiwan and then i'm also going to work some more on this usb host project now i spoke last time about all my adventures with my windows laptop and i still have not resolved what i'm going to do with that so i am using my very elderly netbook here too as a separate as a separate computer to control the stream and that works surprisingly well given that for instance its battery is completely destroyed so i can only i can only use it on the ac adapter and hope that there's never a glitch that would cause it to work to reboot and the windows machine and i'm pretty sure that it is wedged that the current upgrade process just will not work it just keeps rebooting and saying oh undoing trying again etc now i've done some reading on the net and it doesn't look like there is some possibility of being able to recover that you know why mean people who actually want to have windows machines will will will have procedures they can use to try and recover it and get it back into a state where it can be used i'm still not decided whether i really want to do that or if i just want to say okay this this machine is no longer good enough to run current windows i'm going to have another linux laptop out of it but anyway until i get that machine with sons sort of operating system installed on it that can actually run i won't be able to use it so if i want to do this thing with screen capture and so on as i'm doing for my for my usb host development i i'm pretty much stuck with having another machine of some sort so that's where that stands are but first before going any further on that i would like to actually unbox these knobs so i got this i use grey knobs in my a regular assembled module products and blue knobs in the other ones in the in the do it yourself kits and so after having various troubles with the knobs from the manufacturer in mainland china i decided to deal with this other outfit in taiwan and so it was four months lead time from these people so i placed the the order back in january and now they've they've come through here you can see the label there its ok i'm not sure with north refers to with maybe that its like the north north of taiwan or something and this one's going to come canada made in taiwan r o c yetta i solidly packed up box here and on the end there's the description of the quantity three thousand knives from here and these are all blue i'm still working on on a batch of grey ones from the other manufacturer i've not had to replenish those since since switching so just cut open this here and down below the camera is another strap there to come oh and i guess i gotta get this one off so scientists well i've already removed the customs paperwork both because i need it for bookkeeping because it has private information in it off camera here i'm reading moving the binder have usb documentation which i have balanced on top of the garbage can because that was the most convenient place for it cause i'm gonna need to get in there to work put these straps in the garbage try not to disk mode my laptop there isn't putting these away alright so that's those off amd then and now the top flaps have to be opened up here i recently ran out of blades for this knife and i bought some more and replaced them and promptly cut myself with the new blade because it was sharper than the old one and so it would go through the material faster than i expected so i'm trying to get used to that use the weights carefully and not to not do it again yeah double wall box they really want to make sure they're sending a distance distance i saw on the package tracking that this shipment actually got from taipei to toronto by way of anchorage alaska which when you look carefully at the globe is actually pretty much on the straight line between the two alright so here's the thing in the top there don't have it says i dunno if you can read it on the camera but packed in here and of course we've got the east east asian thing of a very very nice artistic looking packing tactic here is large knobs okay these are typical of the kinds of knobs you see on guitar pedals often and those are the ones that i use for like the main tuning knobs on my products that need tuning knobs one thousand of those and now here's another batch of one thousand and these are the smaller ones and they're all blue and they're all supposed to be matching blue so there we go and then the third batch of one thousand these are also the larger ones no these are the smaller ones as they should be okay now i'm not going to its probably easier to move these packed up and rubber banded together but i will pull out tree from a previous shipment so you can see how they're packed here you got this trade and then this bit peels off and inside there are all these little cups quite a nifty little less trade system there i'm not sure what else i might be able to use the empty trays for but it certainly looks like a useful kind of a thing and we also have this nice double wall boxes i currently have some of my spare your home not really spare but your req modules that are not currently in my rack in one of these boxes from a previous order and i really ought to get a new rack so that i can actually have more of my synthesizer usable at once hello to traveled yeah so that is the unboxing of the blue knobs and its a good thing because i although i'm not completely out of the blue notes from the previous shipment i was low enough that and it was certainly reorder time and with a four month lead time on on these you you you have to be be safe about or ordering them in in time for there to be enough when you actually need them because you can't be waking up one morning and say oh i have no more blue knobs i'll just buy some more oh its four months now because of because of the dreaded rona and all the other things that to keep them keep keep manufacturing on a longer timeline so having done that i can start looking at my at my next step here which is going to be working on this usb device alright and its actually a usb host not a device that's an important distinction so i pulled this to a more convenient location the little rubber feet on my laptop here never really want to stay on but i've been trying to extend their life as long as possible anyway alright so this is a i don't know if you saw on the previous stream but this is planned to be my next my next product yeah msk or one for gracious host and the idea is that this is going to be a usb midi interface for your iraq but its its a usb host meaning that you can plug devices into it you don't need a separate computer so if you've got a usb midi controller like this is and became many here this is a device that has the device i guess its called a type b port on it this is meant to plug into a computer or a thing that functions like a computer and you can't just plug it into the common kind of your rack midi interface which also functions as a device you need something that functions like a computer this is supposed to be that thing and given that i'm doing the work to get this to be a usb host it seems like there are other cool things that can do it should be able to do which then extend to the the demands on the design in particular i'd like this to be able to reflash its firmware just by plugging in a usb key with the new firmware say put that in there and then it then it loads itself off there but that means that then it has to be able to for instance decode dos filesystem on the usb stick and there are also constraints in terms of memory capacity on hair and speed of the usb interface because you when you talk to one of these you have to talk to it faster than you would when talking just to a midi keyboard and i was thinking of other cool ways that's a usb hosting device in a synthesizer rack could work one of them that i'm quite enthusiastic about would be the idea that maybe we plug a mouse in all right this is one of my old mice its in terrible shape here but it does i know still answer on the usb port so maybe we could plug this in here and then like as you move the mouse around maybe the x coordinate comes out on one of these analog outputs and the y coordinate comes out on another and you click and get a gate so i can imagine using the mouse as a controller for the synthesizer so that you click ui and then maybe the the vertical can be like a the filter cut off or something and the the buttons can trigger notes and so on given that i'm building a device that is supposed to be a usb host it seems like i can hope if there's enough space in the program memory on this thing that then then i can also add that function and it would also be cool if i could plug a keyboard keyboard like a qwerty typing keyboard into the airport and then use that to control the synth the idea being that controllers are up a whole both in sort of the iraq market and in my own product line i'd really like to be able to have module that people can use to control their synths now as of last last week when i did the stream i had this basically booting up it was owen's i didn't i went into a lot of detail last time i probably won't repeat today unless people want to quiz me about it there are a lot of different reasons why i can't just use the usb stack that the microcontroller vendor provides okay so i'm writing my own in assembly language and that means every little step of the way of talking to the to the usb device everything where i am i have to enumerated and we set the boston so on i i have to write that out instruction by instruction in the driver because i don't have a ready-made driver i can use so as of last week the device was booting up it was talking to the usb hardware that's built into this chip at that time i didn't really have any solid evidence that it was chocking any further to the actual usb device that's plugged in here although it was at least detecting when one is plugged in it and removed so since then i did a lot of debugging and and work in in in the driver i got it as far as loading the what is called the device descriptor because each one of these when it plugs in the computer can query it and ask what sort of device are you so i was loading the device descriptor for a while i was only able to load the first eight bytes of the device descriptor and that was a tricky bug to to debug it turned out that what was happening was i was looking in the wrong register to get the endpoint address but it happened that the first read i tried to do was have eight bytes and when i read eight bytes then it happened that what i was getting in the wrong register happened to be the correct value of the endpoint anyway just coincidentally so then as soon as i tried to read the rest of the descriptor i was getting a different value from that wrong register and it would no longer work so you know eventually i found a place in my code where it said w one and it was supposed to say w two and i changed that and then it worked but there were a lot of adventurous along that way in the last week at this point i've got it to the point where it can correctly read the device descriptor so for some devices in particular hubs which i don't support it can recognize oh this is a hub i don't support it i'd like to be able to demo there for you but unfortunately the only hub i have handy is the one that is controlling my cameras and connecting them to my desktop computer so i can't really pull that how about views to plug it in here but you'll have to take my word for it that now if i power this up and plug in a hub it gives the the blink code on the lcd that indicates hey this is a hub i don't support hubs but my next step is to see start adding code that will recognize other classes of device so i have got here i plugged basically all the random device usb devices i had handy that i thought could reasonably work with this into my desktop computer and i printed out the ls usb outputs from from linux which gives me all the details of the device and configuration and interface descriptors and so i'm going to try to sort of work through this i i've created some infrastructure code which we'll see in a moment for for dealing with when what happens when we recognize the device and the idea is now i have a a and i want to have a generic usb driver in my firmware and then i will add specific drivers for the different kinds of devices so with all that in mind that's sort of where we're going the first thing i'm going to do i i've put some finishing touches on that framework this morning i've not yet tested it so there are quite likely still bugs so i'm going to want to do boot this thing up go through it in the debugger see that it can that the infrastructure code actually works at this point if i plug this in and if everything works the way its intended to it will start giving a blinking lights indicating that it does not support this class of device the usb master marriage and then if that work if that doesn't work well then i fix it and if it does work then i can start blocking in the other kinds of specific drivers that i'm going to want so that's sort of exciting if everything goes really really well it would be cool if i can actually get it to the point where its talking to a mouse in i think i'll do the mouse first cause that's probably one of the simplest devices and get it to the point where its actually talking to a mouse in this stream but there's a good chance that i won't really be able to get that far we'll just see how far how far i get so i documentation out to the side this off to the side i will power up the power supply that stabilize and i'm going to switch to incidentally hello to eol salak and academy impossible and i'm going to switch to the screen capture now you should be aware that screen capture on this machine and there's a considerable delay so as i'm talking and typing i'm hoping that my lips will match my voice but when i when i do something that there's then a few seconds delay like maybe four or five before you actually see it on the screen and i think the only way i could prevent that would be to put a similar delay on both my voice and my my video and that would cause other problems especially because obvious seems to have an arbitrary limit of like two hundred and fifty milliseconds and i would need far more than that amount of delay so you know there's all this extra extra behind the scenes stuff needed to make this work but let me switch to the screen capture okay here we are at screen capture and i can see that that works but actually which way do i want to go i think i probably want to stay on the camera for a little while first because power supplies now stabilized here's the then power this up first i and then this this devices the the interface that allows the debugger to take control over it through the the bug report on the side a regular production device would not have this header but it has a spot on the pc for it and then then i can side of it in when i'm using one for debug similarly a regular production version of this device would not probably have this voltage regulator i am intending this your req module to be one of the few in the world that requires a five foot supply because it really does use a fair bit of five volts including the five volts that it provides to the usb bus alright so i'll see if i can keep this on screen there we go there's our device and now i will switch to the what's happening here now i will switch to the laptop screen capture that is the screen capture from the from the keyboard that you were seeing on the camera a minute ago and oh good there so let's start up the microchip developer tool this one takes a little while to load because the laptop i'm running it on is just barely powerful enough but it does work that's basically why i needed to have two laptops here i can't control this dream and and also be running this developer tool at the same time because each of them is i'd rather having load on the machine and well that's loading really i should go back here and grab the latest version from the and server let's see do i have any local edits only this one which disables the listing i i've been playing with trying to format really nice detail to listings of the assembled code using latex can i don't have a check on this this development machine so i had to turn off that that listing generator in the makefile snp lab coming now its still loading modules mp lab seems to be one of those can't live with it can't live without it things i mean it it does do a lot of really cool stuff but it also has some very serious annoyances slowness among them i mean we see here all this all these empty window views because even though its been able to put up its interface its not actually finished loading okay so there's the code getting close now and come on just checking i i wonder if my voice is coming through okay my levels are looking a little lower than that then i was expecting them to be i think since i'm waiting for them anyway i'm just going to go over and check the mixer which is not within grabbing distance of where i'm sitting back in the second check one two check one two okay i think that's probably okay i may just have not been speaking up enough okay so this seems to be fully loaded now so i'm going to build the project with that new source code i downloaded new devices with pac support released fuck off and this thing is always trying to update itself there doesn't seem to be a way to turn that off and i have learned the hard way that if i allow it to try to update itself on this computer it will run out of memory and crash and there doesn't seem to be any way to like just only update the parts i'm interested in or anything like that and there's no way to actually turn off the auto update which i don't even need because nearly all of the updates are only applicable to chips i'm not working on i spoke yet last week about how its really a serious negative if any language software package or whatever else has its own package manager pack updates fuck off again i and this is a perfect example if if they could just have a file you download and then if you want to update you download another one if you don't you don't that's how updates should be handled but no everybody seems to think that they they need to have a a thing that automatically updates itself and i mean this is embedded development right we're not talking about something that would normally have been major security implications and so on you run this locally there's no reason it needs to talk to a network except that they want to create a reason so that they can run their stupid licensing servers and whatnot and we've already discussed last week how they are they are the ones in the wrong when it comes to licensing because what they're doing with the gpl code here is totally illegal alright but anyway i'm going to program this device so the compiled code is now going onto that to onto that chip and the latest version of my firmware is going to be downloaded onto it i and away we go okay so its fully programmed so now if i launch the debugger it stopped at address zero which is the starting point press f one and it takes us to the first instruction of the program which is here now i believe that if i just let this run i we'll see what happens but this should actually be a functioning driver that recognizes devices and if you plug in a hubby complains and if you plug in something else that complains with a slightly different blinking code on the lights so let me try that okay the firmware is running and i'm going to switch to the camera again so we can see what happens if i plug in my usb stick the lights should go flash green very briefly and then it should be blinking this light in morse code d i know that's not what happened says user program stopped so a question would be where i alright it may be that it stopped at a straight breakpoint that i left in place or it may be that there is something more serious wrong so i'm going to go to program memory hmm it says reset okay so we triggered some sort of reset ah its not very promising okay so i will properly reset and i let's go into usb here's the usb driver let's see how far its actually getting i'm leaving the usb stick plugged in so it will automatically immediately recognize it as soon as it boots up i and okay so here is bus resets the eddy and set the device address let's see if it goes at least that far so this stuff appear goes does the device reset then waits five milliseconds what i'm going to go up to this point render there see if it actually gets that far it does okay so let's see if it makes it through the next transaction which is asking for the first eight bytes of the descriptor run up to there that works so let's see what's next i did a fair bit of messing around with the the linker and defining a custom linker script the thing is i've got my main driver that runs the usb port in general and i i want to have a separate driver for each of the kinds of devices i support like i would have a a driver for mice and a driver for midi keyboards and the driver for typing keyboards and so on and i don't want to have to have code in my main driver that knows about all of those others so what i'm going to do is i will have each of my pr device drivers in its own file and each of them defines a section in this in an assembly code with a special name and then the linker gathers together all those sections and inserts them into the code right right here okay there'll be one section of inserts like this for the things that recognize devices by their device type and there'll be a similar section down here for recognizing things by their they're the type associated with a particular interface usb devices have a device descriptor that tells you here's what this device does and the only ones that actually tell you that as far as i can tell at least that i've seen are hobbes those they are current device type nine and then if its anything else that just says oh you have to look at the configuration and interface descriptors and then each device will have one or more configuration descriptors usually exactly one and each configuration descriptor will have one or more interface descriptors and the interface descriptors are practically the ones that you really care about so what i have not yet done it yet is going to be writing a loop that loops over all of the configuration and interface descriptors and then examines them by running them through this this targeted interface list which is a chunk of code that is compile or put together by the the linker from all of the device drivers that i write so i've got most about stuff is ready to go but i don't have it and i don't know yet that we're actually getting into that code so i know that the code is working up to this point i don't know that its working any further so i guess the next thing to do is try running up to that point there this will be the next instruction that runs after this do control transaction i don't want to step through that because if i do i will be delaying it longer than the device can handle devices will have reset themselves if you delay too long so reset and try running up to here let's see if that works it did very nice so this chunk of code right here is what's supposed to test whether we have inserted a hub and it puts in w for it puts a a handle which is a which in this machine its going to be just the address of function pointer basically an address to branch to an input w five it puts us matching pattern ff zero nine which is it says match device class nine its any subclass and then it causes helper function which will actually test whether the descriptor we have read meets the that description it will not because i just inserted a usb key but i have tested this dysfunction before i'm pretty sure that it works unless i've broken it recently so let's go look at that function alright make a copy of the matching pattern actually get the class and subclass so those go in register zero and one i'm going to remove this little window here yeah so zero ff oh nine one says zero and that surprises me but yeah that is correct the usb key because its one of these ones that doesn't have a class of its own it it says oh you gotta look in the interface descriptors it has zeros for class and subclass so that is correctly guy getting that information out of the descriptor so register to gets all f's now we compare does this compare and skip if not equal of just the low byte cps and he does be very complicated mnemonic there who can attest to the low bytes zero nine and zero zero match no so we skip now we test does the low byte equal ff it does not and so this test we were looking for hub it does not match its not a hub so we jump over to throw which is just a convenient label for a return statement alright and that was the entirety of the targeted device list so now we step through this and then we will i yeah okay so there was no targeted interface list so now we're going to complain about the device so we're going to save the blink pattern and jumped to this finish with blinking set up the blinking command yana this all should work okay and and if i switch to my camera hair it has in fact lit up red okay so we're sort of working the trouble is its not really supposed to be just lighting operate its supposed to be blinking in a pattern of long short short long short short so that's a question why is it not why is it not blinking the way i expected and hello to pitch and child again i have enough other things on my plate here that i can't necessarily always know when people connect and disconnect but i try to greet them when i can so let's switch back to the laptop and see if we can figure out why its going solid red oh part of the reason could be that i've got this i've i've got this program stopped so if i hit continue and just let it run it still doesn't work okay so that wasn't the problem i let me try jumping to complain about hub this will do the blinking thing with a different blink pattern which i know works i've done it before set pc at cursor if i run from there yeah ok that works let me show you one camera i dunno how this will interface interact with my relatively low frame rate but this is blinking in groups of four blinks so its its for for blinks and then and then a brief period of of going dark so if that works why didn't the other one work the again i'm going to set the pc a cursor so this is supposed to be basically identical code this code that worked here was put the blink pattern in all i see it do you see it probably not but there ought to be a hashmap right there okay if you put a hash mark on an operand in this dialect of assembly language it means immediate so you're actually putting the number in so the one that worked was putting the number f nine two four into register one and this one because there's no hash mark its putting the contents of address ff eight into register one now ff a eight is going to be an unmapped area of memory it'll probably return all emphasis on no or or zero i guess it must have been returning zero because that's what the value that would give solid red so i've just inserted a hash mark there and that will save all and now i've got to go back and redo all those other steps i like to clean and build just to make sure everything gets rebuilt theoretically that shouldn't be necessary but you know there are so many things that can go wrong i don't want to be debugging unnecessarily just because i didn't compile the entire program the entire program is the the chip's capacity is sixty four k so its never going to be a large program here i might as well compile or assemble the whole thing all at once alright so now i'm programmed to face for debugging page says hello hi and the programming complete okay so now launched the bugger main product main project and that's ready to go so i just hit run okay and it is working now if i switch to show you the the camera long short short i don't know how well you can see that given the frame rate on the camera but it is blinking morse code de la dad did it which is the the code for unrecognized device if i pull pull this out it goes back to its normal state without a without a device inserted put it in it should blink dead at it that's great okay so this code as far as i can tell at this point it is working the way that i planned for it to work so then i have the opportunity to make it do other things so the next step is going to be i think creating stubs drivers for all of the kinds of devices that i'm sure i'm going to want to work with and then i can start having a trek then and then i guess i will write the loop that tries to get configuration and interface descriptors and then i can try to actually get those drivers to wreck to be recognized or to recognize the devices that are inserted i've got a little menagerie here of mouse a dollar store keyboard i think this was literally three bucks yeah says three dollars there so this is like the cheapest usb keyboard by me can buy ah and i've got various midi devices and other things that i can plug into that thing and we'll see if it can get them to to recognize them if everything goes really really well today i could even try to actually start talking to the devices and implement some behavior for them but i doubt that i will get that far because that means yeah doing stuff like sending and receiving data tokens and so far i've only ever done controlled transactions on the usb bus but we'll see how far we get so i just its fun to just watch that a little like blinking away its supposed to but i am going to stop the code and without the device shuts down hmmmm i'm going to exit from m p lab here which i guess you can't see because i have got to i'm on the camera instead of the screen capture but let's switch to that okay screen capture then off screen i am disconnecting the debugger from the device and disconnecting the device from power to put those off to the side turn off the power supply okay so where am i here i want to be in the firmware directory so i think the next thing i'm going to want to do is create a bunch of a bunch of new files in here i i hope my text size is ok here too be at least sort of readable on the screen i eli deep link is a nice small assembly language source code file here so all right what files am i going to need i'm going to need typing keyboard mouse and midi device mass storage i'm going to call it typing keyboard qwerty i don't want to just call it keyboard because that could be confused with a midi keyboard this will be a stunt file this will be the section as he's used to recognize when you've plugged in a qwerty keyboard and for the moment it won't actually contain any code because we need to create infrastructure before we can really really do that i'm going to put in some lines there to make the listing look nice okay this will be a stub for actually let's put in some know ops there so that i can break that with the debugger alright so what am i doing here abort that i only want to commit qwerty and usb so this is the bug fix from a few minutes ago and also the and also the new starter for qwerty keyboards after doing this commit i will then copy that and to make minor changes to create stumps for other devices the the ok now what else do i need i need mass storage the and yeah i don't really like that name the make it a little shorter usb mass yeah i the and usb media is going to be sort of the front end and when you plug in a year or usb midi device there will be also a sort of a back end which handles midi events because i want to be able to generate midi events from some of my other devices like it could be that when you press a keyboard a key on the qwerty key keyboard that's like if you had sent a media event sharing coats there there'll be a separate file for that i alright usb mouse usb midi qwerty i guess i also want a mouse what other kinds of usb goodies could i have that it would make sense to plug into this can't really do audio because that requires either cronus transfers which i don't think my microcontroller is up to and similarly i can't do or can't really do cameras i just don't have the horsepower to deal with the amount of data that comes from a camera but those four are probably enough for now so let's edit let's be mass usb midi mouse just going to update the names in here the mass storage device driver and usb midi i have a roland boutique mid usb quote unquote midi synthesizer and the descriptors for it are just just say vendor specific its not really usb midi its its own weird thing now i may at some point be able to add support for it to here but that's not really a high priority he must be class compliant let's say okay created those now i do in fact end up having to list all the drivers i'm going to use elsewhere its not absolutely perfectly just handled by linker because i have to put them in the in the makefile but i can come pretty close alright let's see usb mouse usb midi its just mouse usb masses mouse mouse usb mouse he was being midi and qwerty and let's split this across a few more lines okay how scored a usb master and usb midi dot k i think but those changes to the makefile are going to be enough that when i make it which i'll do from the command line instead of booting up mp lab again its going to work now okay so it assembles fine ah if i look in this map file this is the output of the linker that tells me all of the sections that it put together to create the create the program this output section tpl that's where it puts all that all the results of gathering together of the chunks from the different drivers and if i scroll down further in here we'll be able to see what actually went into that tpl output section which should include input sections gathered from all the different driver files and it worked very nicely okay right here this is the stuff that went into the output section tpl and it says going down here at gathered seven c bytes from the usb main driver that's the initialisation he gathered six bytes also from the usb main driver but in this different section this is tedious ten it takes priority ten over other tedious stuff than six bytes of stuff in the middle six bytes bytes each from mouse qwerty usb mouse usb midi if i wanted to set specific priority between those i could although in fact its just using the order they were specified on the command line which happens to be alphabetical okay so all of that code is working nicely i'm kinda attempted to just right now go and and try it even though i haven't run the haven't created the loops let's let's do that maybe i shouldn't have torn down all my hook up there with the different to different items but yeah had her start mp lab again maybe i should have left mp lab running but okay so while that's booting up i will power up the power up the device under test and give you a view of the camera again so pumped up that and get some room here where we can see the see the lights on the other stuff okay well that is still loading but so be it my other time here let's commit those changes actually i want to i yeah i guess i have to commit the changes to makefile as well i was hoping not to commit that that change of removing the listing thing but its probably least resistance to go ahead and committed and i can undo it later so i stub the mouse try more step drivers okay i can as you saw me earlier edit files right in the mp lab but i prefer to use my own editor for that so after the test i'm about to run the next thing is going to be actually creating these loops okay i want a loop over the configurations and then within a configuration pool for interfaces and at each of those steps i'm going to have to be talking to the usb device to to actually get its descriptors from it ah and then that will put information into the registers that this you know there's no code in this file right here but this this comment marks the spot where in fact because of the linker foolishness it will be throwing in chunks of code from elsewhere so what i would like to do is just step through from here and see it go through each of those pieces of code once this is fuck off once this is fully booted up there it can do that i something else i'm going to have to do his deal with common data and this microcontroller has very little ram it has i think a total of eight kilobytes of ram which is not enough to do stuff like flashing its own firmware so i've actually got a separate ram chip on there which is accessed through a serial port on the microcontroller so you can't just normally access it with machine instructions so i have a common data area its a chunk of ram that's different drivers can use when they want to and they all define their own variables in that space on top of each other and then you just have to hope that more there that the i have arranged the drivers intelligently enough that one of them won't be using it while another one is so i want to use that space at the moment whenever i read a descriptor from the device i'm writing it into the stack i want a copy into the common area four so that so that i can trash that stack frame by loading another descriptor so how are we doing on booting this up think we're ready to go on here so i don't have to think about that yet instead i'm going to clean and build for debugging main project okay that's built and i will write to the device okay and now i won't watch the debugger just check i don't have any breakpoints do i don't break points didn't want any right now and so i want to run after inserting my usb key i i want to run through here through the target device list i want to run up to here some hitting a four and now the device goes off and runs and then i'm going to offer capture here i'm going to insert my mia usb stick alright and here we are now as i step through here if all is as it should be i think they should jump into one of my stubbed your ice drivers yeah its gone and loaded ok now at this point although i haven't written the code we are pretending that i have already read an interface and configuration from the device so now that information will be in some variables i have yet to define and now we're running part of the mouse device driver which has the opportunity to look at that configuration information and say hey is this a mouse and if this code which is currently just no ops if that code is going to look at that information so yes it is a mouse then it'll have the opportunities they okay i want to i want to be the driver that handles this so we step through there if we fall off the bottom of this section that means it wasn't a mouse or it wasn't something that mouse driver wanted to deal with okay is this something that the typing keyboard driver wants to deal with no is this something the mass storage device driver wants to deal with no okay is this something that the class compliant midi device driver wants to deal with no and then there are being no more drivers we have fallen right through this targeted interface list and a bunch of comments and now we're going into the routine complain about device which we fixed a bug in a few minutes ago and if i run from there it does the blink code and you can see that on the camera so that's great all that logic is working the way that i had planned for it to so now we can start actually implementing the next phase lists i'm going to try to be smart and only close this not only minimize it not actually turn it off as i go to write new code here alright so i am going to want to see follows substantially the model that i've got stances of code here that get the ok so that send control transactions to the usb device so this one here is here it sends a set packet that sets the device address to one because i'm not dealing with hubs i'm saying no you can't use hubs with this host you just have to plug the device in enumeration the usb has this complicated thing where when you plug in a device the host has to give every device and address number and there could potentially be a lot of devices on the same ah the same usb network and move plugged in through multiple levels of hubs and stuff since i'm not allowing hubs its much simpler there's just one device and so we might as well just say you are address one every time so we send this setup packet here's codes that sets up their packet then it goes off and runs have a sub routine that actually sends it off to the device and waits for a response after setting the address you have to wait five mil i'm waiting five milliseconds specified a minimum of two milliseconds before the device can be depended upon to actually know what its new address is then i'm sending another setup packet which asks for the first eight bytes of the device descriptor and i do that because some devices aren't able to send more than eight bytes at a time and i don't know how many bytes of consent at a time until i've read the descriptor and so forth even though i actually know that device descriptors are always eighteen bytes long in theory i'm using the read length idiot reports so then i extract the length of the descriptor than i ask for the device descriptor which is and almost identical operation that's just asking for its using the new length that i already extracted then once i've got the device descriptor then i can go off and run stubs from from the different device drivers if there are any that actually care about the device descriptor and here's an example of one this is the the driver for what happens if you insert a hob it'll complain about the hub this is the point where i need some new code do i need to save this i'm going since i have plenty of space in the common coming ram ram area i'm going to save the entire device descriptor eighteen bytes i so i guess i need to actually define the stuff that it'll go in that common area and i'm going to do that by imitating the common area stuff that was in the loader i actually that may have been the wrong place to look i know i've got some code already for dealing with the common area so i want to find any comment yeah i may even have some macros defined for that yeah ok so yeah so it looks like i set up the data structure i have previously written macros for this i'm going to just sort of assume that they work here's my existing data structure that's do i want another little section in the no but this is only going to be if you want i don't want to define a whole new section for that so device descriptor is eighteen bytes and i don't remember how big a interface descriptor is but we can find out got the usb specifications here and we'll see if the computer is big enough to load the hat as well as the other stuff its doing i yeah it looks pretty good interface descriptor standard interface descriptor if i'm going to be copying this device descriptor then maybe elsewhere when i deal with it i don't need to read it out of the stack frame so just as a minor optimization i may be able to copy it sooner and then have my other access to it be from there at a fixed address the the advantage of having a fixed addresses that then i may be able to use other yeah or maybe not i may be able to use other more efficient instructions to do that come on where's the actual table that shows what an interface descriptor looks like the interface descriptor describes a specific interface with a within a configuration this is what i want standard interface descriptor how big is it offset it goes up to offset eight that's interesting looks like an interface descriptor is going to be yeah nine bytes long alright i'm going to make it ten because this this machine really doesn't like unaligned access your your data i'd be aligned to boundaries of two bytes and your instructions are to be aligned to the boundaries of three bytes but the pointers to them go up by two for each three bytes alright so let me let me i'm just looking off screen here at my printed off notes to see if oh i see yeah i don't even want to be dealing with interface descriptors here i want to be saving the config descriptor because interfaces go inside a config how big is the config descriptor that's what i actually want to know okay standard configuration descriptor its a bit bigger i think no looks like that is also nine bytes long interesting looking at my notes the configuration descriptor of that i'm printing off one two three four five six seven he configuration yeah nine bytes okay alright so these common variables will be where i store that device descriptor and configuration descriptor i i am probably going to want to define some aliases for individual fields within those such i'll do that when i find i need it and that should be all the code i need right there so the next thing to do is to copy stuff into there i so i'll copy that device descriptor into let's see here alright so i'm going to use w fourteen is the stack frame and the descriptor starts at offset eighteen copy save copy of device descriptor its eighteen bytes so that is nine words so i'm going to use a repeat number eight because the argument for repeat is one more than the number of iterations so instead of writing a more complicated loop or writing this instruction nine times i just repeat number eight as is a feature of the pick twenty four cpu make sure that assembles yeah it assembles okay i think yeah now i'm also going to want to have in the common area variables for the loop now what touches that device descriptor i don't think it would be any cheaper to use the saved copy in fact it might be worse but i'm looking at the wrong chunk of code there this is the code i really wanted to look at hmm think i'm going to do it rather than pulling that out of the stack frame where it might have gotten corrupted by drivers misbehaving i'm going to pull it out of given that i've just made a copy into a known address and cannot pull it out of that known address so i will go back up here and define a twenty eighteen eighteen four alright so what this is saying is that this new symbol saved to have class will point at saved to have desk where i where i'm saving the descriptor plus four and pulling it from there will be just a little safer instead of using w fourteen plus twenty two wrong wrong routine there again this isn't this symbol is in lower case because its a local variable for the file i cannot locate execute code in the data section on line one twenty one may not be able to hunt why does it say finished incoming packet there i dunno where that phrase finished incoming packet came from but it doesn't matter if i deleted it and it doesn't break anything else maybe a straight cut and paste somewhere okay so this code this code now compiles i don't know that it'll work but i but i guess i contest that once i once i'm ready because i'd like to do other things get on other stuff in infrastructure in here first right so the device descriptors got a configuration countach i'm going to need variable a loop variable for the current configuration and i don't really want him as a register because i'm going to be going off and running other codes i would like to leave registers free for it i so i'm going to need a loop variable for that and then i'm put any needed a loop variable for the interface right i'm going to put those in the common area as well don't need to save the configuration count anymore because that's saved in the device tree for the device descriptor that i already saved i loop here ah now how does this work and what are the indices for configuration descriptors i'm going to have to for each descriptor in the range i think they're probably numbered from one up to the number that exist bible that's what i'm having to check right now i asked the device for it by number device qualifiers not relevant to me num configurations identifies the number of configurations that the device supports but what are they know how are they numbered do they start at one let me check my printed notes ah does not actually say when the host requests the configuration descriptor of related interfaces and endpoint descriptors are returned refer to section nine four three let's look at nine for three then the descriptor value descriptor index for example a device can the range of values used for descriptor indexes from zero to one less than the number of descriptors of that type implemented by the device so we're going to iterate from zero up to one less than the number that is stored in the saved device descriptor i and then at the bottom of that loop let's see i have a cat i i'm grabbing my big manual here seeing what what kinds of operands i can run the increment instruction on i i can increment to file register yeah i can increment just a memory location but i don't think i really want to because i have got to one i've got to also compare on the other hand its a fixed location yeah ok think i will do that increment i courage cons and then i need to get the number of configurations into to be zero and okay from the device descriptor which i have saved i need to get the number of configurations which is in offset seventeen i endless this this will be an unaligned byte address sofa single byte field and may have some of the details of the instruction syntax wrong here but it will complain i and then i'll have to deal with that alright so this should be my loop test i and its okay here to have loop tests at the bottom of the loop because there's always guaranteed to be one configuration for the device if the device is halfway sane so increment the current config we clear both bytes of w zero put the save dev a number of converts into w zero that's the low byte but this you know because its underlined its actually the high byte this is a little endian machine except when it gets weird with those three beta program memory words then we compare his w zero being the number of configs greater than the current config if it is we can look at this config otherwise we're done this is probably not going to assemble but with the the assembler will tell us what's wrong if not yeah so you can't move from a fixed file register to to be zero i but i have another idea let's move the whole word and then and then do a shift to shift that because its a high byte we care about and i want to end up with the high byte from the ah yeah from the seer st def desk plus remove that define because its no longer useful maybe i don't even want this one yeah its probably too much work too ah maintain those sensitive four saved deaf desk plus four is going to be this device class and device subclass field which is what it should be and up here saved dev desk plus sixteen is going to be let's see here its going to be the cereal the index of the serial number string descriptor which we don't really care about and the number of configurations in the high byte offset seventy and i want to do an l s r logical shift right and i'm just off screen looking in the in the year big manual here for for the parameters of that ls are logical shift right i find register by one bit by short literalists one i want elsa are you okay ls are working register zero by eight bits result into working register zero and then there we go think that's all good so now i have a a loop that will go through all the indices of all the configuration descriptors but we want to actually look at those configuration descriptors so this will be very similar to earlier i earlier requests i've put in so i'm gonna grab this chunk of code here this is what goes and asks the device for its device descriptor change this to be a request for a configuration descriptor and these configuration descriptors can actually be quite large so on our request what kind of requests do i put in to get a configuration descriptor sanders defects requests get configuration now get descriptor alright so eighty that's the i eighty says that's this value here its easy to get descriptor result be rich in ok eighties request type the host is requesting something from the device get descriptor is going to be zero six the same as the other w value is going to be descriptor type and descriptor index i device descriptor index zero no this is going to be a little different descriptor type device configuration stream interface configuration is true that's what we want see i'm i happen to know that this current confer value is the index with its high byte all zeros because indices can't go over to fifty five so if i just set bit nine of it that that is going to mean that i'm setting the the high bytes to the value to which is what we want for loading config descriptor i but do i have it backwards index value yeah i think that's right value first and then index so what is the the value i have to pass a two byte value that is as specified in this table yeah descriptor type and descriptor index which is weird sets the descriptor type in the high byte in the descriptor index in the low byte i hope that is i little-endian but i think so because i think it was before yup indexing a little bit okay so this is all correct even though it looks a little weird it looks to me i would think you would want to put the type first and then the index but that is not the case the index goes in a in the first bite because his little-endian alright right okay so sorry this is probably not very exciting television but it does kind of have to be done okay so w index is the next to bite field and its zero for anything other than his dream descriptor hmm that means it probably should have been zero other times yeah okay but it it was alright so language id zero now the number of bytes of response desired i know i have a field for this i know i defined in a define here max config descriptor this is the largest descriptor i'm willing to to receive okay and we kill this line which is specific to that earlier thing and then we will add does this make sense i said that that was the max config descriptor i guess its harmless to do this but i was going to that actually should really probably be the i expect a config descriptor to always be nine bytes i guess we said earlier so i don't really need to make space for a k and a half of it because its the interfaces that can be larger but it should be harmless to allow a bigger one unless that confuses the device but let's try this as it stands and let's make sure that the sacrum really was big enough for that as it was alright so this code if it works the way i imagine it should it will actually go and do and retrieve each descriptor in a loop and then go around my stubs which are on the lops for each descriptor so let's let's actually attempt that let's let's compile it and loaded and run it i its not happy does not want to compare abuser or against the current config so what kinds of compares am i allowed to do i'm sure there's a way to compare and compare register zero with a fixed file register yeah jeppe rig see the thing is register zero is special it can be used in some instructions where you couldn't specify a different register because by having the instruction default to that then they can save four bits in the in the instruction code and then use those bits for some other interesting purpose so just try that and in that case i around if the current config is less than as an unsigned number still doesn't like that okay let me take another close look at this sub instruction set cp file register pair file register with w rig oh okay this is this is a funny funny syntax i have to just not specify what register i'm comparing it against and its implicit and now we're we're cooking so a program the device and launch the debugger i want to go until just stafford has run until just after it has read the configuration descriptor if i can so let's go doesn't look good no it seems to just try plugging and unplugging no where am i hung up in due transaction alright the phone call here and set pc i'm going to see where it returns to when it returns well that's interesting bridge okay so it was wait hanging around waiting forever for the for the config descriptor transaction to return probably because i copied this from from an earlier thing there was some some other step it needed to make the transaction run that i neglected to include so what could it be and since i'm certainly going to have to edit this into rican pile might as well do that in the friendlier friendly or window this one here and i should update should update the code i yeah ok so i opted that that comment and let's see what do we have to do when asking for a descriptor set the i am actually looking at these set a dress code here but that's okay because i will want to compare against them both anyway alright so its store what kind of request this is check store the the value field check store the language id which in this case is going to be zero check store the length check setting this flag is not going to be necessary with the control transaction this is getting the device descriptor which we know works i don't see anything wrong with that so okay let's try this go through it step by step in the debugger and see if we can find out why its not not having a valid to result this code here because i haven't saved that change i made to the comment yet i we're not seeing it its right up to there okay to be fourteen i i'm going to scroll this down to look at the buffer that we're creating right here this starting here this is the the request that we are about to send off to the device so it starts with the eighty oh six right that's just saying we're going to ask for descriptor move the current config to w zero which should be zero at this point yes and we set bit nine so that's o two o all and then restore that okay so this is asking for configuration descriptor number zero that's good and then we clear the next field and then we put the maximum config sys in w zero or six all and then we store that in the buffer and then we add eight put the result in w two so hearing read oh six oh wait that's the that's what it should be now we go off and run do control transaction so that puts the flags this is going to be control read she should be into the hi pr w two is step two at this point six oh yeah that's the size that goes in the size goes in there we set the fill point point in point zero at the high pr and then wait for an interrupt so all that looks pretty good i don't know what happens we may have reset the device or something by this point but let's try it i we're still connected check if transaction is completed is not so then we go around this loop waiting for the transaction to complete and there's nothing wrong with that except that it doesn't seem to be working alright so i have few other tricks up my sleeve set the pc to there and return one thing that i that we can do is see how far that transaction gets because this is the first time i've run a relatively large transaction it could be that there's some kind of thing where because i because i'm giving it a buffer that's bigger than the return i expect i only really expect nine bytes to come back from this so it could be that its not calling the transaction complete because the buffer didn't fail that's a case that i don't think i've ever actually had my code hit before so what we can do is reset it let it run for awhile and then see what state the buffer is in if its just sitting there not full and not defining the transaction to be over which is a real possibility now that i think of it that could be what's going wrong so i've reset now i'm going to try to run up to this point and its not running up to this point because its never calling that transaction complete i let's see now i have to decode my data structure here i pr the current high pr is that one o two a one or two a here's the ip our data structure first fields is the link second field is the flags which say this is a control and its not complete yet and its not in the acc phase yet either which is probably a good sign that my guess is right because if it filled the buffer it will go to the acc face i and then six oh wait that's the maximum size that's the size of the buffer and then there is a link to the buffer starting at ten thirty four and there's the buffer fill point which is forty bytes so i think what's probably happened is that we are getting back a short package from the device which is a good thing because that's how the device tells us that its finished but hang on forty yeah okay so we're getting a short packet i think we're getting a short packet from the device and that's how the device tells us its finished and we are still waiting for the buffer to fill so we're never telling the device that its over and so are getting worse edge that way i don't know that's true but that's a reasonable guess and we can test for it so i'm going to run up to just before that point and then said i hope this will work right up to just before that point and then set a breakpoint in the case of a short packet hello to commander root i so here is just before we send off that transaction i don't know if like the device will get confused because we stopped on the debugger before we can only try if that were the case then i would have to do something like set a breakpoint that only executes after a certain number of tries okay no here we've got this is the handling for the case where the hardware comes back the the usb hardware built into our chip comes back and tells us transfer complete which actually happens at least three times during a controlled transaction because you go transfer comply read on sending the request you go transfer complete at least once and getting the response and then you go transfer complete when you send the acknowledgement so when we got transfer complete with an ak here's the stuff ok so inside a controlled transaction if we've sent the acc then we'll go return the ip out to the foreground but we know that hasn't happened because we stopped it and its had not to it had not proceeded to that step yeah if the buffer is full i think we need another clause here that if its a short packet then we also should send the the acc i'm not even sure i need to execute through this i'm pretty sure that i know that that's what the problem is i but let's let's run up to there anyway didn't get there interesting i it seems like it actually got through that loop which i wasn't expecting so let's let's try that again let's pretend that we think everything works as it should run up to here which would mean getting past that transaction no its wedged okay so that was probably some weirdness because i was starting and stopping it in the debugger which is very confusing for usb devices so i if buffer is full then we should send dec also now detect a short packet two points at the actually i think that usb specifies that they're supposed to send a short packet even if they did fill a buffer so if you know you send a maximum packet and it happens to fill the buffer then you have to send a zero length packet afterwards so that the whole store at the other end will know that you're finished maybe i can just comment out this check for buffer fall i and only check so i'm only going to check for a short packet and i've got some code here for doing that i've been through many revisions of this this chunk of code here that deals with different cases of returning transfer finished and it may not be like perfectly factored and efficient but correctness before optimization really w two is pointing at the endpoint flags you know in point flags here so w two plus sixes two for six back max packet size as it should be so we're getting the max packet size into w zero he compare i before the actual packet size and compare let's appearance skip if not equal so if we received a packet that was not maximum size actually we want to compare and skip if equal if it was maximum size then we aren't going to force ourselves to set the accurate but if it was not maximum size then we are not skipping alright this is a pretty low level change that will affect in principle all of my control transactions so it could be that this will cause it to blow up even before the point that we've been getting to but if it does get to the point where its been blowing up it may get past that point alright let's try this again greenbuild for debugging right to the face devices an overloaded word hearing mp lab the device means the the microcontroller that i'm programming but in usb terms that's not a device it is a host and the device is the the usb stick that i'm plugging into it launch the debugger and you will optimistically think they may get all the way to here oh it did alright so that's a good sign now i let's look at the return to descriptor two a is the one or two way is the ip are that is the request the data structure that gets passed to the low level usb driver to make it do something on the bus we are right now and i think of as user code as opposed to kernel code right here so this is the data structure repay passed to the kernel its not really kernel and userspace there is no operating system on this chip and there's no memory protection or anything but its kind of like that we have the interrupt routine that's like the kernel anyway yeah so oh six oh wait is the i buffer size here's a pointer to the buffer here's the buffer fill point i don't like the look of that i feel point says oh wait hmm well we'll see then here's the request data structure which says give me configuration descriptor number zero and you can have it be up to a kilobyte and a half and then here are eight bytes of what looks like the yeah this is no good at all okay so that change that we made i think is making it not ever return more than huh okay i guess we're going to have to sort of bring out the the big guns and build a a data structure and just kind of log all of the sizes of packets that come in would that help okay so the thing is that that change as i had kind of feared its causing other transactions to terminate early also i i suppose one thing we could do would be to just just use the known small size of this descriptor instead of asking for it to be a kilobyte and a half but that will be a problem later when we're reading descriptors for which we really don't know the size let's take another look at that code alright this is supposed to save the packet saw if a packet came in with his size and w for and its different from the max packet size which we're getting from w two plus six and its going to go into w zero then we're going to set the akp it oh here's a thought i think we may be checking for buck for full elsewhere in this code try sending control this is what we're when we're looking at an ip that could represent a control pip transaction that's in progress and not complete this is where we might end up so if if we're sending the setup which is detected by the buffer fill point being zero then there's code for doing that and i believe we're doing that correctly we've been doing it correctly for days already otherwise we go to control data i no if we have declared that we're supposed to be sending an ak then we will go to the sunday neck i'd been thinking maybe it was looking at buffer fall as the only reason to sendak and that's one reason but it will also go if we've already flagged that now two six w one is w one actually pointing at the flags field yes okay so i mean we are we sending the act too soon or too late i think we are sending it too soon because it is the the the bit that would cause it to be sent is getting turned on and also i'm initializing memory to this dare devalue and this is the stack frame where all the stuff that i read gets written and its never going past eight bytes so i think we're pretty consistently going into the act phase after eight bytes of transferred and that's certainly not what we should be doing and i think so yeah ok this is annoying the endpoint told us that it was capable of handling sixty four byte transfers but it is sending packets i think of at most eight bytes so then when we receive a packet that is eight bytes its less than sixty four we say all you sent a short packet you must be finished and that's not the case actually here's a thought what if we only declare that its finished when the endpoint sends us endpoint its the function when the function sends us that's another wonderful overloaded word when the function sends a size zero length packet then we will terminate and let's put back in the thing that terminates if they fill a buffer alright now i know i've got some funny special special comparison instructions for comparing against zero compare with f compared w you know i i'm always trying to keep my keep my instruction counters lowest possible so when there is a special instruction i can do more than one thing i like to use it parents skip have less than compares skip if equal compare with zero i yeah okay so instead of comparing i don't think i can save an instruction there but instead of comparing with max packet size i'm going to compare against zero so now we're saying that the we will decide that the device has finished sending us data when it either fills the buffer or do if it sends us a zero length packet might possibly be able to shift no i don't think so i was going to say maybe i could shaven and another instruction here by somehow combining these but i don't think that's the case unless i can skip over a skip probably not worth it okay compiled program the device march thirteen poker preferably at high speed out the window its run up to here and see if we can we can alright so now let's see this is looking good okay so here's the ip we are that's got the values we expect i buffer fulfill point is forty bytes which is good that's saying we have thirty two bytes of response as well as the eight bytes of a request here's my eight byte request and then starting here is the configuration descriptor they came back from the from from the usb device and he runs up here with all this stuff in red he has configuration descriptor now i though configuration descriptors were only nine bytes but there may be other stuff that it automatically returns like like the stuff having to do with high speed i think there's like an addendum to the descriptor now i have here my printed off notes from my linux machine when i scanned this key so i'm going to try to find the stuff this is lexar usb flash drive see if i can line up the values that are in this descriptor return alright so length nine bytes that matches descriptor type two meaning a configuration descriptor right total length thirty two that that matches number of interfaces and configuration value that's one okay configuration zero i think that's a flags field bm attributes eighty meaning that this is bus powered i two five five four okay f a which is let's see two hundred fifty the low byte of this is two hundred fifty which is two hundred fifty units of two mila amps its five hundred mila amps i fat chance that you're really going to get a half an amp from from this but okay that actually that would be cool if something really tried to get half an amp because then i would get to find out whether my expensive little poly fuse on there really works but okay so that value matches the the value so then immediately it has returned an interface descriptor oh i see okay so when you cough or config descriptor you get the interface descriptors i i think i remember this okay this is going to make looping over the interface descriptors a little more interesting because we're going to have to do a non bite aligned a non word aligned variable length traversal through here okay okay i see so when we're not going to be retrieving a config descriptor and then looping through retrieving each interface descriptor we're going to be retrieving a config descriptor and all its interface descriptors and then writing a loop that looks at each of those in the returned buffer which is fine and that means we have to do less talking to the usb which is probably a good thing and a little bit more intelligence on the microcontroller to actually decode and look at that stuff especially given as i say these descriptors are in potentially odd length and the microcontroller really does not like having to do online access so basically we're going to have to write something that is like an unaligned meme copy or something because i certainly don't want to be facing address error traps again like i was earlier this week i didn't stream that but i had a whole big thing i spent days tracing out what happens if you if you do horrible things that should never be done to a micro controller you know bus errors and so on and trying to to trap them and discovering that the as usual the microcontroller does not work exactly like its data sheet says all that kind of thing but okay we've got then after the after the config descriptor we've got the interface descriptor and since we have it here we might as well start looking at that bite by bite as well and actually let's see if i can look at this in a different format no i was going to try to look at that bite by bite instead of fuck ah i don't want that what what that's not what i meant to do no hvac an undue i think i just deleted my little windows so now i'm going to have to bring those back i clicked on something that i was hoping would be like a maximize minimize okay set aside the debauchery while i re reconfigure my windows here yeah targeting them reviews file registers yeah so pretty this she's here alright that's over here i guess yeah and then they bring this i to their okay change this to be symbol format this is what i was trying to do was remove the binary column because i find it easier to just decode the hex in my head and then i'm gonna want another file registers window just to bring this back the way it was on the one hand it is cool that there's so much flexibility in this interface and i can get it arranged just the way i want but on the other hand its really annoying that i'm with one click i completely screwed it up and have to make a bunch of changes to get it back the way it was yeah alright so now i take this to one or two a day alright so what i was going to do before i interrupted myself and i lost that red highlighting too not that that's very important but anyway so those four lines are the request and then starting here is the configuration descriptor and then in the middle of this bite of this word is the zero nine that's the start of the interface descriptor so let's work through that first byte zero nine that's a length descriptor type is zero four that's fine interface number is zero alternate settings zero number of end points too eight we're up to here by now eight for mass storage six for scalzi i and i'm seeing zero four i interface but that may be it doesn't match what's in my paper notes here but that may not be a problem i oh i see interface protocol that's eighty decimal right i was thinking it was eighty hex yeah okay so then next we've got zero seven the length of the endpoint descriptor zero five is the descriptor type eighty one that's a bit field of the endpoint address zero to four attributes i don't know even what these things mean but i'm just checking that the paper print out matches what my micro controller has extracted from the ah from there and then i forty there are two my printout has two endpoint descriptors but only one of them seems to be in here maybe they're identical no i don't understand what's going on there do i really have forty bytes here's the the buffer fill point forty bytes for the buffer no two four six eight that's the end of the request ten twelve fourteen sixteen eighteen twenty twenty two twenty four twenty six twenty eight thirty thirty two thirty four thirty six thirty eight forty okay i do really have forty bytes i guess those really add up and i'm probably confusing myself because these are all odd length likes nine seven and seven yeah ok so looking back at config descriptor nine interface descriptor nine that's eighteen endpoint descriptor seven that puts me at twenty five another important descriptor that's another seven that puts me at thirty two plus the eight bytes of request okay so i have correctly retrieved the configuration descriptor and do all the in the interface descriptor with its subordinate endpoint descriptors so all this is is the way it should be that's not exactly the format i was expecting i thought that i was going to have to request descriptors one by one but that does put me in a fairly good good position for doing further coding which i think i will probably want to go off and do off stream correctly reading the are a whole pile of descriptors from the usb device and i'm in pretty good shape too to start to start decoding them and interpreting them and although it was a little touch and go there when it was not correctly ending the track the transaction i think that fixing that's for this transaction will then put me in a better better space for for any future communication between the hosting the device so i think that i'm going to call the stream at that point i'm at now well over two and a half hours and i've made you know not quite as much progress as i might hope to but still quite a lot of progress and there aren't any really outstanding bugs right now its just a question of further implementation so i'm not sure who all was tuned in for different phases of the stream i'm not sure how popular these kinds of streams are compared to some of the electronic construction that i've been doing but in large part its just shaped by this is the work that i have to do right now and right now i don't have a lot of construction on need to do and i have a lot of usb programming i have to do and i know that some of my viewers are actually really interested in this stuff although i don't get a lot of feedback and oh yeah that this was a good stream that was a bad stream so to a certain extent i just am sort of guessing as to what what content to pay put up here but if you do enjoy this or really even if you don't because i need the numbers please remember to follow me on twitch i think i met thirty three followers now and there's a big big milestone if i hit fifty that i get all kinds of special privileges at that point although i think i also need to have a higher average viewership during during the streams but one step at a time more view more followers would certainly help and i will be back on monday at the same time and possibly at other times if i feel really enthusiastic and i hope you enjoyed and have a nice day hmm hmm