| Posted: 09:16am 09 May 2020 |
|
|
|
I thought I'd start a thread to try and explain the concepts behind the CMM2 graphics and give some annotated examples of how to use the facilities in the CMM2. I'm sure Mauro will chime in and then perhaps some of what is in the thread can form the basis of a graphics manual of some sort.
This first post will cover the basics of how the graphics are generated and work.
Some of the STM32 chips, including the STM32H743IIT6 that we are using, have an on chip graphics controller (called the LTDC = Lcd Tft Display Controller)
This is programmed to read from a defined area of memory at a specific rate and write the data to a set of I/O pins. In our case the I/O pins are connected to the resistors that make up the three R2R DACs on the CMM2 motherboard and these create the analogue VGA signals. In addition the LTDC is programmed to create the HSync and VSync signals which tell the monitor that we have reached the end of a line or and of a page.
All these signals must waggle at a rate determined by the a defined VGA specification depending on the resolution required.
In the case of the 800x600 display memory is being read at a rate of 40MHz, the line rate is 37.8787KHz and the frame rate is 60Hz
The important point about the LTDC is that all this happens without any use of the processor once the controller has been initialised. It is basically a continuous circular DMA (Direct Memory Access). Of course this isn't completely free as it does consume memory bandwidth even though the processor isn't involved.
So to get something onto the screen all we have to do is write to the area of memory that the LTDC is reading and something will appear on the screen.
For performance reasons the best memory to use is the STM32H743IIT6's internal memory and 512KB of this is allocated to the main video memory. In addition I have allocated 3MB of the 8MB SDRAM memory (this is the chip on the back of the Waveshare PCB) to use for graphics.
So we have 3.5MB of memory available for graphics, 512KB is located at memory address &H24000000 and 3MB at address &HD0000000. We will see in the next section how we can poke this memory to write things on the screen.
However, we need one more concept before starting to explore how to use this memory - the Colour LookUp Table or CLUT. The default resolution of the CMM2 is 800x600 with an 8-bit colour depth so the screen uses 480,000 bytes out of the 512 KBytes available in the processors internal video memory. However, we need to drive 16 data lines not just 8 and the way this happens is that the LTDC takes each 8-bit value in turn as it reads memory and uses it as an index to a table of 16-bit values (the CLUT). This table is initialised by the CMM2 firmware to sensible values to give good colour coverage but can be changed from within MMBasic using the MAP command (subject for another post).
OK, so we know that in 800x600x8 resolution the screen is using 480KB of memory starting at &H24000000. This memory is organised exactly as you would expect. The first 800 bytes are the top line of the display starting at the top left hand corner. The second 800 bytes are the second line of the display. and the 480,000th byte is the bottom right of the display.
So lets draw a diagonal line on the display to prove this.
pix%=&H24000000 for i%=0 to 599 j%=i%*800+i% poke byte pix%+j%,255 next i%

Note how the line just writes across anything already on the screen.
It is a bit silly having to memorise &H24000000 so the CMM2 includes a built in function to give it to us
pix%=mm.info(page address 0) for i%=0 to 599 j%=i%*800+i% poke byte pix%+j%,255 next i%
Of course we could have done the same thing using the command
line 0,0,599,599
Internally in the CMM2 firmware the LINE command is doing exactly what we did with POKE. And, of course, all the basic graphics commands are doing the same thing - writing to memory in order to construct the requested shapes.
Next post I will explore graphics pages and how they allow us to do some of the magic but if you properly understand the above then everything else should be easy. |