Displaying an image using ATmega 328P - reality check

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys

 

I've embarked on first assembler project involving AVR assembly. I'm having fun so far, but have run into something I'd like some advice on if at all possible.

 

First a description of my project: I'm using an ATmega 328P to output a display in PAL in greyscale using composite video. That seems to be working fine in the sense that I can produce the 4us + 8us pulse and then the 52us of time where I can output different bars of grey scale. This is simply looped to output the same line infinitely.

 

I'm now progressing on to the next stage of trying to display a pattern on the screen based on a bit pattern in memory.

My first attempt will involve splitting the 52us into cpu cycles per line. So 614 cycles [52(us) x 8(MHz)] then figure out how many pixels can be displayed.

That is determined by how many cycles I use in machine code to process a given pixel/byte and dividing 614 by that.

It's this process that I'm trying to optimise.

 

The way I figure it, I need to:

Read a byte and process it. This means processing 8 pixels at a time (1 bit = 1 pixel i.e. monochrome output)

Do a bit-wise AND on the byte with 128 to determine the value of bit 7

Is result 0? If so then change output voltage so that black is selected

Otherwise, set the output voltage so that white is selected

Rinse and repeat for each bit field (i.e. 64, 32, 16, 8, 4, 2, 1)

 

My issue here is that the code I have written seems very inefficient and I was wondering if there is another, better, way? The more efficient I can make this code the more pixels I can display per line.

 

Code concept:

(read byte from memory to byteReg register)
ANDI byteReg, 128                       // AND data byte with 128 (bit 7)
BREQ SetBack128                         // If result is 0 then bit not set so we jump to make current colour black (bit 7)
(current colour to white)               // Otherwise we run the code to set current colour to white
BackFromSetBlack128:                    // Label used by set colour to black (bit 7) routine to jump back 

ANDI byteReg, 64                        // AND data byte with 64 (bit 6)
BREQ SetBack128                         // If result is 0 then bit not set so we jump to make current colour black (bit 6)
(current colour to white)               // Otherwise we run the code to set current colour to white
BackFromSetBlack64:                     // Label used by set colour to black (bit 6) routine to jump back 

(rinse and repeat for each bit field)


SetBack128:
(code to set composite output to black)
RJMP BackFromSetBlack128

SetBack64:
(code to set composite output to black)
RJMP BackFromSetBlack64

(rinse and repeat for each bit field)

 

 

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want some inspiration for what can be done with the '328s little brother, the mega88, look here...all the video & audio are being generated using only the mega88

 

https://www.youtube.com/watch?v=sNCqrylNY-0    ...amazing!

 

2 years later he went and made a more stripped down version using pal

https://www.youtube.com/watch?v=sCN1bqRG-7o

 

theses include some links to his software

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is an andi faster or slower than doing a rotate into carry? Then you need to copy the carry into the video port bit(s)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Is an andi faster or slower than doing a rotate into carry? Then you need to copy the carry into the video port bit(s)

 

A few days ago I was reminded of some code I wrote to generate video on a 90S2313. With a 10MHz clock I used this code sequence to generate a pixel every 4 clock cycles...

 

	out	video_port,reg_1	;[1] pixel 1
	lsr	reg_1			;[1]
	nop				;[1]
	nop				;[1]
	out	video_port,reg_1	;[1] pixel 2
	lsr	reg_1			;[1]
	nop				;[1]
	nop				;[1]
	out	video_port,reg_1	;[1] pixel 3
	lsr	reg_1			;[1]
	nop				;[1]
	nop				;[1]
	...etc

I dedicated a whole port to the video output and just used the LSB as the actual pin.

 

I then used the 'spare' pair of NOPs to hold my loop management and video generation code.

 

Simplistically put, this method used 50% of the available time to output video with the rest available to generate the 'picture'.

 

In reality, you use less time to generate the video as you also have the horizontal and vertical blanking periods in which to 'make' stuff.

 

One of my goals was to generate a full broadcast spec sync signal as well.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you should do a search on "atomiczombie" he has done a lot of interesting things with just a simple controller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
I think you should do a search on "atomiczombie"
Or just google "lucid science" which will get you to the same place. Note he does VGA not PAL generation mainly.

 

https://lucidscience.wordpress.c...

http://www.lucidscience.com/

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the responses, guys.  I didn't realise that VGA was easier to do than PAL, so I think I'll head in that direction. No point in heading into a dead end unless it teaches something (which it has - but I doubt there's more to be gotten out of it).

I'll have a look at those links for that and see what is required then I'll revisit my code optimisation.

 

[edit]

One other thing I have to factor in to all of this is reading data from an external RAM IC.

Last Edited: Wed. Feb 21, 2018 - 09:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like that article is defunct (initial page loads, but the rest gives 404 error). However, I've found a few other tutorials on using AVRs with VGA so am diving in with both feet :D.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the Lucid Science site won't work just search "atomiczombie" and "vga" here. Loads of threads and you'll be astonished at what he made possible.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fortunately, it's archived: https://web.archive.org/web/2017...