Skip to content

VGA demo on bluepill (using STM32F103 microcontroller)

License

Notifications You must be signed in to change notification settings

napobear/VGA-demo-on-bluepill

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VGA-demo-on-bluepill

VGA demo on bluepill (using STM32F103 microcontroller)

What it can do

There are 4 demos:

VGA Demo on Bluepill

Video

Introduction

My idea of “fun” maybe odd, but here it is. This is a demo that displays a color VGA video with resolution of 256x192 and 64 colors without any specialized video hardware on a tiny STM32F103 board that can run only up to 72 MHz and has only 20 KB of RAM.

Installation

If you want to try my project, this is the only part that you need.

Hardware Qty
"blue pill" STM32F103C8 board 1
Resistors 470 Ohm 3
Resistors 680 Ohm 3
Breadboard 1
VGA connector (I used one from the old video card) 1
Jumper wires 15
ST-Link v2 or clone 1

Software (under Windows): Install Visual Studio Code, then PlatformIO plug-in.

How to connect wires:

PIN Description Connect To Output
PA0 Red 1 Resistor 470 Ohm VGA red (1)
PA1 Red 2 Resistor 680 Ohm VGA red (1)
PA2 Green 1 Resistor 470 Ohm VGA green (2)
PA3 Green 2 Resistor 680 Ohm VGA green (2)
PA4 Blue 1 Resistor 470 Ohm VGA blue (3)
PA5 Blue 2 Resistor 680 Ohm VGA blue (3)
PB0 HSync VGA HSync (13)
PB6 VSync VGA VSync (14)
G Ground VGA Ground (5,6,7,8,10)

Project Description

To generate VGA signal I am using 3 timers. TIM2 is used as a "shock absorber" (for a detailed description of this brilliant idea, see A Glitch in the Matrix). TIM3 is used to generate HSync signal on PB0 using PWM and also to generate interrupt TIM3_IRQHandler, which calls DoDraw, which outputs pixels. TIM4 is used to generate VSync signal on PB6 using PWM and also to generate interrupt TIM4_IRQHandler, which sets a flag that indicates that we can draw on screen.

USB serial is used in this demo. I decreased the priority of the USB interrupt so it wouldn’t interfere with the VGA output. You can connect using VT100 terminal, such as Tera Term, to use the demo.

Also, since the VGA output is very tight, I disabled SysTick. To implement delay, I am using RTC. It is actually not trivial to read time from the RTC. The reason is that we need to read 3 values, and there’s no way to do it atomically. For the solution, see the implementation of the Vga::millis which I took from Reading STM32F1 real-time clock.

Evolution of the Project

This project was born some time ago when I first installed a great TVOut library on my Arduino Mega. I was really impressed with the fact that so small board (it is based on a tiny 16 MHz 8-bit processor) can display a video with reasonable quality.

I started to look at similar projects and found a "Glitch" demo, which is using more powerful, but still tiny, 32-bit processor. The “Glitch” was an inspiration for this project. I decided to get something in between and chose a "blue pill", which is using a 32-bit STM32F103 microcontroller, similar to the one in “Glitch” demo, but cheaper and less powerful (and as a bonus, it supports Arduino).

The STM32F103 board that I chose can run only up to 72 MHz and has only 20 KB of RAM, compared to 168 MHz and 192 KB of RAM that “Glitch” demo is using, however I was hoping to use code very similar to Cliff’s. I decided to support a resolution of Sinclair ZX Spectrum computers. By using “color attributes” (the colors are defined for 8x8 blocks of pixels, not for each pixel), the whole video memory can fit into only 7 KB of RAM. In this demo I am using 2-byte attributes instead of 1-byte attributes and takes approximately 7.7 KB. The reason is to simplify assembly code that pushes out the pixels.

However, I was disappointed that even though the DMA is supported, it apparently can’t run fast enough for my goal. This article explains this fact in detail. So, the only option left was to use the approach similar to TVOut library. Please note, that it is possible to use DMA+SPI to create “green and white” VGA output (see great Artekit demo).

After some time learning ARM assembler language I had an Arduino code that could display 256x192 with 64 colors; however I was getting a weird “zigzag” effect which I cannot explain even now. After struggling for some time to figure out the reason for that effect, I gave up. It was time to try to get closer to the hardware. I decided to switch to the STM32Cube library. Originally, I thought that it will take a very short time. After all, Arduino is not really an operating system, how hard it can be? After rewriting my demo using HAL, I was hoping that it will run very soon. No, it didn’t.

Since I don’t have oscilloscope or logical analyzer, I had no idea why nothing was shown on the screen. So, I had to learn what Arduino was doing for me at the start, which is actually quite a bit. After some time I realized that the reason was that my processor was running at 8 MHz, not 72! What a surprise! If you are interested, the code that switches to 72 MHz and does some other things, like initializing USB clock at 48 MHz is SystemClock_Config (in startup.c).

About

VGA demo on bluepill (using STM32F103 microcontroller)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 52.2%
  • C 47.8%