Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7778985
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T18:32:09+00:00 2026-06-01T18:32:09+00:00

I am trying to write a bare metal code to program PL111 LCD controller.

  • 0

I am trying to write a bare metal code to program PL111 LCD controller. I am using QEMU emulator set up for Realview ARM Cortex-A8. I earlier managed to print characters on the linux terminal window using QEMU’s “-serial stdio” option.

I have gone through PL111 document and I can’t figure out one thing. I set up PL111 controller’s LCDUPBASE tovcontain the address of the frame buffer in memory. But can I simply write ascii values to the frame buffer and the LCD controller would pick my frame buffer and display the corresponding characters on the screen or do I need to perform some kind of conversion on ascii values( as per an already existing standard which I am not aware of) before writing them to the frame buffer?

In case of the former being true, is this conversion handled by the controller itself as per some conversion table in controller hardware? What about stuff such as background colour? The PL111 document doesn’t say anything about this. This hurdle also made me think about the role of a GPU, if I were having a GPU as well, where would it fit it in this scheme and what exactly would be its role?

Are there any good resources, documents or books that can help to understand these concepts better. Pardon me if my questions sound stupid. I don’t have much experience of embedded/peripheral programming, I am basically trying to learn/get acquainted with ARMv7 architecure and i thought it would be nice and interesting if I could get to print my assembly programming prints on the QEMU console rather than linux console. (using “-serial stdio” option)

I’d really appreciate it if people here can help me with this. Thanks

/* boot.s */

.section .data

.section .bss

.section .text

.globl _start

_start:

/*** Interrupt Vector Table Start**/

b _RESET_HANDLER                /* Reset Handler        */
b _UNDEF_HANDLER        /* Undef Instruction Handler    */
b _SWI_HANDLER          /* Software Interrupt Handler   */
b _PREFETCHABORT_HANDLER    /* Prefect Abort Handler    */
b _DATAABORT_HANDLER        /* Data Abort Handler       */
b _IRQ_HANDLER          /* IRQ Handler          */
b _FIQ_HANDLER          /* FIQ Handler          */

/*** Interrupt Vector Table End******/

_FIQ_HANDLER:

b .     /* Not implemented yet, so go in infinite loop */

_IRQ_HANDLER:

b .    /* _isr_irq   /* jump to interrupt service routine */

_DATAABORT_HANDLER:

b .     /* Not implemented yet, so go in infinite loop */

_PREFETCHABORT_HANDLER:

b .     /* Not implemented yet, so go in infinite loop */

_SWI_HANDLER:

b .     /* Not implemented yet, so go in infinite loop */

_UNDEF_HANDLER:

b .     /* Not implemented yet, so go in infinite loop */

_RESET_HANDLER:

b _initialize_cpu

cpuinitialize.s =>

.section .data

.section .bss

.section .text

.globl _initialize_cpu

_initialize_cpu:

/* LCD initialization code */

    .include "ColourLCDPL111.s"
    .set SYS_OSC4, 0x1000001C  /* Mapped register for OSCCLK4*/ 
    .set SYS_LOCK, 0x10000020  /* reference clock CLCDCLK for PL111*/

     movw r0, #:lower16:SYS_LOCK          /* Unlocking the register*/
     movt r0, #:upper16:SYS_LOCK
     movw r1, #0xA05F    
             str  r1, [r0]

         movw r2, #:lower16:SYS_OSC4   /* Setting the CLCDCLK frequency 36MHz*/
         movt r2, #:upper16:SYS_OSC4
         movw r1, #0x2CAC    
                 str  r1, [r2]

     str  r1, [r0]                /* Locking the register again*/


         movw r0, #:lower16:LCDTiming0_ADDR
         movt r0, #:upper16:LCDTiming0_ADDR
         movw r1, #:lower16:0x1313A4C4      /* PPL = 49 ; HSW = 3 TODO:change*/
         movt r1, #:upper16:0x1313A4C4      /* HBP = 5  ; HFP = 5 */
             str  r1, [r0]

             movw r0, #:lower16:LCDTiming1_ADDR
             movt r0, #:upper16:LCDTiming1_ADDR
             movw r1, #:lower16:0x0505F657        /* LPP = 600 ; VSW = 2 TODO:change*/
             movt r1, #:upper16:0x0505F657        /* VBP = 2   ; VFP = 2 */
             str  r1, [r0]


     movw r0, #:lower16:LCDTiming2_ADDR
     movt r0, #:upper16:LCDTiming2_ADDR
     movw r1, #:lower16:0x071F1800          /* CPL[25:16] = 799     ; BCD[26] =  1 (PCD Bypassed)   */
     movt r1, #:upper16:0x071F1800          /* PCD        = ignored */                  
             str  r1, [r0]


     movw r0, #:lower16:LCDUPBASE_ADDR   /* Setting up frame buffer address to 0x00000000*/
     movt r0, #:upper16:LCDUPBASE_ADDR
     mov  r1, #0x0  
     str  r1, [r0]

     movw r0, #:lower16:LCDControl_ADDR     
     movt r0, #:upper16:LCDControl_ADDR
     movw  r1, #0x082B          /* Setting up TFT 24Bit Mode */  
     str  r1, [r0]

     movw r0, #:lower16:LCDIMSC_ADDR    /* LCD interrupts: Disabled for now */
     movt r0, #:upper16:LCDIMSC_ADDR
     mov  r1, #0x00000000            
     str  r1, [r0]

     mov  r0, #40            /* lets try to print 'A' at frame buffer + 40 */
     mov  r1, #65   
     str  r1, [r0]

