VGA Shield Wing

A VGA Arduino Uno Shield or Adafruit Feather Wing
640x480 - 512 colours

Similar projects worth following
A VGA shield/wing based on the VLSI VS23S040 chip. The board has 2 sets of connectors, one for a standard Arduino Uno shield and one to connect to a Adafruit feather board as a Wing. The Wing connectors also makes is compatible to breadboards. Also 4 channel composite NTSC/PAL video output is possible with the correct crystal. A SOIC-8 standard pinout SPI flash memory is on board for graphics and character sets, as well as a I2C EEPROM also in SOIC-8 package. A level translator chip takes care of the correct voltage levels, so a 5V or 3.3V Arduino could be used (Uno or Zero). The SPI signals are routed through a pin header in line with the ICSP connector, so the shield can be used on an UNO, Mega, Due or Zero with the hardware SPI interface. It is the next generation of my Arduino Video Display Shield.

The VLSI VS23S040 is the successor of the trusted VS23S010 composite video chip with framebuffer. This Shield/Wing uses the VS23S040 to generate VGA signals or composite video.

Currently it is running as 4x composite video output with resolutionS:

NTSC 320x200 in 256 colours and PAL 300x240 in 256 colours.

New resolutions in composite video mode:

NTSC 426x200 in 256 colours and PAL 500x240 in 256 colours.

I plan to get it running in the future as VGA with 640x480 resolution with  3bit per RGB to generate 512 colours.

VGA sync signal are running stable, next is the colour output. Software will be released when output is fully functional.


Schematics PDF (Done with KiCAD)

Adobe Portable Document Format - 200.69 kB - 12/30/2022 at 02:44



Schematics PDF (Done with KiCAD)

Adobe Portable Document Format - 133.28 kB - 01/30/2021 at 01:19


BOM P42-VGA_ver2.pdf

Bill of material

Adobe Portable Document Format - 424.75 kB - 01/30/2021 at 01:19



Assembly Drawing

