Go Down

Topic: Code: VGA RGB Signal (Read 18061 times) previous topic - next topic

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

WilliamK Govinda

Ah, ok, I will try to post a video and some pictures later today. I also will update the code to work with something more usable and handle at least 2 bit color information. It won't look as great as some of the other solutions we find, but at lest this I understand and not much complicated assembly is been used. ;-) Still need to learn a bit of ATmega328 ASM so I could improve things up.

Wk

WilliamK Govinda

I was wondering on doing a "tiles" based display. So it takes much less RAM and still can do some nice things with this. But I need to know ATmega328/168 Assembly, to render the screen at x number of cycles. Any hints on this?

Wk



WilliamK Govinda

#20
Oct 23, 2011, 07:44 pm Last Edit: Oct 23, 2011, 07:49 pm by WilliamK Reason: 1
Here's a new code, it has only one color, but handles 21x32 tiles on the screen. Each tile is a 7 byte icon stored in flash, so you can have a lot of icons in flash, not RAM. The problem now is that the code needs more optimizations and also if I try to change the memory data for the tiles in real-time, the video goes out of sync. I need to figure out why.

Edit: I also changed the connections, I'm using SPI for the video output now.

Code: [Select]
/*
 
 For connections, use:

 Pin 9 = HZync (PWM) = VGA Pin 13
 Pin 8 = VSync = VGA Pin 14
 Pin 11 = RGB Video (SPI) = VGA Pins 1, 2 & 3 (or use just one to get a single color)

 Ground the following pins on the VGA connector: 6 and 10

 VSync us
 64    - Sync   = 1024 cycles
 1020  - Blank  = 16320 cycles
 15240 - Lines  = 243840 cycles
 350   - Blank  = 5600 cycles

266784 = cycles total (60 times per second = 60hz)

 HSync us (Lines)
 3.77  - Sync   = 60.32 cycles
 1.89  - Blank  = 30.24 cycles
 25.17 - RGB    = 402.72 cycles
 0.94  - Blank  = 15.04 cycles

 508 Cycles per line

 VSync Start = 2 lines
 Vsync blank = 32 lines
  480 lines
 VSync Blank = 11 lines
 
 Total of 525 lines
 
*/

#include <SPI.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
volatile unsigned int linecount;

#define vSyncLow PORTB &= ~(1 << 0);
#define vSyncHigh PORTB |= (1 << 0);

uint8_t tileData[34*21]; // 714 bytes

void setup()
{
 set_sleep_mode(SLEEP_MODE_IDLE);
 
 pinMode(11, OUTPUT);
 pinMode(8, OUTPUT); // VZync = VGA Pin 14
 pinMode(9, OUTPUT); // HZync = VGA Pin 13
 
 digitalWrite(8, LOW);
 digitalWrite(11, LOW);
 
 SPI.begin();
 SPI.setClockDivider(SPI_CLOCK_DIV2);
 SPI.setDataMode(0x04);
 
 memset(tileData,1,sizeof(tileData));
 tileData[0] = tileData[3] = 0;
 tileData[9] = tileData[12] = 2;
 tileData[21] = tileData[21*3] = 0;
 tileData[21+7] = tileData[(21+7)*3] = 3;
   
 // Disable Arduino Timer0 and UART Timer
 TCCR0A = TCCR0B = 0;
 TIMSK0 = 0;
 
 TCCR1A =  _BV(COM1A1) | _BV(COM1A0) | _BV(WGM11);
 TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); // No Prescalar
 ICR1 = 508;
 TIMSK1 = _BV(TOIE1); // Enable timer overflow interrupt
 OCR1A = 60; // HSync Pulse
 
 sei(); // enable global interrupts
}

uint8_t y = 0;
uint8_t y2 = 0;
uint8_t temp = 0;
int line21 = 0;
extern PROGMEM prog_uchar charData[];
#define topOffset 39

void loop()
{
 if (linecount >= topOffset && line21 < (34*21))
 {
   sleep_mode();
   temp = pgm_read_byte_near(charData + (tileData[0+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[1+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[2+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[3+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[4+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[5+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[6+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[7+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[8+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[9+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[10+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[11+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[12+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[13+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[14+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[15+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[16+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[17+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[18+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[19+line21]*7) + y);
   SPDR = temp; temp = pgm_read_byte_near(charData + (tileData[20+line21]*7) + y);
   SPDR = temp;
   
   y2++;
   if (y2 == 2)  
   {
     y2 = 0;  
     y++;  
     if (y == 7)
     {
       y = 0; line21 += 21;
     }  
   }
 }
 else if (linecount == 0)
 {
   y = y2 = temp = line21 = 0;
 }
}

ISR(TIMER1_OVF_vect)
{      
 if (linecount == 0) vSyncLow;
 if (linecount == 2) vSyncHigh;
 if (++linecount == 525) linecount = 0;
}


And the symbols-test:

Code: [Select]
#include <avr/pgmspace.h>

PROGMEM prog_uchar charData[7*4] = {
B11000110,
B11000110,
B11100110,
B11101110,
B00111000,
B00010000,
B00000000,

B00010000,
B01101100,
B11000110,
B11000110,
B01101100,
B00111000,
B00000000,

B11111110,
B11111110,
B11111110,
B11111110,
B00111000,
B00010000,
B00000000,

B00010000,
B01111100,
B11111110,
B11111110,
B01111100,
B00111000,
B00000000};

robtillaart

Quote
But I need to know ATmega328/168 Assembly, to render the screen at x number of cycles. Any hints on this?


no assembly expert, but you can make an assembly dump of C code with objdump.exe  -S

(from another thread)  --   %avr%objdump.exe -S %build%%target%.cpp.o >disassembly.txt

At least a way to learn from your existing code ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

WilliamK Govinda

Oh, good to know, I was wondering about this last month, thanks for pointing it out, specially how to use it, as I had no clue on how.  :smiley-red: Will try to check this tomorrow or later on.

Wk

dwan

Hi William !

I'm eager to try your code on my CRT VGA screen. What next ? a VGA sync lib ?

Code: [Select]
set.vgasync(800,600, 60);

8)

WilliamK Govinda

Ah, if only that would be possible. ;-) Actually, the signal sync could be possible, but not any image. Handling 640x480 is already pushing the Arduino to its limits, really.

Wk

Nabe_RMC

Hi William !
I watched your nice work videos !

Quote
But I need to know ATmega328/168 Assembly, to render the screen at x number of cycles. Any hints on this?

I got instruction set manual from Atmel web site.
And I used inline assembler.
http://www.nongnu.org/avr-libc/user-manual/inline_asm.html
http://www.stanford.edu/class/ee281/projects/aut2002/yingzong-mouse/media/GCCAVRInlAsmCB.pdf

You can download example codes - using inline assembler.
http://homepage3.nifty.com/two_legs/neo/project/Arduino_LCD/proj_Arduino_LCD.htm
http://homepage3.nifty.com/two_legs/neo/project/Arduino/proj_Arduino.htm

I was inspired by waching your work.
So, I will  modify my codes to VGA signal timing.

Nabe

WilliamK Govinda

Oh, that's nice work, I will check those out tomorrow or so, thank you so much!  8)

Wk

Nabe_RMC

#27
Oct 26, 2011, 06:12 pm Last Edit: Oct 26, 2011, 07:12 pm by Nabe_RMC Reason: 1
I tried with Arduino Duemilanove.
64colors 64x64pixel
http://twitvideo.jp/06hhv

Interface - only 6registers and VGA connector
Red-2bit, Green-2bit, Blue-2bit  -> use 2*3 = 6registers
H-sync and V-sync 2registers
like this
http://twitpic.com/763wr8

Next,I will try to display my twitter icon.

Nabe

Nabe_RMC

Quote
Next,I will try to display my twitter icon.


I did.
http://twitvideo.jp/06hzk

Next, Text Display
I will busy this week end.
So, I will try it next week.

Nabe


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy