Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (Cyborg)
  • No Skin
Collapse
Brand Logo

CIRCLE WITH A DOT

  1. Home
  2. Uncategorized
  3. Let's make a Pi Pico 2 powered video card.

Let's make a Pi Pico 2 powered video card.

Scheduled Pinned Locked Moved Uncategorized
retrocomputing
144 Posts 30 Posters 0 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

    We'll definitely be using an RP2350B directly instead of soldering on a Pico 2 board. But I guess it's okay to still call this a Pico.

    We basically double the number of available GPIO pins, meaning I no longer have to make compromises. Light pen? Sure. Capture every address line? You betcha. QSPI PSRAM? All day long.

    Raspberry Pi is nice enough to provide a reference KiCad project, so you can more or less copy and paste a RP2350 into your project.

    Link Preview Image
    gloriouscow@oldbytes.spaceG This user is from outside of this forum
    gloriouscow@oldbytes.spaceG This user is from outside of this forum
    gloriouscow@oldbytes.space
    wrote last edited by
    #26

    Okay, first priority - let's make our Pico OSC pin simulator.

    Raspberry Pi has a very nice Pico development plugin for Visual Studio Code. We just choose "New Rust Project," name it, and click create.

    Link Preview Image
    gloriouscow@oldbytes.spaceG 1 Reply Last reply
    0
    • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

      Okay, first priority - let's make our Pico OSC pin simulator.

      Raspberry Pi has a very nice Pico development plugin for Visual Studio Code. We just choose "New Rust Project," name it, and click create.

      Link Preview Image
      gloriouscow@oldbytes.spaceG This user is from outside of this forum
      gloriouscow@oldbytes.spaceG This user is from outside of this forum
      gloriouscow@oldbytes.space
      wrote last edited by
      #27

      This gives you an rp-hal project, and GlyphBlaster is currently written against Embassy, and I don't really feel like rewriting all the overclocking code, so I'm just going to switch this to Embassy too and copy-paste that stuff.

      I would like to thank FreddyV of PicoMEM for giving me the tips on how to stably overclock a Pico. It requires tweaking the on-board flash timings in a way I never would have figured out for myself.

      The key do doing this in Embassy is this bit:


      const PICO_SYS_CLOCK_HZ: u32 = 300_000_000;
      const FLASH_QMI_TIMING_UPDATE_THRESHOLD_HZ: u32 = 280_000_000;
      const FLASH_QMI_TIMING_HIGH_SPEED_HZ: u32 = 380_000_000;
      const OVERCLOCK_FLASH_QMI_CLKDIV: u8 = if PICO_SYS_CLOCK_HZ > FLASH_QMI_TIMING_HIGH_SPEED_HZ {
      4
      } else {
      3
      };
      const OVERCLOCK_FLASH_QMI_RXDELAY: u8 = if PICO_SYS_CLOCK_HZ > FLASH_QMI_TIMING_HIGH_SPEED_HZ {
      4
      } else {
      3
      };

      //...

      let timing = embassy_rp::pac::QMI.mem(0).timing();
      timing.modify(|w| {
      w.set_clkdiv(OVERCLOCK_FLASH_QMI_CLKDIV);
      w.set_rxdelay(OVERCLOCK_FLASH_QMI_RXDELAY);
      });
      gloriouscow@oldbytes.spaceG 1 Reply Last reply
      0
      • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

        @Kroc Oh, believe me, I know all those guys (hi @polpo) and they've been a huge help already in making GlyphBlaster so far.

        kroc@oldbytes.spaceK This user is from outside of this forum
        kroc@oldbytes.spaceK This user is from outside of this forum
        kroc@oldbytes.space
        wrote last edited by
        #28

        @gloriouscow With your graphics card, all that's needed is an Pico 8086 emulator and you've got an "Oops, all Pico!" IBM PC 😛

        gloriouscow@oldbytes.spaceG 1 Reply Last reply
        0
        • kroc@oldbytes.spaceK kroc@oldbytes.space

          @gloriouscow With your graphics card, all that's needed is an Pico 8086 emulator and you've got an "Oops, all Pico!" IBM PC 😛

          gloriouscow@oldbytes.spaceG This user is from outside of this forum
          gloriouscow@oldbytes.spaceG This user is from outside of this forum
          gloriouscow@oldbytes.space
          wrote last edited by
          #29

          @Kroc Don't give me more ideas

          gloriouscow@oldbytes.spaceG 1 Reply Last reply
          0
          • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

            @Kroc Don't give me more ideas

            gloriouscow@oldbytes.spaceG This user is from outside of this forum
            gloriouscow@oldbytes.spaceG This user is from outside of this forum
            gloriouscow@oldbytes.space
            wrote last edited by
            #30

            @Kroc There's already a Teensy 8088 emulator so i'm sure its possible

            1 Reply Last reply
            0
            • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

              This gives you an rp-hal project, and GlyphBlaster is currently written against Embassy, and I don't really feel like rewriting all the overclocking code, so I'm just going to switch this to Embassy too and copy-paste that stuff.

              I would like to thank FreddyV of PicoMEM for giving me the tips on how to stably overclock a Pico. It requires tweaking the on-board flash timings in a way I never would have figured out for myself.

              The key do doing this in Embassy is this bit:


              const PICO_SYS_CLOCK_HZ: u32 = 300_000_000;
              const FLASH_QMI_TIMING_UPDATE_THRESHOLD_HZ: u32 = 280_000_000;
              const FLASH_QMI_TIMING_HIGH_SPEED_HZ: u32 = 380_000_000;
              const OVERCLOCK_FLASH_QMI_CLKDIV: u8 = if PICO_SYS_CLOCK_HZ > FLASH_QMI_TIMING_HIGH_SPEED_HZ {
              4
              } else {
              3
              };
              const OVERCLOCK_FLASH_QMI_RXDELAY: u8 = if PICO_SYS_CLOCK_HZ > FLASH_QMI_TIMING_HIGH_SPEED_HZ {
              4
              } else {
              3
              };

              //...

              let timing = embassy_rp::pac::QMI.mem(0).timing();
              timing.modify(|w| {
              w.set_clkdiv(OVERCLOCK_FLASH_QMI_CLKDIV);
              w.set_rxdelay(OVERCLOCK_FLASH_QMI_RXDELAY);
              });
              gloriouscow@oldbytes.spaceG This user is from outside of this forum
              gloriouscow@oldbytes.spaceG This user is from outside of this forum
              gloriouscow@oldbytes.space
              wrote last edited by
              #31

              I'll use GPIO16 for this which conveniently puts it on the top right corner of the Pico 2 board.

              Our PIO program is stupid simple:

                  let clock_program = pio_asm!(
              ".wrap_target",
              "set pins, 1 [10]",
              "set pins, 0 [10]",
              ".wrap"
              );

              .wrap_target is just a standard label for the PIO loop, which will be restarted at the end with .wrap. The value in brackets is how many cycles to spin - the set itself takes one cycle, then we spin for 10 after. This should give us the 11 cycles on, 11 cycles off behavior we want.

              'pins' here just targets GPIO16, via this:

              let clock_pin = pio1.common.make_pio_pin(p.PIN_16);
              clock_sm_config.set_set_pins(&[&clock_pin]);
              gloriouscow@oldbytes.spaceG ldcd@social.treehouse.systemsL 2 Replies Last reply
              0
              • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                I'll use GPIO16 for this which conveniently puts it on the top right corner of the Pico 2 board.

                Our PIO program is stupid simple:

                    let clock_program = pio_asm!(
                ".wrap_target",
                "set pins, 1 [10]",
                "set pins, 0 [10]",
                ".wrap"
                );

                .wrap_target is just a standard label for the PIO loop, which will be restarted at the end with .wrap. The value in brackets is how many cycles to spin - the set itself takes one cycle, then we spin for 10 after. This should give us the 11 cycles on, 11 cycles off behavior we want.

                'pins' here just targets GPIO16, via this:

                let clock_pin = pio1.common.make_pio_pin(p.PIN_16);
                clock_sm_config.set_set_pins(&[&clock_pin]);
                gloriouscow@oldbytes.spaceG This user is from outside of this forum
                gloriouscow@oldbytes.spaceG This user is from outside of this forum
                gloriouscow@oldbytes.space
                wrote last edited by
                #32

                PIO is the secret sauce that makes Picos so good at interfacing with retro hardware. They allow you to react to pin changes instantly, and read and write busses, doing the sort of high speed bus interactions that were normally the exclusive purview of FPGAs.

                gloriouscow@oldbytes.spaceG 1 Reply Last reply
                0
                • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                  PIO is the secret sauce that makes Picos so good at interfacing with retro hardware. They allow you to react to pin changes instantly, and read and write busses, doing the sort of high speed bus interactions that were normally the exclusive purview of FPGAs.

                  gloriouscow@oldbytes.spaceG This user is from outside of this forum
                  gloriouscow@oldbytes.spaceG This user is from outside of this forum
                  gloriouscow@oldbytes.space
                  wrote last edited by
                  #33

                  All in all, not too shabby for a $5 board. Let's see how our clock looks, right after I unbag this and hook it up.

                  Link Preview Image
                  gloriouscow@oldbytes.spaceG 1 Reply Last reply
                  0
                  • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                    All in all, not too shabby for a $5 board. Let's see how our clock looks, right after I unbag this and hook it up.

                    Link Preview Image
                    gloriouscow@oldbytes.spaceG This user is from outside of this forum
                    gloriouscow@oldbytes.spaceG This user is from outside of this forum
                    gloriouscow@oldbytes.space
                    wrote last edited by
                    #34

                    14.318MHz, baby.

                    Believe it or not, a sawtooth clock isn't that hideous. This is pretty much what the OSC pin looks like for realsies.

                    Link Preview Image
                    casandro@f-ckendehoelle.deC gloriouscow@oldbytes.spaceG 2 Replies Last reply
                    0
                    • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                      14.318MHz, baby.

                      Believe it or not, a sawtooth clock isn't that hideous. This is pretty much what the OSC pin looks like for realsies.

                      Link Preview Image
                      casandro@f-ckendehoelle.deC This user is from outside of this forum
                      casandro@f-ckendehoelle.deC This user is from outside of this forum
                      casandro@f-ckendehoelle.de
                      wrote last edited by
                      #35

                      @gloriouscow Could that be a probe issue? Not all probes go up that high in frequency.

                      gloriouscow@oldbytes.spaceG 1 Reply Last reply
                      0
                      • casandro@f-ckendehoelle.deC casandro@f-ckendehoelle.de

                        @gloriouscow Could that be a probe issue? Not all probes go up that high in frequency.

                        gloriouscow@oldbytes.spaceG This user is from outside of this forum
                        gloriouscow@oldbytes.spaceG This user is from outside of this forum
                        gloriouscow@oldbytes.space
                        wrote last edited by
                        #36

                        @casandro Nah, I've gotten a clean read from a 66MHz crystal on this probe from a 386 motherboard. This is probably a limitation of the Pico's GPIO drive strength. I'm not sure if that's something you can configure on a Pico, you can on an STM32, although I usually don't as it can produce overshoots which ends up being worse to deal with.

                        gloriouscow@oldbytes.spaceG 1 Reply Last reply
                        0
                        • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                          @casandro Nah, I've gotten a clean read from a 66MHz crystal on this probe from a 386 motherboard. This is probably a limitation of the Pico's GPIO drive strength. I'm not sure if that's something you can configure on a Pico, you can on an STM32, although I usually don't as it can produce overshoots which ends up being worse to deal with.

                          gloriouscow@oldbytes.spaceG This user is from outside of this forum
                          gloriouscow@oldbytes.spaceG This user is from outside of this forum
                          gloriouscow@oldbytes.space
                          wrote last edited by
                          #37

                          @casandro The real CGA also cleans up the OSC pin by immediately passing it through an 74LS04 which we will probably also do.

                          1 Reply Last reply
                          0
                          • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                            I'll use GPIO16 for this which conveniently puts it on the top right corner of the Pico 2 board.

                            Our PIO program is stupid simple:

                                let clock_program = pio_asm!(
                            ".wrap_target",
                            "set pins, 1 [10]",
                            "set pins, 0 [10]",
                            ".wrap"
                            );

                            .wrap_target is just a standard label for the PIO loop, which will be restarted at the end with .wrap. The value in brackets is how many cycles to spin - the set itself takes one cycle, then we spin for 10 after. This should give us the 11 cycles on, 11 cycles off behavior we want.

                            'pins' here just targets GPIO16, via this:

                            let clock_pin = pio1.common.make_pio_pin(p.PIN_16);
                            clock_sm_config.set_set_pins(&[&clock_pin]);
                            ldcd@social.treehouse.systemsL This user is from outside of this forum
                            ldcd@social.treehouse.systemsL This user is from outside of this forum
                            ldcd@social.treehouse.systems
                            wrote last edited by
                            #38

                            @gloriouscow the 2350 also has an extremely flexible clock tree for micro; each off the gpouts has an individual int/frac divider with duty cycle correction and coarse phase adjustment

                            The PLL can also run up to 1600MHz (don't think any of the IO buffers can manage that though) and you can input an external clock to it (I think this is what you're doing)

                            gloriouscow@oldbytes.spaceG 1 Reply Last reply
                            0
                            • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                              14.318MHz, baby.

                              Believe it or not, a sawtooth clock isn't that hideous. This is pretty much what the OSC pin looks like for realsies.

                              Link Preview Image
                              gloriouscow@oldbytes.spaceG This user is from outside of this forum
                              gloriouscow@oldbytes.spaceG This user is from outside of this forum
                              gloriouscow@oldbytes.space
                              wrote last edited by
                              #39

                              It's actually kind of silly how close we already are to outputting something on a real CGA monitor.

                              We could drive two additional PIO state machines with divisors to control HSYNC and VSYNC.

                              Now, if you just output color all the time, you have no idea whether your picture is actually synchronized - the monitor will just keep the beam on all the time, so if you just say, emit magenta forever, you'll just see a solid magenta screen even if the monitor has no vertical hold.

                              gloriouscow@oldbytes.spaceG 1 Reply Last reply
                              0
                              • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                                It's actually kind of silly how close we already are to outputting something on a real CGA monitor.

                                We could drive two additional PIO state machines with divisors to control HSYNC and VSYNC.

                                Now, if you just output color all the time, you have no idea whether your picture is actually synchronized - the monitor will just keep the beam on all the time, so if you just say, emit magenta forever, you'll just see a solid magenta screen even if the monitor has no vertical hold.

                                gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                gloriouscow@oldbytes.space
                                wrote last edited by
                                #40

                                So we're going to have a color latch like the CGA does.

                                This is a 74LS174 flip-flop, that is fed our generated colors and is clocked by /OSC.

                                The CGA doesn't use the 174's clear input, but we can - another GPIO output of the Pico should be able to pull that low to blank the screen, I think. Having a vertical blanking area will let us tell if we have vertical hold.

                                gloriouscow@oldbytes.spaceG 1 Reply Last reply
                                0
                                • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                                  So we're going to have a color latch like the CGA does.

                                  This is a 74LS174 flip-flop, that is fed our generated colors and is clocked by /OSC.

                                  The CGA doesn't use the 174's clear input, but we can - another GPIO output of the Pico should be able to pull that low to blank the screen, I think. Having a vertical blanking area will let us tell if we have vertical hold.

                                  gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                  gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                  gloriouscow@oldbytes.space
                                  wrote last edited by
                                  #41

                                  I can't overstate how useful it is to have a working digital simulation of the thing you are intending to make.

                                  gloriouscow@oldbytes.spaceG 1 Reply Last reply
                                  0
                                  • ldcd@social.treehouse.systemsL ldcd@social.treehouse.systems

                                    @gloriouscow the 2350 also has an extremely flexible clock tree for micro; each off the gpouts has an individual int/frac divider with duty cycle correction and coarse phase adjustment

                                    The PLL can also run up to 1600MHz (don't think any of the IO buffers can manage that though) and you can input an external clock to it (I think this is what you're doing)

                                    gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                    gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                    gloriouscow@oldbytes.space
                                    wrote last edited by
                                    #42

                                    @ldcd The plan is to drive the ISA board version off OSC, yeah. Can you give a Pico 2 board an external oscillator?

                                    ldcd@social.treehouse.systemsL 1 Reply Last reply
                                    0
                                    • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                                      @ldcd The plan is to drive the ISA board version off OSC, yeah. Can you give a Pico 2 board an external oscillator?

                                      ldcd@social.treehouse.systemsL This user is from outside of this forum
                                      ldcd@social.treehouse.systemsL This user is from outside of this forum
                                      ldcd@social.treehouse.systems
                                      wrote last edited by
                                      #43

                                      @gloriouscow you can clock the system off of GPIN yes, although I don't think you can clock the PLLs off of it.

                                      (So like if you had an NTSC freq input you could clock a PIO SM off of it or the CPU off of it but you couldn't generate a multiple of it with the PLL unless you remove the crystal and solder a lead to one of the pads)

                                      ldcd@social.treehouse.systemsL 1 Reply Last reply
                                      0
                                      • gloriouscow@oldbytes.spaceG gloriouscow@oldbytes.space

                                        I can't overstate how useful it is to have a working digital simulation of the thing you are intending to make.

                                        gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                        gloriouscow@oldbytes.spaceG This user is from outside of this forum
                                        gloriouscow@oldbytes.space
                                        wrote last edited by
                                        #44

                                        Time to start breadboarding!

                                        Link Preview Image
                                        gloriouscow@oldbytes.spaceG 1 Reply Last reply
                                        0
                                        • ldcd@social.treehouse.systemsL ldcd@social.treehouse.systems

                                          @gloriouscow you can clock the system off of GPIN yes, although I don't think you can clock the PLLs off of it.

                                          (So like if you had an NTSC freq input you could clock a PIO SM off of it or the CPU off of it but you couldn't generate a multiple of it with the PLL unless you remove the crystal and solder a lead to one of the pads)

                                          ldcd@social.treehouse.systemsL This user is from outside of this forum
                                          ldcd@social.treehouse.systemsL This user is from outside of this forum
                                          ldcd@social.treehouse.systems
                                          wrote last edited by
                                          #45

                                          @gloriouscow I wish you could clock them off of gpclk0/1 but that would have probably been a pain to route

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups