Pokitto generating 640x480@60Hz VGA


#1

#Warning : this is NOT usable in any meaningful way yet!

Pokitto generating 640x480 VGA mode at 60Hz, 25.1 MHz pixel clock

Every 2nd line red. Nowhere near stable.

#include "Pokitto.h"

//mbed::DigitalOut HSync(EXT1);

mbed::PwmOut HSync(EXT0);
mbed::InterruptIn HSCount(EXT1);
mbed::DigitalOut VSync(EXT2);
mbed::DigitalOut R(EXT4);

#define CLR_VSYNC LPC_GPIO_PORT->CLR[0] = 1 << 12
#define SET_VSYNC LPC_GPIO_PORT->SET[0] = 1 << 12

#define CLR_R LPC_GPIO_PORT->CLR[0] = 1 << 14
#define SET_R LPC_GPIO_PORT->SET[0] = 1 << 14

int lines, vstate;

#define VSTATE_DRAW     0
#define VSTATE_FPORCH   1
#define VSTATE_VSYNC    2
#define VSTATE_BPORCH   3

#define LINES_DRAWEND      480
#define LINES_FPORCHEND    LINES_DRAWEND + 10 // 490
#define LINES_VSYNCEND     LINES_FPORCHEND + 2 //492
#define LINES_BPORCHEND    LINES_VSYNCEND + 29 //521


void hsincrement() {
    lines++;
    switch (vstate) {
    case VSTATE_DRAW:
        if (lines&1) SET_R;
        else CLR_R;
        if (lines==LINES_DRAWEND) {vstate++;SET_R;}
        break;
    case VSTATE_FPORCH:
        if (lines==LINES_FPORCHEND) {vstate++; CLR_VSYNC;}
        break;
    case VSTATE_VSYNC:
        if (lines==LINES_VSYNCEND) {vstate++; SET_VSYNC;}
        break;
    case VSTATE_BPORCH:
        if (lines==LINES_BPORCHEND) {vstate=0;lines=0;CLR_R;}
        break;
    }
}

int main ()
{
vstate=lines=0;
VSync=1;
HSync.period_us(30);
HSync.pulsewidth_us(27);
HSCount.rise(&hsincrement);  // attach the address of the flip function to the rising edge

	while (1)
	{

        wait_ms(5);

	}
}


#2

Quick explanation of method and wiring.

This is a bog standard Pokitto with no external hardware driving the VGA signal from the PEX connector.

Horizontal sync is generated with PWM from EXT0. Period 32uSec, HSync pulse width 32 minus 27 uSec.

EXT0 goes through a 47Ohm resistor to VGA HSync. Output of EXT0 is looped back to EXT1, which is set as Interrupt In to detect the horizontal sync firing. This is attached to a horizontal line counter interrupt function, that takes care of vertical sync. EXT4 is feeding the VSYNC of the VGA through a 47Ohm resistor

Red signal connected via voltage divider (0.7V max) to R signal of VGA connector.

Thats it. Took 2 hours and a bit of study.

Edit: this was a quick proof of concept. The picture is still not stable horizontally. But the monitor detects the signal as 640x480@60Hz and does not complain so that’s half the battle won right there.


#3

If you’re drawing horizontal lines, how can you tell it’s not stable horizontally?

Since you’re not initializing the lib, does that mean systick isn’t getting in the way of the hsincrement interrupt?


#4

Because I tried other patterns earlier.

I am not initializing Pokitto lib. I’m using it purely as an mbed board.

I’ve learned to start with the simplest implementation, then begin finetuning.

Edit: so yes, systick is NOT firing


#5

Makes sense. I’m just curious about what could possibly cause the instability if there’s nothing else running. :slight_smile:


#6

Oh thats easy to explain. The VGA signal is actually very timing sensitive. HSync is supposed to occur at exactly 31.78 uSec period and last for 3.8 uSec or something like that. I’m throwing it 32 uS and 4 uSish :wink:


#7

Sort of like how the arduino tv-out implementations are not 100% accurate, but good enough to fool most TV sets?

…640x480 it’shard enough to get 220x176 at a reasonable speed!


#8

OK, so this is an important distinction: 640x480 VGA timing mode is not the same as 640x480 pixels.

It still remains to be seen how many pixels we can push.

In fact, I’ll be trying to get 160x120 @ 256 colors at first

Edit: and I need to build 3 resistor ladder dacs for the RGB signals, since they are analog, not digital


#9

its neat that your sending derectly from pokitto, but this seems very timing critical might it be better to use an external chip to buffer the video and render it? like arduino tv out or a tinyFPGA might be better or some other cheap chip


#10

Yep I agree with you. I just wanted to see what the standard Pokitto with just a couple of cheap resistors can do. We can always improve from this. Now we know its possible to do.


#11

I realized there should be an easy way to make the horizontal clock dead accurate.

PWM is just a counter with a value. I can delay or kick the counter forwad at the end of each line by a set amount to land it exactly at the required pulse width. Doh.


#12

I got the hsync working. Looks awesome. More soon


#13

Nope.

I can’t get the horizontal dimension under control

Reading / writing pwm->Count results in hard fault. This is what led me to the wrong conclusion: scope was showing rock solid 32uS but in fact MCU was in hard fault (brain dead) evwn though PWM was still pushing a signal.

The problem is that the hsync is off by a few microseconds. There seems to be no way to recalibrate the pwm per line

Timers are not accurate enough, because we need parts of microseconds accuracy (<1000000 of a second)

I was able to get 28 scruffy vertical lines. Nowhere near enough.

Only options left:

  1. external chip to help the Pokitto make the signal
  2. pure assembler with cyclecounting and bitbanging

#14

Taking a break from real work by playing around with something I got off ebay (LPC2148).

First ARM7TDMI I have ever used. Feels momentuous. This is the thing that powered so many old mobile phones.

Makes slightly better VGA.

Setting up was easy, Code::Blocks + arm gcc


#15

ATM7TDMI is what the GameBoy Advance used :D


#16

Oh no, too much power. Not retro enough!


#17

If you want proper retro, let’s scrap the VGA and use UHF :P


#18

Too much power? It’s like an LPC11u68 but with 512kb of flash instead of 256kb. Still has 32kb of RAM, similar clock speed. :thinking:
The major difference being support for 32-bit instructions instead of just thumb2.


#19

Relax everybody. The ARM7TDMI was here just to teach little Pokitto some tricks.

And boy, did he learn:

Yep. That is rock-solid VGA signal coming out of Pokitto using only PWM0 from EXT0 pin to generate HSync.

Meaning every Pokitto without additional hardware is capable of this.

EDIT:

Story behind this.

Back when ARM7TDMI was the thing and dinosaurs roamed the land, VGA was still very much a thing to need. Therefore examples of how it was done on the ARM7TDMI could be discovered.

A little bit of reverse-engineering, some oscilloscoping, a new idea and: presto!


#20

I want to tell a little bit more about this case, because it is so interesting.

So, 2 weeks ago I tried to generate VGA with Pokitto. I could get a picture but the sync was all over the place. The picture was shimmering and glitching.

Turns out clean VGA is not exactly easy to make: you have to be within very small time windows. For example, horizontal sync only lasts 3.77 microseconds.

So 2 weeks ago I abandoned the idea, thinking some sort of external chip is needed. Especially if Pokitto has only 1 PWM signal free.

One evening, I was looking at ways of generating VGA from FPGA projects to Parallax Propellers and so on. I came across 10 year old videos of Philips LPC2148 (ARM7TDMI) driving VGA.

I found that an old LPC2148 dev kit had a VGA connector (NGX Blueboard) and its schematics and sources from ~2004-2006 were still available on google code.

I then ordered a NXP2148 stamp board from Ebay (the0.net), zero documentation of course.

It arrived last week and today I got to give it a spin. After that it was easy to see how they did the VGA signal in the NGX source code, and then adapt it for Pokitto. Biggest problems were to acquaint myself with the internals of the ARM7TDMI, fix the ancient source code so that it would compile and finally figure out a way to do it on the single available PWM on the Pokitto

I KNOW I should be doing other stuff but I need this kind of small achievements to remain motivated :wink: