## Displaying an image using ATmega 328P - reality check

10 posts / 0 new
Author
Message

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)

```

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

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

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!

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)

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/...

#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."

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

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/

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.

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