User avatar
nick.mccloud
Posts: 1280
Joined: Sat Feb 04, 2012 4:18 pm

VGA board arrived

Tue Feb 16, 2021 1:38 pm

Just one thing, I need to find a monitor with VGA ...
VGAboard.jpeg
VGAboard.jpeg (199.07 KiB) Viewed 2777 times
Pico/RP2040 ≠ Arduino
Pico = hot rod kit car, Arduino = hot rod kit car wrapped in cotton wool with buoyancy aids & parachute

User avatar
nick.mccloud
Posts: 1280
Joined: Sat Feb 04, 2012 4:18 pm

Re: VGA board arrived

Tue Feb 16, 2021 1:39 pm

Need to debug the PWM - the DAC example works fine but no noise out the PWM which is odd as I've PicoBot playing tunes on PWM. Not tried anything else yet.
Pico/RP2040 ≠ Arduino
Pico = hot rod kit car, Arduino = hot rod kit car wrapped in cotton wool with buoyancy aids & parachute

lars_the_bear
Posts: 229
Joined: Thu Jan 28, 2021 8:13 pm
Contact: Website

Re: VGA board arrived

Tue Feb 16, 2021 2:06 pm

I have a VGA monitor. I was going to throw it in the dumpster, but maybe...

Kevin.

bobtrex
Posts: 27
Joined: Mon Jan 25, 2021 6:24 pm

Re: VGA board arrived

Wed Feb 17, 2021 1:55 pm

Hi all

I would be interested on what examples have been proved to work.
So far I have tried all the VGA examples and get no VGA output eg;
demo1, sprite_demo, textmode etc.

My VGA setup is tested with a Porpeller board with VGA so is know to work.

I can get two of the auio examples to work;
USB sound card - PC recognises pico as usb sound card and i get Extreamly low quality audio out of PWM jack, nothing on the DAC jack.
Sine_wave_i2c - Get a low quality sinewave out of the PWM jack nothing on the DAC jack again.
Sine_wave_PWN - no sound

User avatar
aallan
Raspberry Pi Trading Employee & Forum Moderator
Raspberry Pi Trading Employee & Forum Moderator
Posts: 207
Joined: Mon Feb 09, 2015 11:30 am
Location: Exeter, UK
Contact: Website Twitter

Re: VGA board arrived

Wed Feb 17, 2021 2:22 pm

Just a reminder for folks playing with the VGA Board. If you're building code for the VGA Board remember to pass -DPICO_BOARD=vgaboard to CMake. The default pin settings, which are for Pico, aren't going to be correct. See https://github.com/raspberrypi/pico-playground/issues/9. If you have everything connected up and you're not seeing any VGA output, this is probably the problem.
Technical Documentation Manager
Raspberry Pi (Trading) Limited
About me, http://alasdairallan.com

User avatar
nick.mccloud
Posts: 1280
Joined: Sat Feb 04, 2012 4:18 pm

Re: VGA board arrived

Wed Feb 17, 2021 2:32 pm

Reminder?

Cough cough.

Cheers, I'll give it a try with that
Pico/RP2040 ≠ Arduino
Pico = hot rod kit car, Arduino = hot rod kit car wrapped in cotton wool with buoyancy aids & parachute

bobtrex
Posts: 27
Joined: Mon Jan 25, 2021 6:24 pm

Re: VGA board arrived

Wed Feb 17, 2021 2:58 pm

Ah, thats it. Thanks alan.
VGA samples now working and getting proper sound out of the DAC. I must spend some more time to understand CMAKE.

Thanks.

User avatar
nick.mccloud
Posts: 1280
Joined: Sat Feb 04, 2012 4:18 pm

Re: VGA board arrived

Wed Feb 17, 2021 4:32 pm

Good sticky on the Other Boards - found a VGA monitor so can have another play with things later on.
Pico/RP2040 ≠ Arduino
Pico = hot rod kit car, Arduino = hot rod kit car wrapped in cotton wool with buoyancy aids & parachute

User avatar
aallan
Raspberry Pi Trading Employee & Forum Moderator
Raspberry Pi Trading Employee & Forum Moderator
Posts: 207
Joined: Mon Feb 09, 2015 11:30 am
Location: Exeter, UK
Contact: Website Twitter

Re: VGA board arrived

Wed Feb 17, 2021 5:18 pm

nick.mccloud wrote:
Wed Feb 17, 2021 4:32 pm
Good sticky on the Other Boards - found a VGA monitor so can have another play with things later on.
I figured it was a good place to leave a note about it. :)
Technical Documentation Manager
Raspberry Pi (Trading) Limited
About me, http://alasdairallan.com

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Wed Feb 24, 2021 12:05 am

My Pimoroni board arrived as well, 15£ + 3.80£ tax + 5£ shipping to Germany:
https://shop.pimoroni.com/products/pimo ... -demo-base

As described on product page, I did "git pull" in pico/pico-extras and pico/pico-playgound.
Then created build directory in pico/pico-playground, CDed into, "cmake -D"PICO_BOARD=vgaboard" .." and make.

First tested with headphones audio/sine_wave pwm and i2s demos.

Then first VGA demo scanvideo/mandelbrot, 16MP photo:
https://stamm-wilbrandt.de/en/forum/20210224_004357.jpg
15% photo to meet attachment size restriction:
20210224_004357.15%.jpg
20210224_004357.15%.jpg
20210224_004357.15%.jpg (43.28 KiB) Viewed 2386 times

Everything just worked, basically because Pimoroni board is for VGA just what is described in Appendix D / page 267 of the C/C++ SDK documentation. There are three buttons as well, as well as pwm and dac audio out, and an SD card reader, and USB for powering the board (that is pure powering, no USB access to the Pico, but USB cable can be plugged into Pico for that).

I did solder 2x20 male headers under my 2nd Pico, and with simplified test program was able to verify that all 26 GP pins work fine:
viewtopic.php?f=144&t=304849&p=1825606#p1825606


I did play with VGA in 2016, with 84MHz 96KB ram Arduino Due.
Color resolution was too low, but 1024x675 monochrome did fit into ram:
https://forum.arduino.cc/index.php?topi ... msg2575055
Image
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Wed Feb 24, 2021 12:38 am

Maximal overclocking that worked for me was 250MHz at 1.3V:

Code: Select all

+#include "hardware/vreg.h"
+
 CU_REGISTER_DEBUG_PINS(generation)
 
 #define vga_mode vga_mode_320x240_60
@@ -254,6 +256,8 @@ int main(void) {
     set_sys_clock_khz(base_freq * 3, true);
 #endif
 #endif
+    vreg_set_voltage(VREG_VOLTAGE_1_30);
+    set_sys_clock_khz(250000, true);
     // Re init uart now that clk_peri has changed

I uploaded smartphone video to youtube:
https://www.youtube.com/watch?v=LcZ3Sm6yFlc

Before 15 full screen drawings did take 25 seconds, overclocked with 250MHz 19 seconds.


Flashing code with that board is easy.
I used my "flash" tool:
https://gist.github.com/Hermann-SW/ca07 ... 6d81de01a7

Code: Select all

pi@raspberrypi400:~/pico/pico-playground/build $ flash scanvideo/mandelbrot/mandelbrot.uf2 
/home/pi/.local/bin/flash: line 2: /dev/ttyACM0: Permission denied
waiting

Then I pressed bootsel switch on Pico, and then the Run switch on Pimoroni board.
Then board reboots into flash mode and flashing automatically continues:

Code: Select all

copying
done
pi@raspberrypi400:~/pico/pico-playground/build $
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Wed Feb 24, 2021 12:49 am

Code: Select all

pi@raspberrypi400:~/pico/pico-playground/build $ flash scanvideo//textmode/textmode.uf2 
/home/pi/.local/bin/flash: line 2: /dev/ttyACM0: Permission denied
waiting
copying
done
pi@raspberrypi400:~/pico/pico-playground/build $

'm' is U+6d, ' ' is U+20:
78 characters width, 31.5 rows
20210224_014518.15%.jpg
20210224_014518.15%.jpg
20210224_014518.15%.jpg (112.88 KiB) Viewed 2329 times
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Wed Feb 24, 2021 12:53 am

Code: Select all

pi@raspberrypi400:~/pico/pico-playground/build $ flash scanvideo/demo1/demo1.uf2 
/home/pi/.local/bin/flash: line 2: /dev/ttyACM0: Permission denied
waiting
copying
done
pi@raspberrypi400:~/pico/pico-playground/build $ 

Bouncing raspberry is nice:

Code: Select all

../scanvideo/demo1/demo1.c:#define vga_mode vga_mode_640x480_60
20210224_015223.15%.jpg
20210224_015223.15%.jpg
20210224_015223.15%.jpg (28.4 KiB) Viewed 2322 times

P.S:
The only of the 9 demos that did not work on my monitor (just black screen) was "sprite_demo":

Code: Select all

pi@raspberrypi400:~/pico/pico-playground/build $ ls -l scanvideo/*/*.uf2 | wc --lines
9
pi@raspberrypi400:~/pico/pico-playground/build $ 
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Wed Feb 24, 2021 1:27 pm

I played with sine_wave_pwm again, after seeing USB keyboard processing in its code:
https://github.com/raspberrypi/pico-pla ... ave.c#L110

I realized that (by mistake) the demo was not enabled for USB.
I added this line to "pico-playground/audio/sine_wave/CMakeLists.txt":

Code: Select all

     # create map/bin/hex file etc.
+    pico_enable_stdio_usb(sine_wave_pwm 1)
     pico_add_extra_outputs(sine_wave_pwm)
After compiling and flashing, demo worked fine.
Small loudspeaker is plugged into VGA board PWM jack.
In the recorded video you can hear the sound effects triggered by keyboard.
And you can see the current state in miniterm:
https://www.youtube.com/watch?v=ThmTOEw ... e=youtu.be
sine_wave_pwm.jpg
sine_wave_pwm.jpg
sine_wave_pwm.jpg (77.25 KiB) Viewed 2210 times
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Thu Feb 25, 2021 2:47 pm

I flashed pico-playground/build/scanvideo/flash_stream and saw junk on VGA display, that changes every few seconds. Next I found in directory pico/pico-playground/scanvideo/flash_stream/img there are three images, and tool pack.sh to create pack.uf2 that will upload the three images to flash address 0x1003c000. That should make the Pico slideshow work. But last command of pack.sh is "uf2conv", and that is not available anywhere on ~/pico:
viewtopic.php?f=145&t=305314


I found workaround in using this command to do what is needed:

Code: Select all

sudo picotool load pack.bin -o 1003c000

The photo to display changes every 300 frames according code, and with 640x480@60fps that is every 5 seconds.
I uploaded smartphone video of VGA monitor:
https://www.youtube.com/watch?v=x6kS9Cn ... e=youtu.be


Nice, Pico slideshow from .png files stored packed on Pico flash:

Code: Select all

pi@raspberrypi400:~/pico/pico-playground/scanvideo/flash_stream/img $ file *.png
Lighthouse_at_sunrise_by_Frenchie_Smalls.png: PNG image data, 640 x 480, 8-bit/color RGB, non-interlaced
Stone_Mountain_by_Brad_Huchteman.png:         PNG image data, 640 x 480, 8-bit/color RGBA, non-interlaced
Voss_by_fortuneblues.png:                     PNG image data, 640 x 480, 8-bit/color RGBA, non-interlaced
pi@raspberrypi400:~/pico/pico-playground/scanvideo/flash_stream/img $ 

Here you can see animation scaled to 25%, with correct 0.2fps change rate:
x.anim.gif
x.anim.gif
x.anim.gif (234.92 KiB) Viewed 2122 times
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Thu Feb 25, 2021 9:04 pm

flash_stream demo does slideshow of three 640x480 8bit .png photos.
That pretty much fills Pico flash, RGB555 pixels are stored in uint16_t, so three frames have size 3*2* 640x480=1,843,200 bytes.

I did take photo of trumpet of my younger son, and wanted to show fingering chart of 7 images.
7 images can take up to 205 rows with same amount of space as the three full frames.

I did cut out 200 rows, and with the help of gimp have all 7 images from trumpet fingering chart:
Image


I converted them to pack.bin as described here:
viewtopic.php?f=145&t=305314#p1826625

Finally bzip2 allows to attach here because size became less than 250KB:
pack.bin.bz2
pack.bin.bz2
(234.11 KiB) Downloaded 19 times

You can bunzip2 the downloaded attachment and store on your flash:

Code: Select all

sudo picotool load pack.bin -o 1003c000



You can even flash unmodified flash_stream demo, and it will show you three screens with more than two trumpets on each.
But you will get nicer slideshow of 7 frames if you flash modified "flash_stream.uf2" showing 640x200 frames centered:
flash_stream.zip
flash_stream.zip
(15.87 KiB) Downloaded 14 times

This is the whole diff, allowing for centered slideshow of photos of FLASH_IMAGE_HEIGHT height.
I just filled the rows outside of center part with color "brass".
This is precursor of pico "trumpet" demo utilizing sound, VGA and the three demo board buttons A+B+C.
flash_stream.diff.jpg
flash_stream.diff.jpg
flash_stream.diff.jpg (178.29 KiB) Viewed 2071 times

Again I did record smartphone video, because of "#define FRAMES_PER_IMAGE 60" this time with 1fps:
https://www.youtube.com/watch?v=Z067san ... e=youtu.be
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Thu Feb 25, 2021 10:55 pm

"Hardware design with RP2040" has section "3.2.2. User buttons":
https://datasheets.raspberrypi.org/rp20 ... df#page=20
The user buttons are not strictly part of the VGA, but because we’ve decided to add them (SW2, SW3 and SW4, see
Figure 19), connecting them to the LSBs of the Red, Green and Blue channels, it’s important to talk about them, and on
their use in the software. We thought it was important to add a few buttons to this design, especially as VGA, SD Card
and audio gives us a lot of potential applications that could use a button or two (e.g. video or music controls, etc). As
we’ve already said, pins are at a premium, and we couldn’t afford to dedicate a pin or two to something as frivolous as
buttons, so we’ve come up with the idea of making the VGA LSBs multi-purpose, with a simple hack.
The basic idea is that the GPIO in question is used for VGA as usual during the active periods of video data, but during
the video blanking periods, when the DAC levels are not as critical, we can flip the GPIO direction to an input, and then
poll it, before flipping it back to an output for the next active video period.
20210226_000020.10%.jpg
20210226_000020.10%.jpg
20210226_000020.10%.jpg (31.03 KiB) Viewed 2024 times

I wrote minimal button demo, just copy over pico/pico-playground/scanvideo/flash_stream/flash_stream.c and build.
Top third of display is red, middle third is green and bottom third is blue.
If you press Pimoroni VGA board buttons A/B/C, then top/middle/bottom third gets black.

Code: Select all

/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>

#include "pico.h"
#include "pico/scanvideo.h"
#include "pico/scanvideo/composable_scanline.h"
#include "pico/sync.h"
#include "pico/stdlib.h"

#include "hardware/structs/dma.h"
#include "hardware/structs/ssi.h"

#define VGA_MODE vga_mode_640x480_60
extern const struct scanvideo_pio_program video_24mhz_composable;

static void frame_update_logic();
static void render_scanline(struct scanvideo_scanline_buffer *dest);

int r=0,g=0,b=0;

int __time_critical_func(render_loop)() {
    static uint32_t last_frame_num = 0;
    while (true) {
        struct scanvideo_scanline_buffer *scanline_buffer = scanvideo_begin_scanline_generation(true);
        uint32_t frame_num = scanvideo_frame_number(scanline_buffer->scanline_id);
        if (frame_num != last_frame_num) {
            last_frame_num = frame_num;
            frame_update_logic();
        }
        render_scanline(scanline_buffer);
        scanvideo_end_scanline_generation(scanline_buffer);

        gpio_init( 0); gpio_set_dir( 0, GPIO_IN); r = !gpio_get( 0) *(0xFF>>3);
        gpio_init( 6); gpio_set_dir( 6, GPIO_IN); g = !gpio_get( 6) *(0xFF>>3);
        gpio_init(11); gpio_set_dir(11, GPIO_IN); b = !gpio_get(11) *(0xFF>>3);
    }
}

int vga_main(void) {
    scanvideo_setup(&VGA_MODE);
    scanvideo_timing_enable(true);
    render_loop();
    return 0;
}

void __time_critical_func(frame_update_logic)() {
    static uint slideshow_ctr = 0;
    static uint image_index = 0;
    if (++slideshow_ctr >= 3) {
        slideshow_ctr = 0;
        image_index = (image_index + 1) % 11;
    }
}

static inline uint16_t *raw_scanline_prepare(struct scanvideo_scanline_buffer *dest, uint width) {
    assert(width >= 3);
    assert(width % 2 == 0);
    // +1 for the black pixel at the end, -3 because the program outputs n+3 pixels.
    dest->data[0] = COMPOSABLE_RAW_RUN | (width + 1 - 3 << 16);
    // After user pixels, 1 black pixel then discard remaining FIFO data
    dest->data[width / 2 + 2] = 0x0000u | (COMPOSABLE_EOL_ALIGN << 16);
    dest->data_used = width / 2 + 2;
    assert(dest->data_used <= dest->data_max);
    return (uint16_t *) &dest->data[1];
}

static inline void raw_scanline_finish(struct scanvideo_scanline_buffer *dest) {
    // Need to pivot the first pixel with the count so that PIO can keep up
    // with its 1 pixel per 2 clocks
    uint32_t first = dest->data[0];
    uint32_t second = dest->data[1];
    dest->data[0] = (first & 0x0000ffffu) | ((second & 0x0000ffffu) << 16);
    dest->data[1] = (second & 0xffff0000u) | ((first & 0xffff0000u) >> 16);
    dest->status = SCANLINE_OK;
}

void __time_critical_func(render_scanline)(struct scanvideo_scanline_buffer *dest) {
    int l = scanvideo_scanline_number(dest->scanline_id);
    uint16_t *colour_buf = raw_scanline_prepare(dest, VGA_MODE.width);
    // Just use a random DMA channel which hopefully nobody minds us borrowing
    // "It's easier to seek forgiveness than permission, unless you hardfault"

#define LINE_FROM_RGB5(R, G, B)                                           \
  for(int i=0; i<VGA_MODE.width; ++i)                                     \
    ((uint16_t*)dest->data)[2+i] = PICO_SCANVIDEO_PIXEL_FROM_RGB5(R,G,B);

    int thrd = VGA_MODE.height / 3;
         if (l <     thrd)  LINE_FROM_RGB5(r,0,0)
    else if (l < 2 * thrd)  LINE_FROM_RGB5(0,g,0)
    else                    LINE_FROM_RGB5(0,0,b)

    raw_scanline_finish(dest);
}

int main(void) {
    set_sys_clock_khz(200000, true);
    setup_default_uart();

#ifdef PICO_SMPS_MODE_PIN
    gpio_init(PICO_SMPS_MODE_PIN);
    gpio_set_dir(PICO_SMPS_MODE_PIN, GPIO_OUT);
    gpio_put(PICO_SMPS_MODE_PIN, 1);
#endif

    return vga_main();
}

The basic idea is that the GPIO in question is used for VGA as usual during the active periods of video data, but during
the video blanking periods, when the DAC levels are not as critical, we can flip the GPIO direction to an input, and then
poll it

Code: Select all

    while (true) {
        struct scanvideo_scanline_buffer *scanline_buffer = scanvideo_begin_scanline_generation(true);
...
        scanvideo_end_scanline_generation(scanline_buffer);

        gpio_init( 0); gpio_set_dir( 0, GPIO_IN); r = !gpio_get( 0) *(0xFF>>3);
        gpio_init( 6); gpio_set_dir( 6, GPIO_IN); g = !gpio_get( 6) *(0xFF>>3);
        gpio_init(11); gpio_set_dir(11, GPIO_IN); b = !gpio_get(11) *(0xFF>>3);
    }

This is simple color output

Code: Select all

#define LINE_FROM_RGB5(R, G, B)                                           \
  for(int i=0; i<VGA_MODE.width; ++i)                                     \
    ((uint16_t*)dest->data)[2+i] = PICO_SCANVIDEO_PIXEL_FROM_RGB5(R,G,B);

    int thrd = VGA_MODE.height / 3;
         if (l <     thrd)  LINE_FROM_RGB5(r,0,0)
    else if (l < 2 * thrd)  LINE_FROM_RGB5(0,g,0)
    else                    LINE_FROM_RGB5(0,0,b)

    raw_scanline_finish(dest);

This is monitor with button C pressed (blue switched to black):
20210225_235227.15%.jpg
20210225_235227.15%.jpg
20210225_235227.15%.jpg (26.65 KiB) Viewed 2028 times
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Sat Feb 27, 2021 5:49 pm

I modified code compared to original flash_stream.c in painting bottom half blue.
Lines start with horizontal position changed every other row:

Code: Select all

 void __time_critical_func(render_scanline)(struct scanvideo_scanline_buffer *d
est) {
     int l = scanvideo_scanline_number(dest->scanline_id);
     uint16_t *colour_buf = raw_scanline_prepare(dest, VGA_MODE.width);
+
+    if (l>240)
+    {
+#define LINE_FROM_RGB5(R, G, B)                                           \
+  for(int i=0; i<VGA_MODE.width; ++i)                                     \
+    ((uint16_t*)dest->data)[1+(l%2)+i] = PICO_SCANVIDEO_PIXEL_FROM_RGB5(R,G,B);
+
+         LINE_FROM_RGB5(0,0,0x1F)
+         return;
+    }
+
     // Just use a random DMA channel which hopefully nobody minds us borrowing

Blue line is 640 pixels long, left and right side prove that display width is really 641 pixels:
vga_mode_640x480_60.641pixels.png
vga_mode_640x480_60.641pixels.png
vga_mode_640x480_60.641pixels.png (210 KiB) Viewed 1948 times
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

hippy
Posts: 10554
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: VGA board arrived

Sat Feb 27, 2021 8:22 pm

Has anyone tried multiple VGA yet ?

I was thinking, with 26 pins exposed on a Pico, that's conveniently 8 x 3-bit/8-colour RGB with 2 pins left for VS and HS which I would guess need to be hardware buffered. Maybe all pins to limit current draw on the RP2040 pins.

Limited colours but could be suitable for some information display and simple signage. The big issue is frame buffering but 128KB as a single, shared, 32-bit wide frame buffer, can support 160x120 4:3 or 200x120 16:9 which might be good enough and there's possibly better to be had.

DarkElvenAngel
Posts: 1875
Joined: Tue Mar 20, 2018 9:53 pm

Re: VGA board arrived

Sat Feb 27, 2021 10:12 pm

You could do gray-scale and have multi VGA out, however to what end? Looking at my old propeller set up I have 2 bit per colour so it take 8 pins to a VGA signal so you could have 3 VGA outs. I've got a VGA board on the way so I can't wait to get into this Pico.

hippy
Posts: 10554
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: VGA board arrived

Sun Feb 28, 2021 1:13 am

DarkElvenAngel wrote:
Sat Feb 27, 2021 10:12 pm
Looking at my old propeller set up I have 2 bit per colour so it take 8 pins to a VGA signal so you could have 3 VGA outs.
That's a possible alternative, would better suit a 3x3 matrix of monitors if one wanted such a thing, and 3 or multiples thereof may be a better idea anyway.

That should also allow a doubling of resolution in both directions and 64 colours is better than 8.

DarkElvenAngel
Posts: 1875
Joined: Tue Mar 20, 2018 9:53 pm

Re: VGA board arrived

Sun Feb 28, 2021 1:39 am

In case your interested in the resistor values used here's a snap.
VGA.jpg
VGA.jpg (211.81 KiB) Viewed 1847 times

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Sun Feb 28, 2021 8:36 pm

In front you see the remainder of my VGA connector for DueVGA work with 84MHz 96KB ram Arduino Due.
Pimoroni demo board is much nicer, VGA, 3 user buttons, run button, PWM&DAC sound, SD card slot:
20210228_211544.10%.jpg
20210228_211544.10%.jpg
20210228_211544.10%.jpg (29.57 KiB) Viewed 1725 times

Pico can do 320x240 with 16 colors (mandelbrot), and slideshow of 640x480 .png files (32768 colors) with "flash_streaming".
I want to use framebuffer as in mandelbrot, but with monochrome display as in Sierpinski demo with Arduino Due:
https://www.youtube.com/watch?v=aPsMzO5XJxs
DueVGA.Sierpinski.jpg
DueVGA.Sierpinski.jpg
DueVGA.Sierpinski.jpg (37.84 KiB) Viewed 1725 times

The time one has to generate the 2*640 byte line is really small.
From flash_stream I learned that dma transfer from flash is super fast.

Initial Idea was to map 8 pixels (1 byte) simultaneously to 8x2=16 bytes read from flash.
Size needed is 2^8 * 2*8=4096 bytes.
That is only capable of filling less than half of the line in time.

Next I tried to map 16 pixels (2 bytes) simultaneously to 16*2=32 bytes read from flash via dma.
2^16 * 2*16 = 2097152 bytes, or complete Pico flash.
Using whole flash would be possible with flashing code using COPY_TO_RAM method.
But only slightly more than half of the line was able to read in time with 640x480@60Hz.

So next I tried to map 32 pixels (4 bytes) simultaneously to 32*2=64 bytes read from flash via dma.
That was successful, but needs 2^32 * 2*32 = 256GB of flash ... ;-)
Here you can see steady frame (all mappings are constant for now):
20210228_211250.10%.jpg
20210228_211250.10%.jpg
20210228_211250.10%.jpg (24.02 KiB) Viewed 1725 times

This only works when rendering code runs on core1.
I tried to split work between both cores, but DMA is limited.
I tried to update left half in one frame and right half in other.
That worked, but with unusable flickering.
Have not found how to make 640x480@30Hz -- that would work with 2GB flash (16 pixels).
(640x480@50Hz is working, had to comment stuff in to make that mode available)

Next will look into how mandelbrot is fast enough to fill 640*2 bytes for each line in time ... for getting 640x480 monochrome.


P.S:
Here are the main changes for 32 pixel maping shown:

Code: Select all

 void __time_critical_func(render_scanline)(struct scanvideo_scanline_buffer *dest) {
     int l = scanvideo_scanline_number(dest->scanline_id);
+    int core_num = get_core_num();
+if (core_num==0)  return;
     uint16_t *colour_buf = raw_scanline_prepare(dest, VGA_MODE.width);
+
+//    if (l>60)
+    {
+        flash_bulk_read( ((uint32_t *) colour_buf)+0, ((uint32_t) img_base)+0, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+16, ((uint32_t) img_base)+16, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+32, ((uint32_t) img_base)+32, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+48, ((uint32_t) img_base)+48, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+64, ((uint32_t) img_base)+64, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+80, ((uint32_t) img_base)+80, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+96, ((uint32_t) img_base)+96, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+112, ((uint32_t) img_base)+112, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+128, ((uint32_t) img_base)+128, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+144, ((uint32_t) img_base)+144, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+160, ((uint32_t) img_base)+160, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+176, ((uint32_t) img_base)+176, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+192, ((uint32_t) img_base)+192, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+208, ((uint32_t) img_base)+208, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+224, ((uint32_t) img_base)+244, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+240, ((uint32_t) img_base)+240, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+256, ((uint32_t) img_base)+256, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+272, ((uint32_t) img_base)+272, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+288, ((uint32_t) img_base)+288, 16, 10);
+        flash_bulk_read( ((uint32_t *) colour_buf)+304, ((uint32_t) img_base)+304, 16, 10);
+        raw_scanline_finish(dest);
+        return;
+    } 
     // Just use a random DMA channel which hopefully nobody minds us borrowing
     // "It's easier to seek forgiveness than permission, unless you hardfault"
     flash_bulk_read(
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Tue Mar 02, 2021 9:29 pm

I started with mandelbrot demo, and removed mandelbrot and added drawing horizontal/vertical/arbitrary lines, (filled) rectangle, (filled) circle, all on 320x240 display with 32768 colors. Just was in process of adding drawText function when I got nothing displayed after flashing. Tested other scanvideo demos, nothing worked. Switched VGA monitor, did not work. Flashed sine_wave demo, and neither PWM nor DAC did work. Did reboot Pi400, no change. Flashing hello_pwm and blink did work, so the Pico plugged into Pimoroni demo board works. This is frustrating, will test tomorrow whether all 40 header pins soldered to the Pico for plugging into demo board socket still work. If yes, I will buy a new board, so many more ideas what to do with it ...
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

User avatar
HermannSW
Posts: 4518
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: VGA board arrived

Wed Mar 03, 2021 8:14 am

I tested with my 2nd Pico with headers soldered, and here as well sine_wave_pwm.uf2 did not work.
I cloned pico-playground and pico-extras again to new place and build with those, still not working.
So it seems my pico demo board is broken.
I just ordered a new board from Pimoroni, website claims it will ship today, and last time board arrived 5 days after shipping here at my home in Germany.

This code did run yesterday on core1, drawing a lot of filled and non-filled circles in 32768 random colors faster and faster. I use core0 for just handling VGA display with my "easyVGA":

Code: Select all

void core1_func() {
    srand(time_us_32());
    for(uint16_t *p=framebuffer; p<framebuffer+FB_WIDTH*FB_HEIGHT; ++p)
        *p=0xF800;
...
    for(;;)
    {
      set_color(rand()%256, rand()%256, rand()%256);
      ((rand()%2) ? raster_circle : fill_circle)
        (10+rand()%200, 10+rand()%100, 50+rand()%50);

Code: Select all

      static int old=10;
      int ms = 9 - (time_us_32() % 10000000)/1000000;
      if (ms > 0)
        sleep_ms(ms);
      if (old==0 && ms==9)
      {
        set_color(255,0,0);
        fill_rect(1,1,FB_WIDTH-2,FB_HEIGHT-2);
      }
      old=ms;
    }
}

P.S:
I used Bresenham's algorithm for "plotline()":
https://en.wikipedia.org/wiki/Bresenham ... #Algorithm

And based on Bresenham's algorithm, midpoint circle algorithm for "raster_circle()"
http://rosettacode.org/wiki/Bitmap/Midp ... lgorithm#C

Using "line_x()" and "line_y()" instead of "set_pixel()" in that algorithm immediately allowed for filled circle drawing:
midpoint_circle_fill.png
midpoint_circle_fill.png
midpoint_circle_fill.png (26.01 KiB) Viewed 1549 times
https://stamm-wilbrandt.de/2wheel_balancing_robot
https://stamm-wilbrandt.de/en#raspcatbot
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://github.com/Hermann-SW/raspiraw
https://stamm-wilbrandt.de/en/Raspberry_camera.html

Return to “General”