 Hello. Hello. Let's see. How are we doing? Excellent. Fair. Oh, looks like YouTube is going. Restream is going. Can you hear me? I feel like I'm blowing the dust off all this all the streaming stuff. Very loud static noise. There is a fan going. I can turn off. Let me see. Kick to the cat out. You can hear. Thank you, Michael. Is that better, unexpected maker? Does that sound better? You know, I think this does have a problem that it does rub against my shirt. So many fans. Let me know how that was. I did open the window. Let me say hi to folks. Hello, unexpected maker. Hello, Dave. I have random windows open here. Ah. Did you hear the cats fight? I just kicked him out. Kicked him out because I'm talking. Hello, Bruce. Nice to see you all. Michael, thanks again. Hi, Eric. Bruce says it's a bit smoky up here north of Vancouver. Cat cam. I tried to get cat cams usually here and it's not working. So I'm going to have to get a new cat cam. I have a C922 and it's just like it wasn't showing up. I tried and then also the cats aren't in here. They're fighting out in the hallway apparently. Yeah. I know Vin doesn't like to be in here so I was kind of surprised that that spook left too. We could see. But yeah, the cat cam wasn't running. I don't know why. I was having trouble with it ages ago too. So let me say hi to folks in the Discord server. Hello, C Grover. Welcome back. Thank you. Hi to Shippu. Hey, David. Hi, Paul. Hi, Beata. Hi, Ham's Labs. Hi, Yanni. And Scurr and FOMI Guy. Oh, thank you to FOMI Guy who has been keeping Deep Dives going. I really, really appreciate it and I chatted with him earlier this week and was like, hey, how would you feel about me doing Deep Dives again? And he was like, I'm going to keep streaming on Saturdays and I'm happy to fill in for you. So he'll be here when I'm unable to make it. And thanks again, FOMI Guy for doing that. Sorry, Dave. Sorry about the cats. Yeah, I don't know why. I don't know. Spook's usually in the cat cam. If anybody has recommendations for cheaper webcams, I can use this as a new cat cam, let me know. Because this C922 shows up but it wasn't like OBS wasn't seeing it. And I tried to use Kemoso, which is also like a KD camera app and it just crashed. So I wasn't able to confirm that it was actually like working in any particular way. Hello, Tim. Nice to be back. A month in Prague for me and to have me back. Thank you. And hello, Snakey Maker Cat. So let me introduce myself. My name is Scott. I work for Adafruit on Circuit Python. I started Deep Dives at the start of the pandemic and then took a bunch of leave last year because my partner and I had a kid. So we have a one-year-old who's now in daycare. And so Friday has actually turned out to be a pretty reasonable day for me to start streaming again. So I was like, maybe I'll just do that spot. So Adafruit hired me originally to work on MicroPython and that became kind of under our guidance, Circuit Python. And the rest is history, I guess. So I continue to work on Circuit Python. If you haven't seen a deep dive before, it's kind of a bit of here's what I'm working on within the weeds of Circuit Python. So like really low-level, I'll cover low-level topics, but if you have questions about it, I'm happy to answer them. And those of you have seen them before, you know that when I answer them, I'm more than happy to also deviate and go off in tangents and discuss stuff. So yeah, before we get started, does anybody have some questions to lead us off with? Otherwise, I've been working on USB host stuff and that was kind of where I was going to go. But it's been a minute. It's been a while. And thanks for being patient with me as I'm getting all of my streaming chops up to snuff again. Martio? Says USB host subject that few discuss. Yes, it is. I don't know how many people actually work on USB host, so that's one of the reasons I like to do these deep dives, is because I watch a lot of technical content on YouTube too for stuff like this. So I don't rewatch myself, but I appreciate the longer form, really technical discussions. And I should also say that I used to do deep dives for two hours, but I'm going to make no promises about that. I'll commit to doing an hour, but we'll see. We'll hit that hour mark and we'll see how we're going. DJ Devon3 says, welcome back. Tyus says, new cams, surely you've got a Pi Zero 2W kicking around. And couldn't help but buy the new V3 camera module. Hello, Clevver. Yeah, I want something a little simpler to maintain than a Raspberry Pi. Must resist to have it jack and stream if we're working on the Raspberry Pi native tiny USB host. Clevver has been. We've been hanging out in the tiny USB channel on Discord. So I guess two other housekeeping things. I'm paid by Adafruit to stream and work on CircuitPython. So if you like what you see here, please just buy stuff from Adafruit.com. We've got lots of neat things and my desk is covered in bits and bobs. So maybe we take a tour of my desk. And then the other thing is Discord. If you want to join Discord, you can go to adafru.it.discord. And that will get you into the Adafruit Discord stream where we hang out kind of all week long. Those of us paid by Adafruit to work on CircuitPython tend to be here around. We tend to be here around during the US work week. I try to take the weekends off. The other says is that doing autofocus in user space? That's for the Raspberry Pi cam, I think. And I don't know. So one thing that I have on my desk is this is the 10 by 10 swirly grid. Swirly grid is the thing that I kind of been thinking about a lot. And then Jeff augmented and made really cool. This is the 5 by 10. And you can see that I've got a prototype feather with standoffs attached to it. And the thing that I was thinking about is one of the cool things that has happened in CircuitPython since I was streaming. I think the last time I did it was like August of last year. One of the cool things that happened is SynthiAugua got a lot of love from Jeff. And I was thinking a lot about making a way to make a modular audio synthesizer that was really just controls that feedback into Synthio and CircuitPython. And one of the things about that is you need something to hold modules on. And so I was thinking, I thought a lot about this. And then most of the stem of stuff is on a .1 inch grid. But unfortunately a .1 inch grid is not really possible to make with .1 inch holes. So what happens here is that there are a bunch of slots that give you not infinite options, but a lot of options on where you can put things that are not on the .2 inch grid structure. And then JLCPCB does aluminum PCBs. So these are actually done through their PCB service. So I ordered the 5x10s, the original one, and then this is a 2x10. And I have it on eye focus, not product focus. And then I also got a 5x5. And so this is generated by KeyCAD. I wrote a generator script. Thanks for the first question, Unexpected Maker. They say, I know it's not CircuitPython related, but did you get any time over the last year to continue on any of your hardware projects? I did. My hardware stuff tends to be my hobby time more so than that. So Swirling Grids is one of those where I was like, I'm just going to take a day and see how far I can get. And it turned out really well where we just ordered these and they looked really good. Didn't quite understand the silkscreen by .1 increments. Yeah, so the silkscreen here is, this is a repeating pattern that repeats every .6 inches. So the lines there mark kind of like the cells of the pattern. And I just realized after I got these ones that my X and Y are backwards. In the script they're known as row and column. And so it's backwards and it drives me a little bonkers. They really should be X, Y. But you can see like the top row is all starts with a zero, which if it was, it should be flipped. So I might fix the script at some point to do that. Yeah, so hardware related, one of the things I did manage to do and I don't have it on my desk. One thing is that like the JLCPCB assembly service is really cool. So what I was playing around with is I've been thinking about having coprocessors for CircuitPython. And it was originally thought of as like having an FPGA that you could load over I squared C. And it would be off on its own doing whatever you programmed it to do. But I realized what I could do for a lot cheaper is actually just put a microcontroller off on its own. And I know I have them right behind me, but I am currently strapped in. Hold on, let me get them there on my desk behind me here. So I realized what you could do instead is use a microcontroller for that. And so what I found is what I also realized kind of like in the confluence of brainstorming this is that the STM chips have I squared C bootloaders in ROM. Which means that you can't really mess them up. The worst you can do is you can make it so that you can't get into the bootloader. But you could do that via a button if you need to. So this is one of the hardware projects I've done. These are a STEMI QT boards, but they have STM32G0s on them. So they're Cortex M0s with a few K of flash and a few like 32 K flash and a few K of RAM. And it's meant to be like a coprocessor for CircuitPython. And I've gotten reasonably far, like I think I got the loading code for over I squared C working, but I haven't done like the C level infrastructure for that yet either. So yeah, that was one thing I did. And then I don't know if I talked about this, but my watch is running CircuitPython and that's my sister's name. Oh, let me let you read my email. So this is a, it's a, it's, the watch is carried in the Eight of Roots shop and it's the one that the Esprit folks came out with. So it's a, it's a NRF 52840 in the watch. And I have CircuitPython running in it. And it's actually my daily watch that I use. So it's not really a hardware project, but it's like in that vein of like not really paid for by or not really eight of fruit work. So there's that as well. And then other hardware projects, I don't know. Keyboard. Watch Python. Is the lowest I squared C speed a bottleneck for getting data in and out of the STM32? I don't think it's too bad. I haven't looked, I haven't clocked it. It's been, it's been a little while since I was playing with that. Yeah, Beata says another seesaw type thing, but reprogrammable on I squared C. Yeah. So seesaw takes the approach of like having a firmware that can basically do everything. Whereas the idea with this is that you would have similar to the way that we support the ULP on ESP is where the library can bring along the compiled code with it and then wrap it all in a Python class for you. That was the same idea. So the idea would be that you have a driver for this device that includes all of the code that would also be loaded onto the device and do that kind of under the hood for you. How you use that, it's like anything you need a coprocessor for and the reality is that I don't have great example. One of the main things I was thinking about is going back to the SYNTH idea was that one thing you need for feeling like a modular SYNTH is the ability of plugging from one plug to another plug. And my idea was to have low cost MCUs at each end of that that would be able to tell what was connected to what. So that was kind of like my first thing I was thinking about. And David, I didn't miss your questions. I saw your questions about USB host. I appreciate that. Oh, DJ Devin also talked about PySigRock. Yeah, so that's not a hardware project, but I did do some work on getting, re-implementing SigRock and Python so that it was much easier to extend. Yeah, and unexpected maker if you could think of any of the other hardware projects I was doing, let me know at all. I can tell you what happened to that. Modular SYNTH CAN bus. Well, the idea in my mind was that behind the modules would be just I squared C and then connect one thing to another thing would be more specific. Okay. David gave me a nice segue into USB host land and I know it's late for them. So let's let's let's start talking USB host. So David says what hardware will be supported by USB host? I have at home three feather RP2040 USB hosts, which I should show. Let me actually go into product showcase mode. Yeah, you have small kids too. So here's a USB host feather. So it's got a USB A plug on there. And then I have it just on the screen. So that will be supported and then three or one teensie 4.1. It's also supported by USB hosts. And then the last one is the ESP 32 S 3 USB OTG. The S 3 is not on my radar for USB host support because it's either device or host is not both at the same time. So the cool thing about and the reason to support USB host on both RP2040 and the IMX RT, which is the teensie, is that you can have both device running and host running. Now on the RP2040, the native USB device is used for device. And then there's this really cool project that somebody did where they use the second core and two PIOs to do host to do USB host. So that that allows us to do both device and host at the same time with the RP2040. And it was working and now it's not working. So what I've been trying to debug today is actually why it's not working anymore. And then the other one is the teensie 4.1, which is an IMX RT and the 1050 and higher. They have two copies of the USB peripheral in it. So you can run one as device and one as host. And I've got the, let's see, it's not super plugged in. So on my desk I've got, I've got so much stuff on my desk. I really need to clean my desk. But I've got this, which is the IMX 1060 evaluation kit. And I've got this OTG dongle that's hanging out of one of the ports to use as host. And then you can plug into the other one and get device support as well. So my main focus to answer your question for USB host is the RP2040 and the teensie, the IMXs. Yeah, there's a difference between, so there's a difference between doing both at the same time and not. I'm pretty sure I have this, I know the board you're talking about and I usually use it for the S3 work I'm doing, but I'm pretty sure there's a switch to tell it which, pretty sure there's a switch on here that you have to set for whether you're doing host or not. Oh, it's not going to show me there. Yeah, like there's a USB interface switching circuit. The ESP32 S3 only has one copy of the USB peripheral stuff. So there's a mode where a USB port can switch between the two, but it can't be the same at the same time, which is what we actually want to do. I consider the IMX in a different ballpark due to high clock, but the RAM is still less than an ESP it has its place. I did see we added support for another IMX in the 8.2, I think. So the IMX is definitely faster because like the lowest clock speed you see on them is like 500 megahertz and a lot of them are 600. And they do have a lot of RAM and that RAM is internal. One thing to always consider with the ESP is that it's a lot of RAM, but it's RAM that's not in the chip. So it's like connected via a slower connection. So you get a lot of RAM, but that RAM is not necessarily as fast. So like for speed, the IMX RTs are the way to go. And one of the cool things is that they have two USB peripherals for some of them as well. If you're new to the IMX RT LAN, there's a great chart on the site here where you can see like the Cortex or the Metro M7 is the 1011, which is this family. So it's 500 megahertz with 128K RAM and half of that RAM goes to tightly coupled memory, which is why it feels really small RAM-wise. But then you get up into the 1040s and the 1050s and they're half a mega RAM and they only lose the 32K as well. And there are 600 megahertz and this column here that you can't see the header for is USB. And it's USB high speed, it's not full speed. All of these are high speed versus full speed on basically everything else. So that's an area that I think we want to explore with CircuitPython as well. And then this 1060 is what's on the teensies. So it's got a mega SRAM and you get most of that into CircuitPython and you also get the two USB devices. Yeah, so unexpected maker asks is that ESP32S3 doesn't have enough height and points. No, you actually need two peripherals or things that act like peripherals. And I've been learning more about USB host and one thing that's so that the way that USB works is the host kind of initiates all transactions. So there's this notion of frames and those frames happen for full speed and low speed. They happen every millisecond where the host will say, OK, we're starting a frame and then it will say, this device tell me what you've got, this device tell me what you've got, this device tell me what you've got. And it has a queue of stuff that the host wants to get done in a particular frame. And that's a lot different than device where you're waiting for the host to ask you something. DJ Devon3 says ESP has external queue spy, but IMX must use internal queue spy. So for RAM, yeah, ESP can use either quad or octal RAM. But IMX, its RAM is actually connected on the regular bus that is like 32 or 64 bits wide. There are, if you look in this chart here, like 1064 is something that has four megabytes flash and that is flash that's internal. So a similarity is that both the IMX RT and the ESP S3, they use external flash. So there's caching that happens to prevent you from running really slowly off of that. And then also like the IMX RT in particular, and ESP does this too, is like when you start up, you'll copy some critical code into RAM so that you don't need to run it from. So you don't need to run it from flash. That's true for RP2040 as well. Yeah, Dave is a timestamp and writing down the topics covered today. Who's doing that? Yeah, it was David, DCD. He wasn't sure he was going to be able to make it and I like ran out of time to, like I had forgotten that I made docs for it. So my plan is I'll just go in and add a few timestamps to kind of like set some markers throughout the video. Sorry. Like yeah, I'm getting back in this thing of things. So yeah, USB host. So let's maybe let's start by demoing it. Yeah, we'll do that on the VOD. Yeah, I'll just I can skip through it and add them. So one thing I wanted to do with USB host is that pause got a got a question from DJ Devon 3 says what is a MIPI display and any plans for Adafruit to use that? MIPI is that what you're seeing here? So you can see it here on the IMX MIPI and DSI is what I've heard it called as well. MIPI is like a standards body and then DSI is a standard high speed, I think it's differential bus that goes to displays instead of doing a bunch of lines in parallel. So you can see parallel here. We are we do have MIPI on our radar, but the reality is that we don't really have chips that support it right now. One thing that we're looking at actually like, well, that's not true. I think I think the more Lady Ada has been doing MIPI DSI stuff with the Raspberry Pi. So it's pretty common there. Oh, it's it's differential and DVR dual data rate. In CircuitPythonLand, so in CircuitPythonLand, we're not going to be doing DSI anytime soon. I'm not going to rule it out in the long term because we probably will. UnexpectedMaker says it's 1.4 megabit, right? Meaning that you're just like not fast enough without dedicated hardware. Yeah, 500 megahertz max of two gigabits of bandwidth. Yeah, so it really like it clocks it ramps up the clock rate so that to get bits across on fewer fewer data lines. So that will come. I mean, part of the reason it will probably come is that like it's really common in like Android Diane for displays and stuff. So, you know, like a lot of what we do at Adafruit is take common hardware components and make them more accessible. The thing that we're looking at more more immediately is parallel support, which we actually already support on the ESPs. But parallel is like you'll see those 40 pin displays that you can get and the Raspberry Pi's do this as well. I think these 40 pin displays that have literally like 24 pins of color plus a bunch of control signals, like that's something we're looking at nearer term than maybe DSI. I found a chip that's used on the eval board for the STM32 MP1 that does 40 pin to HDMI conversion, which is pretty neat. And that chip actually takes in I2S as well. So you get both like display and an audio to be very cool. But yeah, CP12 maybe. That's not like the next three years, four years. That's about right, I think. We're just like just trying to turn the corner into working on CP9. Awesome. Hi Karon. The window a little bit down. LinkedIn user. I didn't realize we streamed the LinkedIn. The 8080 parallel display type thing, I think it's different than that. There's also 8080, which is more like what we call four wire. It's just also more parallel. There's a little bit of a difference. I think one defining factor is whether the display itself has memory or not. So like in our four wire world, the display has a copy of everything that it's showing. So you only have to write what changes. And I think Intel 8080 displays have that too. But with RGB 40 pin displays, like that is a world where you have also V sync and H sync. So I think you're actually like literally writing to the display. There's no like intermediate buffer for that. Bruce asks, does IDF 5 come with CP9? And hello Bruno as well on Twitch. I think, yeah, I think the plan is that we will, we're certainly updating the IDF 5 for circuit Python 9. And if five ones out, I'm sure we'll be there as well. There's a pending PR for it and we'd love to get it in. I'll do it at some point. And we would merge it now if it was ready, but micro dev is kind of like often on available in their schedule. So we'll get it, we'll get IDF in, we'll get IDF in upgraded at some point in 9.0. Oh, I like the ECS 3 box. Yeah. Oh, great. Unexpected Maker says five ones already out. Perfect. So when we circle back to IDF 5, we'll certainly go to 5.1. Generally, we stay on the latest table that they've released. It's just that there's a bigger gap between the four series and the five series that we wanted to do with 9.0. And then also in 9.0 is we're working on upgrading the micro Python bits of circuit Python, which is not an easy thing to do. And Dan's been working on that. So yeah, it's in the works. Any other questions before I talk to you as the host? Yeah, no pressure. Well, see, circuit Python 9 is going to be probably next year, like stable next year. We're going to have quite a bit. We don't want to. So we have two, but more likely three versions of micro Python to update to. We have 119, 120 and 121 will be out soon. And both 19 and 20 change the NPY format. So there's a couple big merges that we have to do. There's a couple merges that we have to do before we want to do a pre-release. Ah, DCD is here and says I'm your LinkedIn user. Awesome. Okay, yeah, I'll try to keep the windows away from the very top. Clever's got lots of information on the different display types. So yeah, so USB host, let's talk USB host. So USB host is the ability to plug another USB device into a circuit Python device. And then there's two, well, there's either the user code is going to use it, or if it's keyboard, we want circuit Python to use it as input. So I got that working both on RB2040 and IMX RT mostly. And then the next thing I was working on that I've been working on in the last week is allowing you to plug in like a USB key. This one doesn't work and I haven't figured out how to get this fully working. But I need to try others. And I actually, and I showed this on Show and Tell, is I was playing around with using another circuit Python device for mass storage from the other one. It's circuit Python inception a little bit. And I did get that working on the IMX, but I wasn't able to get it working on the RB2040. If you saw Show and Tell, I plugged it in and nothing happened. Hello, Michael. Good morning. So yeah, that's the thing that I've been trying to figure out. I have a suspicion because another Discord user also tried to get a USB host working on the RB2040 and it didn't. So I have a suspicion that it broke for some reason. So I've been trying to figure out why that is. And I've been fighting my debugger tools a little bit on the RB2040 and it's been a little frustrating. But I thought we could take a little bit of a poke at that as well. But yeah, so there's two ways that we imagine USB host being helpful. If you plug in a keyboard, you get a circuit Python will automatically translate the HID reports into serial input. So you could just use input in your user code, but you could also control C, control D, and potentially edit a circuit Python code all self-contained. And then the other thing is that we have a very small subset of the Pi USB library implemented in circuit Python. And you can use that to write Python code that uses a USB device and does whatever. So for the mass storage, for example, it would read and write blocks and then the file system on top of that would, like the VFS stuff, similar to an SD card, would make it available to you above the file system. Okay, DJ Devon 3 has some host questions. I thought it was something like a feather RB2040 would require hard-wiring a second USB port. Doesn't it need two USB ports, one for input, one for output, or is that just an easier way to do it? You do need two ports because you're going to connect two cables. That's what the RB2040 USB host device is for is that you've got both your USB-A here for plugging something in and then this one, this type C for plugging into your computer. The other option, and this is harder to show because it's a bunch of wires. But maybe I'll try to show this off, is you can also... So this is a feather RB2040 regular, which has the debug port on it. And I just realized I don't need to be using this because the debug port's been giving me so much trouble. And then I've also got, this is a serial to USB converter. So one thing that's tricky is debugging with print statements over USB when your USB stack is the thing that's causing you a lot of problems. So I actually have the ability to use UART to output debug messages and that skips USB, which can be more reliable when you're messing with the USB stack. And then I've also got a Beagle. So this is a Beagle 480. It does capture. So we might take a look at some of those captures as well while we try to debug what's going on. So I plug the Beagle into there and then I plug the device and I'm trying to use via USB host under the Beagle itself. It's kind of complicated. I had the idea of a keyboard post screen circuit by the device that uses a terminal to work on a USB device that you want to configure. Replacement for a PC. Yeah, so one of the challenges is that, well, that's what this is, right? Like this is a screen and a USB host. And I showed this and it was working and now it's not working. So I'm going to have to fix it. But we have the DVI support. So we have another feather that is DVI, but unfortunately, USB host and the DVI stuff, they both use the second core exclusively. So you can actually do one RP2040 that both does HDMI or DVI and USB host. Something worth thinking about. Yeah, and Clever says if circuit by then isn't connecting to another computer, then you don't need the second port. That's true, but it's really nice to be able to program via a computer. That's why it's more important to us. It's more interesting to us for the cases where you can do both device and host at the same time. But it shouldn't be too hard if somebody wanted to add what's called on-the-go support, which is the ability of a port to switch back and forth. Like we would merge that if somebody wanted to. Hub support if the USB storage presents is more than a simple single device. Yeah, so I haven't set up to do support two hubs right now. It was one, but then there's this hub that is not on my desk. But the eight different cells, and it's a seven port hub, and seven port hubs happen to be two hubs, one connected to the other. So yeah. And I don't think it's composite support either. I'm not sure. I was looking at it like I was doing Linux traces and comparing it to R traces. I'm not sure. First I got to get circuit Python mass storage working with RP2040. Yeah, Jeff was a little inspired by his standalone CPM machine too. It's something I wanted for a long time. And Clever, who's in the chat, is the person that I've been trying to convince to add tiny USB host support for the host controller in the Pi 400 so that we can use the Pi 400 as a standalone. Hi, Quinman16. Thanks for dropping by. It's going pretty well. I'm happy to be streaming again. David asks, are you going to crash your computer live by doing USB things? Potentially. Yes, potentially. And how frequently did it happen while you're doing development? I restarted once today, and I definitely hosed it before. But I think it's actually easier to do. USB host is more isolated than USB device stuff. Let's see circuit Python crash with that. A 20 petabyte USB drive. Yeah, we'll just be like, nah, that's not fat. That's not a fat file system. I mean, it crashes now with different devices. OK, so what do I want to try first? So if I plug in this, and I didn't get my hover cam working, so I'm going to have to use this, but let's just see. One thing I wanted to try is I was just debugging on here. And the screen updates are a little slow because the screen is gigantic. It's also upside down. But it's running this code that's looking for a mass storage device. And I just wanted to give it a shot. I've got this keyboard that I tested with before. And it's one of those things. It's not actually a Bluetooth one. It's like one of those with a dongle. And I had success plugging the dongle in. So I'm just going to see if the keyboard still works in this build. So I plugged it in. I was realizing what I should do is I don't know if it's active. Oh, so I found there. I found this is a good test still. So it found the, and I should. One thing I haven't looked at it in a tiny USB land is the ability to only do debug prints for USB host. So if we do this, we'll see that it did find the device. But it said like, oh, I didn't find a mass storage device. So that's a good check to know that it is indeed finding it. And now if I do control C, and so this is all working. So I'm typing from my, I have to watch my hands because it's query T. So that's good to know that that works. So I can, so that all works, which is cool. Yeah, cursor support. Yeah, either. Anyway, so that's the first thing that we got working is the ability to do the ability to do a keyboard input automatically in the circuit Python. So we do, we've, tiny USB discovers that there's an HID device, which is a human interface device. And then the reports about what buttons are pressed get converted into a serial stream that then is treated like any other serial stream into circuit Python. So that works. Now let's turn that off. Just connect it. And I was using a, my desk is such a mess. I should really clean it. Here's the circuit Python device I was using. So I was using this device to test it. And so, ooh, so I will plug it in. You'll see it should blink. Yeah, so like that's circuit Python. So that is the USB keyboard workflow. That's the start of it. I still think we want to think about what an editor situation looks like. And then let's hit control D here. See, so it just says searching for devices, but whereas like it enumerated the other dongle just fine, it's not able to find, not able to find this device at all, which is a problem. Especially because the IMX I think is able to do it. So let's, oh it did. It is in safe mode now. The other device. See the three flashes. So maybe I'm crashing device mode on the client device. Oh, I do have a Metro RP2040 here that I was using to test as well. Okay. But you know why this is working? It might be working because it may not be running the latest code. I think it is. Hex streams are a foreign language within a foreign language. One thing that can be really helpful for Hex streams is having a protocol decoder. I showed the Chi-Ti struct stuff before and that can be really helpful. Okay. So I've also got the Beagle software here. I'm just going to clear the capture rule. Do a new capture. So I'm going to select the device. I'm going to plug it now into the Beagle. And we don't get anything. No enumeration. Let me just, I'm going to hit reset on the host wing, the host shutter. Yeah. So it still doesn't work. Stuff is happening, which is good. But I'm not sure why. So we're getting setup packets. And I think all of these setup packets are supposed to be. The other thing we could do is disconnect that. And now what I'm going to do is we're still doing a capture. I'm going to capture what it does when given the, ah, so you didn't do anything. So host tried to query the device descriptor and it didn't get an answer. If you power the lipo then you can connect the feather USB host to itself. You could get the device descriptor first aid bytes. Yeah. Well, this is interesting too. So I just plugged the other thing in and there's nothing happening. So I think it's possible that we're crashing the USB host side of things. So here's what it looks like when it works. And if I type in, we'll see. Okay. So let's see what this does. So here you can see these input reports. And it even tells us what key. And then that's those input reports are what circuit by them is then converting into a serial stream. So this get device descriptor is what? And it looks the same except for the fact that there's getting no response back with the other device. Circuit by the device. Set up data and then I just try to set up the data again. Oh, that got an act packet. Let's get device descriptor in setup data. And then in data. I have a feeling that what's happening is that the I thought this is my this was my working theory is that the second core is crashing the second. Yeah, the second core is crashing. And if the if the second core that's running all the USB host stuff crashes, you're basically like your your host stuff doesn't work anymore. Yeah, I know. I know the set up packet can be. If it was working better, one one of my complaints about the packet packet analysis and vehicle is that if the packet is only partially complete, it doesn't like decode at higher level. Like it should know from the set up packet that it was a descriptor request, but it doesn't even tell you that. You can see that when it succeeds, it does tell you that, but only after it fully works. Just kind of silly. And it's like not as helpful. Okay, so what do I want to do? I'm going to. So one thing I did add is the ability to. So I can log to the console. I would do maybe do my debugger, but it's not. Not happy with me. So I'm going to attach a serial. Converter alongside this, and I'm going to do d-bed prints, but only over your. So let's go to this more complicated screen. So this is the you are output device output here. And then we can rebuild here and we'll just use the USB host. And before I compile it to ports. Raspberry Pi USB host. And comment this out. Hi, AircrackNG. Thanks for stopping by. We're hacking some USB host stuff. What software hardware are you using for that capture? I'm using a Beagle USB 480 and their corresponding data center. Just a terrible name. Data center application. So it's a Beagle 480. I'd love to use open tools, but the open tools are not. The challenge with using open tools is that they don't work as well or better than the closed source ones. You just get end up in this rabbit hole of fixing the open source ones. I was like literally just trying to use the black magic stuff for the RP2040 and it flashes at like 4K a second. I was just like, I can't do this. And I was having a bunch of trouble with JLink after that too. Yeah, it's not cheap. The Beagle 480 is not cheap, but if you're doing this debugging, it saves you a lot of time. So yeah. I'd love to use some open source stuff, but I haven't found something that is as easy to use. So now I'm going to... This is like the really manual painful way of doing all this, but putting it into bootloader mode and then I can run this command. So this mounts the drive and then copies it over. Yeah, I ordered a Luna Now Syntheon thing and it still does not exist. Like I don't have one. I don't have one and the tooling is like, they restarted making all the tooling. Like it was in Python and now it's in Rust. It's just like, I don't know. I don't know, I'm very torn. Like I got an Orb Trace, which I'm still very excited about for tracing. Actually, I should talk about that. I ordered, I hacked. So this is an Orb Trace. And it's an ECP-5 just like the Luna Syntheon thing is. And then it's got these two connectors. It's got a regular SWD connector and then a trace one, which is basically SWD plus trace lines. And I ordered from JLC a version of the Metro M7 that has a trace connector instead of an SWD connector. So I'm kind of excited to try doing full trace. My ideal world was where I could just use the Orb Trace, because you could use it as a regular debugger as well. And they were really helpful on the Discord getting me going. But loading on the RP2040 in particular was like super slow. It's like correct, but it's super slow. And I just, I couldn't take it anymore. So I just like kind of switched away from that. Okay, so we mounted and we got, now we got in this window here, this is the serial output. So it's a mix of, where does it start? Yeah, so it always prints out serial console setup. And then this is the prints that we have going on in Circuit by Thought. So let me, it's currently got the keyboard thing in there. Let's switch it over to the Circuit Python device. There we can see a couple of control transfers and a software reboot. And I think this code, so I think I do have a thing in the hard fault handler that says it will print out if the hard fault happens on the second core, which is what I was thinking was happening. So let's go back to our Beagle trace. Yeah, I'd love to, I'd love open source tools, but somebody's got to pay for them and be good. And that group of people is also the people that's willing to just pay for closed source tools. Okay, so let's redo it and get it up in there. Let's just reset and see what happens. Okay, so here we're getting setup, but then we're also getting, here's an in transaction, which is good, but then the out data is not happening. It's waiting for, so what this out data knack is, is that there are these out packets. The out packet is the host saying, okay, device such and such, we want data from you. And then the knack, it looks like it's getting data, and then the knack. So I think the knack would then, well, out is going from the host to the device. So the knack is from the certified device. The other thing we can do is, if we're not confused enough yet, I thought I had a second. So I have also this, it's a prototype RP2040 feather, and I could use this instead because I think this has firmware that is set up to spit out the device side of things. Act phase of the control in the knack is the device rejecting it. Yes, the Orb Trace Mini is what I was referring to, thanks, TCD. It feels like an issue with the USB device. Yeah, so let's see what the USB device is saying. So let me look down on my desk again and find, I could have sworn I had a second serial of the USB converter around here somewhere. I know I do, I just don't know where it is. Here's a prototype of the Swirly grid that I did. Well, pre-Swirly grid. But that was the thing that caused Jeff to think, like, oh, how did I lose this? I probably thought I was cleaning my desk and I ended up burning myself off. Well, here's the USB cable. Welcome to Deep Dives, where I think, what is wrong with this? What's the problem? Let's see if it works with this. Yeah, plug it into you. Where did my other serial converter go? Here's one where I keep them. Sorry you can't see this. I realize I should have the overhead cam for it. What I'm doing is rifling through my box of wires, getting one wire here for the TX of this Metro RP2040, and I need a second wire. I have, like, this bin of wires and they never are the wires that I need. I don't know how that works. They're always, like, pin-to-pin or socket-to-pin or whatever. Whatever I don't need is what I pull out. And this is why I don't like plug-in wires. Never find the wires I need. All right, great. Great YouTube here. All right, I found a ground wire. Let's take this I'm not using. I'm going to do devserial, Silicon Labs 2014, I think. Reset. Yeah, so we're getting USB debugging there. Now let me do reset on the host, which is the two right ones. Assert failed. Well, that'll do it. USBD control transfer callback, assert failed. That would explain why the device is stopped, like, the wire. Don't let the frustration win. I do let the frustration win, just not immediately. I went for a walk right before I started streaming, so I'm freshly replenished with it. Okay, so let's pull up the source and let's see what this assertion is, why it's failing in line. Tiny USB source. Actually, it doesn't tell you what file it is. USBD173 is my... This is my guess for the file. No, that's not right. Fresh tank of anti-frustration. Yes, for sure. Source device 302, USBD control. There, that looks like device, USBD control 173. Transferred bytes is zero. End point 80 with eight bytes. Data stage. Like, it got the get device descriptor, so the host is still running. Oh, the get device did work the second time. Set address. It is the zero five, so that's what setup received. And then it's... Oh, this in packet is wrong. Right, so I think this is the eight bytes it's complaining that it got. So that's weird. So for some reason, I think we're probably getting ahead of ourselves. Right, whereas like this looks... This bit of stuff looks a little similar to what the setup packet is. Five in the setup before that. Right, so I think the set address worked. Like it did the set address, but the transfer complete didn't work. And then here... Here we don't have logging turned on yet. And this is where it gets kind of annoying because, well, one place it's annoying. If we turn on tiny USB logging, we're going to get all of the device traffic logged, which we have device active on the USB host thing right now. Five is set address, six is get descriptor. Yeah, so in this case, it looks like the set address worked. They get the descriptor worked and then the set address worked on the device side, but not with the confirmation back from the host. You know what? The first is if we just do it again and see if we get the same thing again. So let's do another capture. I'm going to hit reset on the host side, which I guess I should... Oh, panic! So this is warning starting new transfer on already active endpoint zero in. So our cert failed and then it got the device descriptor again and then panicked and started over. And that must be why we're in safe mode. So I'm going to reset the device and now I'm going to reset the host and we're failing that cert again. So it seems like it did the same exact thing a second time. Yeah, so I cleared it. Should be able to enumerate again when it gets a USB reset. It should accept if it crashes. If it's a well-behaved device, then yes. It didn't fully reset upon USB reset. Uh-huh. Yeah, so here the set address is failing again. So it's getting set up and then in. And in packet is the thing that's causing the problem. It's funny because I'm pretty sure this does work with... I'm pretty sure it does work with IMX. And the host, let's do set address stuff. Zero byte out. Yeah, maybe there's a bug in the PIO stuff. The challenge with switching to Linux and differing the enumeration is that it will do high speed. And this is not high speed, this is full speed. That doesn't look quite the same. Set up. So I can selectively turn on and add some prints. I wonder if this could be a cross-core synchronization issue. I don't think so. There's not caches between the two. There's not caches, but we had to... Let's try this. So this should just give us a little bit more on the host side and more info on the host side for what's going on for setup. Yeah, junk hubs, that's a good idea. Full speed hub. I'm glad I had... That was the thing, I was trying to get the mass storage, like my thumb drive working. And I was like, oh, this is so frustrating. I'm like, wait, I could switch to circuit Python and then I could actually have it give me all the debug info. Which is a good call. Okay, so what do we have going on here? Intermingled, which is in the link. Control setup 00 and the control data. Which looks like it's empty. I wonder if I should turn... I could turn off the circuit Python prints. That might make it easier to read. So maybe we're trying to send no data and it's sending it instead, right? So this is the control data. Oh, and then log mem is not. So I mean, my suspicion is that this is a bug in the PIO USB code. If it's like sending data that it shouldn't... I don't think it's in the tiny USB code because tiny USB, the same code I think works with IMX. So it's something about the PIO USB stuff that's wrong. Is my guess. I'm not going to go that much longer because the stuff burns me off real fast. Oh, you know, the other thing I was going to do is I was going to turn off console prints of the... Everything else. So the place that that happens is in supervisor shared serial. This is where the serial stream out. So it's also what sets up this console UART printf that I'm calling as a debug printer. And then there's read and bytes available and write substring. And I'll just turn it off. Just comment on this out. Which would make this pane cleaner and we can see the regular circuit byte that I'll put on the top one. So yeah, control ends, three stages. Yeah, I believe that the... I believe the device is correct because it's like the standard device stack stuff that we've been using for a while. It's the PIO host side that I don't trust to do the right thing. Yeah, so that's... I'm going. So I just reset the device again because I panicked again. Control data length eight. Am I seeing all three phases on the data zero or on the Beagle? I don't think so. There's the get device descriptor and here's the address set. Setup data zero act. Oh, but then we're not getting the data zero token. Yeah, the other thing I have is a good resource is this book that I bring out every time and you think it must be complete. So let's add more logging on the host side. Oh, sorry, I missed it. I missed Dave said that he had to go. Go to bed. It's great to have you back, thanks. After that, the device had to panic. Yeah, but I think the device had to panic second already active. New transfer on already active on input one. I don't know. It got get device descriptor twice which is weird. I don't know this is all weird. The device reset. Play it reset on the device. Suspend. We'll do it on the host and then it panics. So it is weird that it's doing the to get the device descriptors. The first one fails but it looks like it does a setup and then another setup. Yeah, I did the host again. Yeah, I know there's a delay too. I like having the delay because it does the auto captioning. Which is great. Okay, so maybe the problem is that we're doing to get descriptors in a row that are not completing correctly. Let's go back to tiny USB host. This is the tiny USB host stuff is it shows two gets but the first get doesn't get correctly parsed. So there's this one that fails, that's red and then there's the second one that does complete correctly. And then there's the setup that causes it to crash and go off the rails. Control data. The ethereal concept. So this is in the callback. You know the new device. Process enumeration. Oh, you know what? I could do this TU log USB H instead. I think that'll give me everything then. Oh yeah, because I have to turn it on. That's too much work. TU log level two and blah, blah, blah. Process. Clear reset. I'm just trying to turn on some more plugins so that we can see where it is. I think what's causing it to be red is that it just doesn't it's not a complete control transaction. H, C, D, setup send look like. Like it worked with the other device though which is very weird. Like the host code works with not circuit by then. I don't know. How often do I solve these problems on the stream? You know what a good solution to not be able to figure this out? The answer is weekend. You think a quick walk is going to do it? Well then maybe right. It's a tiny USB sending in the setup twice or is the PIO side doing it twice? Good question. Alright, let's reset our device. Enumeration attempt. One, two, three. Here's where it starts. Get 8 bytes of device descriptor. Set address. It looks like that had to happen twice. Yeah, yeah you're right. Let's um, let's dig a little deeper and go into, actually let's take my declaration with me and go into portable Raspberry Pi, PIO, USB, HCD. Put this at the top. Set up. And which byte do we care about most? The second one. The second one will give us an idea of what. So I got it in bootloader mode and copy it over again. Thrilling deep dives as always. But yeah, this is why it's like USB host is not primetime ready yet. I've been squashing, there have been tons of bugs on the IMX side around caching where the RAM that the USB peripheral talks to is behind the cache to the CPU is really tricky. So you have to invalidate the cache to load the RAM again after the USB device is written to something. But that invalidation throws away any changes you've made to that memory so you have to make sure and not reuse the memory for something the CPU used to keep me track of as well. And so basically you have to align all your buffers to the 32 byte boundary of the cache lines, which is just a lot of work. A lot of very air prone than the too soon serial constant setup. Yeah, so there is two setup sends here. Two setup sends sixes. Panicking is more difficult. Yeah, panicked again. Setup sends six here and then setup sends six here. Get eight bytes of the device descriptor is called twice. Oh, the fancy color stuff. Oh, emojis here. So it does look like it's tiny USB post doing it twice. And why is that? It's being too eager control transfer, which we do see two control transfers enumerate to enumeration intent one. But that's really failed. So I put it in bootloader mode. I'm going to reset the device now. I'm going to bootloader mode. And clear. Michael says it's normal for hosts to try to get only eight bytes of device descriptor first and then reset. Yeah, I was but it should it should be able to fully get it, right? Like it shouldn't it shouldn't fail trying to get it when you call htd event transfer complete. Right, so somehow something saying the first one fails before it actually fails, right? Kind of where it's at which is causing the second one too early. I wonder if this is a signal problem. Panic with fire. That panic comes from like in the pico SDK low speed max packet sizes eight. Okay, so it's searching for devices. We panicked again because we got set up and then set up and here get eight bytes of device descriptor attempt one failed with one and then we try again. So a numerous attempt one failed is not helpful. I think it's literally just failed. Right, so the callback eight bytes set up eight byte out and zero byte in here's stall handle endpoint IRQ so I think that is on the second core like this is endpoint error bits which I think runs on the second core. I think I might be able to do emoji. Serial console set up. Ah, interesting. Oh, I know what that is. Core one hard fault because I'm trying to log the core one hard fault is because I have the MPU settings so that it doesn't run flash code. Shouldn't really be a problem. We could get rid of that for a little bit. All right, we've got 10 more minutes. If folks have any more questions please ask them now. Potato in this room and I think it's gone reasonably well. I tried to use the hardware encoding and it didn't work but I got enough CPU not a problem. Good to know that that hard fault handler thing works though. Just kind of funny. Well, we know we got there because it crashed. Yeah, so it had like a PIO error which is what caused it to fail in the first place which I have not seen before. I think that is well, let's look. Then they give us more information about that it failed. PIO. USB examples not example source low level. So it's a catch-all. USB in transaction. Are we doing an in or an out? I think we're doing a transaction. PIO USB host IRQ handler. I think it's it's a weak it's a weak thing. And it's coming from in this PIO Pico PIO USB. Let's see what this does. Complete. Yeah, see there's this like host IRQ handler. Yeah, and it's so this PIO USB host frame is running on core one. So it's not actually an interrupt. It's kind of like pretending to be an interrupt. It does it at the end of so this is literally like I'm running a frame send the startup frame and then do all of the transactions we've queued up and then check for a new connection and do the interrupt handler increment or start a frame counter and one way it works is with a timer tracking it but in circuit by them we actually just have a loop that calls this frame function. This is not in tiny USB. This is in this is in Pico PIO USB which I think is in tiny USB but as a sub module. Okay, David said so by default you will catch the keyboard for the Apple that can we have the keyboard for reading from the code maybe to add macro or do keyboard in slash keyboard out. Yeah, so there is a way to like detach and attach the kernel. I haven't tested it but there are function calls there that should allow you to like take over the take over the keyboard and basically disconnect it from circuit Python so that you can raw access it yourself. But the other way to go about it is like whatever inputs you want into the input stream you could do conversions into PIO enumeration isn't resetting properly. David's got great questions. Okay, David asks where does the IntelliQ development the part that uploads the firmware fit into what are you doing is it also circuit Python? Is it sub development? Yeah, so the IntelliQ is not on my desk but it's a big assistive tech input device and it's an old easy USB thing where you have to load the firmware so it was kind of like what I'm doing now in mass storage where it was like another use case I was trying to make sure that we supported and it did work so it did a bunch of control transfers to load the firmware and then once you load the firmware you reset it and then it comes back up and you read HID devices format. So that was all in circuit Python code and that was testing the lower levels of host. Yeah, Pico PIO USB so that's what we have some modules in circuit Python. I think it is some modules into tiny USB as well but maybe it's not going to work because they're a little intertwined. Yeah. It's unclear to me is like I could just I would like to figure this out so I'm going to be a little reckless and print out from the second core I think basically wherever error bits or maybe I find this L transfer complete but that's not going to tell me as much as I want so let me just do PIO in there. Last thing tiny USB has a non sub module copy so this is this like in out setup data like the building blocks of USB lowest of the low levels it looks to do the setup data zero that waits for act if it doesn't get the act it claims error bits even though we see the act here maybe it takes longer than alright last thing to try and then we'll wrap up yeah you know what's you know what's more fun do you know what's more fun than debugging one USB stack it's debugging the same USB stack on two devices at the same time okay so it was a setup error okay I said that was the last thing but now that we know it's a setup error these two buffers are if they're not sync and PID sync and act what are they yeah it does have time stamps so let's see about Clever and I are on the same page about what to debug print any final questions should I think I'll be here next week but we are trying to go camping so the deal I have with Tim is that I'll let him know and if he can he'll fill in for me as well so one and a five what is supposed to be it seems like act should be D2 I don't know where this a five is coming from is that something are we getting ahead of ourselves if you like this one thank you sync is 80 and act is D2 so that's not right huh you're receiving the sync for the act every token starts with a sync symbol oh and yeah I was doing salier capture of the bus 2 and that might actually be what we need to do in this case but not on the stream not going to get salier yeah alright let's let's wrap it up thank you everyone for joining me on this dust off the deep dive equipment for myself as I said before I'm Scott I go by tanute online if you want to keep chatting about this or anything else please join our discord server it's adafru.it slash discord to join where we usually chat in the live broadcast chat that's what is next to me here this is YouTube and then we have a circuit python dev channel and also a tiny USB channel where we can talk about all sorts of this USB stuff I normally stream starting again now assuming everyone's healthy in this house and the child can go to daycare Tuesday 2pm fridays here on the adafruit server server discord channel blah blah blah I'll get more practice at this if you want to support me you can do that by supporting adafruit who pays me to do this and the development I do by going to adafruit.com and purchasing any of the cool toys and devices that you see there if you have ideas for devices let me know if you have ideas on a new camera for cat cam I'll probably shop for that right now so I'll get a new camera webcam here for cat cam and then maybe the cats will be in here too they're not even in here right now yeah other than that I think that's it I will see you all on the discord and then hopefully next week if not I'll we have a deep divers role as well so I can ping you there and let you know if I'm gone and if Tim is going to take my spot and all that sort of stuff so if you're not in the deep divers let me know and we'll get you in there too and that's on discord so with that have a great weekend everyone and thank you for spending your time with me Ramble about usb host I'll see you all later and I can't oh yeah I pet the cat at the end well the cat is outside