 Hello everyone Welcome to another deep dive if you're watching this after the fact be aware that you can Check the note stock on you or the the description on YouTube for time codes so you can skip through stuff We've got We usually cover a lot in two hours worth of streams So that's a great way to check out what we did and I actually went back and Did a red last week, so I would actually kind of have An idea of what I did last week, so today we got lots of exciting stuff. I'm not going to go into it quite yet We're gonna wait a little while longer to let people get going and the cat is on my lap He's funny. I had the door closed getting ready and Spook was that he he doesn't meow all that often, but he meowed to get let in So I thought that was cute And uh Yeah, he was just in a litter box. He got me Um Anyway So we're getting going. I won't do housekeeping quite yet because I still need to arrange my windows a bit better and of course I have My test stop up. I was a little behind Just just just a smidge It's good to hear that that explains Let's say let's Let's say hi to folks Before we do housekeeping So I saw Musa we was waiting unexpected maker. Good morning. Hello Dave Odessa Mark comas hello mark So used to discord mr. Who 30 says so many streams so few time You got to prioritize me Bruce says I saw some video of circuit Python on the Raspberry Pi spoilers Hi Piata Hi Pierre you're just on time. I was a little a smidge late Hi Randall hi Paul Dave says haircut. Yep, definitely got a haircut yesterday Hi Minnesota mentat And Lindholm says such a potentially useful stream nice to nice been using Certified on an eight different models and sensors and Raspberry Pi lately to avoid memory issues Unexpected maker says your apartment has movable windows I don't know what you mean by movable windows. I Live in a house and this window is open right now because it was a little hot in here. Hello, Vinyesh Hopefully I said that right Let's say hi to folks in the discord DCD's in the discord. Thank you David for doing notes. Hi doctor. Hi Patrick Hi Keith I love the factory marks there again. Hi Andrew R Hi Bruce s And folks in discord need a haircut. Yeah, it was I was lucky I was able to like schedule it pretty quickly It was only a few days so Yeah, thanks for helping I really appreciate it had parky welcome Okay, so Let me pause my videos here. I Don't need to see me delayed. I think YouTube will be a little bit more delayed than normal because I have it Oh arrange my windows before you get going. Yeah, the desktop desktop windows Let's see, I think I've got everything set up right YouTube is on normal latency so there may be a little bit more of a delay, but that's Because the auto captioning only works in normal latency, and I think that's important Twitch may be a bit quicker if you're concerned about how fast I see what you're saying Let's do housekeeping So hello everyone, my name is Scott and I work on Circuit Python for Adafruit. Those are two things you may not have heard of so let me cover them briefly so circuit Python is a version of Python designed for Microcontrollers typically which are these little inexpensive computers that are Really inexpensive they have a lot less megahertz power like CPU power and RAM then is typical for something that runs a full operating system a circuit Python itself is kind of like the operating system all-in-one and Yeah, so that's circuit Python over where today we're I've been working on this weird world where we're putting Circuit Python on a Raspberry Pi, which is something that you can run a full OS on so it's it's pretty exciting and Then I am paid by Adafruit to do these streams and the code that I work on so Adafruit is an open-source software and hardware company based out in New York City I work remotely for them. So I'm actually in Seattle and therefore I think of Pacific Times and stuff Oh Yeah, Spook settling down. We had the cleaners earlier. So he didn't get to do his regular cat nap Well, he's coming. He's coming back for the for more lap time. I think Yeah, so that's Spook the cat He's been doing so well. I use I used to give disclaimers about his seizures, but he's just been doing So good See his face Oh, oh no Cat cam down. I had it clipped in He didn't run away though Yeah, so Adafruit is based out of New York City if you want to support me you can support me indirectly by buying stuff from Adafruit by going to Adafruit comm checking stuff out there. I'm working on a Working on a firmware Development and debugging Gift guide will more ask me to do this. So it's it's all the things I basically just like stared at my desk and put the things that are on my desk in the gift guide So keep an eye out for that that'll come at some point. I don't know. I don't know the timing If you want to chat with me and a lot of others you should join the discord server, which is the middle box here That is a place where we can chat all week long We do certify the development in that channel so you can keep an eye on on how things are going and I gave a little bit of a spoiler about A bit of a spoiler about what I've been working on there last night because I got stuff going That's discord so this is a deep dive that happens Almost every week normally on Fridays at 2 p.m. Pacific, which is seven minutes ago We will shift. I was looking it's like November 7th So we have a couple more weeks until the US shifts time. So be aware that in a few weeks it will Little it'll change a little bit And it typically goes for two hours or more We'll probably shoot for right around two hours like we normally do We actually tend to have people fall off after if we go over two hours So two hours is a good good amount of time that we all kind of like I think commit to so that's the plan If you have questions about what I'm working on what I'm not working on you're welcome to ask them We know this is a very casual chill stream And so we're happy to get interrupted, but we've got lots to show so We'll show that to you. Oh Yeah, Spooks in the main cam instead of the cat cam. I can adjust cat cam He's in both Manual So let's see And Lynn Holmes says oh whoops I'm using blink it not circuit Python prototyping on the pilot blinker before I moved to an MCU With circuit or micro Python It'll be too too Pacific Too Pacific Standard Time so whenever whatever time 2 p.m. Here is So I will not change I will not change what day or what time it is for me But for folks outside the US be aware that we haven't done our time change yet I think outside the US it has happened already Um M M Lindhol brings up a point about using blinker on the Raspberry Pi rather than circuit Python And this is a distinction that I've been making trying to get us to make for years because I knew I always wanted to do Uh this native circuit Python on Raspberry Pi stuff that uh, we'll talk about more today Um LinkedIn user says woot land of grunge indeed Yeah We've got a number of Seattle lights in the in the chat here Um, okay. So where we left off was actually I looked back at the notes. Thank you again to David and uh, I had I was having trouble we had gotten the repel over the ur and been able to do one plus one But we couldn't print hello world Um, and we were trying to figure out how to debug that so Uh, I've made a ton of progress this week on this Raspberry Pi stuff not all just thanks to me. Um, But we'll get into that a little bit later Uh, let me just kind of catch you up. So I figured out a way to do the backtrace stuff that we spent all last week doing and so let let me just start by showing that because Um, I think it's just kind of neat and We should take a look at that so Let me actually just do it through github. So on github. There is this broadcom peripherals Repository that I've been working in this is meant to provide like a simsys style layer for the raspberry pi Even though simsys is technically only for cortex m chips um, there's some weirdness because Cortex a chips can have virtual addresses. So like SVD files and that sort of stuff where like addresses are fixed doesn't quite work in a world where Doesn't quite work in a world where you can like remap addresses um, but assuming that you're like not uh Not remapping stuff. So simsys is cmsis um, it's the cmsis, what does it stand for? Common microcontroller software interface standard Um, so it's it's really common for microcontroller vendors Who are all built around arm to be using like standard arm tooling to put their systems on a chips together um So there's these like these core bits and it's interesting that they do have some stuff for a 5 7 and 9 um But this like the pack and sv SVD stuff are kind of like the things that I really like so s SVD files are system view description files Which tell you like what address ranges are all the different peripherals and what the registers do and stuff Um, hi tamon scoop. You're gonna be very excited spoilers. Um Actually, I thought about digging out my payonora. Maybe I'll Maybe I'll give that a shot too. Um Yeah, so where we left off was we were trying to get the back trace working across an exception And uh, I'll show you how I figured out how I finally figured it out. So there's this cortex a Uh gdb.py file And this is where I've been putting kind of like So gdb is the new debugger and uh, we can I can just show it to So, oh, I'm not I'm not showing my desktop. I'm sorry about that Uh, so if I want to so I can do open ocd To connect to it and then I can do Tar ext so let's like target external This port um And what you can do is if you have it, um In a source you can do or you can source um peripherals Cortex File am I in Cortex a gdb. So that what that does is it gives me this arm v a exception Oh, I hope you're feeling better It's not going any anywhere. So nothing happened because we're not in an exception Um, but if we go back to the file, which I don't think you could see until now Um, let me just I'll dump the link In the discord Um, so what you do is you take this file and you source it into gdb and that gives you this, uh arm v a exception And then further down what I was finally figured out how to do was, um, you can actually do unwinders in, um Python as well So what that is is a back trace is a thing that shows you, um Um Like where you are so like starting from main and then what functions were called. So this is gdb here And you can see that we're like in this enable interrupts, uh thing right now I think if I do so you can do breakpoint and I think timer One handler will oh that won't work. I don't think that works. Um, but basically We were having when, uh, we were reloading the wrong file and it wasn't working We were having trouble like seeing kind of past the exception that that was triggered by the air um, and so what I finally figured out is that there's There's two critical bits to, uh, adding your own unwinder So what what you get is a pending frame and it gives you where the stack pointer is for this frame and the program counter um, and In order to kind of consider a full frame what you have to do is you have to then say, um There's this pending frame create unwind info and you give it an id And then what you can do is you can add saved registers And it's important the thing that I was missing is that you need to add, uh for this is for arm You have to give, uh, both program counter and stack pointer updates into those add saved registers And in addition, you want to like put so this is saying for registers in these, um Read the memory off the stack to figure out what the values were And then add them add the saved registers to that unwind info. So that's um Kind of restoring the state of the stack In terms of registers and that's that's good for your backtrace for like values and stuff that were passed around So this is meant to this the order of these registers that we're reading off the stack is meant to match the boot.s Way that it like saves all the registers. So I figured that out it works. Um Now as far as I can tell so It it only works if it's in a a a hard I added a hard fault handler Um, you can see here that it's in if hard fault is not in the string or irq is not in the string Then it then it doesn't work um, it won't like try to Try to use this on winder to figure out the frame so I did that and um, this is all trying to figure out why I couldn't print, uh A string and I was getting like that address that was wrong and I finally realized that um, micro python And therefore a circuit python have different ways of representing objects. I don't know if I talked about this before But there's a good explanation in pi um mp config.h um So there's there's four object representations. There's a b c and d and They get kind of like more complex as you go further down um, and this object representation c is actually what we use kind of In all the microcontrollers and it has this nice property that it can store Um data in the pointer itself Which means that you don't have to always go to the the heat to allocate some things So here you can see and it's probably dark and small Um, let me make it a little bit bigger. Hopefully It's a bit easier to read In in micro python and circuit python. This is pi mp config Where these comments are But you can see here that they lay out all the bits of the pointer And basically say that like pointers on this architecture have to be four by a line. So If the last four last two bits are zero, then we know that it's a pointer. Otherwise we can actually put Like values in that those two bits to indicate what it actually is um, it's a yeah, it's Kind of fancy. Anyway, so I I was using this um I had set it up to do object representation d Because it was it's for 64 bits Um, but what I didn't realize is when I looked back at like the history of this It was added for doing 64 bits, but on a 32 bit system. So there was some weird stuff that it was doing uh to like account for the fact that it was Pretending to do 64 bits but on in a 32 bit system And uh, I guess we can see that here too. So for the pointer Like the pointer is still only 32 bits. So I was trying to use a 64 bit representation designed for 32 bit cpus on a 64 bit cpu Uh, which was a problem. So I looked and I figured out so Micro python does run in 64 bit mode because it can run on linux and unix and stuff And it turns out it's just set up to do this object representation a which can work for any number of bits. So We'll have to use the heap more for some some data, but besides that We can just use object representation a So I switched to that and suddenly I can print hello world So that was really good That was really good progress and then um, I was The next thing I was working on is like, you know, we had your and I was like thinking I could circle back to usb um But I was like, you know, I think the thing that excites me most about bringing it to That had to be a great feeling seeing the hello world print. Yeah, it was nice. It was like kind of silly Um, because I had been like trained to fix up some of the object representation d stuff that I found And it was just like, oh, I just shouldn't be using that um Which is silly So that was cool and then um The next thing I wanted to work on was the hgmi outfit because Uh, that is something I think that brings that something unique that the raspberry pi brings to things Is its ability to do native hgmi um And so it's pretty straightforward Um, there's like good tutorials on it here um It's like here's part five frame buffer And they talk to you about like you have to do so there's this mailbox thing that I think we talked about Yeah, the heap size should be more than adequate. Yeah, I so I have the heap size right now fixed at 32 megabytes Out of the like gigabytes that I actually have Which kind of boggles my mind Um, I don't know what to do with all of it. Although I think we we might do some stuff for that today If we get there um, so I did more mailbox calls and there's this like very straightforward Uh call to get a frame buffer from the gpu. So basically It's not here Basically you do this frame buffer call that's like setting up how much physical frame buffer you want and how much, uh Virtual frame buffer. So that's like the virtual frame buffer size is the size you're actually going to output The physical one is like how much memory you have and there's a frame buffer Or there's a mailbox call that you can call to tell the gpu to move where the virtual one is So that makes like scrolling and panning and stuff potentially like really quick and smooth um And I just like In general the pi peripherals are really not so crazy to handle as I thought it might I think like, you know, I I always I think it's largely been kind of what I expected where it was like One of the big hurdles was just like moving to this cortex a land um Where we have virtual like the memory the mmu we have um The different exception levels and we have exceptions instead of interrupts And so all of that like, you know, I I feel like we've gotten over that hump a lot, which has been great um, although there's just like Thing after thing after thing and I've like when I've been like talking a little more about it And I know some of you saw that was just like it's slow and steady progress Like I I get so far and then I hit this hurdle and I get so far and I hit this hurdle um but uh Yeah, so I like spent all of Yesterday I spent all of yesterday trying to get this frame buffer call working and I have this um, I had this I got rid of it Uh, when you do a frame buffer call it will write a value and tell you whether it um Correctly uh Was parsed or not So it'll give you a status of like, yeah, it worked or it didn't work And if it didn't work what I had it doing was just spinning so that I could find that it didn't work um And that's this so if people want to know more about The cortex a stuff this thing that I printed out This pdf the the programmers guide to for arm va. I highly recommend it. It's a great resource um If you're just getting into doing these cortex a stuff like I wish this there was a video of this like a presentation to go over all this Um, I haven't been able to find a whole lot of stuff online about it Um, I have to clean my desk Um, okay, so I spent like all thursday trying to get it working and I Like went back to basics and I was just like I haven't seen any so I have I haven't shown this Let let me give you a little bit more of a tour of my setup with cat cam here Although I do have the overhead here too So there's the kitty He's like are you talking about me? um, so my setup here that I have is I've got the cm4 ioboard And then I actually have this like seven inch elicro hdmi screen that I bought off amazon so I was using this to test hdmi and I like went back to basics. I was not getting anything on it until The bootloader like the raspberry pi bootloader will actually show up on the display. So if I Let me just see if I can't show that Let me see So that's my setup what I've actually got now also is um Is it under the normal arm pages? You know, I don't know where I found it I think oh, yeah. Well, there's the programmer's guide for arm v7 guides for v8 You can see my desktop a profile in advanced features So I have this open the gic I'm sorry. I don't I don't know where I got it I would just google it Like google the name of it. It's like 2000 pages long Something like that Um, I'm sure it's somewhere here Find the link to the pdf Yeah, that looks right And then if you download it, that's probably Yeah, see it's The second one I got Yep, that looks right Moto Timber says did you have heated issues with the monitor between that and the refresh rates embedded hdmi can be tricky? I am ignoring eat it right now At least I'm not dealing with it. The gpu might be doing some stuff I told lady aida. I was working in on she was just like You should do 640 by 480 to start because that's what like all the devices. She knows will support Um So let me just see if this works. So I've actually got a cheap video capture thing Um Plugged in here for the hdmi output from there So I'm going to what I'm going to do is I'm going to take out The sd card See if this shows anything I don't I tried to test it. There we go Nice, okay, so this is the um Beagle 5 has a low odd refresh rate and works with zero of my monitors. Oh no So this is what happens when I just took the sd card out of the raspberry pi um and this Is what happened like you'll get a display on the cm4 Uh with that so I'm glad that video is working um What I found yesterday after spending all day on it was that this test uh didn't actually work With this monitor that I've had here And I was so so frustrated and then I looked more at the I looked more at the raspberry pi or the cm4 ioboard and it was a little like the module It was a little tilted and I looked more closely And half the pins were not connected So there the cm4 has like two different pin connectors on it and one side of it Has like power and gpio and that one was set correctly But the other one was like sitting on the connector not so I pushed it down and it worked. I was like How many weeks have I been using this setup? And I didn't figure out that my my cm4 module wasn't plugged all the way in And I was like, oh This is the worst But again, it started working and then the uh The mailbox call then did work as well That's I was like, okay great like I got it working I just hadn't plugged it in right um, and it hadn't been plugged in right for weeks And then I was like, oh, you know what this might have been my problem with the usb as well I was like Let me look and see what pin usb is on which of which are the connectors it is And I pulled it up and sure enough usb is also on the other connector that wasn't plugged in right so I took a glance at usb yesterday and uh Saw that like more was happening on the bus, but it still wasn't working perfectly. So that's as far as I got yesterday Um on usb So let me just see I think I actually have it turned off So let me go and see if I can't get the display working Uh, so I just commented it out Yeah, all the low speed stuff so like blinky Ha floating tx pin for ethernet. I know I know right it's just uh um Okay, so let me recompile and load it again And this is unhappy too Folder oh, and you can't see do I have I do Bad solder joint. Well, that's better than Oops, I might have to fix something. We'll see That's okay. So I was actually trying to get Starting to do the st card sport. Hello, doctor little build Yay All right, let me get this out and I wonder if I can just Pop it in while it's unhappy See what happens Look at that So it's currently set to do 640 by 480. Uh, it's just manually set So we're not doing any detection of what the display is um But it does work So if I go and I this is over you are if I type something in It's pretty slow But I can do print hello world And that's nice and quick. It's the scroll that does really killer So I can do one plus one And then the scrolls are pretty slow Um, I actually had to fix a bug with this So when I first had a when I first got the output working It was all jumbled up and I meant I should have taken a picture of it It was all jumbled up and it was all white It was like white and blacks and I could kind of make out like where the text was So I had a pretty good idea that like I was close Like I was I was writing to the memory, but I wasn't right like Yeah, the the bad red diode. Yeah, totally Just like Yeah, yeah, that's scroll though. So One thing I wanted to talk about later is to see if we can't speed this all up So right now I should caveat the reason that it's so slow I think is because right now we have no caches active So every time it needs to load an instruction or load data Um, it is going all the way to memory to fetch it and back. So there is two level There's an l1 cache and an l2 cache that should speed us up a lot Um, it just makes things more complicated Um, so I think what we'll do Probably in 25 minutes, I've got more updates more updates Um Is I think maybe we'll try to turn the caches on and see much how much quicker it is That's actually also why I have it at 640 by 480 because I I was able to output at 1080p Um, but it was It was even slower So first thing is to get all the caches going and then the second step is like we could potentially Optimize how scrolls happen for the terminal i o class like I was thinking about this like we could have terminal i o like output one One box to render per line and then it could do computations of like if you're scrolling one And the the tile Like the two tiles that you're scrolling are the same then you know, you don't have to update it, right? um Anyway, so so I've got ideas. I know the scrolls slow, but I think the caches is I suspect that the caches themselves are going to be what speed us up um I did actually get um I did get a Blinking with digital i o working I showed it on show and tell On wednesday Although I don't have uh all of the pins laid out yet. So if you do import forward They're born You can see that I've only got like A couple pins to find right now. These are the four pins that I have leds on my breakout set for um Anyway, so I think there's a there's a lot of um Yeah, the esp32 s2 and rp20 40 Slow scroll as well Yeah, so I think like there's definitely optimizations that we can do in terminal i o to optimize like The the problem with terminal i o right is that it's a giant grid It's a giant grid of values and when you scroll it Your it it doesn't know like which parts actually change it just assumes the whole thing has changed So you have to like recompute all the pixels for all of that whole area Um, so if you wanted to make scrolling faster what you could do is you could take some time to figure out like which tiles Change when you scroll and only update those um Yeah, and the more pixels you have the worse that gets But the raspberry pi should should be pretty quick. Um so And I know that like CPUs like this Is the unit of scroll size constant as you scroll. Yeah, so the way that this scroll works is well, it um It's scrolling one Well, I guess it could scroll more than one Like when it does that that's on the scroll of one Oh, it says I have a pi pico and I'm trying to make a midi sync witzer, but I can't get a precise ppqn clock using time dot monotonic nanoseconds I heard we can't use timer timer interrupts with circuit python. What should I do? Um, I don't know what a ppqn clock is but like time monotonic nanoseconds is pretty good the problem is is that like Circuit python and python in general is not like doesn't run consistently fast um because you're Like managing memory and and some actions to manage memory take longer than others um DCD says is there an api that does hardware gpu type support for scrolling there is and um Yeah, so that's that for the virtual frame buffer thing um You could use to do some scrolling. Yeah, that would help a lot actually um pulses per quarter note um Yeah, I don't have a good solution for you If you're trying to write you are out stuff on a precise timing um But terminal term the terminal io stuff is just not written for any hardware sort of support um Unfortunately like I really wanted to support it like a lot of those um A lot of the spy displays that we support in circuit python. They will allow you to shift To wrap around the the display for scrolling the problem is that's only in one direction usually um, and it's usually not the direction you care about Uh, which is super unfortunate as well so Yeah, it's just like It's probably worth instead of supporting hardware stuff. It's probably worth optimizing The Like a lot of what display io does is figures out how like what areas of the screen changed And so like we could have terminal io optimize that more and I think like uh Keith is alluding to like the faster you scroll like if you're shifting five lines at a time like the chance that you have the same things Uh At the end like if each tile is the same at the end is probably less likely I don't know you could figure that out because the terminal or the tile grid stuff does know like the I guess Yeah, tile grid would will know how much it shifted between this refresh and the previous refresh Um, so yeah, there's definitely room to optimize that this problem It's always a trade-off with code size as well So it's probably worth being behind a flag so that for small boards We don't inherit that code, but and they'll only support small displays, which is fine Would this build work on any other version of the pi or only the cm4? Uh, it should work on any pi 4 I think um, I think it should work on a regular pi 4 the challenges is that the usb Is on the power connector Um sparkle beard. Oh, this is circuit python running bear on the raspberry pi 4 correct So what you're seeing now this um terminal output here is uh hdmi 640 by 480 output from the raspberry pi Running circuit python bare metal um Couldn't you define the display as larger than it is and mess with the start row to result in the scroll like effect uh Yeah Start row on the spy lcds, but almost always the start rose the wrong direction Like it's usually like the ribbon cable is showing you rows And then more often than not like it's sideways Like on the like a pi gamer the ribbon cable is on the right hand side And the scroll goes would go the native scroll goes left to right But if you're doing terminal you're you're running the scroll vertically it's really just like You could optimize it, but there's going to be so many cases where You can't take advantage of the hardware scroll Um, all right. Well, that's pretty cool, right? Well, let me So I try I was like, oh I It was not working Um sideways or it wasn't working because it wasn't seated all the way and this um bootloader test Where you take the sd card out and just make sure it shows up on hdmi is a really good way to test that Um that it is working um And I was like, okay today. I'll take a look at usb. However Well, I did look at usb today, but tack Uh pinged me last night and said hey, I got it working So I had asked him to take a look at it. Uh, those of you don't know tack is the uh Creator and maintainer of tiny usb, which circuit python is built on Um paid for by adafruit. So adafruit.com supports tiny usb and tack as well He had taken a look at it. He got his ioboard um And he got usb working As well, uh, so let me see if it works here. Um, I'm gonna plug it in So this that doesn't mean that um The drive is not working yet. It it works on the usb side, but I haven't implemented the sd card side yet um, so now if I go to yo Maybe it'll work I did have to fix a couple things All right, so now we are connected Uh over usb I'm like Compared to where we were last week I'm so excited. I was like so excited. Like I was just about to go to bed and tack was like, hey, I got it working. I was like Like I had just gotten hdmi working and now we have usb working as well. Um It's he only got usb full speed working um But that's like normally what we have across all the microcontrollers So it's totally good for what we're doing, uh right now um Pierre says could it be that it wasn't working for you because the board wasn't plugged in fully. So I did check um I did check that uh I did check yesterday Uh that the current code that I had put together What did not work once I plugged it in so I know that uh Like tack got it working. I did not um I didn't figure out the usb stuff. I had to I had to fix uh, the like Circuit python side, uh a little bit just to work with tiny usb But uh, yeah, I had to fix like There's a check in circuit python to know whether it's in an interrupt or not. Um, have a good walk doctor um And yeah, so there's this check in the serial side to make sure that it doesn't output to usb Print statements to usb blah blah blah. Anyway, it caused an exception. So I had to fix that. Um I feel like there was like one other thing actually I could look and see what I What I've changed or did I commit it? Let's see what I've got Changing here. Yeah, so this I haven't committed yet and I will switch back to Oh So I switched to my tiny usb branch Um, I got the additional tiny usb stuff source to build Yeah teamwork for sure Yeah, tack is like awesome Um Tiny usb is like growing tiny usb itself has like 2.1 K stars like it's going to surpass circuit python, which is totally cool. Um because Like it took me less than a day once tiny usb was working to integrate it into circuit python. It just makes like so Having circuit python centered around tiny usb just like makes it So awesome Hi, anthony Thank you. Awesome job. Yep usb usb was tax doing Thank you for the well wishes Yeah, it's a ton of progress this week. It like finally came together Which is like super exciting. Um Oh, I guess one thing I should do for the display is make Make board dot display work. So this is all display ios. So we should be able to just do any display ios stuff via it as well Um, but it is super slow. So I think it's worth poking the caches a bit Um, but in terms of figure getting usb working I had to add the system core clock Uh, which was not too bad Um, and then this is a check like this is to see if we're in an interrupt and I had to make sure that it didn't do, uh It was only for cortex m It was it was Trying to read an address that wasn't mapped. So it was Uh hitting the hard hard fault handler Hard fault handler in air quotes that you can't see Um, yeah, so that's working. I think maybe I'll just commit this And if folks want to try it, I'd be happy to help you try it Um It is slow I will warn you especially with the display on it's quite slow um But that's kind of what I thought we could poke at for the next hour But let me commit let let's commit this first So I think we want all of this What does peripherals have changed? Oh, this just has the base address for the second emmc. Let's just commit that now Oh, no, I reset hard oops Yeah, so the next step I was trying to get going is that So my plan is that The sd card will have two partitions it will have um Two partitions the first partitions the boot partition And that will have the kernel 8 Which is like circuit python and then we'll have a second partition That will be the like Uh the circuit pi drive um And so what we'll do is we'll make that circuit pi drive available Over usb like we normally would um So what I did I just like put my headphones on earlier and jammed out the registers for the emmc peripheral, which is what you can use to read the sd card Although there's a second peripheral called the sd host that you can also use so I got to figure that out Um Uh, what did I miss? So I was that's what I was doing earlier today But that's not what I want to do for the next hour. I think that's the written memory address. I just want to get that committed Okay, we'll switch to origin And I think we just want all of this but we can use merge to go through it So yes, we want to use my copy of tiny usb the new version of it we want this and this and this And this Oh, yeah, I had to change endpoint pairs because I had a I had a safe mode Because I didn't have enough endpoints Oh, and I had to I had to call usb irq handler. I was calling tiny sb directly and that wasn't scheduling the follow-up stuff Which I realized Usb works Usb cdc works um, it's possible that like Uh hid and midi may work as well Okay Why did you need more endpoints? It was set to zero and uh The new dynamic turned off off and on usb stuff actually checks at runtime whether you have enough I give you set up your usb to use more than you have then it will fail Then it'll go into safe mode I guess it's Fine because it won't change usb at that point um Okay, so I push that and Let's talk caches. In fact, let's just pull up this So this I this is what I have printed out um This cortex a series programmers guide and I read the chapter on caches last night um So I think it's always useful It's always useful, uh, or it's it's really important to reiterate how important caches are This is something I learned in university, but then I think a lot of people Uh, don't fully appreciate it when they're looking at like different microcontrollers or different processors um Is that people will look at clock speed of the cpu, but they won't look at like cash sizes cash hierarchy um and Just like memory throughput. This is something that the raspberry pi team did really really really good job with the rp20 40 um, is that they they made a really They have a really well thought out memory system Which means that although their cortex m zeroes they can get a lot of data in and out So, you know, here's main memory. This is like the ram chip on your raspberry pi But between there and like the cpu's so um, the cpu's in this diagram Are they salted or unsalted caches? unsalted Did I say caches? cash issues Uh, so so what we have here is kind of like a diagram of a multi core system This is all arm specific terminology Uh, I don't really know the x86 version. So I can't really compare But um, you'll see here that there's their core zero and core one And they're in a cluster And then there's could be a second cluster in the in the raspberry pi chips There's always just I think just one cluster of four cores or less Uh, of course And then within the core what you have is you have this level one cache and you have a level two cache And the level two cache is shared amongst all the cores in a cluster um and The important thing to understand about caches is that the the like Closer it is the faster it is to access. So when the cpu is doing its job It's it's getting instructions from memory and it's getting data from memory And if that data is Or or instruction is in main memory It can take actually a long time to even just load it Which means that like your your execution speed is going to be really slow Because even though your cpu is really fast it doesn't have the instruction to actually run um Cash talk ones for cash use Yeah, I go for some cash use So the only way that you can get really high speeds, uh on a cpu is if your Instructions in your data are really close. So Um, that's why that's why these like level one caches. Hi alvara um level one caches are really important. Um, and then uh the The level two cache is the way that you can share between cores Um, and then the further away you go the the slower it is. So Right now, I'm running and I don't have cash as enabled So I think for every access and thing I'm actually having to go to main memory Now the cpu will be a little bit smarter. It will kind of like try to look ahead and speculatively fetch stuff still I think But it's still going to be really slow. So I think basically And the reason to start with that is because, um There are other things so this remember that there there are other things that we're sharing memory with so In our case the frame buffer is shared. So the frame buffer We write to it and it's in ram, but the gpu is also reading it to output So we have to worry about that usb does a similar thing. So like you'll say like hey usb put stuff here And then they'll fill it in and you have to make sure that it's correct. Um, so If you don't do that correctly what could happen is that like somebody else is is writing main memory And then you're loading it, but you're getting a cache version. So it's actually old and stale and basically incorrect So there's a lot of complexity around, um kind of keeping All the cores view of the world consistent Which is why when you're bringing something up you should not worry about it Uh, definitely don't worry about it in that case. So I think you know, I think kind of what I expect us to Try and do is like we can probably get things faster to sundegro today And then like with more work you can get it faster and faster basically um So this is the this is kind of cache basics and right now they're just off So they should be going to main memory for everything that it needs to do which is going to be very slow um Sets in ways and blah blah blah um Yeah, if you want to figure if you want to see more details about this, this is a really good resource um I read it last night This is talking about write buffers um Write back versus write through Not exactly sure what we want. So there's other like cache maintenance things you can do so If you write to think If you write a bunch of data and then want to make sure that main memory has it What you do is you say you clean it and that basically pushes that data all the way back to main memory So like we could do all the frame buffer stuff and then clean it and hopefully the gpu would see it And then invalidate is the opposite. So If you're going to be reading something that somebody else had changed you want to invalidate it and get it out of your Caches so that you have to read it from memory again um Here's another Oh, this is a different terminology thing. So inner versus outer Um, and I think in our case, it's probably both inner, but there's actually ways of discovering this stuff um So I thought we'd start playing around with this one thing I think that I want to start with is Um Yeah, so I guess we should just get into it first. I want to do a performance test I want to be able to measure it. Uh, kind of loosely so I think that I was thinking about this and um import time And then we can do time dot monotonic And let's just do the nanosecond version Oh Oops, well, that's the first thing we could do is we could turn on long in long integer support um Good night, Dave or we could just do time dot monotonic Uh, and it's the reason it's slow is because uh The display is still running So if I back to this We should be able to see what I'm doing here on the display as well So I wanted to do while. Oh, I guess So what I was going to do is just um I guess I could put it in a function So let's do that, uh T So I'm going to do i equals zero Start equals time dot monotonic while Uh Time dot monotonic This start is less than 0.1 Plus equals one That's right. Oh, it's so slow So if we do t So 57 We run it again Oh interesting That's very variable but hopefully the The improvements we make are greater than Hi hams labs So we got hdmi and usb working on the raspberry pi On circuit by thumb bare metal All right, so we're seeing a little bit of fluctuation here Uh, but I'm hoping we can get like Orders of magnitude better Like in the thousands or tens of thousands Uh, and maybe I should copy that copy this so I can I it's because I don't have storage working yet. I'm gonna have to type it in every time we want to test Although I guess I could do paste mode. I don't actually know how to do that Okay, um So that's our first step and the one thing I thought we could start with is so the tricky bit is for the data that, uh You're going to share between yourself and a peripheral That's really hard to to get right One thing that we can do though Is that there's two different types of caches. There's instruction caching and data caching Um, and Let's just take a look. Um Right now we are Where's our linker script so when we lay out memory we're putting like So in in microcontrollers We usually have flash and we have ram Right and the in the flash is all where all of the stuff that doesn't change lives And then ram is where the stuff that does change live Um, but the way the raspberry pi works is that the bootloader reads our file and puts us all in ram Um, and so right now we're treating all of ram Kind of as a read write thing, but I think what I want to start by doing is just splitting Our ram back up so that we can have a section that's Like cacheable never going to change like cache it as much as you absolutely want to And then another region that we're going to leave as is Because that's going to mutate and we don't necessarily want to maintain Everything so I think the very first step we're going to I want to do is I just want to set aside a Flash version a flash Area of ram and then a ram area of ram if you will Um, and luckily we have a ton of ram So We can basically do whatever we want. Um Which is great. I think it does mean that it may start up a little slower if it has to like Uh load the file like a bunch of empty Stuff between them so we may not want to have too much of a gap just because it'll start up a little slower But I figured that's where we could start so Here's what we've got. Um We've got this kernel load address So this is where we start and then text and read only data are the things that don't change And then data and bss are the things that do change Um, so I think what I want to do Is I wonder if I can add, um Different sections Let me I think I can Where's I am But that makes sense, right anybody have questions about that approach That's this I think So let's say that Should we call it Let's just call it read only Read only Is here We can mark it whether we can execute or not too, but I don't think that matters Our origin is going to be Eight And I think for length what we want to do is we want to match it with so we're going to have to Change our mmu settings And that's going to be origin Equals zero x eight zero zero zero Plus one m. I think it's one Uh, we'll see in just a sec Basically, I want to make it with an easy page table size So then what we do is this goes into read only This goes into read only this goes into normal And so does this these might want to be in here I don't know what this bss size is, but I'm going to leave it in there Uh, oh good. You can see what I'm doing. So the next thing I wanted to check was The mmu In fact, I think I might have it noted I mean, I could just do it. I have a two gig module I shouldn't do that I think I really do want it down to What's this say? Each entry I said gig And then what is the second tables size page table tool This is the person that had the good article about it Like the finest unit is 4k And then what is the next smallest unit? each table 64k I think it's actually in this video Like a really good diagram of it two megabytes Yeah, um, yeah, so there is The one gig and then there's the two megabytes So we Would need a We need instead of this one gig table. We're going to need another table of two megs so We're going to need this level one table still, but we're also going to need A level two Which goes to 40, I think That's what a gig is, right? I think it gets this So this will be there I don't know my hex digits that high up. That's my problem so Our first entry is not going to be That anymore our first entry is going to be this other level two table is Zero So I think what we'll do is we'll just do How much is two megabytes? I don't even know like in hex. What is two megabytes? It is two times 10 24 times 10 24 right Kilobytes megabytes So it's 200,000 if it's if you read it that way So There's 80,000 That's where we start 80,000 is 512 k Okay, so what we can do is we can do the first We'll do the first as The first two megabytes range that'll be the stack and Oh, it'll be the stack Probably okay That's probably okay Except for the mailbox stuff is all done on the stack Which maybe we could just figure out a fix Yeah, let's do that. Let's let's just let's get this Bay sex because of traveler role playing game Okay, so we're now setting up this first gig is Oh, you know what and we also have 16 megabytes at the end of uh As frame buffer memory, which we don't need to read Or like it's not going to change on us so we could cache that we can Yes, I think we can figure this out stack code RO data BSS and so What we're gonna do is The first entry of this is the first two mags And this is where If I mark these tables as cons, that's where these tables will live and make them cacheful as well, which will be Good In fact, I don't know why this is marked volatile This should be const I'm gonna break stuff. That's why it was like let's commit this before I start breaking stuff So we're pre-computing this all no or not. We're filling it out here Reflecting me very interesting. Looking forward to seeing this on the pi4. Thank you. It should be cool Um, okay, it doesn't need to be const. It just shouldn't need to be volatile either It should just be able to live in normal memory and maybe we can Figure out how to make normal memory cacheable Break stuff smash it I'm trying to make it faster Um, okay, so level two Entry zero is going to be equal to basically this Maybe I'll set it all up as the same and just make sure that it's We're still running. So first two megabytes is going to be That's and actually the remaining the remainder that will as well zero Actually, we could just We can add this execute never flag, right? We have a good way of catching the exceptions now be this level two after that it's going to be Execute never but normal caching otherwise And we figured out that we have to have the access flags at This We don't need anymore Let's do this double up too All right, so the only change that we should see is now we're doing one more level one more page table level So now we can do two megabyte chunks in the first bit And Everything's self set up the same Did I copy this twice? Looks like I did we we don't need the second copy Okay, so this is I think I want to I wanted to read like first to the end So this is the first two megabytes. This is the rest of the megabytes in the gig And then we set the top level And then we do the next we do the third gig We ignore the first bits and then Yeah, so I think that's right So I think that's correct. I didn't finish the linker changes So let's just do two megabytes there and two megabytes there and um Actually, this is going to be 1.5 And then this is just going to start it two megabytes And the length of this is actually 10 22 Right, so that's the first gig maybe Should we see if it works? See if it compiles syntax error on line six Do they need to be comma separated? Can the origin not be a size? It's possible What did we decide 200,002? Yeah, I get sashes. I lose track of still syntax error Do you think this normal is a keyword? I mean, maybe the line number's off this length wrong There's me trying to get the led on gpo 14 to flash It's taking weeks and weeks to get here It's that let's just say it's one And what's that 1024 Is it 15 36 15 Oh, I was right can't do points All right, it worked Um, all right, so let's turn this off I was not expecting that hgmy converter box to work. So I'm pretty excited that it is I have her clean I didn't Well, maybe I did yeah, I did copy it over Yeah, so it's a lot bigger now. It's 1.5 megabytes I do math on Friday. Yeah I try It should be more than one and a half actually, but let's just see if it boots up Hopefully it will Otherwise we can gdb it Let's saw the boot loader Hey It still works awesome Um, that's good news Okay, so the next thing we want to do Is change the mirror m a i r Controls some of the Cashability properties of the memory Um 1.5 megabytes. What is this on the electron app? I don't know. I think it's I mean most of that zeroes too. I guarantee it Because we just moved all of our data out It only added like a megabyte of empty space. That's fine This is a whole new world. It's a whole new world of having like gigs of everything, which is pretty wild Um, oh and it worked even though we set execute never So Let's pull up our architecture. I think I have it open here architecture reference Am I on it? Holy moly This oh look at that. It's the last thing I looked at um Okay, so this is so the way that the memory attributes are stored is that the page table Um, which is the thing we were just editing has an index into values in this register the m a i r register so, um When we're setting like this m t normal n c So that's normal memory not cashable And then we have this device Not n g n re ne which I G is gather e is early write Anyway, it's just makes like It's right. That's the right thing um, and if we look at so I crib I crib this Setup stuff from one of the examples If we look here, we can see that like index zero is this and index one is this non-cashable Um, and the flags for each of those are zeros and four four Uh, so what I'm going to actually want to add another um Here just define m t read only And we'll set that as two and So this is like Stuff in ram that's not going to change that we can share with whomever we want to share it with zero x zero zero Actually, we can do it as four four just to be safe And then Here it's to do Yeah, the rpi bare metal os is one of the resources I've been looking at you can find it on um You can find it on uh github and I've been just looking at the github version but m t Read only flags And we're going to scooch that over eight times m t Read only put the flags here And so let's dissect this so so each mar is four bits So if we see attributes here, um device memory is if the top bits are all four and then d tells you something about it But we want normal memory. So normal memory is if the Os are not zero and the i's are not zero and I think the os and the i's here Are um Is outer and inner so if we think back to the diagram I showed earlier where like l one and l two were inner and then outer was l three Um, it's a way to like have different policies for different parts of it I think that's what it is um here you can see here's the device stuff and it's Yeah, it it doesn't tell you Like n it's three bits and the n tells you whether it's not set or not I think it's like gather Really right and I forget where the r is it's in that uh the thing I read last night that we linked to Um, okay, so here is how o is We want uh, we don't even care about writing because we're not going to write it um At all so we can just do it as I don't know what transient is Oh, r w might be Um read write does that make sense normal memory and transience What the heck does that mean? I mean, uh, there are n w bits. I have the following meaning Allocate not allocate, but we we do want to allocate it So we're set up is for Which is this right now So we're not allocating it to the cache but for I think we just want Outer right back. I think we could just set them all high To f and we would be set I think I saw that somewhere else So let's do it. So this is like aggressively cashable So if we go back here and for this first two megabytes, we're going to call it n t read only And let's where do we find out? Always wondered what the not garbled alphabet soup was n g n r e n r And e did you look it up or do you want me to look it up because it's in the it's in this cortex a series thing Um, there's a whole section on on cache coherency that talks about it. I just don't remember what it is Okay, so this is changing it to read only Um, and let's just see if we can't find the access flags thing Let's see if there's any other settings that we could we need to set because I think there are access Is that it's the long form description of the the memory? Oh, this is not gonna work Of more than a thousand matches. That is the wrong thing to search for to find this You know, it's probably if I just look for the mirror references Oh, there's still 600 Oh, but it might just implementation Long descriptor format translation tables That's what i'm looking for But you haven't linked me to it That's a lot of tabs for a raspberry pi for Long descriptor that's what we want Long descriptor Think it's this That looks nice. There's the two megabyte region. Uh, here we go. This is what we want Upper block attributes lower block attributes table Level three. We're not in level three stage one security bit ap table av8 32 long descriptor Page based hardware attributes non-secure el2 execute never privileged execute never Indicates that 16 adjacent translation table entries point To contiguous memory. I wasn't doing that because I didn't want to Not global bit access flag This is global. So I don't think we want to set it shareability That's the thing that I'm thinking of Access permissions not secure And then that attribute index But we're in stage one el2 non-secure el Stage one memory attributes for the shareability field. This is what I was thinking of memory region attributes aggressively cacheable It's right I'm gonna aggressively cache it Overview shareability outer shareable espit I don't know what this text thing is shareability It probably doesn't matter Long descriptor format region attributes Indicates the mayor register to be used And shareability longed Okay, so here Both inner non-cacheable and outer non-cacheable Shows the encoding in this field. So right now it's marked non-sharable We want it to be We want it to be inner-sharable el2 control of non-secure memory region attributes attribute to Is that separate? Oh, this is stage two These things are so complicated Combining the cacheability attribute shareability attribute tlbs Okay Ideally we want to cache that too We just want to cache it all we want to be aggressively cacheable We're about to run out of time though. I'm not sure I'm gonna be able to get This actually done Do we remember what bits are shareable? Because we can set it as inner-sharable. We know that shareability long descriptor format It's linking to itself inner-sharable Okay, shareable is looks like it's eight bits in So let's just do shareable The tcr value Is that better? I don't know I don't think it really matters because we're all running on a single core So that's these flags, but we want and then descriptor Everything Yeah, it's bits eight and nine This is like how do you document all this stuff? It's just So much Normal memory long descriptor Okay, so outer is one zero inner is one one. Let's just add them all zero So I don't so I don't have to think about this again And the last one is I think there's one more Oh non-sharable Let me shift no bits Non-sharable, okay I think we want to be I don't know Inner-sharable versus outer-sharable. I thought you would say both Anyway, let's try it. Let's say Inner-sharable Then how do we turn the caches on? I think they're in this, um system control register sc system control Look at all those bits 64 of them to be precise It may not be the system control register I should probably look for a tutorial branch type Branch predictor would be good if we're not doing that cash maintenance So much complexity for like doing isolation and things instruction access cash ability control for accesses at el2 When el2 is enabled in the current security state and e2h and equals one one Ah the ibit All instruction accesses to normal memory from el2 are non-cashable for all levels One has no effect on the cashability of instruction accesses to normal memory from el2 Hmm So that's set to zero. I think it's basically off I think we do want to set bit 12 to i So that's coming from this Oh bit 12 Bit 12 is one two three four right four eight 12 12 is actually the 13th bit on the That's what it is Mark Wilson says so what's the current status? What did you get to work so far? I see something rather cool on the bottom right hand of your screen. Uh, yeah, so HDMI is working and that's what then the bottom right hand side you're seeing the current HDMI output And that's 640 by 480 and it's pretty slow. So What we're working on here is we're trying to get the cash going So that we can Be faster, hopefully So maybe i'll just try to see if we can turn on the instruction cash here and get things going a bit quicker And usb is also working Not mass storage because we don't have the storage working yet, but usb cdc is working And so we're just trying to i'm perusing all these bits in this register to figure out how I can turn on the caches So that it's not really really slow Alignment faults Which we're not having a problem with See the c bit. Oh, this is data accesses These are just like overrides And this is bit two Oh, no. Oh, I got to the end So that we're setting bit one It is major progress. Why am I oh i'm too far away? Um, so So This is setting turn on the instruction cash and turn on the data cash Let's just go for broke. Shall we Data cash is bit two I guess I could do all of this all at once, but The bit two is Four It's the plan to have the raspberry pi show up as a mass storage device like other circuit python boards Yes, once the storage is working, then we'll have it do that too A lot of the raspberry pies are not necessarily The boards themselves are not designed for that to work though. So there will be caveats around some of the boards all right, let's let's uh Hail Marriott flags Did I Am it wrong? I'm in the habit of doing mp immediate out of range at operand three This or that the immediate encoding is really interesting because it's like a certain number of bits and then you can shift them so Which is why it's complaining about this one where like the bits that are set are too far apart Um, but we don't actually need that top one because we're setting it for the instruction cash So what we're doing is we're taking we're reading the value We're doing three things and then we're setting the value and then we Are us turning on an instruction boundary This probably won't work. It may work. It may not work We will see but if it does work, hopefully it'll be quicker Like I generally don't like to prematurely optimize, but like that It's pretty slow It's pretty slow sync As I understand it, that's the reason for using the pi four or pi zero is they support setting usb port to uh a mode usb sort usb c port on the pi and the second port on the zero and the three a I think they're a connectors, but they can do otg I think as well Interesting. I'm excited to see what circuit pi thing can do on a pi board I was curious how well they would behave as masters since they're closer to being a full-fledged pc than other cp devices Oh, it doesn't look like it worked We're getting the rainbow test pattern but those cv says We can't connect to it, which is good Allocation outside of em new exception value error This could be This could be a data thing. Let's just for now. Um You need a converter cable. Yeah uh, let's turn Let's not do the data cache. Let's just do the instruction cache Um, because clearly like this is a data problem but we should get Some speed from just doing the instruction cache And that should be safer because that's like not data that we're sharing with things So let's give that a shot Which I think is what I should have done in the first place Let's just do instruction cache first because we know that the code is not changing at all We don't have to worry about managing it at all We're not doing like if we had like the native emitter going Then it would matter because then we're actually going to execute from somewhere else, but That is not something I care about Especially right now cache maintenance is A pain bootloader Hey, oh, is that quicker? Not really Oh, let's switch to it All right. Well, what was the test that we did? Let's see if we gained any sort of speed Oh, you can't see my desktop anyway F T i equals zero Oh, no, I didn't import time monotonic Which I think it's fine And we don't have long ends on it feels this is feeling a little bit more responsive, which is nice Oh, no, it went all the way. Yeah, the scrolling or A little painful still zero Just a little bit. We're in the 600 still Feels a little quicker, right? Can you paste in that program? I might have been able to All right. Well, obviously we have some more optimization to do um Getting all the caches going like there there's a cache for the tlb as well So doing all of the memory Accesses stuff and I don't know if that is on Um, that's another thing that we could Turn on potentially Um We've got a few more questions and then we'll wrap it up Um, how is the storage it's set to working now? Do you have an emmc model and use the usb? Boot thing to copy it over or I'm using an sd card So the boot loader is loading from the sd card into ram and then i'm running so I don't have I don't actually have The emmc stuff working from circuit python yet I think it is a smidge quicker I could run these tests with the display off and it would be a lot more reliable probably um Next question from and lindholm is is it still recommended for beginners to start with circuit python 6? I've been finding some of the sensor examples provided don't work with circuit python 7 As the calls functions, etc have changed. Um I recommend starting with 7 There's a lot of good stuff in 7 and it seems to be stable if there's stuff that's not working Please make sure that we have issues filed for them Because we would want to fix them. Uh, we're already talking about doing a 7.1. So We're we're definitely past 6 at this point um And then Todd bot asks Uh Big question if I submit a pr that allows booty.pi as code.pi alternative In the pirate language mode. Will it be accepted? Um I would accept it, but I would argue that booty.pi is probably More an alternative for boot.pi because they're very similar But yeah, generally I'm open Well timon says emmc and sd card would behave the same nothing to do there technically Unfortunately, they're the raspberry pi does have two different ways of managing sd cards. It has an emmc Uh peripheral from some company and then they also have an sd host peripheral that is from Uh, that is like custom They're both supported by linux. So you may not know which one's which the emm Emmc one can do sd i o for like wi-fi stuff. So I was I was just looking at this and um, Like for the raspberry pi 3 Uh, the emmc peripheral is used for the wi-fi, but the sd host one is used for The sd card. So things like that. Um Related question. Is it possible for the community to offer pull requests to update those examples? Would that be best done on the particular sensors github page? Uh, which then would filter to learn.atreford.com. So, uh Yes, so there there's kind of two places to look and um Yeah, pull requests are definitely welcome. Uh, we have it so that if you see code from github in learn Updating the github repo will automatically update the Learn guide. So there's two places to look. There's the driver Specific example, and then there's also one massive repo for learn guides So there's two places to look for where the example code would be for a particular sensor Um, yeah, feel free to bug me on discord more if you need if you need guidance and have thoughts on that Um, okay Thanks, minnesota mentat, and I'll switch Switch to here Um So running circuit by thumb from a multi gigabyte sd card will just work on the raspberry pi Uh, hopefully yeah when when we're done we'll both have multi gig flash flash and multi gig ram Which will be like right now. It's just 32 megabytes and like I don't know what to do with that many megabytes Given that like maybe we have like a microcontroller board with a single megabyte Um There's just a little bit of math We have to do to figure out like how much room we have between circuit by thumb and the gpu and then we could use all that for the heap too, but i'm not sure how well the uh The uh The gc and everything will perform when it's actually that huge um So, uh, hello. All right. Goodbye. I don't know I'm scott. Uh, this has been a deep dive. They happen every Friday at 2 p.m. Pacific that's 2 p.m. Pacific regardless of time zone So if you're in europe in a few weeks, uh, or if you outside the us in a few weeks, the us will change and shift things for you um You can join the discord server by going to adafru.it slash discord Um, we chat in there all the time Uh, and if you want to follow circuit python development, there's a circuit python dev channel There's also this live broadcast channel that you see next to me um You can chat with me there. There's also a deep divers role So ping me and let me know you want to be in the deep divers role if anything wants to uh If you if you if I ever switch things after I like kind of announce them like next week is on friday Which next week it is i'm planning on doing on friday, but if I change my mind i'll ping the deep divers role So make sure you get that Thanks again, uh to tac for helping with the usb stuff and making tons of progress there um Thank you to everybody Uh, who's done bare metal raspberry pi resources has been super helpful and hopefully this is just another one of those things Um, if you want to support me you can support me indirectly through adafruit by going to adafruit.com and purchasing hardware there um All sorts of cool stuff that runs circuit python and we're just going to have like a larger and larger collection of different boards That have different strengths that can do circuit python um, so that's great too next week's on friday um and I will adjust cat cam Because I pet the cat on the way out But also, uh, thank you to patrick and david for david for taking notes and patrick for organizing those notes into the deep dive note repo under the adafruit, uh work as well so thanks again, and uh, I'll see you next week and maybe SD card will work and we'll have the drive showing up and it won't be super slow. Um Fingers crossed, uh, if you want to follow along, uh, I do push all my work to github pretty much every day So if you want to to try this out you can go to github.com slash tan new Slash circuit python and then there's an rpi branch um That has all the latest raspberry pi code in it and with that, um I'll put the cat and we'll get out of here and have a great weekend everybody Go get your hair cut if you need one