Raspberry Pi Pico PIO - Ep. 9 - Direct Memory Access and Pulse Width Modulation: A Deeper Dive

Поделиться
HTML-код
  • Опубликовано: 14 июл 2024
  • Join David as he takes a deeper dive into Direct Memory Access (DMA) and Pulse Width Modulation (PWM) for the RP2040. Included is an example on sequencing through a series of GPIO pins without any processor involvement after the sequence has started.
    00:00 - Introduction
    01:32 - DMA refresher
    02:15 - DMA chaining and aliases
    05:00 - PWM details, slices, and channels
    07:30 - Detailed example
    08:15 - PWM code
    09:50 - DMA code
    18:45 - Closing
    Links:
    Files for this episode:
    github.com/LifeWithDavid/Rasp...
    RP204 Datasheet:
    datasheets.raspberrypi.com/rp...
    Raspberry Pi Pico C/C++ SDK:
    datasheets.raspberrypi.org/pi...
    PWM basics video:
    • Pulse Width Modulation...
    Music:
    (Pinnacle 19.5 royalty-free music):
    Pulsing Dance
    House Fever
    Reaction Time
    City Night Groove
  • НаукаНаука

Комментарии • 37

  • @honorbean2973
    @honorbean2973 5 месяцев назад

    Your videos are very good and thorough. Nice work!

  • @Xperimenter
    @Xperimenter Год назад +2

    Great videos David, these two on DMA were especially clear. I like the way you give attention to every line of the code.

    • @LifewithDavid1
      @LifewithDavid1  Год назад +2

      Thank you very much. Your feedback is very helpful.

  • @MordecaiV
    @MordecaiV 2 года назад +3

    "I've already told you more than I know... " I might have to use that line.

  • @namename8986
    @namename8986 2 года назад +1

    Thanks for this series David, it is really helpful and informative.

    • @LifewithDavid1
      @LifewithDavid1  2 года назад

      My pleasure! I've got another in the works. You can help by letting me know what you would like to see in the future.

  • @Ololoshize
    @Ololoshize Год назад +1

    Wow, it's so hard, I understand the global idea, but not all details, but thank you.

    • @LifewithDavid1
      @LifewithDavid1  Год назад +1

      Let it age like a fine wine and it might make more sense in a few days. I often have to sleep on an idea before I feel comfortable with it.

  • @MrAlFuture
    @MrAlFuture Год назад

    Hi David,
    I'm a bit late to the party but I'm really enjoying this series and am about to embark on porting a temperature logging project from CircuitPython to C on the Pico W.
    Incidentally, I notice the 512 element array setting code writes off the end of the array by 1 element. (512 - i when i == 0). A great example of how Python helps save us from buffer overruns and off by 1 errors and how easy it is to have an error like this creep in undetected in C.
    Anyway, thanks again for such a wonderful series of videos!

    • @LifewithDavid1
      @LifewithDavid1  Год назад +1

      Good luck on the temp logger; that's a prefect project for the Pico.
      Yeah, I'm an old Fortran and Visual Basic programmer; sometimes I forget that C has arrays with an index of 0. I'm working on another video where I'm going back and forth between MicroPython and C and it's a real struggle to keep the syntax straight (I hate that I always forget semicolons in C, LOL). Thanks for watching!

  • @b3kstudio
    @b3kstudio 2 года назад

    Amazing series! I'm not quite sure I understand why it is required to chain the control channels to the fade channels. My understanding was that we are using al2_write_addr_trigger specifically, so that it starts the fade channel and there is no need for chaining.

    • @LifewithDavid1
      @LifewithDavid1  2 года назад +2

      It can be complicated. In this case we are sending two different fade arrays (one to the A PWM channel, and one to the B PWM channel) with 2 different DMAs . Then we chain to the control DMA channel so we can change the write address of the fade DMA channel to the next PWM slice. Using alias 2 just means we don't have to also write the read address, the number of transfers, and the control data. There are a lot of terms with the same name (control and channel just to name a couple);; which can cause confusion. Hope this helps.

  • @derwoodfreen
    @derwoodfreen Год назад +1

    Brilliant series David - but when I try to run this it only fades the first two legs - help please ?

    • @LifewithDavid1
      @LifewithDavid1  Год назад

      I looked at the code. It's been over a year so I'm a little rusty. If the first 2 legs keep blinking, then the write address isn't changing; check the "led_pwm_slice_num" array. If the first two legs only blink once, then "fade_dma_chan_b" isn't chaining to "control_dma_chan_a". Hope this helps, good luck.

  • @dipalzambare9257
    @dipalzambare9257 2 года назад +2

    Hi David, I went through this whole series, hands down the most easy to understand and comprehensive information on PIO. I do need to watch Ep 8 and 9 few times to fully understand it. Have also already my Pi PICO so I can do some hands-on experiments (thanks to you for inspiration).
    Meanwhile bit curious about the closing of your videos, frankly didn't understand what you want to convey, hope you don't mind elaborating on that.

    • @LifewithDavid1
      @LifewithDavid1  2 года назад +3

      Thank you for your kind words. I hope you have success with with your experiments. Regarding the closings, if you mean the shots of scenery after my closing head shot; they are just things that caught my interest during the preceding few weeks. After all, the name of the channel is "Life with David", and I'm trying to share some of my life outside of the subject of each video. I grew up on the southern shore of Lake Erie in Ohio (with the lake in my backyard), and I love the lake. So you'll see quite a few snippets featuring my favorite spots around my home; including the lake.

    • @dipalzambare9257
      @dipalzambare9257 2 года назад +2

      @@LifewithDavid1 Yes, I was talking about the scenery. Thanks for explaining, you are right we get caught up in daily grind that forget to pay attention to other things around us (like I didn't pay attention to channel name :)).

  • @RogerTannous
    @RogerTannous 2 года назад +1

    Very nice intros and deep dives into PIO and DMA stuff!
    @12:00 Isn't it better to use the already calculated value in fade_a[i] instead of calculating (i * i) 4 times in a loop of 256 iterations ? Same issue with shifting, we can avoid shifting twice in each loop iteration.
    for (int i = 0; i < 256; i++) // why ++i ?
    {
    fade_a[i] = i * i;
    fade_a[256 - i] = fade_a[i];
    fade_b[i] = fade_a[i]

    • @LifewithDavid1
      @LifewithDavid1  2 года назад +2

      Thank you very much for watching and commenting. Your suggestions are more efficient; I kinda brute forced it while I was developing the program. I guess I've falling into the bad habits that I used to detest when I was writing programs in machine code 45 years ago. "C" is not my native language; I'm learning as I go. Thanks for the tips.

  • @GordieGii
    @GordieGii 2 года назад

    Can the up/down counter be driven by pio instead of the fractional clock divider?

    • @LifewithDavid1
      @LifewithDavid1  2 года назад

      That's a very interesting question. Although I've not tried it, you should be able to use DIVMODE in the CHX_CSR register to allow the B pin of the PWM channel to control the counter (see table 525 and figure 112 of the RP2040 datasheet). Map the PIO to output to a different GPIO and physically jumper them together (each GPIO can only have one function at a time). That should allow you to single step or start/stop the PWM counter using PIO. Good luck!

    • @GordieGii
      @GordieGii 2 года назад

      @@LifewithDavid1 Excellent! One step closer. Now all I have to do is figure out how to explicitly change the direction of the counter so I can either increment or decrement the counter on a pulse by pulse basis.
      Thanks for your help.

  • @nbj77095
    @nbj77095 2 года назад

    Looking to how to embrace this and create a 60 Hz SPWM with the PI PICO. I have it with the ATMEL328P via Ardunio IDE but they don’t have the support libraries yet for a direct comparison. Anyone interested in tutoring me! I’m and old gray haired entry level tinker…

    • @LifewithDavid1
      @LifewithDavid1  2 года назад

      Although it might only be part of the solution, my next video looks at turning the Pico into an Arbitrary Wave Generator. I imagine that you could send the sinusoidal DMA output to PWM slices instead of GPIO. Interesting project!

  • @itzhakadir1730
    @itzhakadir1730 2 года назад

    Can you please demonsrate how to make funtion generator using DMA channel and D2A converter?

    • @LifewithDavid1
      @LifewithDavid1  2 года назад

      That's a neat idea. I'll look into that. Thanks for watching!

  • @skf957
    @skf957 2 года назад

    Thank you for taking the time and trouble to research these in depth and it has to be said, pretty niche subjects. I struggle to comprehend this stuff, but am very interested nonetheless. I have a few Picos and have dabbled with PIO (cut ‘n’ paste; not my own work), and “made” (a lost weekend in the case of W.10), VS Code work on W.10 and a Rpi-3b+
    David, I have a question that I have wanted to ask for a good while now, and I think that you may be the man to answer it: Do you think (as I do) that the RP2040 is very much more feature rich than MCUs that have gone before it? And if so, why? I don’t think it can be for the home hobbyist due to aforementioned “niche-ness”. I don’t think it can be to take over the world of micro-processors due to a whole host of factors (e.g. price: cheap, clock speed etc.).
    I have been fascinated by the thinking that must lie behind the RP2040 since its launch last January. It feels like a very special and significant chip, but I can’t explain why!

    • @LifewithDavid1
      @LifewithDavid1  2 года назад +1

      Thanks for the kind words, and thanks for watching! I believe the RP2040 is a game changer. It has all the features of Arduinos; plus PIO, DMA, and a number of serial interfaces. The clock speed and significant memory allow for very powerful computing (for an MCU). The range of possible applications include robotics, engine control, IOT, test equipment, navigation equipment and many others. Arduinos are good for lower level control; but the RP2040 can be used for almost every application. It could become the ubiquitous chip for today just like the 6502 in the late 70's and 80's. And the support is great!

    • @danieljimenez1989
      @danieljimenez1989 2 года назад

      Single cycle IO at over 100 MHz is incredible, as is the programmable Io feature. I think the rp2040 is a game changer, too.
      People have even encoded TMDS signals for HDMI on the fly with this thing. I think it's quite incredible that this is done with a microcontroller, and it's even more incredible that it costs under 2 usd (1 usd in the USA from certain distributors).
      Really an awesome chip, it makes some stuff that used to be limited to FPGAs become possible on a tight budget.

    • @LifewithDavid1
      @LifewithDavid1  2 года назад

      @@danieljimenez1989 I agree, the RP2040 has IO performance of a Raspberry PI or other SBC but in a much more robust "package". Just try pulling the plug on a straight Raspberry Pi and you will corrupt the SD card two out of three times. The Pico thrives with that "abuse".

  • @user-wn4qz6ps4s
    @user-wn4qz6ps4s 2 года назад

    1) I did not immediately work, corrected as follows:
    Derived array definition from function (stack) to global space
    uint32_t fade_a[512] __attribute__((aligned(2048)));
    uint32_t fade_b[512] __attribute__((aligned(2048)));
    uint32_t pwm_set_level_locations[4] __attribute__((aligned(64)));
    void main()
    {
    ..
    }
    2) These lines are superfluous
    channel_config_set_chain_to(&control_dma_chan_a_config, fade_dma_chan_a);
    channel_config_set_chain_to(&control_dma_chan_b_config, fade_dma_chan_b);
    since the channels fade_dma_chan_a and fade_dma_chan_b are started through an entry in the al2_write_addr_trig
    3) Pins 1, 3.5, 7 do not completely turn off, pulses remain there, this is not noticeable on the LEDs, but it is visible on the oscilloscope

    • @LifewithDavid1
      @LifewithDavid1  2 года назад

      Thanks for the feedback. Next time I have the Pico attached to that breadboard, I'll check it out. I'm surprised it didn't work for you; it was stable for me. Thanks for watching!

    • @user-wn4qz6ps4s
      @user-wn4qz6ps4s 2 года назад

      @@LifewithDavid1 I inserted your code into my "big" program and either the stack size was not enough, or something else.
      This is how I fixed the non-complete shutdown of channels 1,3,5,7
      for (int i = 0; i < 256; ++i) { // i < 256
      fade_a[i] = (i * i);
      fade_a[512-i-1] = (i * i); // -1
      fade_b[i] = (i * i)

  • @jyvben1520
    @jyvben1520 2 года назад

    sadly not micropython/pio, way too complicated for me ... no interest in yet another language ...

    • @LifewithDavid1
      @LifewithDavid1  2 года назад +3

      I understand. Sadly, MicroPython does't support DMA directly. Limited DMA functionality can be obtained by writing directly to registers in MicroPython; but it's a little clunky. Thanks for watching!