 Check, check, check. Hello, everyone. I'll sit down in just a sec. If you're watching this app to the fact, make sure you check the description for time codes. I'm not sure we have a time code taker today, but I'll try to do my best for some course ones anyway. So we'll wait a couple minutes while people see the notification and get on and join us. I'll give some updates, and then we'll dive into stuff I've worked on. Pause my video streams here. How's it looking? How's my bit rate looking? I think it's looking OK. Audio and video is good. Great. I'll say hello to some folks. Hello, Bruce. Hello, unexpected maker. Hi, Pierre. Hi, Beata. And Bruce again. Hello, foamy guy. Hello, Pierre Cutler. Hello, Gary Z. Ayane Nisgu and AskPatrickW have already chimed in. I see Grover. Hi, Cowstab. What did I say that right? It is the last eBot dive of the year. Not only are the holidays, the eaves of the holidays are on Fridays, but I have my wedding anniversary on the solstice. So taking next Friday off for that. Hello to Shepu. Hello, Nightly Virtue. Hello, Minnesota Mentat. Hello, X Micron. Hello, Allen. Hello, David. Hi, Tuxilo. Welcome, everyone. Got a good crew today. I think there was like 18 people waiting already, which is pretty cool. Hello to everyone. My video is going to shift around a little bit as well for next year. I got a new monitor arm. I got a shelf to put this monitor arm on, and it didn't work. It's on the floor. And so everything got reshuffled. And then I just got the new monitor arm I ordered that'll change all this stuff again as well. So that's why I'm off center a little bit here. And I can change the camera if need be. Hello, Kevin. Thanks for staying up. Don't feel like you have to stay up the whole night. Hello, Love the Factory. Spooks in the spot. The house is chilly, so he's all curled up. And the sun's not out. New toys are always fun. I know. OK, let's do housekeeping. I'll take a time code and do that. I don't think David's here today, so I'm going to do my best to take some timestamps. So if you're new to the stream, welcome. My name is Scott. I go by Tan Newt online. And I'm sponsored by Adafruit to work on CircuitPython. Now, if you don't know what those things are, Adafruit is an open source software company, hardware and software company based out of New York City. I work remotely for them and have for a number of years here in Seattle. So I'm a remote person for them. And I work pretty much exclusively on CircuitPython, which is a project to bring Python and the ease of use that the Python language brings to programming to really inexpensive low power, low complexity devices called microcontrollers. They're kind of like CPUs and computers kind of all in one, which is pretty neat. So I work on that. And if you want to chat with me and a lot of others, I recommend going to the Adafruit Discord server by going to the URL adafru.it-slash-discord. We're on there, although I'm taking the next three weeks off, so I'll see everyone in the new year, which I should say, I will be around the Discord off and on throughout that period. And since I just mentioned that, FOMI guy says, I'm planning to stream the next few Fridays while you're away. I haven't created the events ahead of time, so there are no links yet, but I'll post them here in the afternoon on those Fridays. So if you're missing out on some deep dives, FOMI guy does a great deep dive as well. So check out FOMI guy's stream the next three Fridays while I'm out. So yeah, deep dives. Hello, Mark and Phil. So deep dives happen every week except when I take them off. So next three weeks, no, not true. It's normally Fridays at 2 PM Pacific. Occasionally I choose to shift to Thursday, but generally I've been ticking the week off instead. Nice, Nightly Virtue says, just join this last week. Welcome. Yeah, so I will be back in the new year. And definitely check out FOMI guy's streams as well. So yeah, Fridays at 2 PM Pacific, which is just like six minutes before now. I'm in Seattle. That's why I think I'm in Pacific. It typically goes for about two hours. That's when I run out of steam. So that means we've got plenty of time to cover lots of topics. So if you have questions, feel free to ask them. I'm happy to take a stab at them. And there's also a lot of knowledgeable people that tend to watch live as well that may be able to answer even if I can't. So if you have any questions, feel free to ask them. OK, I think that's all the housekeeping. And we have a question from Love the Factory. So Love the Factory asks, is the flash needs less on those circuit Python targets without USB? So there are very, very few targets without USB. And I haven't tried measuring how much code space tiny USB takes up. I wouldn't expect it to be, I would guess, like 10k. So not a ton, not a ton of space for USB. But I haven't actually looked. And I know like BLE is like on the order like 50 to 60k. But I don't think USB is that much. So yes, but not significantly less, I would say. Hello, Charles. And hello, Paul. Thanks for joining. Let me copy that, too. So I thought one thing I could start with is an update on my sleep issues, computer sleep issues. So last week, I was complaining that my computer would go to sleep, but it wouldn't wake up. And we were guessing at all of the different things that it could be. And I'm happy to report I figured out what it was. It was driving me nuts. I couldn't do anything else. So what was happening is I would be able to go to sleep. But then when I would wake up, it wouldn't fully wake up. The motherboard would give an error code. And I would have to hold the power button and start it all back up, which meant I would lose all my Windows state. And I got lucky I didn't lose any files or anything. But it was really annoying, especially because the way that I tend to work is actually like kind of in two-hour chunks. So you shouldn't be too surprised that a deep dive is about two hours. That's about how long I can focus on something. So I just got back from lunch. And I went for a short walk. And so not having the waking up working was really frustrating me because I was having to reboot and get everything going multiple times a day, which is just annoying. So I think where I left off, I mentioned that when the motherboard starts up, it had this code that said that the RAM was bad. And so I just had a guess that maybe it was that the power supply was bad. So this computer, it's an ATX motherboard. It's a very stock standard part. So I haven't upgraded the whole computer as a whole. What I do instead is I buy a new motherboard, a new RAM. But I haven't upgraded the power supply. So I was taking a look at it. And it was weird because it does run, but it doesn't wake up. And so I was like, you know, let me just try swapping the power supply out. I've got a couple of other computers here that also have power supplies. One of which is actually like I bought this year, but I just am not using it. And the one that was in the computer has a date of 2008. So the power supply that I was using in my main computer was actually like 13 years old, which is pretty good. So I swapped the newer power supply I had in another computer into this one, and it started working, which I was very, very happy about. I was very happy that I got that working. So I think what happened is like thinking back to our electronic stuff is like there's a time period that things have to get stabilized. And I think what happened is that as this power supply, the old power supply got older, it couldn't keep up with the demands of waking up. So somehow, the sequence that everything turns on in the computer when it starts up is different than the sequence that it has when it wakes up. And so I tested with the other new power supply, but that power supply is actually from another computer. So I bought a new power supply to go in this one. And so I've been happily working all this week and not having to deal with the fact that everything was starting over again. So happy to report that if you ever have wake up issues, get a new power supply. All right, we have a question from Pierre. He's been doing a lot of good work in the core. So let's copy that. I will read it off. Hi, Scott. Got a question on the nrf52 bootloader. And where slash who should set the bootloader config regarding the, sorry, regarding the CRC check and setting the bit for app valid bit in the bootloader config register, the nrf52x. Should it be done at the bootloader and set it to assume a good app? Or should it be done at the application level where the CRC might be computed and flashed at the same time as the application? And then perhaps TAC would know. I would ask TAC. I do not know what the right approach for that is. So I can. I don't really know. I did do a lot of work in that nrf52 bootloader when we first created it, but I haven't touched it since then, so it's been a few years. Mm-hmm. Chee says, as it got older, it couldn't keep up with the demands of waking up. Empathizing pretty hard with this power supply right now. I know, right? Hi, Chee. Glad you can make it. Mark says I had one of those power supply issues so annoying to troubleshoot. Yeah, luckily I was able to swap something in to see if that fixed it. And I was very happy that it did. It was just like ruining, ruining programming for me. Gary says, interesting, as I get older, I find it harder to wake up to. Yeah. OK, so that's my update on the power supply. I should also point out that I checked in or Dan merged in support for SPI on the Raspberry Pi. So now you can use the SPI bus.io.spi should work on the Raspberry Pi. So if you're following along with the Raspberry Pi port stuff, please test it out. I tested two pinouts just with a BMP388. And that was working OK. The 388 did some weird things. I think it was having some problems. But the salier was showing me that it seemed to be always correct. I don't know why the BMP388 was unhappy sometimes. So give that a try. And let me know how that goes. So I'm getting pretty close. Let me switch to the desktop here. So I made a list, tasks that I wanted to do on this Raspberry Pi stuff. And it's under CircuitPython issues, or not milestone, labels, Broadcom. And let's see what we've got here. Hi, Keithy. So support Neopixel on Broadcom. I want to do because people expect native root software to support Neopixels. So I thought we'd do that today. I don't think it will be too bad. I did a little bit of the pre-work. LinkedIn user asks, is there an ESP32 port for CircuitPython? Not currently, because the ESP32 does not have native USB. So it can't show up as a drive like most people expect CircuitPython to do. However, in CircuitPython 7, we introduced a BLE workflow. So from a phone, you can edit your files and see your serial output. And my plan in the new year is to get that working on the ESPIDF. So we'd be able to do it on all of the ESP chips that support BLE. So ESP32, the ESP32C3, and S3, but not the S2. The S2, I don't think, supports BLE. So we don't have any ESP32 support in CircuitPython yet. But January, February, I'm planning on doing BLE support for the IDF. And that will bring CircuitPython over BLE to the ESP32. But it's impossible to provide the CircuitPython drive. It just doesn't have the support for that. So that's the plan there. And that's a little bit of a good segue back to what I'm talking about, where I had these issues for the Broadcom port as two separate milestones, basically. 8.0 and long term. The 8.0 stuff I would like to do before the end of the year. And then come the new year, my plan is to work on the ESP stuff. And I should also say January will do CircuitPython 2022, which is a chance for us to all kind of write about what our longer term vision for CircuitPython is. So some of the deep dives in January will be around that. So yeah, so there's four things. So this USB master arch hang, USB host. Unfortunately, I don't think I can do this pass. Wi-Fi support, I can't do this pass. And this bug, I might take a stab at, because it should be pretty small. And it has to do with display IO. So I might actually do this, but we'll see. And then the last things that I want to do before I cycle off this is Neopixel, obviously, like I just said, you really need Neopixel support for CircuitPython. So I'm going to do that. Oh, I got my, I don't know if Timon's here yet, but I did get my payonora, my official one, not the beta that Timon sent me. And so I thought I'd make a board definition for this today, and I think it has Neopixels on the board. So that'll be interesting once we get it going. I think I want to test it just on the IO board. But after I get it working, then we'll be able to get the Neopixels working on the payonora. So let me just show the softsets I'm digging it out anyway. So that's the payonora there. And yeah, there's a one Neopixel labeled 12, interesting. So I've got to find the source for the pinout here, too. Ha, ha, ha, ha, ha. Bruce S is looking forward to all the ESP32 support. Yeah, MicroDev and AniData, some other folks have been doing really great work on the ESP stuff. And Jeff's been doing ESP work as well. So I kind of hope that I'll focus on the BLE side, and then other folks will work on the other stuff. LoveTheFactory asks, any crystal-less USB targets? They're talking broadly or specifically for Broadcom? Because a lot of the Sandy boards are crystal-less, if you're interested in that. I think both the Sandy 21 and the 51 can do it. So if you need something that's crystal-less, you could take a look at that. But beware that the frequency does change on and off USB. Ha, ha, ha, ha. And then Dexter asks, what about HDMI audio on the Pi? It's not in my plans immediately either, unfortunately. Basically, I'm getting kind of tired of doing it. And I know that as the, in particular, the ESP32 S3 becomes more available, we're going to want to have really solid circuit Python support for that, too. So it's time for me to cycle into that a little bit. David Bates says, nice. I'm mostly interested in how circuit Python is handling the DMA access for timing. Are you, David, do you mean a particular platform? Because so far on the Raspberry Pi, I've not needed to use DMA. And I'm pretty sure for Neopixel, I still am not going to need it. I actually do want to get to the Neopixel stuff, but I want to, I was doing something earlier today that I think I could actually try on stream. But let me just vamp a little bit, because I know that the folks watching on YouTube have a bit of a delay for them to respond to what I say. If you do want, I think Twitch is working just fine if folks want to switch over to that. The nice thing about YouTube is that it should be doing auto captions that hopefully aren't too wrong. On the Pi, yeah. So I'm not planning on using DMA yet, not planning on using DMA. And I think I can get away with it for Neopixels, because it turns out the PWM, the PWM peripheral that's used for Neopixel actually has a pretty big FIFO, I think. So I'm hoping to get away with not needing it. But the FIFO is like 64 entries, if I remember right. We'll get into that a little bit later. Well, the factory says, any Chrysalis STM32 targets, I don't know off the top of my head. Sorry, maybe. Generally, if they can do Chrysalis, we like to set them up that way. Yeah, the auto captions are done by comedy writers. OK, so let me take a time code. I want to at least take enough time codes that my talking has somewhat broken up. So Pi 0. So one of the items here on my issues list is supporting the whole line of Raspberry Pi. And specifically, I called out four boards that I think would be particularly good for Circuit Python. I know somebody's run it on the Pi 3, but it doesn't have a USB device plug. So I only want to support the stuff where I can say plug into this USB port and you'll get the Circuit Pi drive. And so Pi Unora, I just showed. And then the original 0 and the 0W. And those are the biggest challenge. So they have the oldest chip of the whole Raspberry Pi series. And it's 32-bit, not 64-bit. So what I was actually working on today, because I was doing Spy yesterday and Dan merged it. It was fine. So I was like, oh, well, what am I going to do this morning? Like, I had already planned on doing Neve Pixel on the screen. So I think I'm pretty much to the point where I can try the Raspberry Pi 0 and see if it works. So I actually thought I would cover that first. And the way that I think maybe what I can do to catch you up is just looking at my diffs. Just from today, I haven't. Yeah, so the challenge with the 0 is it's a different CPU setup. It's a single-core ARM 11. But all of the peripherals are basically in the same. My understanding is that they're all in the same spot and relative to each other. But they are just realized the reason this is not going to work. And it's going to take more time. So maybe we won't do this, but I'll talk about it anyway. So all the peripherals are in the same spot relative to each other. And they're the same as what's on the Pi 3, the 2837. So I think that once I get all of the CPU things going, it should just work. So that's why I was thinking that I'd be able to do this. What I just realized is that the thing that I haven't set up yet is the memory map unit. So with these fancier CPU cores, and we talked about this weeks ago, they have a mechanism for rewriting the addresses. So the memory bus out of the peripherals has a physical address space. But then the OS can control the virtual address space for user programs to run. And then that's like a security feature. And what I did on the Cortex A72 and the A53 it applied to as well is just I mapped it one to one. But on the zero, because it uses this ARM 11, the setup is different. Like the way that you set up the MMU is going to be different. So let's just briefly go over this. And then I'll switch gears. And we'll do NeoPixel, because I kind of think I might be able to do it in an hour. So let me just go over kind of where I'm at on the zero. We'll get it committed. We'll push it to a branch. And then we'll switch gears and start NeoPixel instead. So let me just do this. So here's the make file. Really, it's only seven files have changed right now. But there's changes in two places. So here we're seeing that we're changing compiler flags and actually the compiler prefix as well. So this third one is new for the BCM2835. And this was telling me all of the spots I had assembly code that don't run on ARM 11, which has been nice and I'm close to fixing. I had to add the suffix thing. So there will be different files that get things going. So I reworked that. There's a different linker script, because it gets put in a different spot. And then I added the suffix thing on all the kernels. So the GPU that starts up the ARM will start up kernel.image on the 0 and the 1. It's kernel 7 on the 3? 2 and 3, I think? And then kernel 8 on Raspberry Pi 4. That's why there's this suffix thing. So kernel 8 actually works on the Pi 3 as well. So that's what I was originally targeting. But now we want to actually do these different suffixes. And that's kind of a standard way that Raspberry Pi differentiates between them. So if you look in there like Linux source, there's actually a stub that runs as well that will have that suffix too. So just copied that. Ooh, I haven't changed this yet. This needs to be represent. So representation A is pretty basic, but we typically use C on 32-bit machines. So I meant to change that. Let me just change it right now. So have we ever talked about the different object representations? I think we have. So MicroPython plays this is something we inherited from MicroPython. And they play some tricks to save data in the pointers themselves as a way to prevent needing to allocate memory for everything. Where is it described? Object H. Yeah, so here's kind of an example. So this is an in-circuit Python or MicroPython. You do pi slash npconfig.h, and it tells you how they structure different things. So object representation A can have immediate skew strings and small ints all packed into the pointer. But then C can do a lot more fancy stuff, including floats in the pointer itself. And that's usually what we use. So that's what I was just switching. OK, and that's already been updated. I had one spot where I put U at 64, and size t is a type that represents the size of a pointer. And so that means that it switches to. And then I added pi0 board definition. And in that board definition under the make, we see that the chip variant is the BCM2835, which then causes it to use all the different compiler stuff. There's more work I did in the peripherals thing. So David Welch had a good reference for how to start up. So I snagged that, and I've modified it a lot. And I think that's what I got working. And that will also do the very first steps of handling interrupts. So interrupts was one thing I had to do. And then the MMU is the other big thing that I've got to do that's going to mean that it's just not going to work if I try it right now. Maybe. I'm not actually sure that's true. It depends, because on the Cortex-A72 and the Pi4, if the MMU is off, you can't do unaligned accesses. And that's the thing that stopped it. But it's possible that on the R11 you can. I'm just not going to worry about it. I'd like to do a Neopixel. So here's some assembly stuff that I had to check out, changing defines to pull different stuff in. And then this generated stuff is not actually interesting. It accidentally got switched, which it shouldn't have. That's OK. Here is enabling and disabling interrupts, adding a new linker file for the R11. And the existing one was moved to link 8. And now we're rendering the 2835. So there's a different base address, but I basically can reuse all the work I did for the 2837 there as well. So let's get this checked in, and then we'll switch over to Neopixel, because I don't think I've covered Neopixel before. I thought it would be interesting to talk about timing and actually verifying timing and all that stuff. So I want to get there. Again, I thought it would be fitting to talk about Neopixel, all things Neopixel, which I have done a number of times. So it's good. So I'm just going to, all of the generated files here I don't actually need. So I'm going to move that, and that's OK. I'm going to remove Broadcom Gen. And then I'm going to switch to Main. Oops. As always, get status as your friend. And I think all of these files we want to add. Check again. Hi, Hamslabs. No worries, you're late. We've got plenty of time. We're about to get into Neopixels. OK. And so I'm going to commit that and say initial support for BCM2835. So I'll do work in progress. Work in progress. And I'm just going to push that to Origin Main. I don't think anybody else is using that repository. And Circuitbython itself has a particular commit it goes for in that repository. So it's OK if Main breaks. So now I'll add that to here. Oh, but you know what I do need to do is there's this weird thing where the commit that Circuitbython 2.2 is build. So I pushed it, and now I fetch. And I get a new Main build. So now I want to check out Origin Main Build. So that's going to have all of the Broadcom Gen stuff as generated in the CI, which is nice. It's meant so that you can just sub-module it. So we're going to update that again. And just for Pi 0. Work in progress support for Pi 0. And the translation check never likes me if I don't have a row going. I was going to kick myself if I didn't have my screen showing. Push change A to 0. So now if you want to see where I see the code, I just showed feel free to check out my GitHub. And I just suggest hitting branches. And then you can see the latest ones that I've updated. So take a look at that. Next up, we're going to take a timecode. I'm going to take a timecode, and then we'll get into NeoPixel. I hate that I copy, discordant messes up all the coloring. How silly is that? I just want it to be black. Adam says, hey, Scott, happy holidays to you and yours. Believe you're off the next few weeks. Enjoy your time off. I am. Thank you. I will enjoy it. It'll be nice. Got lots of stuff that I want to get out of my brain, which is, I don't know, we'll see. I'm also going to leave the house and do non-work things. I'm not taking three weeks completely off of work, though. I think I'll be around some of every week, you probably. But thanks, Adam. OK, so NeoPixels. So NeoPixels are these weird things. Let me, you know, the first thing I can do is I can find my test NeoPixel. So I've got these bins on my desk that have lots of stuff. At some point, they're organized, and then they lose their organization as I shove stuff back in it. But I'm pretty sure I've got a NeoPixel that I soldered to a thing. Oh, here it is. So this NeoPixel has been with me a long time. It is, oh, come on. I have these giant strips of NeoPixels. So when I needed to test NeoPixel, here's what it did, is I cut the strip. And there's my test NeoPixel. So under my hand here is just a pin header that I'm going to stick into my breadboard here. And I think I do have the overhead working. And you can see that it's got this arrow for data in. So the way that NeoPixel works is it's power and just a data line. And it's power, ground, and then just a data line. And what happens is the data comes into the NeoPixel, and then the NeoPixel will retransmit all but the first set of data it receives to the next one. So that's how it works, is that you send some data in, it pulls the first one for itself, and then ignores the rest and passes it on. And then there's a certain delay where no data is received that causes that to reset. So that's the basics. So Jeff says, bro, I have too much stuff in the brain that I need to get out, right? So I feel, yeah, I know, right? I wish when people want to give me gifts, I'm like, I really want, I would like somebody that can know all of the ideas in my head and make them a reality. It's just not how it works. Going for a walk in the woods is even better. Yeah, I think that's on our agenda. Okay, so let me switch to the overhead. I'll show you the current setup I've got, and then we'll set it up for the NeoPixel. So, switched overhead. So I don't know what's on here. This is not first string. So what I've got here, this is, so I was just doing spy work. So this is the, let me switch it so that it's great setup compared to where I'm sitting. And we'll do a lock as well. Try to get out of the light. Hi, Jessman, welcome. Thank you for staying up late or waking up early, depending on how it is to hang out with us. So this was my test setup for spy. So I've got, this is actually a sensor that can work on I squared C or spy, but I have it set up as spy. And then you can see there's a lot of wires here. So there's this set of wires that you can't see because it's too close. Let me zoom out and I'm gonna have to reset it here. It's hard for me to like not block the light while I tell it to do that adjustment. So what I've got here is I've got this group of wires. This goes to a CLA that's just off screen it's sitting right here. So that's so that I can look at the signals coming out of the pie. So here's the Raspberry Pi CM4 IO board. This is great. This one in particular is set up to get the latest copy of something off of my computer. So I just have to turn it off and back on and it will start back up. And then there's this set of signals here. This is all of the spy signals coming from the pie and my special breakout to the device as well. So it's actually, we're gonna simplify this a lot for the NeoPixel. The spy isn't wireless that's for sure. Especially when you wanna see it in two places. So yeah, the CLA is such a good, oh you know what I should highlight. The CLA is a great tool if you're ever doing this low speed signal stuff because it can, you can see the signals that you're producing from the thing that you're working on and it makes it way easier to understand why a sensor isn't working. In that vein, I do work for Adafruit. Let me switch to the desktop again. So gift ideas. So right now it's the holidays and we did holiday gift guides and Lady Aida asked me to do this firmware debugging and development shopping guide. So I will drop this in the notes. So this is a list of stuff in this shop that you, I'm sure you've seen me use a lot that I thought would be a really good reference for, for folks who wanna get into this lower level of firmware debugging. This is kind of the things that I find really useful. So let's just, let me actually take a time code and I'll just briefly talk about each thing on the list here. So I did it as kind of three categories. One is like the tools that you need to get code on and like debug it. The second one is dev boards that are easiest to do that with and then the third are, I guess it's four categories. I did this like a month ago. External analysis. So here you can see the salier that we carry. And then inline switches was the last category which I didn't realize, but if you watch me on my stream, having switches in cables is like super useful so that you don't actually have to plug and unplug them and you do that a lot when you're, when you're working. So those are the categories. Let me just briefly go over this. Alejandro says, I'm new here. Is this guy good? Any good at this game? I'm biased, you know? It's not really a game either. Ham's Lab says, I agree 100% when I finally bought a salier a few years ago, it paid for itself and saved time immediately. And Mark says, I think I bought most of these items over the last year while watching this stream. Yeah. This stream certainly helped me figure out what I should put on this list. So the J-Link, as you've seen, it's the thing that talks to the other computer basically and loads code. Really handy to have. It's not the most, it's not the cheapest option for loading code, but it's the one that I use. And even though it's slightly expensive at $450, it's one of those things that if you're doing this a lot, it will save you a bunch of time because J-Link does a really good job of supporting a lot of different devices. So it's super useful. I have it right now, you can't see the overhead, but I was using this to connect GDB to it. And then there's these other things. You can see this cable is kind of like large and chunky. So there's this adapter here that then converts it to a smaller plug. And that's, I have both plugs on my adapter thing, but yeah, so there's that. And then this here is just a, oh, you know, let's just go to the overhead. I'll show you, I have, basically I was looking at my desk. So this is the SWD cable. So right here is like, if I unplug this, this is exactly the thing that I was talking about. Too many wires. Right here is the SWD connector. And then you can plug in the smaller cable into that. And then the last thing in this category is the thing that's right next to it, this board. It's kind of a standard output ordering for a serial connection. So what it's doing is it's taking a serial connection and converting it to USB. And then the nice thing about doing USB serial this way is that it's independent of whether USB is working or not working here and it stays alive. So you don't have to like reconnect every time, which is great, although there's also a program for that. So that's on the list too, and that's inexpensive. So let's go back to the list and just talk about it. So one thing that I've really tried to emphasize with Lady Aida when she does these board designs is that for every particular microcontroller platform we do, it's really nice to have at least a footprint. So here on this picture, there's some like, there's space for the SWD connector. So you buy a bunch, I have a bunch of these. And then if I need to debug it, what I can do is even though it's not placed on here, I can actually solder it on here, for example. Other boards do have it by default. That's what this is here on the M4. So I wanted to highlight the things that make it easier to debug either by having the header on it by default or having a spot for you to put a header. And the Kaluga has a JTAG header, I think. I forget, but the Kaluga is the best one for the ESP S2, I think. And then I was already talked about the salier here. It's great for I squared C spy PWM. So if you need to make sure that your clocks are running at the right speed, you just like do the math, run the PWM and confirm that it's like the right frequency. You could use an oscilloscope, but I don't. I really use an oscilloscope. I use a salier way more. And for example, with the spy setup, not only was I seeing that the spy was working, but I was also measuring that the clock was near to what I expected as well. The Beagle, if you're ever doing USB development, the Beagle is great. Basically what it does is it goes between your computer and the device and records all of the USB traffic. So you can figure out like, oh, it got this far and then it stopped. And you can look in your code that's supposed to handle that and fix it as well. Mark says, I have forgotten about it, but when I got the J-Link EDU Mini, somehow I ordered two. If someone watching now needs one and preferably is in North America, let me know and I can send you one. If you're nearby to Mark, you can get a J-Link EDU Mini. So the EDU versions of the J-Links, they essentially work the same way, but they're more restricted in licensing and you're not supposed to use them commercially. So if you are doing any sort of selling of your devices, then you should buy the base instead. Last up in this tools thing is this, the Nordic PPK-2 is awesome. What it's good for is tracking the amount of power that a board is taking. So similar to how the Beagle is, it's got multiple USB ports. And the, I think that's what it is. Where's mine? It allows you to, I don't know where mine is. I'm gonna tear the place up. It allows you to measure the power. So if you're ever, we pretty often get people asking, hey, how do I get circuit Python in the lowest power state for something? It's like, if you care about low power at all, the very first thing you should do is buy a PPK-2 and measure it. You won't know how well you're doing in terms of power unless you're doing that. Have you tried the logic analyzer feature slash pins of the PPK-2? Not really, not really. It's actually been a little while since I used it. I was using it a lot when we were doing, like when I was implementing sleep for stuff, but I haven't done that recently. But it's my go-to tool now. It's by far the least expensive. So prior to the PPK-2 being released, like the other options were like $400 to $800 or more. So the PPK-2 is a great price for a really pretty good, pretty solid power monitor. What you'll see is like, typically to save power, you go into a sleep state where you should be very low power and then you wake up, do a bunch of work and then go back to sleep. And this can tell you exactly how that's going for you. So if you care about sleep, you care about power, measure it. Don't try to optimize something that you can't see. Last up is inline switches. Like I was saying, like inline switches are great because they allow you to pretend that something is unplugged even though it's not unplugged. So it just saves a lot of frustration, let me tell you. So there's two types of USB cables here. Most of these are these charged data ones. So they're not actually, they don't remove the power. All they do is they disconnect the data lines, which is really handy. And I've got that basically on all of the USB cables here, just to, especially if you're doing USB development and you have a bug, you may wanna prevent that bug from confusing your computer you're developing on. This barrel jack switch I'm using actively right now to turn the power on and off to the Raspberry Pi. And then this one here is actually useful if you wanna turn a proper battery on and off as well. So those are my recommendations. There's a link to this old guide for debugging CMD-21 that I should definitely update. And I was thinking actually that might be something I do towards the end of the year. Last week I was working on the Raspberry Pi guide. I haven't worked on it since then, because I kinda wanna get all of it working. Like there was a Pi 4B bug that I had to fix and stuff. So I think that's gonna be kinda like the last thing I do. And I've gotten a request, I've heard a request for particularly a guide for debugging circuit Python. And this debugging the CMD-21 with GDB, I could totally revamp and have it just be debugging with GDB and then just cover like for all arms, it's very similar across the whole line of Cortex-M's. And then that would just be so, so useful. Analog Devices has an AD-ALM 1000 that's also nice for power measurements. Oh, I didn't, yeah, the PPK I don't think I tried. That would help new people with the contributor learning curve a lot. Yeah, I know, I should do that. I think between switching from Raspberry Pi to ESP, I think I should take a stab at revamping that stuff. Okay, so that's our detour into that. Let's go back to NeoPixel stuff, back to NeoPixel. So let's rewire this breadboard while I'm thinking of it. And it's gonna get darker and darker. So maybe it's a better time to do it now. So I'm gonna pull most of these. There is a particular pin, so power I can leave. And I think I will actually power it with three volts. So you can power it with three volts and then you won't have, it won't be as bright but it also will, it won't be as bright but the logic levels will be better. If folks have ever had trouble with the NeoPixel, you can have problems if you power them with five volts but send them three volt signals. They may not, so three volts is like not super high above the threshold for a one basically. And so if there's a little wiggle room around that value can cause some very weird stuff to happen. So let's simplify all this and then get rid of. This BMP388, Keithie says, thanks for the detour. Good few of those are on my short list. Nice seeing them again to make it more worthwhile to grab. Yeah, no problem. I just, I was, when LaMoure asked me to do that guide I literally like looked at my desk to see what I had on my desk for the stuff that I use all the time. So here's my NeoPixel and I'm just gonna put it in here and it's, ground is on the left hand side so I'm gonna have to move this, stick in. Red boards are so fun. And then power, and that's gonna be three volt power even though it says five. And then last up we have data. So data is gonna come in here. So there, there we're wired up. Um, of course we haven't, I haven't written any NeoPixel code, NeoPixel code yet. So that's a bit of a problem. Let me, let me pull up. Let's go back to the desktop. We're not coding yet so we don't really need to see it. Get a hard pie. This library is what I was referencing. Is there a power switch for a USB-A to USB-C? I'm not sure. In that list I did not have any USB power switches. There's a few more. I think there is. I think the shop has one and I think I did order it actually. I think there's a, I think there's a short USB-A to USB-A that you could use so you could plug. I mean, it puts the switch by the plug which is kind of annoying but. I don't have it on my desk. My desk is a mess. What are you doing that those items are on your desk? Besides everything in deep dives or summarizing them I guess. I mean it's largely what I do on my desk in deep dives. Like the J-links always on my desk. The power switches are always on my desk. I have like those development boards with the header spots on them. I always have those here. They're a great resource. This is something I wanna cover. This is why I think a guide would be nice but like there's like different degrees of debugging that you have to do in Circle Python that I think would be good for a guide. So like the top level is like it works. It doesn't crash. It doesn't hang but it doesn't work and that's when printf debugging can be pretty accessible. And then if it crashes or hangs that's really when you, it's easiest to just get the debugger out. So that's when it like having the debug ports becomes more important as well. And then like the USB stuff is pretty specialized. The PBK2 is pretty specialized if you care about power. Then like the Celia, if you're doing anything with sensors like Celia's are really nice. I think I've showed it on the screen before. If not, I'll try to get it going today and we'll use the Celia to look at the NeoPixel stuff. So let's keep going. So I was looking at how the, so rewind, learn, NeoPixel. If you have any questions about NeoPixels and the wow, look at that, 693. This is the place to start for NeoPixels. I'm sure I've talked about Celia before. Nice, that read was awesome. So NeoPixel is the trademarked brand name for individually addressable LEDs that are started with the WS2812. And so what it is is that it makes it, you can have big long strings and each one of them you can have different colors for. That's what it is and NeoPixel is the Adafruit term for it. You might actually see like WS2812 or WS2812 compatible. And you can see here that there's actually like some different chip types that respond to the same protocol. Notably dot stars, which are, dot stars are another trademark named by Adafruit for the APA 102. Those require a clock and a data line. And so that's, we're not talking about dot stars here. Dot stars are actually way more flexible because dot stars you can just use a spy device for. So yes. Anyway, so this is, let's not get into all of the NeoPixel weeds. But as somebody, what we're gonna do is we need to figure out a way to transmit the signal. So let's take a look. I think the signal is around here somewhere in this guide. So let's just kind of go through here and see if we can find it. And I wanna, yeah, caution people about it too. Oh, these are form factors, basic connections. Lots and lots and lots of information about them. I don't know. This might be all how to use it and not implement it. Anyway, so let's, yeah, I wanna look at a data sheet. That's what I want. And if we look at the data sheet for the WS2812, it has this, where is it? Timing diagram. So the way that it works is ones and zeros are encoded by different, differently length, different pulse lengths. So zeros are shorter than ones. And you can see that it talks about the cascading here as well. And then there's like a, if it's low for so long, that's a reset. So remember we talked about that of like, the first NeoPixel will get its color and then pass on all the colors and the next one will get its color and pass on the rest and so forth. That's what it's showing here. It's funny that this diagram doesn't actually have the timings at all. Which doesn't, oh, they're up here. So it's weird how they do this and they say, oh, T zero high 0.4 and then T zero low is 0.8 and otherwise it's blah, blah, blah. Anyway, what drives the WS-2812 is it just an IO pin plus power? It is. Well, so the technique, so transmitting data like this where a zero still has a pi pulse and then a low, then one is just a longer pulse is actually like non-trivial, it's actually hard to do. So a lot of the circuit Python ports will potentially bit bang it, meaning that there's actually the CPU is doing that timing. So yeah, the warning that I wanted to make is, let's look at the SK-6812-70. I thought I heard a slack sound. I don't think it happened. So let's take a look at the timings in this data sheet. So these are compatible, supposedly. But if we look here, these numbers are different, right? 0.3, 0.6, 0.9. And so there's a lot of confusion about what works and because I had this alien, like I would, when I was first implementing it, I found one of these data sheets and then I figured like, oh, I'll just like get it exact and it works, but it doesn't work that way. Like these data sheets are kind of a lie. And the person that came up with this, that discovered all this NeoPixel stuff and made it a thing is Paint Your Dragon, Phil B, who works for Adafruit. And so I asked him, I was like, Phil B, what's the good rule of thumb for timing NeoPixel? And here's what it is. It's an 800 kilohertz signal. And you may have heard there's also 400 kilohertz NeoPixels if they're really old, but almost all of them are 800 kilohertz. So 800 kilohertz is the how fast each bit gets transmitted and then the zeros are a 1.3 pulse, fraction, so 1.3 high of that 200 kilohertz. And then the ones are 2.3. So you're trying to do 1.3, 2.3 to do the different ones and the twos. Roy says, hello from Idaho, just got a Pico the other day. I'm in the Pacific Northwest just like you, awesome. NeoPixels are my favorite, just trying to get the hang of circuit Python, other docs to study. So the best place to start for circuit Python is the learn guide, learn, and then welcome to circuit Python. It's in my history. This is a great place to start. If you're into NeoPixels for circuit Python, the essentials guide will tell you the basics and then, which I think is just circuit Python essentials and I'm sure there's a NeoPixel page here. It will teach you how to do the basics. Just the rainbow stuff. And does it cover? It does RGBW. There's also a great NeoPixel animation library. Oh yeah, sorry. Somebody on Twitch asked for the link, so let me do that. So here's the essentials. No, that's the welcome to circuit Python link. There you go. Sorry, panda of love. If there's other links that I didn't send on Twitch, just let me know, I'm happy to copy them there. The other thing for NeoPixels is there is a great animation library. Animation, which might be here. This might be older than that though. Yeah, so this uses the LED animation library. So yeah, this is really awesome animation library that Rose and Katnipa put together. When it comes to NeoPixels, that's a great thing. They've done a wonderful job. It's just amazing. I have NeoPixels around the way two front windows and I'm using the animation library to just do some basic animations to be a little festive. Okay, so let's, this is all the fun stuff. Let's go back into the weeds. So when it comes to NeoPixel timing, don't trust the data sheets. Do, from what I understand, it's a 600 kilohertz signal, an 800 kilohertz signal, one third for zeros, two thirds for ones, and that's gonna be your safest bet. Oh, Pierre says, when do you send people to read the docs? For what reason slash purpose exactly? Learning guides are really useful, but I found myself going to read the docs regularly when I wanna see how to call slash use specific modules. Yeah, so read the docs is a reference source, right? So it's trying to be super comprehensive and saying like, here's all the functions that this thing has. Here's a brief explanation of them. The source for read the docs is the circuit by the repo itself. So it will always be up to date with the latest circuit Python stuff. Learn guides are much more pros oriented, so they're really meant to explain everything to you and kind of walk you through in a logical order, whereas read the docs is really meant as a reference. Pant of love says, I have a couple of strips, just need to get it working. Ah, yay, Neopixels are great. Okay, so how do they work in Raspberry Pi? So I had pulled it up. So there's this Python library here, our Pi WS-21X, and this is actually what Blinkit uses. So you can do circuit Python Neopixel stuff from regular Python code on Raspberry Pi via Blinka, which then uses this internally. And they have good explanations here. Turns out they have bindings for a lot of stuff. So if you're doing Neopixels on the Pi, like this is the library that you're probably using. And they hear, this is interesting. So they talk about how what they do is they take the bit pattern you want and then they expand it out into this. So the challenge with transmitting Neopixel is that there's not usually things geared towards setting, like zeros being some duration. The one exception to this is the RP2040, which has the PIO, which is super flexible and awesome and can do Neopixels all on its own. But that's the only exception I know of. Otherwise you have to play some tricks like this. So what you can do is you can, they point out that you can use, it says using DMA and the LinkedIn, oh no, who was it? Somebody was saying like, oh, I thought you needed that. Somebody else is talking about it. Yeah, generally you need DMA to keep up, but it's 800 kilohertz and that's per bit. So it's really not transmitting data that quickly. The challenge with transmitting Neopixel data is that you can't have gaps that are larger than that reset gap and you wanna make sure that the pulses themselves are timed correctly. So that can actually be pretty tricky on its own. Can you do it with a 3B pie or is that too old for Neopixels? You can do it on any pie. Yeah, so these approaches work on any of the pies. So I'm gonna focus on one of these approaches. They say you can either use the PWM peripheral, the PCM peripheral, PCM-5O, PWM-5O in serial mode, almost any number of LEDs in a chain. And then for spy, you could use this Linuxy thing. So basically what you have to do in order to use more traditional serial stuff is that you have to transform the individual bits that you wanna transform into Neopixel into three bits. So a one bit is a one, one, zero and then a zero bit is a one, zero, zero. And that's what gives you the two thirds duty cycle and the one thirds duty cycle of this signal that you need. Lovely A72 says, is this library bit banging the protocol? I don't believe so. I wouldn't consider this that. What they're doing is they're taking the data you wanna transmit, expanding it out, so three times as many bits and then they're using a regular data transmission to do it. So what you would do is you would say, like, I'm gonna send one bit at three times the 800 kilohertz rate and then I'm representing every bit with three bits. So that means that the bits are actually at 800 kilohertz. We got time, hopefully we'll get to that. And then they talk about what the pin numbering is. And I think it's labeled 12 on the PyUnora. So maybe that's the one that we should pick on our test setup here as well. But I was planning on doing just this first approach, the PWM approach. Spy we could do in the PCM. But let's take a look at the spy stuff or the PWM peripheral. I hadn't looked at it before until a couple of days ago. So this is the BCM 2711 data sheet. The PWM peripheral is also present. There's one of them in the older pies and in the newer pie, there's two of them. There's not that many pins that they're connected to but they are actually surprisingly versatile that I haven't seen before. So it's this chapter eight pulse width modulator. And the interesting bit here is this 64 by 32 bit FIFO. So FIFOs are great. They're first in, first out. And what they allow you to do is they insulate, they insulate the peripheral from the timing of the rest of the chip. So what you can do is you can say, I'm gonna send, so it's 64 entries, 32 bits a piece. Ideally what we would do is we would do 64 entries at 24 bits. So we're gonna take one by the neopixel do three bits per bit. So it's gonna end up being 24 bits. And then we'll put it in a FIFO and we'll transmit it out. And that 64 entry FIFO will give us hopefully enough timing slack that we can keep up without needing DMA to keep up. Yeah, and Pira says I've seen people use I2S for that as well. Yeah, so you can do the same approach on other chips. I think on the ESP32S2, at least, they have a peripheral called an RMT, like the remote peripheral, and they can do different pulse train-length stuff. I think it's how, at least we do it on the ESP32S2. So that's the gist of it. If we look further down, there's two modes of operation. There's either like traditional PWM mode where it's just like duty cycle changes, or there's actually like the serial mode where it will transmit ones and zeros over time. And so that's, yeah, you can see serializer mode. So that's, I think the mode that we're gonna use it in. And there's, how many is this? One, two, three, four, five, six, seven, eight different, eight different registers, and that's for two different channels. So we'll have to do figuring out what channel we're on, blah, blah, blah. So where does this go? Where does this code go? So ate a fruit, circuit python. So Neopixel as implemented in circuit python is actually very basic. A lot of the code is out in python land, but what you get from the native implementation, and this is something I think we do inherit from circuit, or from micro python, is that there's just a Neopixel write module that has a Neopixel write function that does the transmission. And you give it a digital in out, but internally what it does is it just uses whatever it needs. So Neopixel is a little weird in the sense that like you don't hold on to the Neopixel pin in all of that state over the lifetime of it. You basically only do the Neopixel thing when you need to transmit and then you're done. So it's called Neopixel write. You rarely will use this directly. There's a Neopixel module that wraps it and other other optimizations and things, but the core of what does the transmission is that's Neopixel write. And so we just look at, let's peruse the other implementation. So in circuit Python, this is in shared bindings. This is the place that we define what the interface is, but we don't actually implement it. The things that we implement are listed in the header file and then we look in the individual ports for how they're implemented. So we wanna see like how the SAMD does it. We go into at mlsamd, we do common how module name, which is Neopixel write, and then it's just in init c. Interesting, I've used UART on occasion for driving dot star LEDs, but most boards don't put the UART clock onto a pin. But then you can use standard IO. Yeah, I think spy is the most common for dot stars. Oh, thank you, Patrick for helping with notes. Yeah, I'm always bad about it. One thing I can do is I can actually just add them later. I can do it one time because later. So here's the nitty gritty for Neopixel and SAMD. There's a delay to make sure that we've given the reset delay, we disable all interrupts because we wanna make sure, the problem is we need to make sure those individual pulses are timed well and then there's just like assembly stuff. So on the SAMD, we don't use a peripheral, we just like stop the world and don't do anything else, which is not, it works, it's worked for a while, but ideally your CPU would be able to do other stuff. Let's see how nrf does it. So we're in nrf common how Neopixel write init, and then looks like nrf does actually use a PWM, but we have to, the duty cycle is like, we have to expand it out into full duty cycles, I guess. So the approach that we have is actually quite different, depending on the chip itself. And so what we're gonna do is we'll make a Neopixel right here and we'll use the PWM peripheral to do it. The reason that we get handed a digital in-out is because that digital in-out then ensures that the pin has been grabbed and is not being used by other stuff. Okay, so let's get into it, see how far we can get. So what, am I in my branch? No, I'm on RPY0. So first we're gonna just fetch Adafruit and then I'm gonna check out Adafruit main. So this is me just making a new branch, see RPY Neopixel and let's get status and this is new, we do make fetch submodules to make sure we have the right thing. Always stop all interrupts, they're not useful for anything anyway. If you're timing Neopixels, that's all you can do. Oh, that's what I should show. So the RB2040 alone is awesome because of the PIO. So it's under Raspberry Pi because they made the chip, not the board, the chip. Common Hal, Neopixel right. And then what we can see is that we have a PIO program here that does that two-thirds, one-thirds timing and then we actually just call directly the Raspberry Pi to PIO state machine stuff to do it for us, which is amazing and awesome and the way that hopefully all new chips and like PIO is really impressive. So that was amazing and there's all sorts of even cooler stuff you can do with PIO. So okay, we're up to date and now we want to create our Common Hal Neopixel folder. So what one do we want to start with? I think I'll just copy the one we just looked at. So Neopixel right and I'll say duplicate and we're going to put it in Broadcom. Oops, I don't want to change that. And then in here, hey, the timing's up to date. We don't need this. We might want this. Well, let's leave that there. So again, the start, next start raw ticks is there, there is a, if you don't wait long enough to start the next transmission, you can end up like on the end of the previous one and the first one will therefore not pick up. Not pick up on the new data that you're trying to transmit it. This we don't need, maybe bit bang. I don't think we ever implemented bit banging it. So we're going to want to capture this weight thing. We do actually want to, we're going to raise an exception. If, we're going to raise an exception if the pin is not supported. So we do want to check that. Yeah, put PIO and the Sandy and other popular chips. I mean, that's why the RP2040 is great. Okay, so let's not do any of this. We're going to replace this. But this outer timing stuff we do want. And then the other thing is we do also want to build it. So in our make file, here, we're going to want to turn on the pixel right. And what we could do is we could actually just add like a garbage just to make sure that when we build it, we're hooked up. HAA32 CM4IO clean. All right, so it did, it did not work. Next start raw ticks. It's not there either. Oh, it's right here. So I probably just confused it. So one thing I've done, RP2040 doesn't go into cars and appliances. Yet, yet, too new for that. Okay, so we do have the build set up. And I already, so the pre-work I did is to access peripherals the way I've set it up is to do these SVD files. So in, I think I did it yesterday. So now there's an SVD BCM file. So this is the, or PWM, that this is the PWM thing and it will generate the bits and the structures and stuff for us. So what we should be able to do here is for now, maybe we don't check the pin because I kind of wanna get to transmitting a signal and we're running out of time. So I think what we wanna do is we just wanna say PWM zero and let's pull up the data sheet. So this is the 2835 data sheet, but the PWM peripherals should be the same. So we just wanna figure out, let me do this. This is older PDF doesn't have an index. So what I'm looking for is just good data sheets will tell you like what to turn on. This is not one of them. Well, it tells us in here. So let's take a look at pin out. Let's figure out how we're gonna get this wired up. XYZ, we're wanting GPIO 12, which is here, PWM zero. So, you know, they could label their pins but that would be way too easy. So it's three, four, fifth in. So one, two, three, four, five. So I should be plugged in. So for now I'm just gonna hard code the pin. Good data sheets exist. The RP2040 data sheets are quite good. Okay, so let's just hard code it to pin 12 right now. We won't actually check it yet. And pin 12 is channel one, I think. So what we wanna do is we want to, set this control register first and foremost. So I'm gonna actually move this off screen so I can try to be a bit quicker. You'll have to take my word for this a little bit. That's the challenge of streaming. So we're just gonna turn it on by assigning some stuff and we do actually want to pull up. In Brog.com Gen there's gonna be this thing here and PWM zero, I don't want. So it generates two things. It generates like C structs that you can use to modify values. So if I was doing a single bit I would use that but since I'm not, I can also find the defines here. So to set all the bits that I want all at once, I can say like, oh, I'm going to enable, so PWM enable one. So that's gonna be something that I do in init. And then I also want to enable the FIFO which is use F1 there. And then I want to debug this other stuff. Miroslav says, sorry for off topic but I just tried to build Sergipython from today and this one does not work. The build from yesterday does work. Can you bug me on Discord and I can follow up after the stream? Cause I don't know what board you're talking about. You can also file an issue is a good way to do it too. So we're gonna leave polarity. We're gonna leave the algorithm. I think that's it. Oh, there's a mode. So if we set mode to one, we're gonna want to set mode as well cause that'll put it in serializer mode. Sorry, I'm referring to the data sheet off screen here. Yeah, the SAMD 21 data sheets are pretty good too. They have the functional descriptions that are really handy. So I think that's it. There is a clear FIFO. So let's do that too to make sure we know what state our FIFOs are in. So that's this bit. And this bit won't be sticky. It says it's a one shot. So it'll just cause it to clear. And then the other thing that we need to do is we actually need to set a function. So we need to do the GPIO set function and we're just gonna do a pin 12. And if we look through here, I bet if we find PWM zero, oh yeah, function select of pin 12. So we can set that. So what this GPIO function does is it connects the outside world to the inside PWM thing. So that'll get our signal out of the chip. And then one thing we want to think about is how fast we're going. Which I think is, so there's a range register, RNG one is a range. In serial mode serialized data is transmitted within the same period. If the value of PWM range is less than 32, only the first bits are sent resulting in truncation. Interesting. So this, the range register is the thing that we use to like send 24, not 32. We'll have to experiment with this. That's pretty much it. We're not gonna use DMA. So there is a status register that we need. So we need to do. So here are our pixel datas and pixels num bytes. So we're gonna do a loop of four size T i equals zero, i less than num bytes. Like I must have had word wrapping on before. Everything I feel like needs to be wrapped now. Maybe it's just cause I'm streaming num bytes. And then i plus plus. So this is for every byte that we need to transmit. What we wanna do is we're gonna want a 32 bit number expanded equals zero. And then four size T j equals zero j less than eight. So i and j are very just classic names that are given to generic loop variables. So what we're gonna wanna do is we're gonna wanna say, if pixels of i ampersand one to the i is equal to one. So this is the ith bit of, or no, we want j there. jth bit, if it's one, what we're gonna do is we're gonna do expanded equals expanded shifted three or with our two thirds pattern. So I might get my bits all flipped and stuff, but that's what looking at the salier can help us with. And then we're gonna do, if it's one, it's the two thirds pattern. So it's gonna be a six. Else it's expanded. And you know what we can do? We could just do expanded shifted by three equals. So this is the point where we're expanding it out. And if we just want, so a four is a one and a zero zero. So like the furthest zero is one, the middle one's two and the last one's four. And the first bit is always gonna be zero. Okay, so we're expanding it out into 24 bit. And then we are going to write it to the FIFO, which we do by writing to, I'm just scrolling up and down the data sheet. It's the dat one register. So remember, we're just hard of coding it right now. I data that, I think that's right. Okay, and then we need to do a couple of pauses. So first we wanna check, before we write to it, we wanna make sure we've got room. So we wanna say while PWM is full, while the FIFO is full, which is full one. And it's in the status register and I want the bit is equal to one. Then we're gonna wait. And then at the end, we also want to, so we have a big long FIFO. So we also wanna wait until it's done. So while PWMIO status, and so this is a little weird because there's, we can wait till it's empty, but the FIFO won't actually be, there's a state bit here. Oh wait, it does tell us what it is. The state bit, zero means the channel is not currently transmitting, one means the channel is transmitting data. So we wanna wait for this date one bit to be equal to zero. Well, so while it's one, meaning it's busy. And this is where we can do the run background tasks thing. We might not wanna do it here. It's probably okay though, I'm told it there too. I need the oddly tilted ultra wide for maximum line length. Okay, so I think that's it. And then what we should do here is let's return the pin. We don't actually wanna return it to input. I guess it'll make it some fancy colors. Okay, so the last component of this, I think is figuring out what speed it's transmitting at. Not entirely sure how to control that. We might be going super fast. I bet we're gonna be going super fast. There is no looking at the data sheet and I can pull this back over. So looking at the data sheet, what I'm looking for is a clock divisor. So a clock divisor will take a clock and divide it down to slow it down. Cause we'd like this clock to be three times 800 kilohertz. So three times 800K to get us going the right speed. There is a way we can ask the GPU to do that. But we can actually use range as well. But the problem is that range I think also controls how many bits we're doing. So we might have to get fancier with how we pack bits into the 32 bits that we write to the FIFO, which would be annoying. Serialized mode configured to load data to or read data from a FIFO storage block, which can store up to 832 bit words. So I don't actually know how big it is. Both modes clocked by clock P2AM, which is nominally 800 or 100 megahertz, but can be varied by the clock manager. So let's just see if it compiles and see what it outputs. And then we'll get the clock right later. The NeoPixel will do all sorts of weird stuff probably. Okay, so it's pointing out that I'm being ambiguous. Another set of parentheses and it builds. Great. So now what we need to get set up is we're gonna source our repo and do sudo Python. Probably shouldn't do this, but I do it anyway. So that's hosting my kernel images so that when I turn it on, it can get it. And oh, you know what? I don't have test code on here yet. So let's pull up the docs. So this let's switch to that. So here's our, this should be, this will be our output from the Raspberry Pi as it boots up. And in the read the docs. So yeah, it's still trying to do my previous demo, just fine. Where did I find that? There's this nice, oh, did somebody ping me? Did I miss it? Did my cameras, my cameras are okay. I think, I just saw a notification out of the corner of my eye. So let's at least get, where did, brain? Brain, where are you? Is it Friday? Oh, it is Friday. Lost my brain. Neopixel write and it has this nice super short example that's just writing three zeros. Streaming solid on Twitch, great. Thank you, Patrick. Let me turn on my, is that flipping my data switch? Oh, that's what popped up. Ha ha. Thing that popped up was my circuit pie drive for the thing I just started to spy. Oh, oh dear, by test. And we're gonna create a new file, code.py. From time to time, people ask me my workflow and all. This is what I tell them. So I will use the right pin, but I'm like in the Neopixel code, I'm circumventing all of the, oh, interesting. It has you set it to an output. Ha ha ha. Guess I shouldn't switch it back to an input. That makes more sense. Pixel off and we're gonna do D12. And let's get logic going. So this is the software for, hopefully my computer stays alive. This is the software for the salier and it didn't find the device. Now it's going. This is the setup for spy, but I only need to capture one channel, this. Do they have a, do they have a decoder for Neopixel? I think they do. This is channel 12, 2812B. That's right. Good night to Shippu, sleep well. And we're gonna do it on rising edge because it starts at nothing. Ooh. I keep putting my leg up and getting caught on the cable. And let's just do one second of capture instead of five. So what we can do here is we can hit save. And then save here. And did it do anything? No. So now is how, what do we do to debug? So print, write, done. And let's leave, let's do a sleep, just a one second sleep to make sure that we're not overrunning it. So that code's working, but you can't see this. Nothing is being seen on the pin output. And we got 10 minutes left. If anybody has any last questions, now's the time to ask them. It's pretty cool that Salie Logic Analyzer has Neopixel format capture now. Gotta go dig mine up. Yeah, so this is logic two. It's their second version. And they actually have a way to write analyzers in Python. So I've actually authored a spy flash analyzer there that people have actually used and like made pull requests against to make it work better. So logic two is pretty cool. And I know that like the open source pulse version thing should be able to work too, but it's just, they don't have great hardware support. And Kmatch, I think, I hope it's Kmatch did a ton of work to do like an open source logic analyzer to go with pulse view. And I don't know if they ever responded to the PR to get that support in, which is just a shame. I'd love to use an open source version, but I need solid hardware support, not buy this thing off TabL and it will work support. Okay, so the first step I'm gonna do is I'm actually just gonna start doing some debug prints, surprise, surprise. So let's just do, printing is actually kind of slow. So we have to be a bit careful, but and maybe we'll be able to see what I mean. I don't know, for all I know this won't work. Right, and you know what we didn't set. I mean, I think we're on the right pin. It's totally possible we're not, but we're clearing the FIFO, we're enabling it. We're saying use the FIFO, we're setting it to serializer mode. Should be all we need to do based on the data sheet. So let's just try it again. So now that we loaded our code, our test code, what we can do is we can actually just say remove and we don't actually need to load it again. So I can use my USB switch to switch it to charger. So that now when I do a switch it off and then I can switch it back on and it will load from my computer over the network. That's what this TFTP thing is. It'll load the newer version of the kernel that I just built. And it has prints in NeoPixel right. So that should be able to tell me that like my test code is still running. But it will only run once, which it did, it just didn't work. So we can see the right, right, right done thing. So that should be the pattern for zeros. Try other pins around it to see if the eathomic pinout mapping is wrong. First I need to have a new line. I do wonder if this is right. I wonder if it's clocked by default. As well. It's possible it's not turned on. We're setting the function. Good number to write I think. Like we should see something. The other thing we can do is we can PW sync. So that's the clock, yeah the clock boundary. See this is a 16 by 30. Where did I see? Oh it's in the broadcom that it's 64. This one might be 16. And then it said eight here. But it turns out because there's two channel outputs the way that the FIFO, that you have to alternate adding them to the FIFO. So they need to be going the same. So the other thing is serial bit transmission 1 MS mode. Yeah so this is what you would normally think of as. Yourself says we'll circuit by the for Raspberry Pi understand HDMI CVT and HDMI drive and config.txt so I can configure the five inch HDMI LCD from WaveShare. So I believe those are both used by the GPU. So it should just work. I know that the E-Ink WaveShare thing that Phil did the demo with had to have some other HDMI configuration stuff. So circuit Python ignores it but the GPU does not and the GPU does a lot for us. So it's worth a shot if you have one already. I would expect it to work. So alt function zero. I wonder if that's right. Is that right? We should actually for alt functions we should double check the right or the other datasheet because that's the one that we're actually using. Enable clearfifo polarity repeat mass data status. We could print the status register and just see if there's an error. If it is larger than 32 XS zero bits are padded at the end of data. We don't want that either. Not a lot of information but there are there are some other sources that we can look at too. We're running out of time. Like I can look at the Python implementation that we looked at earlier and see what they set because I have a feeling it probably talks to the memory directly still. Just run pin 12 PWM zero zero is alt zero which is not actually the value zero which is the confusing part but it is where it should be to be considered zero. That's the confusing part. Ew, that's a confusing link. I think that's correct. All right, I'm gonna call it. Sorry, I haven't figured it out. Any other questions folks have? Okay, thank you all for joining me for another deep dive. This is the last deep dive of the year. I should not forget to say that. So I can report that it does work. Okay, great. Awesome. So yeah, taking the next three Fridays off so going to not do deep dives. The tentative day is January 7th which is the first Friday in January but I did want to call it tentative just because it's four weeks, three weeks, four weeks away. And so I wanted to give myself an out. If you'd like to know, I'll try to ping the deep divers role on Discord. So if you haven't joined Discord, I encourage you to join Discord. You can do that by doing, is there an enable bit? An overall enable bit? You nerd snipe to me. Is there really just an enable bit? I'm calling it channel one enable. So I think I am doing it. Um, clock control enable. Yeah, like me and then what you're looking at. I got to take a break and then I might come back to it. Yeah, so if you want to go join Discord, go to url, a-d-a-f-r-u dot i-t slash Discord. Hello, Melissa. Melissa, we're just wrapping up. I'll pet the cat. He's there, don't worry. The master clock could be a thing too. Get distracted. If you want to support me, you can support me by supporting Adafruit. They pay me to do these streams and work on CircuitPython. You can do that by going to url, a-d-a-f-r-u dot i-t, no. Adafruit.com, Discord. I was saying the Discord one as well. Yeah, I think that's it. Hi, bye, David. Thank you to Patrick for taking notes and assembling all of the notes in the deep dive repo. I hope you all have a great holidays and time off. And I hope I can inspire you to take some time off as well. And we'll see you in the new year. Trying to pull up my notes to see if I forgot anything. The other thing I should say is that I expect to talk about CircuitPython 2022 when it comes to deep dives in January. We'll talk about that. Oh yeah, and thanks to Patrick for putting in, or somebody putting in the notes that FOMI Guy will be streaming at this time for the next few weeks. So join the Discord, FOMI Guy will post links to the streams for him in the live broadcast chat for the next few weeks. So if you wanna hang out, we'll still have those streams that will be going on. And I think that's it. Let me pet the cat and get out of here. And we'll see you in the new year. It's totally fine sniping me, you know, that's how this goes. All right, Smoke, time for your pets. It's like, Dad, you're messing up my fur.