 So I'm sorry, I'm one minute late because I had this snack and I was finishing chewing. How's everyone doing? We'll wait just a couple of minutes because people get notified when we go live. Hopefully you can see and hear me. It looks like I'm dropping frames again, which is weird. Maybe let's do a quick, maybe yes, dropping frames. Easy. Dropped frames and general connection issues. Lower your bitrate. Change your stream server. Enable network optimizations. Your router is slow. obvious24 introduces a new feature called dynamic bitrate. To enable dynamic bitrate, ensure you're using 24 or higher. Settings, advanced, network stream server. Hmm. Network optimizations. Update network drivers. I'm not over Wi-Fi. I'm hardwired. Just stuttered then. Yeah, I mean, it's suggesting contact your ISP. Like, I've got fiber. I don't get it. I do have a VPN on. I wonder if that's part of the problem. I have tail scale running. Can I set dynamic bitrate while we're going? Probably not. Advanced stream delay network. Oh, I guess I'm not running 24 at all. I do have kind of a high bitrate. But I also have like really good internet. I don't know. Oh, I'm in OBS 30. I don't know. I'll try to turn it down when I. I meant to look this up earlier. Blah. I forgot. Been a busy day. I think just like last week, let's not worry about it. And if I stutter, I'm sorry. But hopefully the audio is OK still. That was the case last week, too. I'll try to turn down my bitrate or do something anyway. Let me say hello to folks, and we'll get started. I do hear my fans spinning up a little bit, but the CPU seems fine. OK, so hello ADCC. Hello DJ Devon 3. Hello, DCD. When I do timecones, I actually have been typing them in, but it sounds like it's time to create a CP tool to insert them. You sound great. Yeah, there's definitely time code or time stamping code around as well. I know Dan uses some for our meetings. So it definitely exists. Hi, Feday2. Hi, Tyeth. Yeah, just stutter. Yeah, I'm sorry. Feday2 says, I love 0 tier. It's working more than fine in risk 564. DJ Devon 3 says, I have you set to 720p, and the video is still a bit laggy. I think it's me. It's the upload that's the problem. 64 core, 128 gigs of RAM. That's a lot. Hi, David, and hello, HandsLabs. Got a good meal, cooking great. Hi, Beata on YouTube. Quite sunny day down here in Springfield. Awesome. As you can see, it's quite nice out the window here as well. I will try to figure out my bit rate issues offline, or I'll change some settings and see how next week goes, because it has been pretty consistent the whole last few weeks. I had one good day, and then blah, blah, blah. Hi, Keith, the EE. Welcome. OK, so hello, my name is Scott. If you're just joining us, obviously, you don't take it too seriously. This is a deep dive where we get together most weeks, and we talk about circuit Python internals. I answer questions. We have a good time. I work for Adafruit. It's their streaming platform channels, so if you want to support me and the company, you can go to Adafruit.com and purchase Hardware there. I'm going to have a lot of cool stuff come out this year. So I'm excited about that. So Circuit Python is a version of Python designed for tiny computers called microcontrollers. This is one. This is a Pico W. So this is called a printed circuit board. This one's actually got two separate microcontrollers on it. It's got this one here that's an RP2040, and then this one, there's one under this canister here that is like the Wi-Fi bridge chip as well. So microcontrollers are really inexpensive. They're great at doing one thing, which is good. And what we do is we get Circuit Python on there so that you can edit full human readable Python code all on the device and have it all contained as well, which is great. So this is a deep dive. I do these pretty much every week. Tim, foamy guy will fill in if I can't do it. I'm happy to answer questions and go on tangents. I like to make myself accessible and doing it in this way means that more than just the person asking a question gets to see the answer as well. So that's always fun. So I'm happy to take questions. For a while in the description, I didn't really know what I was going to cover, but I basically had something I wanted to finish today and I haven't gotten to it. My personal life is a little bit busy because we have what we thought was a roof leak, but it turns out to be like the shower is venting up into the roof and then just dripping down, which is great. Not great. So there's somebody in our house fixing that. So that's had me a bit busy orchestrating that, but we're getting it fixed, which is exciting. So that's why I was unable to finish this work that I was doing earlier. There was an issue with the AMD embedded TPM merely being enabled. Might double check that when you have a free moment. Is that an OBS? If I search for OBS AMD TPM issue, will I find it? It's OBS related. Causing problems for some Windows 11. I'm on Linux. I really am quite surprised. It's hardwired, all that. So I'll try to take a look. It looks like it's gotten a little bit better. I have fiber. There's a bunch of people in the building that's probably on the same fiber, but I'm not using that much data. I could turn the bit rate down, too. I'm doing 4,000 kilobytes per second, where I could do more like three. That might be more stable. But again, I don't think I can change that dynamically. Video and audio are frozen, according to EDCC. Keithy EE says, yeah, I had the exact problem with my apartment shower. That's a tough one to diagnose. Yeah, I was looking. I literally had a leak detection service come six years ago, like almost six full years. And they came up with some other answer that did not fix the problem. Yeah, TBM is not associated with OBS. So DJ Never 3 was talking a little bit before the stream started about whether micro-python, porting to micro-python actually benefits porting to circuit-python. And generally, that's not true. Generally, the ports are more dependent on porting to tiny USB, so circuit-python is more tightly coupled to tiny USB than it is to micro-python, basically. Looks like, looks like, yeah. I mean, the drop frames kind of come and go according to OBS. And I am going through restream. Yeah, sorry. We'll switch to the desktop, and it'll become less noticeable, I think. It doesn't seem to be on my CPU side, that's not the problem. And I'm only doing 30 frames per second. Yeah, I don't know. I've got it open here. Bitrate. There was a warning that they wanted it less than. Restream wanted it less than 4,000. I think, yeah, next time I'll just knock my bitrate down to like 3,000 instead of 4, and that should be OK. That should make it better. Yeah, to the restream server. I thought I'm set up to the closest one, but I don't know. I'll see. Yeah, so I talked a little bit about porting. Basically, getting tiny USB porting or support is a good prerequisite for circuit-python support, because we are pretty tightly coupled. And the first thing that you want to get going when you have a new port is you want to get USB going. Like, getting USB in the workflow going is like the most critical part. Mac setting I have for you on YouTube is 1080p, so setting it up to 2K is pointless. Yeah, I'm doing it at 1080p. It's more like the encoding bitrate. And DCD points out that closed captioning seems to be working. I remembered to turn it on because I edited my checklist last week. Hamsab has the tough question of, how do we know that you aren't just really freezing your motion in meat space as a joke to fool us? I think it's really hard for humans to freeze perfectly still. But yeah. So OK, well, let me just kind of pick up where I was working. I mean, I've been a little scattered today because of the roofed stuff. But what I'm doing is some USB host things. So I was looking at, I'll switch to the desktop in just a moment, desktop. This is my secret window down there. I have the YouTube streaming page there and stuff. So this is, so FilmeGuy did this cool project, which I should advertise. I just found it up here because I linked somebody to it earlier, the CircuitPython text editor on the go. And this is using USB host. And there's a couple of issues that FilmeGuy found when doing this, one of which is that this example code that's in the repo doesn't work anymore, which is great. Right? So it's funny because it says the WASD keyboard, but the vid and pid were actually changed. But I have the keyboard here. If we look at, this is not on eye tracking right now either. So here next to me on my desk, I have a WASD keyboard. And then I have over here, it's a RB2040 USB host feather. And the wires coming off of it here are UART TX and RX to a separate USB to serial converter. And the reason that I have that is that CircuitPython has a way for you to print out tiny USB debug statements, which can be really helpful. But the problem with doing that over USB is that you end up generating more debug statements. So in order to debug tiny USB, you've got to set up a UART to send the debugging information out of. So that's what I've got going on here. I just had an idea to how to make it slightly easier. So this is me working on the new build. On the left-hand side is the USB CDC link, the USB serial link. And on the right side is the link for all the debugging. So the console UART. Now, right now, it is actually getting everything mirrored. But I was thinking about turning that off so I could just get the tiny USB output. So we could do that. So here's examples of the tiny USB output. And if I hit Control-D, oh, it's not able to find the keyboard at all. So I'm going to just unplug it and plug it back in, which you can almost see me doing. I don't know if this is a good view, or I actually do have the hover cam view instead. So I'm just going to plug it back in. I think I had gotten the keyboard wedged a little bit. And now we can see that we're getting a lot of debug tiny USB information. That's a funky keyboard. Can you make a desktop cam larger? Oh, yeah, it's a normal keyboard. I just have taken off most of the keys. The humidifier looks amazing on camera. Clouds of wizard like mystery. I meant to ask, does the editor approach the light? Is select the code file around as well as edit? I don't know. It is not smoke. Got to love the typing library. Attribute error none type, yeah. I do have a, here's a bench. Oh yeah, my humidifier of mystery. No, this is, I got a humidifier for this room. That's what this is. It's steam not smoke. And it is in the sun. I've been zapping my desk. Under here is a metal thing. Underneath this tabletop here is metal. And I constantly zap it. And I've zapped my keyboard and stuff. I got a humidifier so that I zap things less. So the humidifier keeps the humidity up and dissipates the static electricity better. I don't think I'd be in here if it was smoke still. Hi, Dexter. I don't think I said hi to you either. So yeah, this is just a WASDE keyboard, except I snagged the keys off of it. I made a keyboard for my partner. And I wanted to use the keycaps from this. So that's why all the letters are missing, is that I've snagged them for another project. I think this is one of the complete buffering now. That I don't think is my problem. I think that might be on your end, DJ Devon 3. OK, so if we go back to the desktop with the overhead, and this is still live too, yeah. So on the issue, one is that this test code is kind of old. So I think I added a required set configuration to be called later after. So our host USB stack is meant to be exactly or a subset of Pi USB, which is what you would do on Pi USB is basically what you would use on Linux or something like that. And I wanted to make the code portable. So our USB host APIs on CircuitPython are Pi USB, basically. So the code should be portable between the two. Feder2 says, I'm getting an AC not because it's very hot, but because they need stable humidity for my two double bases. Nice. He was dropping frames, but the audio is completely fine. That rule is not network issues. Well, I don't know. I don't know how OBS is pushing data up. I think I just have my bitrate too high. I feel like I looked it up like best settings for restream. And it says for I'm doing 1080p at 30 FPS, 3,000 to 6,000. So I'm comfortably within there with 4,000. And then I thought there was a separate thing here. I'm on fiber. I'm on fiber. I'm hard plugged into one router. I wonder if it is tail scale. Having a VPN on could be the problem. I wonder if I could just turn it off. I wonder if it'll break me. Let's not do that. Next time I'll try to turn it off before and see. I don't think it should be going through anything, but maybe it is. OK, so that's a tangent. So for me, I found a couple issues. He says, oh, this example doesn't call set configuration, which is something you have to do in Pi USB. So I added that later. And then it says, well, this says the read still raises an error. Whereas I had a problem where I couldn't actually even print the device.product online, which is frustrating because it's like common in like it's literally this keyboard that it used to work with. So I was trying to figure out why it had changed. So that's what I was doing here. Descriptor, configuration set, descriptor get string, takes in language ID. I suspect what happened is that there was a time where language ID was fixed. Or maybe I'm just wrong. OK, I need to make this bigger. Get device, get configuration, get string, language ID. I just never did it right, maybe. I was passing zero in the language ID and then it's just crashing. Or you get a stall back, which makes it unhappy. Double base, wow. And DJ Devon 3 makes a pun that says, bass need a stable humidity of 100% water. So I'm not sure how it worked and then it stopped working. Get serial string. This still has language ID. Get string, language ID. Descriptor get. I think it's been broken a while. Is the gist of it. There's still language ID. I want to find where it was hard coded. Here is W index. I think it's when it's hard coded. Oh, look, and I hard coded it. It was me. So if we go back one and then this is when language ID was added. String descriptor get. Anyway, it changed out from main to me and we never noticed that it was broken. Can you bisect it? I could. But honestly, I'm not convinced that that's worthwhile. What I was going to do instead is I actually looked at the Pi USB source. And if we look up product. So they have this property product, which is what we're implementing. And we can see that it does this util.get string. And then if we, I'm in a smaller window, get string. But we can see that it says if index is 0, return none. If language ID, so language ID is a third argument that we're not using there. It says, OK, let's get the language IDs. If the length is 0, then we raise an issue. Otherwise, we pick the first language ID and then use that to request. So I'm thinking that I will. What I'll be doing is your suspicions will lead you to the fix. Yeah, so what I need to do is I actually need to get the language ID. So that's why on here you see that there's this error. So I started doing it. I'm trying to add this get language ID, which is just going to be like, if it's set, we'll get it. Otherwise, we won't. So that applies to serial number, product, and manufacturer, I think. And so what we'll do is we'll do static un16t get. Actually, we'll do void because we're going to save it. Get lang id. No, that's not what I want. void, no. No, because we need device number. We'll just do it as self. Actually, yeah, we want it on self because we're going to save it to self as well. So if self first lang id not equal 0, we've already got it, we just return. Otherwise, we are going to do something more like this. We're going to say descriptor, device number. First lang id is 0, temp buffer. We actually don't need that much. We'll change that in just a second and do just as much as we need. Oh, you know what? I guess what we could do is we could say if either of those things are bad, we want lang id of 0. And this is actually get serial string. So we want to call one that is just getting a string. And if either of those, we're going to return. Otherwise, it works. So we're going to do self first. Lang id is equal to we need a temp buffer again. And I think our temp buffer only actually needs to be, I also have the reference USB in a nutshell, where it says we get a length field, we get a descriptor type, string descriptor, and then we get two bytes per language id. And we only want the first one. So we can just get four bytes from USB. Usually what you can do with USB is you can say get four bytes because you know it's at least four. And then what you would do is you would request, because it includes the full length, you could then do a second request to get the rest if you needed the rest. But I only care about the first one. So oh, it is interesting that it's let's look at the tiny USB API. Because we're not going to do serial product manufacturer. We're going to do this get string. And we want to use index, index language id, void buffer. I feel like I'm seeing an issue get string. So it's index and then language id. So language id is zero and that string index is one. But the other issue I'm seeing is that MP array size. Oh, that must be get the number of elements in a fixed size array. Not sure that's right. MP array size, but what is the length here? Void star buffer and then length in terms of what? Get string, get descriptor also has length. I assume it's bytes. And if it's bytes, then that means it's wrong, which could also lead to some crashes and stuff. Get serial string, get string. Get string calls get descriptor. It does not copy it. Get descriptor puts w length directly in. I suspect it's bytes, whereas we're not giving it bytes. We're giving it unit 16s, which is not good. I don't know why that is. So this is where I would do some more get blaming. It's probably all my code. Let's be real. So let's look in shared module USB core device blame. This tree cell test is just not helpful with the smallest screen. So what we're looking for is this temp buff is wanting to be unit 16s, which is what is nice. But this MP array size, I don't think is right. I think it needs to be double that. It's not going to be a problem. It's just going to be too short. So this is unit 16 of 127. But MP array size is going to be 127. It's not going to be 254. I don't think. We can actually confirm that, which actually makes me think that when we are, if we do this again, we go in here and we can see here's the get string descriptor. And it's indexed to this language code and then 255. No, 7f is only half that 127. And w length is in terms of bytes, I assume. Like it would make no sense that it was set up packet. Number of bytes. It's number of bytes here. Control transfers, interrupt transfers. Oh, come on. I think it's just not long enough. I think the right thing to do is actually let's just take a look at this. They do it in this PR, riser shared USB. No, module USB core. OK, so it was MP array size still. But that's not right. Because it's the number of units, not the number of bytes. So we can hit this again to go back further. Use revised. OK, so I just did it wrong from the start. The data sheet is 692 pages. That's not too much. The thing that you really want is you want to look at the USB peripheral and figure out which one it is and if something already supported by tiny USB has it as well. That's the thing that you want. Port to tiny USB for any new platform first. OK, so array size is just smaller than it needs to be. This shouldn't be MP array size. This should just be the size of. Like MP array size, if you look at how it works, it's just doing size of the whole thing divided by the size of a single element. But because we're actually wanting bytes, we just want size of. Otherwise, we won't overflow because we're giving it a too small of a number. This will give us a better. We'll be able to handle longer strings. Forget Lang ID. We don't actually need it to be 4. We needed it to be 2. So it's 2 control bytes for string 1. Size of temp buff, wait for callback. And then it's going to be temp buff equals 1. So let's build that and see what happens. Too few arguments. OK, so now I'm going to. I'm just doing this over UF2 because I'm lazy. Like I'm not using a debugger to load it or anything. Any questions about this stuff? Another nice thing about running the USB or running the serial console is you can actually see it from the very, very early on. So for example, we can see that you can see the output of code.py before USB comes up, which is neat, which I saw. Oh, serial console setup. So that's the first thing that's output. So we can see that the USB stuff starts going and it's intermingling the output from Circuitbython with the USB debugging or the USB debugging stuff, which is kind of annoying. But you can see that the first code.py run, it doesn't actually work as the none type error. Yeah, you can hear it is traced back. It's like working on getting it set up internally. And here's the none type object has no set configuration. So to make code.py work the very first time, we'd actually have to wait until we find the device. And we don't run again because we crashed. So if we just do control D, we'll get a bunch more output. And we can see that we're getting none, none, none. So we didn't get, it didn't work. Get this string descriptor still failed. But it's possible that we got a bunch of stalled information. Although it did not, oh, you know, I think it's index zero instead of index one. Sorry, I'm sitting here putting motion on. I guess you can't see that. I think I'm actually supposed to be doing index zero for the language ID. So let's go back to get language ID. And this one needs to be a zero. Let's make and I will hit the button. Copy it over. I wanted to collect of the USB URLs for future reference. You want me to just, you want these ones like this one? I haven't shown this, but it's also very handy. That's a descriptor parser and pi USB. I think those are the three. Oh, let me know if there's more that you want. All right, we're going again. All this stuff is so if circuit Python detects, if tiny USB detects that there is a keyboard that's been plugged in, circuit Python will use it automatically. So that's what this is doing is it's using it. In fact, I can control D. I can actually control C. Problem is I use Colmec. So you can actually see here the transfers coming in when I do. Oh, there it is. So I can even rerun it from the keyboard itself, which is kind of like meta. And now we got none none USB keyboard, which is great. So I fixed the descriptors by doing the get language ID. So if we look here, we should be able to find the, here we go. So 0 6, 0 3, 0 0, 0 3. So 0 3 means it's a string descriptor fetch. The 0 0 is the index. And we can see that it replied with a thing that's four total bytes. So there's no other languages that are available. And 3 is, I think, like that's a response. And then 0 4 0 9 means English. So we're now doing what Pi USB does, which is say, hey, device, give me the first language ID. I don't know how many devices actually support multiple languages for like their names, but we'll just support the first one. And so I fixed the string descriptor, but now we're getting a separate USB error on transfer failed. I think this is what we actually look. And I do have, I have the debug output for device turned off. I should probably show how to do that. So there's this, is kernel driver active? Detach the kernel driver. And then we're trying to do this read. So I bet what we're doing is we're doing device read, and it's failing for another reason. We'll see. So let's keep trying. So here we can see endpoint transfer failed. This is where we're getting the USB error from. And what we can do is we can dig in a tiny USB and try to figure out. My guess is that it's this claim. I think what we need to do is actually do abort transfer, which I think, I think tack added, but I suspect that's what I mean. So I think what's happening is that, and in fact, you can kind of see this, there is this hidden transfer callback that's happening later. Boot keyboards, so there's two USB protocols for keyboards, and one is boot specific and one is not. So it's not just that it's connected on boot, it's actually that there's different modes, which is kind of wild. I wonder how we should do this. SG2002, I think it's the chip name, but you can actually find there's a company called Synopsys that has IP, like verilog data that they'll give to other folks, that they'll sell to other folks. And so you can actually have chips from different vendors that have the same USB, the same USB stack. If you have the Linux source, actually one way to figure out what's on there is if they have Linux code for it, which they probably do, you could go in there and figure out how they have it configured. Linux has the same problem. OK, so I think this USB error is that we haven't aborted the HID divider in tiny USB is still waiting for a transfer. So what we need to figure out is do we transfer the individual? Do we stop the transfer on the individual endpoint? Or is there a higher level call we can do to detach it? HID device, HID host, set protocol, HID receive ready, mount unmount, report received, internal class driver API? Yeah, so there's no way actually to. So this is all kind of specific to keyboards, because keyboards are the only thing that CircuitPython will kind of start using by default. Be honest, boot protocol was useful at the time since you didn't need a full USB stack to see if the HID interface is ready to receive report. I think what we should do, I'm trying to decide if it's just bad for us to abort. But I don't think it is, because I think that once we do abort transfer, there's a raw API that we are using. And I think once we have a raw API, we call the raw API, then it overrides it until next time. Yeah, I don't know how it conflicts. Check to see if mounted. I guess you know what, we could do this. We could say if it's mounted, although we don't know what interface it is, which is annoying. We only know the end point. That's all about index. HID HClose is what we'd like to call, which maybe is what we should do. But that's internal. Where's the raw API? USB host application. Mounted suspended. Transfer API. End point open. You can only abort a transfer that has not been started. Synchronous descriptors. Transfer. Control transfer. End point open. Are we calling that? It's been so long since I looked at this. Device transfer. End point transfer. Oh, here's endpoint open. So it does look like it's open OK. So endpoint open. And you kind of need a keyboard on a PC. I think maybe let's just put a little logging in here. I feel like endpoint open should cancel any pending transfers, because we're having this problem. This is so niche, though. But this example does it. This example was written, I think, before Circuit Python and used the keyboard. And I think endpoint is usually 0, 2, x, because it includes direction. It seems like this is succeeding. The problem is that we're not stopping the internal HID use. I've been doing this for so long that it went now on these builds. I'm like, wow, they're so fast. They're just much faster. Rp2040 builds are. So we're getting transferred failed, and I assume it's because the endpoint hasn't been released. It's actually working. It would be throwing an error. Actually, it says here, open endpoint 81 was size. So I think if we hit Control-D again. Yeah, so that endpoint was opened, just fine. But then the transfer fails. And I think it's because the endpoint open probably doesn't actually abort. Use be host endpoint busy. So let's figure out exactly what state is. Sorry, it sneaks. It is not a control transfer endpoint transfer. So these verifies will return. So claim, claimed endpoint. Are we seeing those? Yeah, here we go. Here's a claimed endpoint 81, but that was never released. Is there a corresponding release log? You would think so, or hope so. Transfer failed. So to you endpoint claim, not busy and not claimed. Like I saw that. Will the claim busy? Hope epistate has. Epistate does not know. I really want a back button. Wister was a back button. OK, so now we'll log when we fail to claim an endpoint. Thanks. Ty says, I feel an inception moment coming with this use be keyboard stuff. Some use be host feather with use be cable to master programmer Qtify acting as hid to circuit by the device, accepting new files via the repel. Yeah, the back button should literally just go to where I was just where I just was. I think there's a shortcut key for it, but I don't use a whole lot of shortcut keys. And it's like a three combination. It's not simple. OK, so let's do this again. Oh, interesting. So it wasn't the transfer failed. Didn't fail because it didn't hit that log unless the log is in a lie. I have these filters set. See, here's open endpoint with size equals 8. So I'm reasonably sure that it should have printed out. It could be something else. It must be something else. Let's just print when we claim it too. But it's also possible that we're not getting that far. Endpoint claim. Like that's an assert. Oh, so it's just calling it directly. So annoying. Hide to remaper and circuit by the will be so cool. Yeah, it's doable. I think we have all the stuff. It's just not implemented. Keyboard not found, press F1 to continue. Yeah, read a keyboard on one side and spin it out on the other side with keys remapping. I think we'd benefit from today's deep. Yeah, but you don't really need to do this. You can, but you don't really. Well, yeah, you would need to if your keyboard was pretty unique. But generally, you can just do input. Yeah, there's the hidden remaper project where there's some website that does stuff. It's useful. OK, so lots of stuff is being claimed successfully. It is not the reason that our error is failing. OK, so let's take that out because it's too noisy. And we're going to go back to where it's used in send report. That's not what I want. See, I need a back button. It's like, because I'm such a, yeah, from the browser perspective. Like, I'm lost. I don't know. I want to get back to the transfer function. But there is too many. Don't remember what is before it. I guess if I look at device, not that device endpoint open. So we open the endpoint, but this endpoint transfer is failing. So we're not seeing the release or the claim, I don't think. So let's just print. Oh, let's not do it after the verify. Mm-hmm. Yeah, there we go. I mean, maybe we're just not setting the right things. Should be silly. I mean, maybe this sample code is just like so old that it doesn't work. It shouldn't be 0. If either of them are 0, we're going to cause this error. This is all to fix this example code that I did right at the start. Touch OSC that does remapping things too. It's actually like the website uses web hidden to send the new codes to the microcontroller so you can configure it via the web. Yeah, I think that's what I was thinking of, but that hidden remapper project is too fast. But yeah, being able to change the hidden remapping from the website, that would be cool. Mm-hmm, mm-hmm, mm-hmm. Mm-hmm, mm-hmm. OK, we're going. We've got transfer failed again, but we should get more. Device 1 endpoint 129, which is why we should print endpoints 0, 2, x. And it's still saying transfer failed, even though clean endpoint, USB host claim endpoint. And when I thought we had to print here, let's go back to, see, I need a back button. Any time I do this navigation, it's like, back to host host. Say device OK. I mean, at least it's reproducible, right? I suspect that we won't see this endpoint claimed line. Why it's not claiming it? I don't know, because I thought I put a print that would show that it didn't. Do you want Sublime to keep a stack of functions visited? Like, it's just location in a file. It doesn't even need to be functions. Most nice with the thumb button is the back button in web browsers. Mm-hmm, mm-hmm. Yeah, see, device OK, but claim OK was not printed. So it's the endpoint claim that's failing. Get device assert. See, here's a host. Maybe that's what. Let's just do a log 2. I don't know if the assert will stop us. 318, my goodness. Well, we found at least one bug, right? Two bugs. We found that array size was misused, and we found that we needed the language code, alt minus. I know, I literally want a button in the UI, though. That's what I want. Like, hotkeys are great, but they're not discoverable. Assert device before claim transfer failed. So the claim is failing. Pre-check, oh, here we go. So let's do this. I bet we're failing the pre-check. That's why we're not getting a print. If not, this stuff. Oh, and what is a button? I don't need a stinking hotkey. I don't know. I was actually trying to, like, a couple internal folks were using the Zed editor, and I tried to get that working. But I doubt they have a back button either. Like, so much of programming is a browsing code, right? Like, I think maybe for this frame dropping issue, what I should do is just drop my bitrate down to 3,000 from 4,000. Serial console set up. Run again. Yeah. Unable to claim endpoint with busy one, claimed one. I wonder where these are coming from. Like, the hidden stuff is just continually, I don't know how to fix this. I don't think I can actually abort it. I think I need to figure out, I think I need to ask Tak, who does tiny USB. Because I have this call that says de-chatch driver from this device or whatever. But it's clearly not doing enough so that I can actually use it. And I'm not sure if it does anything. Yeah, USB keyboard detach. You see report. Is there a list of the endpoints that are involved assuming they're all keyboard endpoints? Well, here we're tracking interface, which is nice. But we're not actually cancelling it. I am streaming 1080p at 30 FPS at 4,000 kilobits per second. And I'm not able to stream that many frames for some reason. Even though I have fiber. It could be restreams problem, because I don't go straight to YouTube, which I could try. So here's interesting. Hit report, received callback, and then we call it again. But there's no, like, cancel hit receive report, which is what I would really want to do. Check see if it is ready to receive report. It's not busy. Get indexed by endpoint address. So the hit interface thing does no endpoint in and out. There's no way to say. See, receive report doesn't claim stuff as well. Hit close. Open. Second pig. It is the weekend. It's too early. Too early. He's in Asia. So I think what I'll do is I'll make a PR with the changes I have, and then basically say, it doesn't work. Like, we don't have to fix this before 9.0. It's not that important. The other thing, there is two issues. So the detach is not fully detaching. Is kernel driver active? Detach kernel driver. But we saw detached kernel drivers not doing anything. And this is specific to keyboards. So yeah, I think, well, let's look at this. And then there's have to unplug and replug USB. Various states of powering on the microcontroller with and while USB keyboard plugged into the host port we found that if the microcontroller powers up with the keyboard plugged in, the keyboard will not work until it's been unplugged and replugged in. Start with the microcontroller unplugged from power, but with the USB plugged in and the USB ports, it's unresponsive until you unplug it and plug it back in. So let's fix this bug. So what we can do here is simply I can unplug it, plug it back in, see what happens. Serial console set up. And interesting. Like it's binding endpoint addresses, but it's not open endpoint 85. So how does it work? It doesn't do anything if I unplug the keyboard. USB H device attach. It tries twice to enumerate and then it's working. So maybe it's as simple as we need to power up after. Port Raspberry Pi. Or it's 2040 USB host. Board.C. Host port construct. Reset pin number. So let's say we could probably just put a toggle here. All right, this will be good. We'll get these two things fixed. But it might be like, oh yeah, we just need to turn the power on after. Paid it over. Streaming 1080p with half of what YouTube recommends. I don't think so. I'm not streaming directly to YouTube. It'd be interesting to see if it worked. Let's see if it did this. If it works better. Let's see any output. I break it. Do those printfs just cause it to crash? Console. I think that runs even earlier. Might be too early. Board in it is quite early. After a reset port. Serial in it, early in it. Well, let's see if that works. I think that's what it's called. TJ Devon 3. Like the thing that I was looking at said 3,000 was the low end of 1080p. I don't know why you're saying I have to raise it up. Like the network stuff is doing me uploading too much, I assume. Like I said, I also could be the tail scale VPN. I'll come in a mountain and see if it's broken. Also, sometimes I think I fill up the TO buffer. Nothing. What did I do? What did I do? How did I break it? Like I need to see that attached thing happen later. I'd rather do 15 frames a second. I mean, it's weird. It just, hey, it works again. So putting those prints too early is a problem. For some reason. I wonder if I could do the second one. This is not useful. That's not used anymore. I wonder how this is supposed to work. Like, do we need to toggle power or should 10 USB be able to see the things that are already plugged in? Again, this is a question for tech. Maybe I'll make the PR and then I'll, let's just try this. You know, in this case it's 18. How long do you think we need to wait? Can't we call time sleep? It might be nice to have a flag in settings.tumble for not enabling USB keyboard on boot so it could be purely used as a game input. This is what the detach is supposed to do. Yeah, so you're supposed to be able to call detach and have it give control over it to USB code. I don't want it. It doesn't need to be settings.tumble. There's already, this is exactly what you would call this detach function on Linux if you wanted to do the same thing. It was gonna say that I should be setting it low and then back high again. And there's no time to forget what it is. Cause I kind of want to sleep for a little while. I'll just do microseconds, 100 maybe. Let's just try it. You gotta stick detach and boot up or something like that before code up high runs. I don't know why you need to do it before code up high runs. I'm using the print LED debug technique. Yeah, I'm not sure why it's crashing. Um, like why it's not starting. I think, I'm not sure why it doesn't work. I thought it would be great. I don't feel like 10 is gonna get going anywhere. I bet it's a tail scale having that on for some reason. Like having some VPN stuff or things. It's hard to test without like turning off and back on. I'm not using AV1 yet. I did not get a new one as AV1 encoding because I don't think that the OBS will work anyway. I wanted to see if keyboard immediately is my default to wake a device. It's not the point. The point is that the keyboard should be, I think, yeah, I don't know. Could see if there's any tail scale stuff related to it as well. Okay, did we get, does it work? Oh, you know what? To test it, we have to actually unplug, plug it in. Serial console set up. It's happening way too early. Like all this binding things should happen after. All right, I'm just gonna ask Tak about this. The keyboard, I want the keyboard to work automatically. If you control C, you're running code and just control D it again. Like I had this vision of circuit by thumb being able to use the keyboard outside of the VM running. It's kind of a point. Just like having displays running. All right, I do have some fixes here. They don't really fix all the issues. There is my console, you are. Okay, so first laying idea we do want. These NP print outs we do not want, but they're kind of hard to discard. And then, oh, you know what? We do want this test code needs to be updated. This test code comes from tests. Circuit Python manual, USB basic keyboard. So now if we look at here, what we could also do is device equals none. Device is none. This will wait for it to be plugged in, which will be nice. Swap these, and let's put that back here. Let's actually test it. So now it's just spinning waiting for it because we haven't powered cycled it. It is interesting the keyboard has all its LEDs lit up too, like I'm not super happy. All right, well that worked. It busy waited until it got it, which is nice. You should be able to detach it from the kernel temporarily. The kernel while your user crutch running. But then once you're done, you can say it back. I'm gonna give a talk about this in April, which I don't know if I said, but I've given a talk at PyCascades. I don't think they have announced it yet, but I'm on a schedule. I have a look at the schedule. I don't know. I don't think I did. Hopefully it's at a time that I can do. It's close, it's not too far away. Okay, so stage that, stage that, and then we just need to remove these prints. Stage, prints. PyCascades always has great talks to watch online. Yeah, I think so too. It's in Seattle this year, so I'm gonna go to that. I'm actually going to two conferences in Seattle in April. I'm doing PyCascades and I'm doing, there's an open embedded online or embedded open source software or something. Whereas that for people are gonna be at it too. And that's like two weeks after PyCascades. Downtown. Okay, we want that as well. So we have questions for TAC, but we've got some fixes. We're gonna go get commit. Should I mark it as fixed? I don't think I can mark any of these as fixed, but I kind of want to put on them because it's only keyboards. You're Asian error. Yeah, so the read is still gonna fail. Okay, so I'm just gonna say related to 88. 8885. Fix. Getting the patches. This improves. It doesn't fix. This doesn't do anything for the unplug, re-plug. Ooh, look at that. We're down to seven tax around. So I'm just gonna write any other questions before we get going. Yep, DCV found the event. I already bought tickets, so I'll be there as long as I'm healthy and the child is healthy. It's kind of a big if, but we'll see. Yeah, I guess I have to ask TAC on this one. HIV read transfer. So I'm gonna try to get in touch with TAC for these two issues. These are both like, I don't know, what the right way to get it doing. But in the meantime, we can do this for request. Language ID, fix the test itself. Okay, I think I'm done for the week. My toast is still dropping frames. Actually, you know what? Since I'm at the end of my stream, I wonder if I should stop. Maybe I should fuss with it a little bit rather than doing it at the start. Okay, so I think what I'm gonna do is in, I think I am gonna play around with this just a little bit. So in restream, let's see what it's saying. It's giving me different bit rates. It's saying it's excellent. OBS is happy. It says dropped frames 27, 24%. Oh, now it dropped. Now it's fair. It's just warning me that it's not recommended for X. Yeah, I think I can leave the, I can leave the YouTube stream going. It will just like, hiccup. I think I'll turn off the other ones. So we're gonna say goodbye to Twitch and X and LinkedIn and then we'll leave the YouTube manual one. Cause I don't know, I don't wanna notify people that it's happening again. So I think what I'll do is I'm gonna turn off Twitch, X and LinkedIn. So if you're watching on those, then watch on YouTube. Cause I think YouTube, I won't, I just don't wanna notify people that I'm starting streaming again when that's happening. So I'm gonna, I'm gonna turn those off. Thank you everyone. I guess maybe let me say the formal. So this has been a deep dive. I'm gonna do some streaming testing afterwards. So I won't actually finish it, but some of the folks may not see me on that. If you wanna support me, support Adafruit, go to adafruit.com, purchase some stuff there. If you want to, if you want to join the Discord server, you can go to the URL, adafru.it slash discord. That's the middle chat here is the Discord one. It's around all the time, which is great. And yeah, so I'm gonna do some streaming testing stuff. For a little bit here and see if we can't find a better thing. I might turn off the VPN as the first thing. And then, yeah, we'll see you all next week, hopefully. I think next week I should be around. Look at my calendar. I don't think there's anything. I'll let you know there's a deep diver's role on Discord and it's been a pleasure. I will see you all soon. And I'll turn off Twitch and X and LinkedIn. We'll go for the other ones. Instagram, I gotta remember to turn those back on. Okay, so if I, let me, can I just, how do I turn off? Arch, turn off, Tails, use Tails' scale, start the service and do Tails' scale up. So then I just do, okay, I think it's down. Tails' scale has stopped. Okay, so in OBS I still am seeing issues. So I wonder if I just, I don't think it's Tails' scale. Yeah, DJ Devon3 says I'm still, I'm watching on 480p and that's still an issue there. I think, yeah, I think it's an issue going up rather than an issue coming down to you. So, now let's, can I change my output setting stream server auto detect? I wonder where I can see what restream server in 3000. I applied a different, I don't see the dynamic rate change thing. All right, I'm gonna stop streaming for a second and hopefully I didn't notify people again. Am I back on YouTube? How's that looking? So one thing I did just change was I, it had auto detection for server for like which restream server I was going to. So maybe that was part of the issue. OBS looks good so far. Oh, current bit rate is lower than recommended. Open widget, stream health. Oh, there was a warning briefly. Oh, interesting and this says we recommend that you use a stream bit rate of 6,800 kilobits per second. Okay, so it's looking really good. OBS is not reporting any dropped frames. I can move around. And interesting that YouTube's saying 6,800. So actually I'm gonna stop again. Let me go to settings. Cause I think that output, well 6,800 is pretty much higher. It allows me to change it on the fly. Like it doesn't prevent me from changing it. DJ Devon 3 says it's much better. Maybe YouTube saw another warning. I don't see a higher bit rate coming out of, oh, there it dropped. No drop frames, but it was a little sketchy there for a second according to OBS. Restream's pretty happy. Real-time analytics are not currently available at S restream. It looks good. Interesting. They don't even list. Okay, we did have a few dropped frames just there. Now it says it's 1% 59. And it looks to me that it's going at the 3,000, the 3,000 issue still. Okay, actually there's more streaming sessions here. Let's just see if I can look at the stats. I guess I could viewers, monitor incoming. I think it just might be my network. I mean, I'm on fiber, but it could just be limited. I mean, we could try it. I can stop and I can do. So if I show you like this desktop, I think there's another secret on here. This is like the report from the two hour stream. Like my bit rate was never like a solid 3,000 even though that's what my setting was. And you can see like frames dropped and stuff. 13% drop rate. Okay, so let's, I'm gonna turn it off again and I'm gonna see if it, if 6,800 like YouTube wants is too much. Yeah, so open some code windows. I think you're, yeah. So hopefully you can hear me, but I'm probably really choppy because this is with trying to do 6,800. Unfortunately, dropping frames like mad now. Yeah, so I think it seems to me that like the 3,000 kilobits per second is really. So this is still not super happy. I wonder if I'm being throttled by like one of the, one of the routers. I mean, it's not, it's not that much data is it? If I can do 900 megabits per second, I should be well below that. Well, well, well below that and have that. Like, yeah, my network really should be not. Okay, so this is back to 3,000. Just do desktop. See, what do I want to do? 410, I think I'll just go to the pharmacy. I was thinking about running, but I didn't extra walk and I have to go to the pharmacy to get cat pills. Okay, I think that's, I'll just leave it at 3,000 and we'll deal with it. Hopefully the quality isn't too bad. I maybe I'll Google around it some more. Right, DJ Devon 3 says like, you have gig fiber, you should be able to have like 10 to 20 simulest day streams. Yeah, like in fact, I bet I could get like pretty good numbers just on that stream test, like live here, I don't think, like even while I'm streaming. Oh, interesting. I'm only getting 30 down. Okay, well, I'll do one. See, look at my uploads, still 200. I am in a building with a bunch of people. Fast.com, that's just Google's version. You didn't even do my upload speed. It's fast.com.comcast, no, it's Netflix. I don't know what the deal is. It just seems to come and go as well, right? Like usually it's fine. Usually it's a lot, but like pretty regularly it dips down which is very weird. It could be like this router or the router and the like closet in their building gets too hot or something. So it can't like, it literally can't sustain it. But it has to like throttle down briefly because I'm pushing too much through it or something. I don't know. I could bug CenturyLink and see if they know what the issue is as well. Because like, yeah, I should have plenty. Don't underestimate me. Yeah, they don't have AC in like the closet with all of the ethernet to fiber adapters. I don't know how hot it is, but it could be quite hot. And there's a bunch of people in the building and stuff too. But it does seem less reliable. Like I never had these problems when I was at my house. So there's something to do with that as well. All right, well, 3000 is fine. 3000 is fine. We haven't dropped any frames yet. So it'll just make it a little less rough when we hit those bumps. All right, thank you everybody for hanging out around. Sorry we're doing USB host and that we didn't like solve it, solve it, but hopefully TAC will get it back soon. And with that, I'll do a little bit of a window view and then we'll get out of here. Nice clear day, good for fixing your roof.