Code snippet for filling the frame buffer that actually turned the whole screen white. I took a randomly large value 10000 when simply using i=800 and j=600×4 didn’t work

  void PopulateFrameBuffer(void)
  {
  unsigned int i,j;
  unsigned char *ptr = (unsigned char *)0x0;
  for(i=0; i<800;i++)
    {
    for (j=0;j<(600*10000);j++)
    {
      *ptr++=0xFF;

    }
  }
 }

I called this function from assembly after initialization code. Frame buffer start address is 0x00000000

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T18:32:11+00:00Added an answer on June 1, 2026 at 6:32 pm

    This isn’t really an answer, it’s more of a comment, but the comment box only allows limited space and formatting.

    According to this knowledge base article, the PL111 supports only pixel mapped modes. i.e. you have to turn on and off each pixel. So, if you have chosen 24 bit true colour, 24 bits from the frame buffer are used to control the colour of each pixel, 8 for red, 8 for green and 8 for blue. how those bits are organised is anybody’s guess. For instance:

    • it might use a contiguous sequence of three bytes,
    • or it might use a contiguous sequence of four bytes but not using the most significant byte
    • or it might organise the bitmap into planes, for instance, all the red values, followed by all the green values, followed by all the blue values.
    • as an extreme option, you could have up to 24 planes, so the first bit of all pixels come first followed by the second bit of all pixels and so on.

    My guess is that the first option is the one used (24 contiguous bits per pixel). You can test this by putting 0xFF in the first six bytes of the frame buffer. That should turn the left hand two pixels on the top row white. If it turns the first white and the second pixel cyan, you know that you have 32 bits per pixel ignoring the most significant byte (and the bytes are little endian). If the first six pixels turn red or another colour, you have a frame buffer organised into planes.

    In order to make actual characters come out, you’ll need a bit map for each possible character and you’ll need to blit them into the frame buffer. You can do this in software, but there should be some sort of hardware support available.

    Edit

    OK, let’s set how to put a character into the frame buffer. I’ll use C because my ARM assembly skills aren’t fantastic. Also, this is totally untested or even compiled

    Assume 8 x 8 characters packed 8 pixels to the byte and a 24 bit colour frame buffer.

     #define PIXEL_WIDTH 3   // width in bytes of a pixel
     #define CHAR_WIDTH  8
     #define CHAR_HEIGHT 8
    
     #define RED_BYTE    2   // Index of the RGB components in the pixel in the framebuffer (little endian)
     #define GREEN_BYTE  1
     #define BLUE_BYTE   0
    
     struct FrameBufferDescriptor
     {
         uint8_t* start;           // Address of first byte in the buffer
         size_t rasterLineWidth;   // width in bytes of each line of pixels in the display.
     };
    
    /*
     *  Draw a character at the (x, y) coordinates (0, 0) is top left.
     *  frameBuffer: describes position and width of the frame buffer
     *  x, y: coordinates of top left corner of the character
     *  characterMap: monochrome bitmap of 1 x 8 x 8 character.  Pixel packed 8 per byte.  
     *                If a bit is set, it means foreground colour, if cleared, it means 
     *                background colour
     *  foreground, background: RGB colours for foreground and background.
     */
    void drawCharacter(struct FramBufferDescriptor* frameBuffer, size_t x, size_t y, uint8_t* characterMap, uint32_t foreground, uint32_t background)
    {
        // first where to start drawing in the frame buffer
        uint8_t* destination =  frameBuffer->start + (y * rasterLineWidth) + (x * PIXEL_WIDTH);
        // char is 8 x 8
        for (int row = 0 ; row < CHAR_HEIGHT ; ++row)  // iterate for each row
        {
            for (pixel = 0 ; pixel < CHAR_WIDTH ; ++pixel)   // iterate for each picxel on the row
            {
                // determine the coloutr of this pixel
                uint32_t colour = background;
                if ((characterMap[row] & (1 << (CHAR_WIDTH - pixel - 1))) != 0) // Most sig bit will be on the left
                {
                    colour = foreground;
                }
                // Put the RGB values in the framebuffer
                destination[pixel * PIXEL_WIDTH + RED_BYTE] = colour >> (RED_BYTE * 8);
                destination[pixel * PIXEL_WIDTH + GREEN_BYTE] = colour >> (GREEN_BYTE * 8);
                destination[pixel * PIXEL_WIDTH + BLUE_BYTE] = colour >> (BLUE_BYTE * 8);
            }
            destination += frameBuffer->rasterLineWidth;  // Go to next line of the frame buffer
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have been trying to write a bare-bones ping scanner using Perl for internal
I am trying a write a program that implements a bare bones POSIX cat
In trying to write more testable Java code, I have been using the Model-View-Presenter
Im trying to write a piece of code to set the image of the
I'm trying write a code that can the set property value through the lambda
Trying to write a code at the moment that basically tests to see if
I am trying to write a Python code analyzer, and I am trying to
Trying to write a windows speech recognition macro. Written using XML and scripting language
Trying to write this small program to help me in my Stats class, everything
Trying to write a code that searches hash values for specific string's (input by

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.