Adobe Portable Document Format - 21.57 kB - 01/30/2021 at 01:19


  • 1 × VLSI VS23S040 4 Channel video output with 4Mbit frame buffer

  • Detour: Arduino Benchmark with Mandelbrot

    MagicWolfi09/26/2021 at 15:47 0 comments

    With a display and a bunch of different Arduino/Feather boards, I figured it would be a fun little exercise to see how fast those boards would render a Mandelbrot set image with my video shield. Contestants are Arduino Uno, Mega, Due and a Feather M4 Express in NTSC320x200 and PAL300x240 resolutions. Calculations are done in float numbers for the standard number range of -2.5<x<+1 and -1<y<1. Results are rounded to the next full 0.1 second.

    BoardNTSC 320x200
    PAL 300x240

    And here is a bad quality demo picture of the resulting image.

    The code is not optimized for speed, I have read about implementation that use only 3 multiplications instead of 6. Work for the future.

    // Draw a Apfelmaennchen
    void Mandelbrot (byte channel, float Xn, float Xp, float Yn, float Yp){
    	float x0, y0, xtemp;
    	float x = 0;
    	float y = 0;
    	u_int16 Px, Py;
    	u_int16 iteration = 0;
    	u_int16 max_iteration = 256;
    	for (Py = 0; Py < YPIXELS; Py++){
    		y0 = (Yp - Yn)/YPIXELS*Py + Yn;
    		for (Px = 0; Px < XPIXELS; Px++){
    			x0 = (Xp - Xn)/XPIXELS*Px + Xn;
    			x = 0;
    			y = 0;
    			iteration = 0;
    			while ((x*x + y*y <= 2*2) && (iteration < max_iteration) ) {
    				xtemp = x*x - y*y + x0;
    				y = 2*x*y + y0;
    				x = xtemp;
    			P42Display.SetYUVPixel (channel, Px, Py, (byte) (iteration&0xff) +0x20);

  • New Resolutions

    MagicWolfi08/19/2021 at 00:58 0 comments

    The 4x composite video output has gained new higher resolutions in the format of:

    NTSC 426x200 in 256 colours

    PAL 500x200 in 256 colours.

    The resolutions are very unusual for 2 reasons. I was going for the highest resolution that still can display 256 colours and they are full dividers of the pixel clock to give the best quality image possible. An pixel clock divider with remainder would bleed the colour into the next pixel and one would get never twice the same color.

    The code with new header files can be found under Video4 in the Github repository. The new PAL resolution does not allow for the Amiga Boing Ball demo any more, as there is not enough video memory left for the ball data.

  • Rev3 with better IO access on MEGA boards

    MagicWolfi05/23/2021 at 01:14 0 comments

    Rev3 of the 4xVideo Shield with VLSI VS23S040 chip is abailable now. It is identical to the last one, just got smaller at the RCA and VGA connector end to expose the IO pin underneath when plugged into a MEGA form factor board.

  • Semi-Duplex UARTs

    MagicWolfi03/02/2021 at 02:24 0 comments

    The idea is to have messages from 2 serial ports being displayed and scrolled up. I would call it semi-duplex, as ideally one side sends a command/line and the the other side. If both sides send characters at the same time, they get mixed with each other in the same line. Different colours for the 2 sides are used, so it is visible if that happens.

    HW Setup:
    Arduino Mega with P42 Video4 VGA Shield
    Standard serial port setup as SERIAL 115200 8N1
    2nd serial port setup as SERIAL1 38400 8N1 (this is also a hardware serial port on the Mega on pins 18:TX 19:RX). The baudrate is set to 38400 to be operational with the Arduino SoftwareSerial library as well. For the 2nd serial port a TTl-UART adapter is required with connections to RX, TX and GND.

    SW Setup:
    !!! The Arduino Serial Monitor is not suitable for this setup. A proper terminal software is required, I use two instances of TeraTerm, configured with the correct serial settings, local echo and transmit CR+LF.

    The display shows the 2 different sources in light and dark colour.

    The global variables ScreenX and ScreenY as well as the function printlineXY() are the heart of this demo.

    ScreenX, ScreenY point to the coordinate of the screen where the next character will be printed. Function: byte printlineXY ( byte channel, char* Text, byte colour, bool ln )
      byte channel: is the video channel used for display; can be one of CH0, CH1, CH2, CH3.
      char* Text: pointer to a string, null terminated. To print a single character, the character + a NULL byte need to be content of the string. Maximum string length is the remainder of the current line + a full additional line as only one linebreak is currently implemented.
      byte colour: a 8-bit colour value picked from the colour table in the user guide.
      bool ln: of TRUE a CR+LF is performed to start a new line after the string got printed.    byte return value: currently always 0.

     At the bottom of the screen, if the last line is full or LF = TRUE, a line scrolling is implemented to make room for the next line of text.  Implemented control codes:
     0x08 : Backspace, the last character gets deleted to free the area for the next character to be printed, so technically it is a 'delete char'
     0x0A : LF Linefeed, cursor go to next line, but same horizontal position  0x0D : CR Carriage return, cursor goes to the beginning of the current line

    SW repository

  • Revision 2 is a go.

    MagicWolfi01/29/2021 at 00:57 4 comments

    Revision 2 of the board is running as planned. I replaced the trusted level shifter buffer 74LVC4245A with a TI TXS0108, which is automatically bi-directional. The bi-dir feature is not needed here, but a good exercise for future use. Attention has to be paid, as there is also a TXB010x family which works better with fully driven signals. The TXS0108 is on order for open drain signals, e.g. the MISO sinal on SPI slave devices.

    Channel 0 is on the RCA connector, channels 1,2,3 are on the VGA connector, accessible with a VGA to 3x RCA cable.

  • 1st steps first

    MagicWolfi03/22/2020 at 12:53 0 comments

    Soldering the BGA was amazingly easy. I use some low-temperature solder paste and a boatload of flux with my hot air pencil and everything aligned itself into place. How do I know that I have good contact? Measuring with a multimeter in diode mode, I see a diode drop of ~0.55V between every IO and Vcc. Now I have to solder all the other parts and start talking to the chip. Then comes the hard part, writing good driver software and config code...

    The other parts went on just as easy... Well, mostly.

    This looks like a nice schematic, all signals are there (sigh):

    The board needed some wire surgery, but in the end it works and now I have 16Mbit of SPI Flash for character sets and images. 

View all 6 project logs

Enjoy this project?



MagicWolfi wrote 03/23/2020 at 01:01 point

No more reply, 4 comments deep ;(

I think there was a comment from Panu in the VLSI forum about the S040 dies.

SPI works tricky, as everything else in the chip. There is a register to disable access to any of the 4 register/memory sets. So you can write all 4 or only selected ones at the same time, same as 4 identical chips connected to an external SPI bus. For read commands only one can be enabled to give a meaningful answer.

  Are you sure? yes | no

Thomas wrote 03/25/2020 at 21:30 point

These guys really have a bag of tricks! I guess it takes a while to understand the finer details of this ingenious chip design. I'm thinking of buying some and make a breakout board.

What kind of solder paste and flux did you use?

  Are you sure? yes | no

MagicWolfi wrote 03/27/2020 at 00:18 point

Try contacting VLSI sales, they sent me samples of the S010 and S040.

Yes, the datasheet is a handful, but there are some very good articles in the forum, explaining stuff in detail. And sample code, which helped me a lot. When I saw the chip, I also thought about a breakout board, but never followed up on it. I even asked around about the style.

My shield wing turned out to be OK, so I don't need a breakout any more. I am using low temperature MG Chemical M3 #4902P solder paste for my prototypes. It is lead free and has a melting point of ~140degC. For production I use Chipquik NC191SNL15 lead free paste, very easy to work with. For flux, I have Chipquik SMD 291 no clean tack, which is great gooey stuff, but ugly residue when I don't clean it!? I like clean boards.

  Are you sure? yes | no

Thomas wrote 03/22/2020 at 08:57 point

That's a very interesting chip for retro-computing! Do you know where it's commonly used?

By the way, you mention 640x400 in the project title and 640x480 in the details. There certainly enough RAM for the once-popular 800x600 format but are there other limitations?

I briefly browsed the data sheet and noticed that there is a memory-move command - nice! This means that even text mode with scrolling should be feasible. An 8bit µC playing "character generator" will still be a bottleneck, but that's likely still OK for that 80s feeling ;-)

Edit: I had a look at VLSI - they have a maker/small company friendly store (single quantities, PayPal!), and the team looks like it consists of the kind if Finnish people I've learned to value:

What's there not to love?

Edit2: I just found your post in the VLSI forum - from browsing that I now understand that achieving 800x600 isn't possible but who cares?

  Are you sure? yes | no

MagicWolfi wrote 03/22/2020 at 12:21 point

Yes, it is a family of 2 interesting chips. Thanks for pointing out the error with the resolutions. I'll fix that to ...x480 because... VGA. The RAM distribution is 1Mbit per channel as the chip is basically 4 dies of VS23S010 in one package. Higher resolutions does decrease the colour depth as well. 

My P42-Display project #NTSC/PAL Video Display Shield uses the VS23S010 chip and I have seen this one in one retro platform but have no idea about commercial applications.

My demo of the bouncing AMIGA ball uses the memory move command. The memory mapping is very unusual as the source block does not allocate a consecutive block of RAM, but has enough bits between the lines to fill up a full line! The character map could live in the free part of the video RAM as well and use the block move for fast display.

VLSI is a nice company, they shipped directly to Elecrow for a small build for me. Panu and the other guys are super helpful in the forum.

  Are you sure? yes | no

Thomas wrote 03/22/2020 at 15:33 point

Thanks for the explanation and details! The VS23S0x0 are a bit like 80s ingenuity with today's silicon and density (it address-space / control trade-off reminds me a bit of the Apple II).

I didn't notice the 4-dies-in-a-package thing. I'll check the datasheet again to learn why SPI still works!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates