I'm going to get everything going here. If you're watching this video after the fact, make sure and look at the description below for all the time codes. I know last week I had some audio issues, so we'll get those hammered out at the start if that's the case today. I don't think it is. And then also, we'll just say hello's and stuff. So make sure and look in the description for all of that. Sorry for the audio problems last time. I was super hopeful that we weren't going to have discord issues, but it looks like it is having issues still, which is unfortunate. Let me just stop all these streams here. I don't need to look at the video coming back to me. Looks like everything's going. Hi, unexpected maker. Hi, Paul. Hi, Dishapu. Hi, Moonlight Shaker. Have I been objectified? Yeah, well, apparently no. Apparently it's like half working, which is good. Is the audio OK, everyone? I was going to just check the thing that I forgot. We will have a guest as well. Audio's great today. Perfect, thank you. Hi, Johnny. Thanks, Tinkering Rocks. Audio's good. Hi, Gary. Hi, Mr. Certainly Bruce. Hi, Hugo. Hi, Ken. Jeff says, hi. Jeff, you've got to let me know when you're going to call in. Jeff's going to join us today, so that's going to be exciting. Check Twitch. Oh, you know what? That's the one thing I forgot to do is I forgot to pop the Twitch chat out. And I do have mod rights on Twitch now, which is good. During the first hour, please. OK, well, Jeff, why don't you just call me and as we can just get that going as we get going. Just video chat me on Discord. And we'll just get you in right now. Open in browser. And then, yeah, I'll let you go after the second hour. I don't think my video will work. Let me turn your audio on and pop you out. Can you hear me, Jeff? I can hear you. All right. Can you hear me? Yeah, I probably need to shut off YouTube or we'll end up with feedback. I'm not sure which of you I'm replying to now, actually. Yeah, you probably want to mute your YouTube. I will have to do housekeeping here first. Hi, Don. Hi, Alvaro. I'm probably saying that wrong. Hi, Bruce. Hi, Mark. Mr. Certainly is on Twitch as well. I think we gave you mod rights as well, Mr. Certainly, on Twitch. Great, Unexpected Maker can hear you too. And it looks like I was wondering what this empty space on my screen was. It's the spot that I normally put the restream chat. That's why. All right. Perfect. Awesome. Oh, I'm on camera. I didn't realize. I'm going to take you off just briefly while I do housekeeping, but then we'll go straight into you. I always have this period of getting going. We are starting a little late because JP, it's Thursday. So yeah. But looks like everything's set up, which is good. And I don't think David's around to do time codes because it's Thursday, so I'm going to try to do my best as well. I do have my time stamp thing going. All right. Hello, everybody. Thank you for hanging with me. I just wanted to introduce today, do some housekeeping. My name is Scott. I go by TAN News Online. And I'm paid for, Adafruit pays me to work on Circuit Python. In fact, they hired me to create it based on MicroPython in the first place. So if you want to support me, you can support me through Adafruit by going to Adafruit.com and purchasing hardware that runs all the open source software. It's open hardware that runs open source software that a number of us work on. Today, Jeff is in the background here as well. We'll introduce Jeff in just a bit, but Jeff is also paid by Adafruit. So please support them. If you want to chat with Jeff and I and a lot of other cool people, you can go to the Adafruit Discord server by going to the URL adafru.it-slash-discord. Join us there. This is a deep dive where we tend to do questions for about the first hour. We'll talk with Jeff this first hour and let him go by 3 o'clock my time. It normally happens on Fridays at 2 PM Pacific, but I'm going skiing tomorrow morning and didn't want to have to worry about getting back for it. So I bumped it to Thursday here. So no stream tomorrow. Next week should be on Friday. But that does happen occasionally. I try to give like 22-ish hours of notice on the blog. So if you're ever wondering about that as well, keep a lookout for that. You can ping me on Discord as well if you have questions. Questions are welcome. We have two of us here to answer them. Otherwise, I will try to answer them as well. And I think that's it for the deep dive. The last thing is that the cat here you can see is Spook. And he is epileptic, so he does have seizures from time to time. So if I'm not communicating with the stream, it's because I'm watching him, but he's been doing really good, so I don't expect that to happen. And let me just try. Oh, look at that. I can pull Jeff up in the cat cam spot too. Okay, so let's introduce Jeff before, we'll do questions of course, but Jeff is two hours ahead, so we don't want to take all of his time. So, Jeff, welcome. Thank you. So as many of you probably know, I've been working on Circuit Python as my main gig for about a year and a half now. And it's a lot of fun working with Scott, working with some of the other people. And it's a huge change from my previous industry, where we weren't particularly friendly as developers to our customers. And it's just a lot of fun to be a lot closer to what I'm doing. And I think I'm not focused here. So just give me a second. I'm gonna play with my webcam setting. So talk, talk, talk. Yeah, so there was something I was gonna say and I forgot. Jeff's been doing lots of good work. Jeff and I, it's interesting. I think Jeff did like one PR or maybe two for Circuit Python before you were actually in Seattle visiting. So you and I actually got coffee pretty early on and talked about the like, oh shit, like can you start working with us and how awesome would that be? So that was really cool. Back in the time where I could actually like get, get coffee with people outside of my household. And that time will come again. Yeah. There wasn't already one important question in the Discord chat. And it's, do you have a cat? No, we don't have any cats. We had cats who lived with us until the ripe old age of 16 and 17. That's a good cat. They went on to a different place. So I now work that, we're without cats. You're without cats. And I don't wanna get too much away about where you live but it's been really cold there, hasn't it? How's that going? I don't mind saying I live in Lincoln, Nebraska. And we've had, yeah, like temperatures, record setting low temperatures of minus 30s lately here. Not as bad really as what they're going through in Texas in terms of the impact on the infrastructure. We're a little more ready for it, but yeah, it's probably been real weather here. Yeah, so how are you holding up? Is it all par for the course? You know, it's fine, already not going out much but I miss being able to take a walk of any length. Oh yeah. Yeah, but you know, we'll get up to freezing on Saturday and then we'll get up to 41, fairly like one Monday. So really getting back to those warm temperatures. Nice, yeah, I think we just broke 50. At least for a little while, it's raining here today but I'm planning on going for a walk after the stream as well. So how would you, so you've been working with us technically part-time, technically half-time for like a year and a half, how would you characterize the kind of like the big things that you've done for CircuitPython? What are the things that people should ask you about? Well, the first paid project you offered me was audio and I'm not a person with a big audio background but I muddled through and so now often the audio projects come to me and so I owe a big thank you to you for doing these two audio projects on Pico because I don't mind the break from it. I'm already there with these ones, like I'm very excited to like get finally past him. Yeah, yeah. So I like dabbling in everything and I primarily work on the core so that means writing the C code and I don't do as much work in the libraries although what we're gonna talk about today has a part that's in the core as well as a part that will be in a library at least that's how I see it playing out. So I like to be able to work everywhere within a piece of software, not concentrate necessarily in just one area. Right and you've been doing some guides as well, right? Yeah, doing some guides, doing some projects. I wanna get more into doing like maybe some videos but we'll see about that. Laura's been giving me some support for the idea of doing some short videos about my own projects so that'll be fun. What are those projects? Well, for our audience here. Yeah, so I can't see how well I'm holding things up to the camera here. How do I get back? This is weird. Anyway, this is a circuit sculpture that I made and showed a few weeks ago on show and tell and so I'm doing a gonna do a short Twitch style video just saying, you know, here's what it is. So you take brass rods and you shape them in soldering and you know, I've got a feather and a bunch of neopixels and if the battery weren't run down it would be twinkling away because we need more rainbows in the world. Mr. certainly calls it a mini stargate. Yeah, a lot of people have thought it looked like a stargate. So you are definitely, here we go, we'll plug it in. In good company. Of course, the LEDs always have trouble coming up on the camera, right? You may get the idea. Yeah. Definitely need the stargate sound to go with it. So back to the audio, right? Yeah, yeah, and you did MP3 in particular and like I tried to turn it on on the Pico and then it was like, you don't have these instructions because like it does some of the like basic SIMD stuff that the Cortex N0 doesn't have. Yeah, that and I think maybe Audio Mixer will need some rework because you know, we've got the CPU power on the Pico to do these things. But yeah, some of the code just says, no, I'm not an M4, not gonna do it. Right, right. So not necessarily the best distinction but it's kind of the one that we used. Yeah. In the case of MP3 the distinction that somebody else used because you know, MP3 and like RGB matrix is another contribution of mine.  Right, right. Which is a perfectly valid kind of programming but different thing than being able to understand how to drive or how to decode an MP3 or how to drive a complicated matrix display. Right, right, right. Yeah, yeah. I think MP3 is something we'll get to but like I have just, I'm sure you've seen these too.  I know MicroDav's working on it as well but it's just one of those things that like you didn't you don't really know. Like I started audio like three weeks ago or something and it's gone longer than I expected but then again like everything does, everything does, especially when it's audio. And so like audio is going to be very cool. I think people are going to be excited about it. A lot of what I have coming in this next PR is also like PIO improvements which were also something that I knew we would need to do. Right. So it's really good to knock those out. Like yesterday, we talked about this a little bit but like when you first started with PIO you struggled getting the pin directions right, right? And so that's something I just went, yesterday I was pretty productive today. Not so much, but I went heads down and like I added like for outset and side set like just initial value, initial direction for each of those. And it is going to make a huge difference to usability, so kudos. Yeah, yeah. The idea that you like, you really need like a default that makes sense. Whereas like the default previously was that we wouldn't touch it at all because we didn't know the state that you wanted it in. And I actually did, I know we should talk about your project but I was talking with Luke, so Luke Wren who works for Raspberry Pi and is like I think one of the core folks on PIO I was asking some questions in the Discord for it and my mental model of it had been like if you enable it like then it runs, right? That like the PIO state machine runs. Okay. But it turns out that like most of the state machine is always running even when the enabled flag is off. So does enable just stop the outputs from going out or? No, what it does is it stops from it like moving on to the next instruction. So the PIO has this like register that's like here's the instruction I'm running and if you write to it, it just executes that instruction. In lieu of whatever else it would have executed. Right. And that's true even when enable is off. Hmm. So like what if it's sitting at a pole instruction and there's nothing in the queue? Do you know if you're, if the instruction that you put in takes precedent or? I think if you write to the instruction register it overwrites it immediately. But if that instruction is a pole itself like there's a way to detect that it's stalled. So you would know that it didn't happen but even when it enables- Yeah, that's like a weird corner case so. Yeah, the one caveat with that is that it doesn't do delays. So if you're doing that like I was like, oh could we do like single stepping? You could mimic single stepping by just having enabled off all the time but it wouldn't do delays for you. So that's why- I was also thinking that like a PIO emulator that you could run on a desktop computer would be interesting. Right, right. I don't know if anybody's done that yet. And then David Glaude mentioned that there's a disassembler for PIO program. So all of that is, yeah, kind of offers up different ways to approach problems in your program. But if the problem is that your outputs aren't enabled which was my problem for like four days. Right. Then that's just gonna be solved by this code you're working on. And another thing, you said UART and I know it's not the UART thing that you were talking about but this one that Dan is working on. Oh yeah. The CDC UART is also going to be amazing and just coincidentally I needed it yesterday. But there you go. Yeah, that's one of the reasons I haven't written any code today is because like both you and Dan have really good PRs out to review. Along with- Yeah, this is a lot more substantial than this one of mine. Yeah, a lot of it's methodical though. So David G says, so we can send one instruction at a time to the PIO. That is correct. You can just write. And in fact, in this PR that I'm working on I have a run function that you can call and just give it instructions and it will just run them serially. And it turns out that's really useful for this setup process that you were talking about. Right, right, right. Although you won't have to use it as much as you did before because we'll do all the pin direction stuff for you. Yeah, but that's what it's doing under the hood as I understanding is issuing these instructions but also other changes to the PIO peripheral that might be needed. Right, so I was looking at it actually and it uses set. Look, it uses set instructions for all the pin stuff. Mark asks, any thoughts about opus in Circuit Python? It's much more awesome than MP3. I mean, there are a number of codecs that are more interesting kind of at a technical level. There's, I think opus is a voice codec. So you get things like low latency and really low bit rates. And there's AUG which was the patent free alternative to MP3. But we picked MP3 because when people talk about I wanna play music they think of MP3's first so it's kind of a brandy thing as much or more than a technical decision to choose MP3 over AUG. And yeah, like low latency thing could be super interesting and someday we're gonna have audio going over the USB would have a lot of possibilities but it's a lot of someday stuff. Yeah. Yeah, I mean. Yeah, it's nothing that I feel like we don't have an open issue where somebody's pinging it once a day. Like you aren't as at this point. Yeah. And so if somebody wanted to provide it and merge it like we have, the audio stuff is structured well enough that we can add things like that in. But I think for like eight of four. To a certain degree it's fair to ask, MP3 is not a patented format anymore. It's expired so everyone can use it freely. So specifically with AUG what is the use case that having both formats enables? Why not just use an open source, no cost converter to convert it into MP3? Because flash space is gonna forever be at a premium even if we sometimes feel like it's not right when we get a new chip. Yeah. Well, it was funny right before the RP2040 was released because as you know, I had access like a month early or so. Like we actually changed how much room we were allocating in the external flash for a circuit python and like the day before or something like I did.  Like it was, I think it was like 512K and then it was like 684 which what micropython was doing and like at some point we're like, okay, let's just make it a megabyte and that will leave us lots of room to grow into. Yeah. Yeah, I mean, if you look at what is the size of ESP32 it's a lot bigger when you bring in all of the wifi and SSL. Oh yeah. But I mean we just, everything that we wanna add it takes up code and until and unless we have a dynamic loading method which is one of those other, we would love to have this but it's not a top priority. You know, everything comes out of one fixed budget instead of coming out of a flexible budget. Right, right. And yeah, I agree with object object. Aug has, by virtue of being newer Aug has been able to make different trade-offs and I think at a given bit rate it has better audio quality. I don't have much of an argument with that statement. Yeah, but I think in terms of work priority and I'm trying to be clearer and clearer with people about this when we talk about what circuit python will have is like there's a difference between what circuit python will have and what folks paid by Adafruit are gonna work on adding, right. And I'm lucky enough that I feel like I have influence over what that is too. But if I had to pick what audio work we do next I would pick getting MP3 running on the Pico like on the RP24. Yeah, other fun MP3 stuff that I think enables new use cases is we've talked a number of times about streaming them from say Wi-Fi. Right, right. And that would be fun. You'd have your podcast player circuit python but the Wi-Fi co-processors aren't quite fast enough and the audio support on the ESP32 S2 we just haven't got solid enough yet to make that a priority. But that's another fun audio item we might do someday. Right, right. Yeah, Naradak points out like where would you store that? Like you'd have to, like the board's flash is not usually big enough. So at some point you need SD and then the SD has to be fast enough to read as well. Yeah, SD is really fast enough now in circuit python. That's another thing where I did some refinements. We moved an implementation of SD into the core and that gave us a good speed up. And then some microcontrollers support SDIO which is a four bit at a time protocol for SD. So yeah, the SD cards are way fast enough to play MP3s. In fact, you can sometimes play multiple streams back with audio mixer. I did a demo of that. I also did a trellis version of it where it was just some tiny little samples as a soundboard that was fun. But were we gonna talk about audio all day today, Scott? We can talk about whatever you wanna talk about. I mean, like Lamora started coming on this because she was like, she like watched the stream and was like, wow, it's really casual. And I was like, yep, just ping me and you're happy to do that. David G, David G did ask like would MP3 decoding run on the other core? And I don't think, I really am tempted with the Pico with the RP2040 to really leave the second core alone as much as possible because I do wanna make it available for user code at some point. So I don't wanna just use it internally necessarily. I kind of like the idea that we kind of have going with CircuitPython already is like, we run on one core, when we have stuff we need to do, we'll do it, we'll deprioritize the Python code. And I'm okay with that. I think it would be cool to use the second core for something else. Yeah, I don't know what multiple core, multiple thread is not my idea. Yeah, it's not mine either, so. Which is part of the reason that like, it's frustrating for me when I see comparisons with like MicroPython to CircuitPython and it's like, oh, like CircuitPython doesn't have threading and that's why you shouldn't use it as like you were getting to before, like we really try to focus on the like what is the thing you cannot do and that's not like threading. It's just like, I need to do these actions all at the same time, like that's what we wanna hear. We wanna hear about the project you're making, not the feature that you're missing. Yeah, that's a really good way to put it. And it's really hard, right? Like it's really hard to not get into a features for features sake sort of mentality and I think Adafruit's guides are a great forcing function for making sure that you don't. Which I think is why Lamor is totally happy to have you do guides is that like it ensures that you're still, it ensures that you're operating at the right level. Yeah, it helps you stay grounded. I mean, another thing in contrast to my other job is, you know, I love the software and I use the software and in a lot of people they write software that they don't use or don't enjoy using. So yeah, that's a huge perk. But let's talk about LEDs. I wanna show you this project, which if you were on show and tell yesterday, you would have seen it. But, oh, I've got a cabling problem here, hold on. Always, I always have cabling problems. And while you're at that, let me just answer, there's a question about not that. Secondary CDC on the M0, but also the ESP32 S2 don't have enough USB end points. That is correct. That's my understanding based on Dan's PR. So you'll have to use something else or modify the build to turn it off to make room. That's which microcontroller? The S2 and the CMD-21. Yeah. But he found enough space to actually fit in the other stuff. So like the CMD-51 will have secondary CDC by default along with Pico and NRF, I think. We'll all have that extra one. All right. All right, so this is in some ways because you can project, but we've got the Pico and what's called a shift register here on the breadboard. And so the Pico sends out at a very high rate, like 12 megabits per second, a bunch of data to the shift register. And then the shift register sends it out to these eight individual neopixel strips using the PIO peripheral. Right. And the main advantage of this is, well, first of all, it gives you more freedom for wiring up your strips because you could kind of radiate out from a central point instead of doing this zigzag thing you have to do. Right. But the other is it's actually nearly eight times faster. The process of actually sending the data to the pixels is eight times faster because it's happening for all eight simultaneously. Right. Whereas if I took these strips and laid them in to end, now it takes longer. And ideally, the best possible speedup is eight and we measure 7.4, so that's great. There are two parts to doing this and one is the program that runs on PIO to create the waveform that neopixels need. And then the other is to take the original data as Pixelbuff describes it and get it into the form that the PIO program needs because it needs to take, say, the first green bit of the first and 30th and the 60th pixels and send that out together. Then the second bit of all those bytes and then eventually goes to Pixel 1, Pixel 31, Pixel 61, Pixel 91 and so on and it's just a big mess of moving bits around. And so this pull request that Scott mentioned, reviewing and talking about is the one for doing the bit manipulation part of this whole equation. Right, right, right. So I don't think people fully understand how cool this is. So in some ways this is, you know, what did it enable is a hard question to answer. There's the increased speed and there's the freedom to lay it out differently. So like for example, while I won't be able to necessarily find the numbers again, but say you had 25,600 pixels with the neopixels show, you can only get 1.3 frames per second, but with this you can get nearly 10. If you have a more reasonable number of pixels, like say just 2,500, then that's going at 100 frames per second instead of 13.  But you know also part of this is just proving the concept of what are useful things PIO does and as my learning exercise. And this is a concept that Lamor had had and tried to implement on some other microcontrollers and couldn't. So, you know, we proved we could do it, but so I'd be interested to hear what you think the kind of the use case, what project does it enable if you have an idea about that? No, I think you're right on the money. I think in particular it's speed. Like people don't realize when they're doing animations on neopixel strips, like how the amount of time it takes to transmit the data is directly proportional to the number, to the longest string, right? Like the number of pixels in the string. You know, there are some problems of like how do you compute all the colors, especially if you're doing all that math in Python. But generally like that's a big bottleneck is just transmitting the data. Cause it is, it's an 800 kilohertz protocol and that's per bit, right? And it will take 24 bits. So Alvaro says, what shift registers are you using? Breadboard, Stemma, how fast can it go and how many strips would work? As many PIO pins are available? So this is using a 74 HC595 shift register. And I think it is clocking it at something like 19 megahertz to do a strip of eight. I kind of did the math or not to do eight parallel strips. I did the math and I think it might be possible to get up to 16 parallel strips by using two of the shift registers. But I don't know and it needs more core code because the core code is very optimized for the particular reorganization that it needs to do. And to do more than eight bits would take another piece of optimized code. And we're just not gonna do that right now at any rate. And yeah, there's another way of doing this which, so this uses just three pins on the microcontroller which go to the shift register. And then the shift register has an output for each strip. And a single state machine, right? Yeah, and one state machine. There's another thing we could do to, I think, how many different pins can you drive by? I have to use both set and out. So how many pins can we drive at once? So set can, are you using delay? Well, set can do five. No, I don't do a delay. Set can do five pins and out can do up to 32. Okay. The way it's set up, I use both set and out. I think I can go around this. I think I can change it so it uses out. I'm not sure. But for now I think we might be limited to doing five strips without the shift register just by doing them direct from the CPU but that's not what we've investigated yet. And there might be a way to do more. I don't know. Right. And yes, you should always order more neopixel strips because you should be constantly giving them away to your friends and making them hang a sculpture on the wall. You can also cut them apart. If you do have one big long strip but you like the idea of speeding it up, you can cut and then you will have to solder to them but you can cut and solder them together to make it happen. Yeah, I am not the best when working with wires so I deliberately chose some strips of modest length that I could reasonably just get eight of them. I mean, that's totally fine. Yeah. That's a good option. Like I have neopixel strips around the front windows of our house and like. Yeah, you showed those at Christmas time. Those were cool. Yeah, they live there all year but like every year I have to like go in and like fix the wire joints in the corners because I have like it's soldered down. It's a pain. So yeah. Yeah, if you can just afford to buy it then that's the easiest option for sure. Let's see, there was one other question and let me snag the time first. This is probably not cost effective but can you replace the shift register with a mock exo tiny FPGA and instead of optimizing the code on the side of circuit Python just do it on the FPGA? Yeah, I think that would be great for somebody who understood FPGA is better than me. Exactly. And Emmett is asking, what is the RP2040? The RP2040 is the new, it's the name of the chip on the Raspberry Pi Pico. It's a new micro controller chip by Raspberry Pi foundation or Raspberry Pi trading. That is the latest hotness and has lots of RAM and two cores and PIO in particular, which is really interesting. So I feel like you said you turned the corner for PIO. So I imagine there's a lot of folks that are watching or will watch that haven't jumped into PIO land yet. How would you recommend that happening? Like what tips or tricks would you give folks? So if you get the RP2040 data sheet there are some examples in there and the example I recommend starting with, let me back up and say, this assumes you understand what SPI or SPI is. Start with the example for SPI because it's pretty small and it lets you learn a good number of the concepts. I think you learn about side set and you learn about pulling and pushing and these other things that you need to do for a basic program in PIO. And the other thing is wait for this pull request of Scott so that it will automatically set up your pins which need to be outputs for you and that will bypass the thing that left me stuck. And I think it helps that I have some familiarity with assembly language, but it's just a list of instructions. If you don't get into branches it just starts with the first one and does the first one and the second one and the third one and goes back to the top. So it's like a program where you don't have a for loop or an if statement just at a very basic level. It's just a forever loop which a lot of us are familiar with from other programming environments. So dive in, give it a try. I used a Salier logic analyzer to kind of see what was going in and going back out. So that's like a really nice tool for understanding what's going on but you can also run them really slow and have it show on an LED. So I forget who was discussing this on an issue but there is an example of just creating a square wave and you can run it slow enough that you can see it on an LED turning on and off. And so directly visualize what your program is gonna do. And so yeah, all the things but just it's a new learning experience in a new language. Right, right. David asked, so as we're more going to do a board of that shift register and eight connectors for new pixel strips. I don't know. I'm thinking of doing an Osh Park board because one of my 2021 ways that I would like to grow is to do more circuit boards. And if I do do that, I will mention it on the discord because yeah, the breadboard got a little out of hand but if it had had those three pin connectors for the strips, it would have gone together so fast. Right. And yeah, been much prettier. Yeah, I think if I had to guess, I would probably say no. Like we already have the NeoPixel 8, right? Which yeah, which this won't work with because it is using the shift register and NeoPixel 8 does not. And that would be one interesting reason to look into the version that can do them independently without the shift register but by using up more IO pins. Right, right. And that's what I'm thinking. Like I think like the transpose thing that you're adding is really convenient because that's what you would need for that case as well. And then we'd be able to use, we'd be able to use NeoPixel 8, that assumes that does assume that like the pins that the NeoPixel 8 uses are consecutive in the feather design. From the point of view of the ARP2040, yeah. And I haven't looked into that. I don't know if we, I think LaMoure already has the PCBs but if not, we should make sure she doesn't. A Reve kind of PCB that she's shown on some videos. Right, I mean, I've got one, right? You've got one. Yeah. Like when we were talking about what the pinout would be, I don't think we would check this. Are the panels on the... Yeah. Yeah. Yeah, exactly. I don't know. Right. There is some flexibility on that board with solder jumpers to change. So that might be do it. Although I think for a couple of pins, there are two choices. So it may not be enough choices for us. It may not be perfect. And I'm not gonna get into looking that up right now. Yeah. And I don't know. We could take a look, we'll make sure. Is the schematic of the ARP2040 feather, I assume that sign that is not released yet since it's still not a released product, right? I don't think it's public. Yeah. No, but... Yeah, so otherwise... I have access to it if we wanna check it. We should check with them more if nothing else. Yeah, it would be fun if that worked. And yeah, that is gonna build on this same bit manipulation routine. Right. But it wouldn't require the shift register, but it would require eight IO pins or five or three or however many you wanted of independent strips. Right, right. So, Slinky, I see your question, but there's two folks that had this... Let me take a time. David, you said Nita, an ARP2040 signal analyzer to work on PIO and see what I'm doing. And Deshipu also said it would be interesting to do a signal analyzer with PIO. Didn't someone work on that? As far as I saw it on Twitter or something. No, Mark Gambler, who goes by Gambler. That's not his last name. He did a show and tell, I think, of it. Basically, the PIO is really good at just sampling data, and so he just ingested it and then saved it to his computer, transformed it into a thing that PulseView could do. Like, this is something I started and I really wanna do. Yeah, Mark says I did that. I really want... I have this project called Tiny Logic Friend, which was my... I would like to have a standard protocol for logic analyzers over USB. That I haven't been able to find one. And one of the constraints that means that the existing protocols don't do is I want to be able to send pin names back to the software, so that you just take a board, you plug it in, it reads the pin names off, and then shows you the pin names in the capture software. And I don't know of anything that could do that, so that was kind of the crux of what I was doing. So, yeah, it's something I'd love to do and connect it end to end, so it's really easy to use.  And I've gotta remember the things that are most important. SlinkyTangle asked, can you talk a bit about implementing a high-speed counter running in the Pico? So, I'm not sure what you're counting. If you're counting edges, you can't increment, but you can decrement. Which just means you have to think of the numbers as being negative numbers. Right, so, yeah, you have the ability to wait for an edge or wait on a pin. So, you could just wait until the pin is low and then loop around and then wait until it's high again and loop again. Yeah, I have a feeling that what you're gonna wanna do, if this is for frequency counting, which is in interest of mine because it's adjacent to timekeeping, I think you're going to wait for the value to be low, say, and then once it goes low, you'll loop incrementing or decrementing X until it goes high and goes low again. And then you'll send, as a return to the Python program, what the value of that X register was after it saw whichever edge you were waiting for. And there will be some details around it, but because you'll have, I think you'll have an instruction to decrement X and then you'll have a branch instruction conditional on the pin that you're checking. So, that's two instructions. So, you should be able to get up to 125 megahertz over two of, like, fidelity of your counting. So, your counts will be at, what is that, 62.5 megahertz, which is really pretty good. Yeah, and I think the PIO gets all the love, but there is, like, the PWM peripheral can do capture stuff as well. So, if you want to, like, wait for an edge or count when something is high, like, you don't have to use PIO. And I think, like, people are like, oh, we're just going to use PIO for everything. And it's like, well, you don't need to. You can, but you don't need to. The neat thing about PIO in CircuitPython is, it is a lot more low level, fast programmable than Python code is. And so, if you don't want to go changing the core, but you do want to be working in CircuitPython, because, like, making the rest of our frequency counter kind of appliance in CircuitPython would be way better than doing it under another environment. But you need that core part of counting your pulses, so. Right. And Slinky says, I'm reading a two megahertz pulse from a Zeeman interferometer. I think that would be well within the bounds of PIO to do a two megahertz. I don't know what a Zeeman interferometer is, but I'd love to know. But yeah, it sounds like you want, like, I assume you're wanting, like, density, so, like, how many counts over a period of time you want from an instrument that does a two megahertz pulse, I'm guessing. Emmett says, only two spy buses, that's a pity. Yes, that's true, but in practice, I haven't seen people use more than two, and if you really need more than two, you can do PIO and do more than two. Yeah, with PIO, you can do some more, for sure. Are so few kind of sensors on spy? Well, from Adafruit, anyway. Adafruit is all in on I squared C. Right. But, you know, you've got one for your display bus and one for your SD card bus, if you need it, and I don't know what else you would really need to do with spy, but if you have a spy peripheral, that sure is a valid. You could also share spy buses, just by having separate chip select lines as well. It's just really bandwidth that you don't have. I want to say hi to Somersoft, who dropped in the live broadcast chat. Oh, I didn't see that, hi, Somersoft. Yeah, and says, RP2040 PIO kind of reminds me of the IO and the parallax propeller. A chip I never learned. I've not learned it either. I checked the new products at Digikey under the MCU evaluation board category. And I've seen that the prop two board is now available on there. So folks are propeller folks, check that out. I think the critique that I've heard for a little more about it is that it's just like really power hungry. So that's one of the reasons that we haven't taken a look. It's also like completely different. Yeah, it's a very different system. I've tried to just at a casual level read some of the video generators, for instance. And there's a lot to pick up there before you can really use that thing well. Right, right. Yeah, I think the PI is really neat. Yeah, I think we're just going to see. Slinky Tangle says, yes, if I could read it at PIO speed, I could replace an FPGA currently in my design. The Zeeman can measure distances to submicron accuracy. Yeah, that seems doable. Oh, this is just like time of flight kind of thing, I bet. I don't know.  I'm sure I'm with you. You just don't have the background. But there are so many things where you need more background to really get into it, that's for sure.    There's lots of things I don't know about. So I don't want to keep you super long, Jeff. Well, did you want to actually get into any of this code or? Well, David says, so no talk about clock and time. I did just. So another thing that you did is I reviewed and merged. Your RTE, your U-random. Oh, yeah, that was a fun little type version. Do you have any time thoughts as we run out of time? Well, I did notice some weird results out of time.time on the RP2 today, but I didn't figure them out yet. So yeah, I don't know. That does bring me to the way that I was hoping to close talking with you, is what are the things that are upcoming for you? What's on your radar? What are you excited to work on? If you want to do more PIO, what do you want to do with PIO? Well, kind of the other main idea I had for PIO, I've come to understand is a little bit of a silly waste of time. Just as a proof of concept, I wanted to run some like RGB or not RGB. Some of those seven segment LED matrixes direct from the PIO, but there are I squared C devices that do that, and they do it a lot better. So we're probably going to leave that aside. That does get, I think, to some use of PIO that I think we're going to want to API for at some point, though, of I want to share a memory buffer with it. I want a memory buffer, and I just wanted to loop over it. Yeah, that's the core functionality that that requires. And say, you must have kind of done this with the I2S, where you're continuously giving it more data, but we can't do that from Python land. So no, I don't actually do that. What I do is my I2SPIO code will save the previous value, and then if there's no value in the FIFO, it will just produce it again. Well, I mean, in the general case of while you're playing an audio sample, it's continuously looping, but that whole audio sample isn't there at once because it could be an arbitrary file. So it's looping over one or two DMA buffers, I'm guessing, based on how other stuff works. And while the one buffer is being used to produce the audio, the other buffer is waiting to be filled by the background code. And so it's that thing of continuously reusing one or two memory areas that is similar to what we're talking about, but not exactly the same. Yeah, and there is this special case as well, as if the sample you're playing is a single buffer. It's kind of like what wave table is the right term, where you just have one sample you're going to loop. There is a special case for that. It's interesting the way that it works on the RP2040 because the registers that you write for a DMA channel are live registers, which means that as you increment, your read address moves. And that would seem to provide some challenges in getting the code right. Yes, but it's also very convenient if you want to know where it's at. True. But the challenge is that if you have like, I want to loop over the same buffer the whole time, if you want to run that same DMA thing again, you actually have to copy the original value back. And the way that you do that is you have a second DMA buffer or a second DMA channel that's triggered by the first that copies the configuration back into the same registers. Oh, I said, uh-huh, but it turns out I didn't know at all what you were just about to say. Yeah, the DMA is kind of weird in that it self-references and you can self-modify it with DMA. Like, theoretically, you could have a sequence. You could be DMAing a sequence of DMA setup code. And they actually have aliases for the DMA registers because you can trigger DMA based on a particular register right.  And you have options as to what that register actually is. I think I almost understood that. Yeah, that's weird. It's just like, if you're writing a DMA register, you have to be aware whether it's a trigger one or not. And you'll see that in the Pico SDK API, there's like this trigger Boolean flag on all of them. And if you look at the code, it says, if trigger used right to this address, if not right to this other address, that's not the trigger, which is pretty weird. Slinky said, the Zeeman is a stabilized laser for optical measurements, which is pretty wild. But yeah, I think, yeah, the PIO is just going to get, it's going to be more and more interesting what people can do with it. Just as like, Jeff and I are pretty smart and we're just starting to understand the basics of it. So that's true for a lot of folks that are just seeing it. So it's going to be neat. It's going to be super neat. Well, it seems like I'd better plan to come back another time and talk about time because there's at least one person who's interested in that. Yeah, I mean, I don't know a lot about it myself. So, you know, and I think you and I were talking a little bit earlier today about how like, oh no, I haven't really looked into it. I haven't really made sure that it actually works. And that's kind of one of the things that we want to do later. Let's see. We got an unrelated question about extracting ID3 data from an MP3 file. I don't know something off the top of my head, but I'm assuming that we could do something or there's like a program that will do it for you. So I would look into whether there was a regular Python library for doing this because, you know, you can just open the MP3 file as a file and then do run Python programs on the content. So there's bound to be an ID3 tag reader that's just coded in Python. So bring it over to CircuitPython, fix whatever is broken, and then you can read the data. I did not do that in my MP3 player project, but that was kind of out of running out of time to get the project done rather than it being an impossibility. Oh, look at that. I thought we would do, I know you didn't want to be here more than an hour. No, that's fine. But oh no, there's two of me. No, I had to cover you. I thought we'd do the pull request, although we did get another question. So Andy Roberts, 1, 2, 4, 3 says, what's the best resource currently to understand PIO? I think it's a mix of read the data sheet and then try to apply it. And I think the best, the way that I would recommend people like applying it is actually, I linked, we have the PIO ASM library and they're, I'm putting all of the examples in there. So when I implement something like Neopixel with it, I put the examples in here and I'll do that. I have, I have I2S and PDM as well. So this is actually like read the data sheet, the Raspberry Pi docs are really good. And then take a look at these examples for CircuitPython. All right, so, and Johnny says, ID3, EYED3 is a Python tool for working with audio files, specifically, oh, MP3s, let me move you off screen.  Yeah, Mark says the data sheet has great examples Pico examples and just playing with it. Oh yeah, don't forget Pico examples. There's Pico examples, there's also Pico extras, which is the examples that they don't really want to document, they don't want to have really good documentation for. Oh, it is, it is challenging to really document things. That's something I'm understanding more and more as I work in the learn system in particular. Right, right. The right thing that is going to be useful for people at all levels, or even just one or two levels that you think you're targeting. And so I'm so happy to have people helping like Ann with getting those guides good and hopefully growing a little bit as an author as I do it. Right, yeah, and Katnick is really good at that too. Okay, let's do your review so that you can get out of here. So I think I've showed myself a review on the stream before, but folks may be new. So what this is, this is the dark version of GitHub. And sorry, we have two videos. And so it's kind of hard to manage being able to see both Jeff and I, but so this is a pull request that Jeff did. It's 4219 if you want to follow along. A pull request is somebody wanting, someone is proposing changes to your version of the code. So in this case, our version is like the shared version of Circuitbython, which is the github.com slash Adafruit slash Circuitbython. And then this is a particular proposal that Jeff has made from the Jepler bit transposes the branch name. So he's made some changes. He's proposed moving those changes into Adafruit Circuitbython and that's what a pull request is, is that you are requesting somebody pull your changes into their version. And so the way that it, we have it set up in Circuitbython is that Jeff, even though Jeff has access, he cannot do it directly. He has to have somebody else take a look at it and review it and make sure it's reasonable before we merge it in. So I did an initial review earlier today and I made these comments. I said like, hey, please. So maybe I should pull up the full thing. So what this is, we were talking about the cool like eight strips at a time thing that Jeff did and he needed some code to be able to move the bits around really quickly. And the nice thing about Circuitbython and MicroPython as well is that you can use C code to do things that you need to do faster than you can do in Python. So what we're looking through here is what Jeff is doing is he's added a new native module to Circuitbython, now called bit ops. It was not originally called bit ops. So you might see that there's a comment for me that says, hey, can you change this and all market is resolved? Although Jeff could have marked it resolved as well. So this is a perfect. It's better because it makes it disappear and then you don't remember it and maybe you don't know what was resolved. Yeah. So I can do it either way but that's why I left it. Yeah, and that's fine. I also try to like, I don't necessarily do that because I do a lot of reviews. So like if you say it's resolved, I'm like totally okay. Yeah, I can only get away with that quite much. Let's see, sorry, I'm gonna, I'm trying to do time codes as well. Let me just drop one in here for PR review or this is what I get for being on Thursday. David is nice enough, DCD is nice enough to do time codes for me usually on Fridays. Okay, so we're gonna go through here. So we're gonna call it bit ops. And so this is like this NP config port and this Pi circuit pi stuff is all very boilerplate. So if you're ever gonna make a, and this is a good reason for me to take a time code, right, is that I can, this is where we explain how to add a new module to circuit pipe on. Yeah, there are a number of things you have to do. So it's good to know them. Yeah, so circuit pi definitions.mk is like make file level stuff. And then this mpconfig.h is the C level stuff. So it's important to note that anything that happens in C land can't impact make files. That's why there's like two places that you have to do stuff. And it's very formulaic. If you look at this full file, you'll see that it's like a lot of just this. Just repeat it over and over. Yeah, which has influenced what I would love to see as a build system in the long run, but no, I can't do everything. So this circuit pi mpconfig.mk is just setting the default whether it's building or not. It's, you might be like, oh, that's kind of like a lot of work and blah, blah, blah. But at some point, it's okay to have APIs that are like a little bit tedious as long as they're regular, meaning they're consistent. It's like, yeah, it kind of sucks, but it's also like, it takes you two minutes because it's the thing you always do. Okay, so let's see, we have nine total files and we've already looked at five. Shared bindings, bit op init C. So all of it's gonna be in init C because we don't actually have any objects in this case. Right. And for those who are new to a circuit Python, shared bindings is the place that we document what the Python API is. And we also do the conversion from Python objects to C API under the hood. Oh, you could change this copyright. I meant to mention that. Oh yeah, I should. Yeah, cause this is all fresh codes. So I should change that. Yeah, yeah. I'm bad about it sometimes. So this is, so anything with a slash slash bar, let me make it bigger. So anything with a slash slash bar is going to be pulled out as Python stub documentation. So the very first triple quoted string here is the module level documentation. So this will be documentation for bit ops. And it just says routines for low level manipulation of binary data. And maybe we'll have others in the future. We just don't know what they are yet. So it's hard to be more specific. Yeah, totally. I think there, you were on this track that there may be some interesting things we can do for manipulating bitmap data just beyond this. Yeah, yeah. I like, yeah, I expect for that to be the case. Background is, is that if you look at this PR, you'll see it was originally called like bit transpose but Jeff has renamed it, am I request? Okay, so there's one function called bit transpose. It takes an input buffer and an output buffer and a width and also returns a writable buffer as well. So this is actually where I do most of my reviewing. Jeff probably has realized this. But when I do most reviews, I care most about shared bindings and what the APIs are. Yeah, well, the rest you can fix later on but when we put something in a stable release of CircuitPython we are stuck with it for at least a stable release version. So it's important to get that right. Totally, yeah. And like, And I've noticed my inconsistency here just to get real specific. I have underscore typing in two places and I don't have it in one place. Do I not need it in any of the places? What place are you, what's the third place you think it would be? In bit transpose, if you scroll over to the return type, I omitted underscore typing dot. Now I'm just wondering what's, whether that's maybe not needed at all. I mean, the thing that would fail if you got it wrong would be the stub stuff. The documentation I think would fail to build. Yes, yeah. So I mean, if the CI passes, it doesn't really matter. Well, I should go back and make it consistent. Yeah, sure. I think the writable buffer is a bit weird because it's actually like a union of a bunch of different types that we've defined. Like it's not a Python thing, it's something that we actually have like a file that says it just to make it easier to define like when you take writable or writable things. Assembling each output byte with bits taken from each of the width different input bytes. Yep, that makes sense. This can be useful to convert a sequence of pixel values until a single stream of bytes suitable for sending via parallel conversion method. Right, more bytes, multiple width, blah, blah, blah. Stride is equal to the length of the input divided by the width. Yeah, so this is what I was saying where you take pixel zero and 30 and 60 and 90. So you could have thought about it the other way where you take, you know, pixel one and then pixel eight or pixel one and pixel nine and pixel 17 would all be on the first strip and I had to make a choice and I decided that it would make more sense to a usual person if all of the pixels on one strip came first when you looked at your whole buffer with all of the strips in it, so. Right. But it was a choice that I had to make as to which of those would be. Yeah, I think it makes sense to me. And it returns the upper buffer again. So this is all boilerplate stuff. This is where my eyes kind of blur. Although it is good to note that like one thing to check when you're checking argument validation is just like if it's like a new port of something that exists, you might wanna like make sure that the strings are the same, like the error messages that you produce are the same because anytime you add a new string, it means it has to be translated to, I don't know what we're at like now, like 12. 15 or 16 languages. 15 or 16? A lot. Yeah, and that's something we haven't talked about but Jeff was the person who set up Weblate which makes it much easier to translate CircuitPython. For those of you who don't know, we have versions of CircuitPython for these 15 and 16 different languages and what changes is primarily the error messages but also like the other messages that you see kind of regularly as well. The goal being that like having errors in your language make it easier to understand what the problem is. Yeah, so it's 17 languages and that is excluding pirate English. Oh, is it? Yeah. That's good. Yeah, so you can't unfortunately translate pirate English using Weblate. Although that's just kind of their, I don't know, for fun, for testing. Right. It was, it was meant to of like, oh, we'll just like have a language that you can use to understand how it works. Which I guess is kind of like, that was pre-Weblate so it reminds me that maybe we don't need it anymore. I don't know. Although I'm hoping to get Pimeroni on board and I bet they want to use it. That will be the killer feature, huh? Right. Yeah, not HID or audio or MIDI or any of that stuff. It's the pirate version. Yeah, Somersoft added pirate. So kudos to them for doing that. Okay, and then here's the actual implementation. So I clicked through this other shared bindings that just basically has the one method that is called and now we're in shared modules. So this is all like, it doesn't care what CPU it's on. It doesn't care what microcontroller it's in. So it goes in shared module, not one of the common house. So you cite where you got this stuff and I glanced through this. This is one of those things where it's like, it's much easier to just test, right? Like I could try to understand how this all works, but testing it will take me time. It's first time I don't understand how this transpose function works. If you have the hacker's delight book, yeah, it explains this, it shows some ASCII art diagrams, but how it actually is achieving, transforming from the one way to the other. It presents, this is a great book by the way. If you have any interest in like low level, how do I work with bits and numbers in computers? Kind of beyond the basics of and or XOR and arithmetic. It is a fascinating book, I love it. But a lot of it, even once you read it, it goes over your head. But this way of doing it is twice as fast as doing it in a straightforward way with a couple of loops because it can use these bit manipulations in a really clever way. So Alice Trice says, it's useful having language you can use to check that you've got everything localized properly too. True. And David G says, is this somehow related to micro lab matrix manipulation? It's not related to micro lab. I mean, if you're working with matrices of integers or of real numbers, then micro lab is gonna help you out, but it didn't have this particular kind of thing because it doesn't have a lot of routines for working with individual bits. It's concentrated on eight bit numbers, 16 bit numbers and real floating point numbers. Right, right, which makes sense to me. Anyway, so it looks good to me. There's just like that one copyright that you probably want to update. Yeah, I updated it to 2020 in my working file. So I'll just go fix that to 2021. Well, this one is, it's not even attributed to you. Which one wasn't attributed? There was the one that had Roy's name on it. Yeah, that's the one. Okay, yeah, I changed it to 2020 and Jeff Hepler for Adafruit Industries, but then I realized it was 2021. It feels like March 2020, right? Isn't that the running joke? Yeah. So here's, so just to finish the process. So what I did is I said, hey, wanna update this as a comment, you can see it's pending, although I'm blocking it. So there's the comment, it's pending. What I do is you go finish your review and then. It says request changes, I think. Yeah, let me move myself. That third check. Yeah, so there's a request changes thing and I can say, I would probably say like just one super minor thing. It is important to note that we do have the setting for, like I could approve it, but in CircuitPython, if Jeff or anyone pushes to their branch, it will undo any approvals. Yeah, so it can really do you much good to say, it's fine except for this. Still, it has to come back after I make that change. Right, so what Jeff can now do is, well, actually we can mark these resolved. So I'd require the output buffer, which you did. So we can just say resolve and document it independently in NeoPixels, which you did as well. So we'll resolve that. And so there's just this one thing and it's important to note that these checks, the check in the cross, I guess, are the state of the continuous integration system, which automatically tests code. You can see here. Or I hope that one that failed was the one that I canceled, but I see that it was the newest one. So I must have two problems. You might. I just added that writable buffer without the typing underscore typing dot in front of it. So I bet that that's what failed and that the CI caught it. So answered my own question. It looks like that because, so the way that we have the CI set up for CircuitPython is that we do these three builds first before we build all of the other four, because we build every artifact. So we build like 3,000 versions of CircuitPython every time we have a new change. But in order to do that. That's a change even. Yeah, so every time we need to do that, it needs to pass at least these three things to start. So if you ever have something fail, here's how you find the problem. You hit the red X and then you hit details and then it will show you run failure, which is not very helpful. But if you scroll up, you'll see translations. Translations failed. So. No, translations failed. Well, that's another common way to fail. It's very common. And that's part of it, because it's so common, that's why we put it first, right? Right. See, I... Some day we'll figure out how to make it a part of pre-commit and that will be even better. But there are some tricky things about that. Right, right. And I know you looked at that already a little bit. So the other thing that I'm not saying is that like, yeah, we build everything, but there is a limit to how many things we can be building at once. And that's like a limit for eight of fruit, probably. And so anytime we have a circuit pipeline build that's building like, it has like 60 boards at a time that it builds. If we have multiple pull requests and merges happening at once, it can actually back things up. So by having this initial check of like, make translate is something that's often needs to be fixed. And doing that before we go to that like, build everything just means that like, we don't have extra builds that like, we could build all of the boards here and that would be helpful potentially, but like we'd also still need to build them all again. So it's just a bit of a short circuit to make it a little bit, a little bit better. Any last questions for Jeff or, so what's left on this is that Jeff will push the new stuff so we can see requested changes here. And if I go back, and then I'll have my translation fix, which I already pushed fixes for most of what you asked for, but I didn't know about this translation problem because I didn't look, I just looked. Right, so under this files change, you'll see seven of nine are viewed now. And so if we just look, this is the one that changed. So 2021 now, and this one as well. I'm actually surprised that I didn't, I'm in the mode of- If you can go up and see just from a range of commits, is another use point to visualize it. So yeah, why don't you show that? I don't know how to do it. File, tilt, is it the, no. Oh, view changes, changes since you last viewed. Here we go. Yeah, this is what, so if you hit changes since you last viewed, you can see the exact things that were- It's pretty good how it looks a little different each time I use it. I know, and I'm like, I have my like settings and stuff on it too, but that looks good. And I just, the translations aren't pushed. So I won't bother, this is resolved, but I'll wait to approve. I'll wait for that to prove with McTranslate. So yeah, usually, usually Jeff and I would not be talking to each other while we do this process. Usually it's something that like, I regularly do all of, I showed this on a previous deep dive, but I go through all my email, I open tabs for all of the stuff that, so I get GitHub emails about reviews like this, and then I open tabs for everything, and then I go through all those tabs, and I do that once a day in the morning. So like my process, I did this review this morning, and I, unless I had like 20 minutes where I wasn't gonna be able to do anything, I would probably not take a look at it until tomorrow afternoon. It would usually be morning, but- That's the reason to get on deep dive with Scott, because then you can review your changes for an hour until it's acceptable. Yeah, yeah, we can get all of the good stuff in. And now that McTranslate is pushed, we can do a few changes again, and now I can approve it, and then- Hopefully, hopefully we'll be able to merge it in then. Right, so- Once McTranslate comes back. So I'll approve it, and then what will happen is that in an hour or two, the CI will be finished, and because it's approved, Jeff would be able to merge it. I wouldn't have to merge it. And there is actually a setting we could turn on that allows you to auto-merge once the CI is done. But I- We necessarily wanna do that. So I'll go in and cancel the earlier workflow. You shouldn't need to, right? Because it'll fail and make Translate still. Well, that's true, it would have failed before too long, but if you were gonna have those 3,000 things that don't remember where that number is, it doesn't hurt. Right. It would be nice if GitHub would just do that itself, honestly, to change it. I was thinking- Status, but what a website to create GitHub. I mean, it's tempting, but you shouldn't fault them if one particular part of it doesn't work the way you want. Yeah, and the other thing that I think we take for granted is it's a lot of CPU time to build all of CircuitPython. And if we weren't an open source project, we would have to pay for that, and that's not a trivial cost. I think at one point we ran the numbers, it's like $15 a build. And it's like a day's worth of CPU time. So thank you to Microsoft who now owns GitHub for basically paying the bill for all of the open source projects to use GitHub Actions. Yeah, and when it's working well, it is a good advertisement for their services, and I think probably an effective one. Yeah, I think- This is Microsoft Azure, and you can see how well it's working or not working. So, it's cool. Right, and their business model is like, they have companies that pay to use GitHub, but have private repositories, right? And so by having open source, that means everybody uses it, and then when you want to use it in your super secret startup that nobody should have access to stuff, you end up paying for it. Okay, we got a couple of questions. Jeff, you can leave if you want. I assume we're kind of gonna do questions till the end here, although I could talk about my audience. I can do it here soon, so I'll get around until we've answered just these questions, and then I'll get off. All right, we'll do these last two. David and Mark, let me be good and find my timecode window before I... So to answer David, is the BitStuff only for the RP2040? It is only enabled for the RP2040 builds. There's nothing about it that isn't suitable on another build. So if you have an idea about how to use this, we could potentially enable it in another port or for another board, but if we don't know how we're gonna use it, we wouldn't necessarily turn it on. Right, but yeah, it should be like, oh, it would be nice if it was on this port, we just flipped the switch and it would be on. Okay, and Mark's question. Are you not gonna answer this one, Jeff? Oh, so Mark, I guess everybody can see it. I don't need to like read it or something. I usually read it anyway. Yeah, so Mark asks, would your other contributors merge their own work once approved? Or say, I do a review of Jeff's code and say, yeah, this is fine, choose to merge it or wait for one of the maintainers to do it. I mean, I think we are pretty much on, we're adults here kind of footing. So we review because it improves the code, but once we've reviewed it, it's like anybody, any involved adult can go ahead and press that merge button. And if somebody thought it shouldn't happen, then you shouldn't have approved it or you should have said, I've approved it, but we need to wait for other thing to happen first. It's something that happens sometimes. So like when we've had a release imminently coming out, I would get a review which says, this looks good, but I'm gonna wait till after beta three to merge it. But yeah, in general, the review process is about checking for errors. And then after we've done that, I think it's up to whoever wants to, and with privileges to go ahead and merge it. And I'll let you correct any of that or amplify the parts that you thought made the most sense, Scott. No, I think you're right. I just wanna be a bit more explicit. I think Mark, so background for folks, Mark has access for reviewing and merging and is not at least paid a lot for Adafruit for stuff. I don't know if he's paid it all, but he should be at some point. But Mark's been great. So he has access and I think Mark's alluding to this idea that folks paid by Adafruit have different privileges than those who are not. And that is definitely not my intention going forward. I think anybody who we give right access to, and there's actually quite a list of folks that do have it, like you should, yeah, so Mark is not paid by Adafruit. So anybody who has review access should feel free to merge and approve once things are reviewed. There is no special thing with us paid by Adafruit or not. And the reason I can say that is one, you can always undo stuff, right? Like we have full history. We can always undo stuff if something was mistakenly done. But two, like we really wanna move this project to be bigger than Adafruit. So like I don't wanna treat anybody, like it's a very fine line and I definitely am like dancing around it of like paid versus unpaid and privileges and stuff like that. Like really the project I want to be more than Adafruit over time. I also want, I would love to have more companies besides Adafruit pay for folks to work on Circuit Python. And that happens a bit with folks who are like unexpected maker, for example, who sells boards and does do issue filing and bug fixing for that as well. So we're getting there. So I wanna explicitly say like Adafruit funded folks should not have review privileges that are different. We do have administration stuff. But when it comes to reviewing, you're trusted for a reason. The one thing to be aware of is that like, if there is a pending review. So if somebody chimed in and said, hey, what about this thing and you think they might wanna follow up, that's the point where I won't automatically merge in. If there was like a second person that was doing the review and may have follow up further, I won't do it. But that should apply, again, that should apply to whomever did that portion of the review. For example, there was a review I did on a library today that Lamor had reviewed. I actually disagreed with her on the review and approved to the request, but I did not merge it because I wanted to give her time to say like, no, really, like we should change it. And so that's an example of where like, even though it was approved, I wouldn't merge it automatically. So yeah. I guess I'll say one more thing. And this isn't exactly what Naradok was talking about. They said, I've heard of that payment and exposure thing. I heard it's great. I've spent many years working on open source and free software not compensated. And I did that A, knowing that I was creating stuff to give away, B, educating myself, and C, I was giving away what I was making, but so many other people give away what they're making and we enrich each other without money changing hands. And now being in this world where I'm compensated for software that I get to give away, that's awesome too. And I think all of these different kinds of contribution and growth and building each other up are great and I love it. I'm so happy my life can be centered around it right now. Right. Yeah. And it's like as somebody, like I was at Google previously and like you spend so much time learning software that you immediately don't have access to the moment you leave. The idea that like I can work on circuit Python and circuit Python can be a part of what I do even if I stopped working for Adafruit is like incredible. And Mark to say, I just don't wanna break the bill. Like that's not the problem. Like breaking the bill is like if our CI tests pass then you haven't broken the bill. That's what they're there for. It's not your job to worry about that. It's the computer's job. All right, well, thanks for having me Scott. You're welcome. And I'll let you wrap up your stream and happy skiing tomorrow. I'm so happy for you that you live in a place where you can seek out snow because it's exciting and different. You're stuck with outside forever until April. Yeah, yeah, we did have snow on the ground this weekend but it's all- Oh yeah, it's Seattle proper. Oh yeah, we got like, I think the official measurement was just over a foot. So that's like similar to that storm of, was that two years ago? I don't remember the last time we had that much snow. Oh, I feel like I do because it was the year that I came out and met you in the spring because my wife was in the area for a training then. I think that would have been two years ago but if you've forgotten that, I guess it was no big deal. I mean, I would say that like, typically about once a winter, we have like a few days of snow in the lowlands, right? Like it snowed on like what, Friday or Saturday and then it was gone three days later because warm weather rolled in and rained. And for the day of the snow, she was staying up further north. I don't know how much difference an hour and a half north makes. It makes a huge difference because usually for us, we get snow where warm, wet air meets cold, drier, right? It's that convergent zone where you get the snow. And then depending on whether you end up with cold air or warm air, dictates how long you have snow on the ground. And so it's not necessarily that she was north but it's like where that convergent zone ends up dictates where do you get snow? And Seattle proper this time was like where it happened. So we got a, we got, I, I guesstimated like eight inches but yeah, it's nearly all gone. I can see a little pile out my window. That's it. And yes, Bruce, it's Jeff. Good to see you. Awesome. Yeah, thanks again, Jeff. And we'll check in with you again when you have some more stuff you want to show off on the stream. All right, sounds good. Have a good weekend. Awesome. Well, thanks again to Jeff for joining. We've got about 20 minutes left. So maybe what I'll do in the 20 minutes is just go over what I've been working on and where I left off last week. So last week I left off with I was working on I2S and it was having the problem that it was hanging. And so what I did is I found that the reason it was hanging or I'll take another type code. Oh, the time is not too far off. So the reason it was hanging is that it was actually tearing everything down. It was reusing the same PIO state machine for the NeoPixel again. But the problem was is that the DMA was still set up. The DMA was still set up to send the I2S bytes to the state machine, which meant we were basically transmitting audio bytes to the NeoPixel. And the NeoPixel code waits for it to finish and install and it wasn't stalling because the DMA was continually writing to it. So it was a problem. So what I did is I added more code to tear down the DMA and that fixed the stall issue. So in particular, since we've been talking about PIO, I actually particularly wanna talk about the improvements that I've added this last week to the PIO for CircuitPython. So if you wanna follow along with what I'm working on, you can go to github.com slash tannewt slash CircuitPython. And there's a lot of branches. I wish that Github was better about this about telling you the most recently updated branch. I should probably, actually, what does view all branches do? Ah, here we go. This is exactly what I was just saying. I wish they did. So you can see my default branch and it shouldn't be because I don't ever update the master branch. In fact, we call it main now. But you can see active branches here. And so audio PWMIO is what is merged in now. And then there's also this audio bus IO, which is where I've been working. So this is where the changes are. And you can do this compare. It usually fails because by default, because I forked MicroPython originally, it actually compares me to MicroPython, which is a pain. Yeah, sorting on the dropdown would be nice. Bruce asks, has anybody done CAN bus yet for the PIO? Not that I know of. I assume that it's doable though. But in CircuitPython, that would be CAN IO. It looks like it actually passed. So there's 5,000 plus commits different and 4,000 changed. But we actually want to switch this to A to CircuitPython. And then this is usually unhappy. Oh, I overrode. That's silly. Changed the branch, but not the thing. Okay, so here's the comparison versus Bruce says, I usually do get branch dash R dash dash sort equals minus committer date. That will work for local branches. That's a good tip. Actually, I've looked at reflog to know where I've been working recently. Okay, so this is all work in project risk code. I will rebase this. So here you can see I'm actually doing resets. And anytime you see, I do a lot of printf debugging and I'm still in the middle of it. So you can see that I have a printf here and more DMA teardown stuff. Let's look, this is the interesting bit, I think, which is the changes I've made to RP2-PIO state machine. And mainly I'm adding initial pin state and initial pin direction. So there's three ways that you can do outputs from a PIO. And they can all also do direction setting. And so as it is checked in right now, we don't mess with it and you have to run instructions on PIO to set it up to what you want. But most people, when they first get started with PIO in particular, they expect to do outputs immediately. So what I'm adding here is I'm basically setting the initial state to, yeah, Bahamut asks, this is for the Raspberry Pi Pico. Yes, it is. It's for the chip on the Raspberry Pi Pico, which is the RP2040. I also have a prototype feather on my desk that I actually use more than the Pico largely because it has a reset button. But those should be coming out not too long because we're kind of all designed it already and we saw pictures of chips that are bound towards Adafruit. So we should start to get the first batch of Adafruit specific RP2040 stuff built once we have the chips in hand. And the Raspberry Pi people have chips and they've said that they're coming our way. So hopefully it's not too long until that happens. Okay, so here's what I've got for out, for out, oh, this is not right. I never updated it here. It should be, these two should be out, these two should be set and these two should be side set. Let me, since I'm going over this, let me just pull it up. Let me just fix it in case I haven't already because I'm basically reviewing my own code. So we're in state machine in bindings and we found that this might be easier to read as well. Yeah, these are wrong. So it's a lot of stuff. So here's the out pin settings and then these are set pins. So this needs to be set and this needs to be set and then these two need to be side set. So the challenge with these is that you kind of have like two states. You have the value that they're outputting and whether they're actually like out, whether they're actually outputting it. So for each of those, we have a pair of initial states. We have initial state and we have initial direction. So by default, the values will be low. Did I change it to value? No, I call it state. State might be a bad name for it. And then direction is all ones, which is output by default. And the reason it's one F for set and side set is that you can only have up to five. So five bits is one F, one F. Yeah, Mark says, Evan's tweet was very exciting. I wonder how many total microcontroller chips are being sent to each vendor? Well, I think that the tweet said it was like what 1200 per something like that. We'll see. I fully suspect that they will, they're gonna make a ton of them. This is gonna be very popular. And at some point like it will catch up to the what people want. David G says, so you will get a few chips. The Lamor will do a limited run. Then she will send an email during the stream to say they're available from the shop and you will leak that potentially. We'll see what the timing is on that. But yeah, well, I like she literally got 10 to start with. My feather I'm running is like literally from that 10. Mark says, oh good, hopefully that will be enough. Super excited for the Adafruit feathers based on this chip. Yeah, watch the Discord. There can be a delay between when the product goes live and when the email goes out. Because secretly we, when like I need a board, like I need it, but when I will need to get a new RP2040 feather because the version I have is older than the production one. So like she'll ping me before she'll ping the people who are on the email list. So occasionally that happens in the public Discord. So if you, if you're really keen on getting that first batch, make sure you're on the Discord server. And what David is also referring to is it literally, like I've gotten those pings during the stream. So that could happen as well. The other thing is, the other thing is JP's stream. Sometimes what they'll do is they'll JP will stream and then they'll do the email after that as well. Neurodox says, what, not even putting a heat gun to a Pico, that's too easy. Yeah, you could do that. I don't think she's had to yet. That's one thing you could do if you're trying, if you're developing your own board is you usually have an heat gun that could actually remove the chip from a Pico. And for $4 on a Pico, like that's not a bad proposition. So Bahamut in the Twitch chat is saying, I ran into an issue with the ESP32 MicroPython and tried it and see but still had timing issues at one megahertz clock. I would drop in the Discord to ask folks for tips on making that. Okay, another question. Let me, since I'm questioning type code. It's good, I like questions, even if I can't answer them. So Ian says on YouTube, has anyone asked why did Pi develop their own chip? So I don't work for Raspberry Pi. I found out about it a bit earlier than normal but I don't have a ton of insight. I would recommend listening to that amp hour that the Raspberry Pi folks were interviewed on. I think it's just the amp hour.com. Yeah, if you go here, you'll see there's this recording they did with the Raspberry Pi team. I think they cover it, I listened to it. They always, I think thought that they were gonna do that and they had ideas about what they could do if they could develop it themselves. Like they have the background in designing chips because Raspberry Pi was founded by people who designed chips for, designed chips for Broadcom. So like they have the skill set to start. So I think that's part of it. And then when you add the skill set to make something, like you see the flaws in the other designs. And particularly, I think the thing that caught my eye with this is like the PIO is really cool and the documentation is excellent, but also like they clearly focused on the ability to get data through the memory bus and stuff. Like a lot of people when they talk about microcontrollers are talking about the core and the clock speed, but that's like just one component that dictates how fast things can happen. And seeing the RB2040 data sheet and how they thought about memory accesses and like being able to stripe data across the bus and the DMA that they have, like they were thinking outside the core as well, which is pretty interesting. Mark says, just wanted to say that I've been watching recordings out to the fact as I'm usually at work. Thank you for going over debugging on the last live stream. It was super helpful. Awesome, glad it was. I think like that's what these deep dives are all about is to like show all the different things that I do because I'm not a good documenter in the sense of like writing it out, but I can record me doing it and talk about it verbally as I do it. Okay, back to, yeah. Something I did just yesterday was this initial state, which should make it much easier to get started with PIO. I added this wait for TXStall flag, which impacts how write works. So basically as you're writing data out, it goes from memory to a FIFO via DMA usually, but it can also use the CPU to do it. And then once it's in the FIFO, which is a first in, first out thing, and it's either four entries long or eight entries long, depending on how you have it configured. And then those values get shifted into the state machines, output state register, output shift register, OSR. And then depending on how many bits and how you're transmitting them, like it may take some time to get all the bits out of the OSR. So what TXStall does is it ensures that when you write data, it ensures that the data you've written is not only in the FIFO, but also like out of the OSR as well. And the reason I added the stall in the first place was with Neopixel, but because in the Neopixel code, I initialize the state machine, I write the bytes, and then I shut it down. And I was actually shutting it down too early. I was shutting it down before all the bits were shifted out. And so I made write just like finish once that happens. But with I2S, where I'm never stalling, I2S is like pulling values, but if there's no value, it uses the last one. So it doesn't wait, it doesn't stall at all. And so if you use that, then your write call will never return because you'll never stall. So that's why this is here. This is the longer form description of all that. This is the boilerplate to add it. So I'm adding more functions as well. I'm adding a restart, which allows you to just reset the state machine. It reruns any initialization you did and it re-enables the clock. And you can see a to-do here for me. There's actually cases where you would want multiple state machines to restart at the exact same time. And so in the future, what will likely enable is like restart one and then you could pass in more state machines that you want to restart at the same time. So it would manage that. This is what I alluded to earlier, which is run. So this allows you to run instructions on the state machine.  And that same code is used for the initialization sequence as well. Like I said earlier, I was talking to Luke about this and you can have it, the clock disabled, but still write stuff to the Instructure Register and they all still, like it all works still. The only thing that doesn't work is delay because you're kind of like manually timing it at that point. Stop does the opposite, which is it just stops it from running altogether. And I use this for I2S where you can actually stop the I2S and it won't output any clocks or anything. Oh, and in this change, I also have it where you can, you'll now be able to have. So as it is checked in right now, you only write byte arrays and it only copies eight bits a byte into the FIFO at a time. But again, with I2S, we potentially want to write either 16 bits or 32 bits all at once. And so I added the ability to pass in, in Python land, it's arrays with a particular type code. And then this is the under the hood stuff that figures out like how many bytes long within a regular byte array it actually takes at a time. So you'll see that just to the right here, there's this stride in bytes. So stride is the idea of like how many bytes per kind of unit you're talking about. That's what stride is usually referring to. So added that to write, which is what we had already. I also am uncommoning read into. So this will allow you to read data back, which I'm actually trying to implement PDM, pulse density modulation, which is a common way to read a microphone, which is what I actually have here. And I need to debug, but we're almost out of time. So we won't do that on the stream today. So read into will be great. That's getting data from the PIO into Python. And it does all of the stride stuff as well. And it doesn't work because I'm trying to use it in PDM, but it's not working. So there's some debugging there to do. Write, read into is, these three functions are modeled after spy, where you can write, you can read and you can read at the same time as writing. But this one's a little bit different. Like I literally copied. I copied a lot of this from there, but the state machines are different in that spy, you have one shared clock and like the data goes in at the same rate it comes out. But with a state machine, you don't have that constraint. So basically this will wait until both everything's transmitted and everything has been pulled in before it returns. And we'll see, like I haven't actually used this yet. We'll see how people like that. I added the ability to set the frequency. So this will allow you to change the frequency of the state machine from initialization. This is important for I2S because the rate that we transmit data depends on the data rate of the sample that we're playing. So we needed the ability to set the frequency. So I've plumbed it through here as well. And here you can see I'm uncommenting and adding those things in. That looks good. Here's just adding more there, adding the common hell stuff. Yeah, so I have I2S and I think it's working. It's not perfect. The buffers are a little bit small. So if you get a hiccup it can cause your audio to hiccup a bit. So there's some tuning to do, but it does work for what I can tell. So I2S is working in this. And I know some folks who watch the stream have pulled my branches before, so give it a shot. The other thing, so I2S is part of this audio bus IO module and the other counterpart to it is PDM-IN, which is like a more basic form of audio, digital audio where it's just like the percentage of, or like the fraction of ones dictates the value. And there's some digital signal processing that I don't really understand and we'll see that in just a second. But I cribbed this from the Sandy 21. And so the PIO, I think that should work is very straightforward. You do in bit pins, in from pins of one. So just shift one bit in and then the side set here is clock. And that should just shift in a bunch of ones and zeros. MD Robert says, what codecs will you support on I2S? So there's two versions of I2S and I think I have both working from what I can tell. Like it's just the version of I2S that I know is just like the sample values, right? Like, and there's like classic I2S where the last bit happens after the frame has changed and then there's left justified where it doesn't. And both of those should work although I've only tested the regular I2S version. But I don't know, codecs seems to imply that there's more than just that over I2S, but those, yeah, those are the ones that I know of. It's just like raw sample stuff, which might be PCM. Okay, so this is for PDM in yeah, and Alvaro says, so that's for PDM mics. Would it work with this one? Oh, you mean, no, because that's an I2S MEMS microphone. It shouldn't be hard to support, we just haven't had a need to support it yet. It works with this one that I have here, not this. Let me unplug. Here's what I've got set up. So there's, this is my current testing setup. There's the PDM mic there. It's the same one that we have on both circuit playgrounds, I think, I think it's both on there. The I2S would be easier, but like PDM we already have. So that's why I'm supporting it. Yeah, so that's setting up the program and it basically just needs to, so here's a sync filter. This is the thing that converts like a bunch of one bit samples to like proper 16 bit samples. That's what this does. I don't really understand how it works. It's something more did for the same D21. I like totally got lost in those weeds and it couldn't find my way out. So she rescued me. This is all untested good. I have a PIO version like I alluded to. Like I alluded to. Yeah, so here's my testing version. So this is just using, you can see I'm just using the RP2 PIO directly. And then I was just trying to like do a read into and print out the values, but it wasn't, it's hanging for some reason. So this is exactly the example code that I will put in the PIO ASM library as example code. Summersoft says, yeah, sync filters. I don't miss researching that when I briefly worked on the NRF 52 PDM and DSP is such a strange land. Yeah. Yeah, we'd love to find somebody who understands it to help us out with that. It's just, we haven't been able to. Yeah, so that's basically it. There's this record to file, which the thing I copied from didn't implement either. So I'm not sure if we implemented it at all, but then this is just the boilerplate of like what's in this, the struct for the object. So that stuff's coming. You can see these are just debug. This is just debug stuff. And I'm just trying to figure out exactly, I'm trying to get it all kind of working before I check it in, which hopefully tomorrow, I'm hoping, so I'm going skiing, but we're gonna try to get out of there kind of early. And so we're gonna work later in the day. So the hope is that I'll have some time and be able to get the PR out then. So that's it. I think if there are any final questions, ask them away, but I'm kind of hungry, I need a snack. And I didn't grab my other water, but oh, I should say I got my Hacktoberfest t-shirt finally, it's not October anymore, but it took them a little bit. I wasn't one to let it kind to people. I didn't get the tree planted for me. I got the t-shirt. All right, well, I don't immediately see. I know Bahamut asks, so is there a good JTAG debugger for the ESP32? So I think both Jeff and Lucian in Discord have gotten the ESP32 S2 working with JTAG. So I would ask on Discord. I got it working just so much that I could connect to it. I didn't know how to use it at all. I think I'm gonna actually need to get the J-link going for this bug I'm hitting because it's freezing to the point where the USB disconnects. So I've got to figure out why that is. Mark says the only DSP I've, Mark Tomlin says, the only DSP I've done is from the software defined in the radio world. Reading and trying to understand I over Q, data is very hard. Awesome, well, let's wrap up. Let me take one final time code here before I go have a snack. So thanks again for everybody for joining me. Special thank you to Jeff for joining me for this deep dive. Hope you all enjoyed it. As always, I do this deep dive usually on Fridays but occasionally on Thursdays if Friday's gonna be busy for some reason. It's tomorrow I'm going skiing so that's why we're doing it on Thursday here. 2 p.m. Pacific, I'm based in Seattle so that's why it's on Pacific time. Usually Fridays, check the Adafruit blog on Wednesday to see if I have posted there. I do try to stay ahead of time but I totally messed that up last week because we were supposed to ski on Monday but we decided to go on Friday instead. Anyway, usually happens once a week. Occasionally we have guests and if you wanna hang out with me and a lot of other folks and ask more questions, please join the Adafruit Discord server, a-d-a-f-r-u-dot-i-t-slash-discord to check that out and Bruce S says they'll be skiing where they are as well. Anyway, thank you to all our circupything contributors. We really appreciate it. It's a great project. Hopefully everybody enjoys working on it and as always, if you wanna get started contributing, also feel free to reach out to me or anybody else on the Discord server. And with that, I'll pet the cat. All right, thank you all and we'll see you next week. All right, have a good weekend, everyone.