Over the Christmas break I visited my mother. She had become fed up with her old TV, and wanted a new, larger one with a built-in DVD player. We went for a shopping trip and I helped her choose one she liked. I set it all up and it it seemed to do the job, so the old one (a 20-inch HDMI flat screen) was now surplus to requirements. As you can imagine, it was not surplus for long! I proudly brought it home and now have an HDMI screen I can use just for my little Pi.
Getting it working under Linux was actually pretty easy. I just plugged it in to the HDMI port and booted the rasspberry Pi from the Linux card. After a minor confusion (the display is a TV, not a monitor, so it defaulted to its built-in tuner rather than the external input. A quick play with the input select showed me a lovely Linux startup process. I couldn’t do much more than that, though, as I had no keyboard connected, so I just powered it off again. Still, it had proved that the hardware all works.
Now on to the tough bit. driving it from bare-metal code. This turned out to be a lot more complicated.
I started by continuing with Lesson 6:Screen01 from the Cambridge “Baking Pi” tutorials. Following the habits from my previous efforts, I mostly just copied the assembler code into a source file, built it and transferred it to the Pi. The first few Screen Lessons (Screen01 drawing colours, and SCreen02 drawing lines) worked OK, but to get Screen03 going I had to tell the Pi to use the old boot process (add a line kernel_old=1 to the file config.txt on the SD card and reboot. I’m sure that, given enough time and patience, I could have worked out what I needed to change to make it work, as I had done to make OK05 work. But I could not be bothered. I wanted to move the whole thing over to C anyway.
So I tried to move it to C, which also turned out to be tricky. I certainly got very familiar with the four-cornered colour gradient which the GPU puts on the the screen before it is initialised. I also made a lot of use of my new morse code emitter to help find out which of the many loops and tests in the code were stuck. Despite all this I still could not get it working properly, so I decided to take a look at some existing C code from other operating systems. The elinux wiki had a more detailled equivalent to the “Baking Pi” description, and included a reference to a tarball of some source code which did mainly the same stuff. This approach got me a bit further, and a lot more morse code messages, but still would not properly work.
I was almost ready to give up, when I found a forum post from Brian Widdas which led me to some C code for setting up the Raspberry Pi framebuffer which finally worked properly. It read a bunch of information from the underlying system and displayed it in several colours on the screen. Brian certainly seems to know what he is doing, and I recommend that anyone interested in bare-metal Raspberry Pi take a look at his Raspberry Pi code on github.
Brian’s approach is quite different from the one at Baking Pi Rather than try force the display to a particular resolution and bit depth, it more politely asks the BCM2835 for its preferred settings (set up by the GPU on boot, based on hardware capabilities and the settings in config.txt, then makes a call to initialise the framebuffer to the appropriate settings. Works much better than the somewhat hit or niss approach taken by the “Baking Pi” and “elinux” tutorials.
So far I have not done much with this screen other than prove that I can change the colour, but I’m confident that when I need it I’ll be able to go further. At least it’s progress.