Fooling the Beagle (VGA out)

This weekend I went to dust off my BeagleBoard and tried to do something useful with it . ( now that was the beginning of the end of my weekend! )

I've had it lying around for a while but only recently got around to actually unbox it and plug it into the USB port of my computer. 
Just like everybody else I was baffledTM and amazedTM to see this credit card sized board present me a fully functional Linux shell!

From skimming over the specs I remembered that this flavor of ARM even has a graphics processor and LCD driver.

I decided to attempt to connect the PSP Screen I fumbled together earlier to the Beagle board since all the necessary signals are readily available and a display driver is included in the  Ångström distro.
How hard could it be ? Right ..?

Well, to cut a long story (and an even longer rant) short, most of my weekend went down the drain googling my fingers sore before I realized that without Linux Super Guru skills I wouldn't get anywhere.
(I coudn't even find information about how to change the default resolution of the display driver, or how to get it to load without a cape for that matter)
(Update: I did eventually manage to hook up my PSP screen to the beagle. See bottom of page)

With the weekend almost over I decided to cut my losses and try a different angle. I had made a VGA dongle for the DE0-Nano board which was collecting dust and a perfectly good Multi Sync monitor connected to my computer that can easily adjust to whatever screen resolution I throw at it.


So here's the idea (it's not a great one but I was desperate for even the tiniest victory):
If I could somehow fool the board into thinking I have the official DVI-Cape plugged into it, the kernel would probably fire up the driver for it all by itself. This driver seems to be hardcoded to a resolution of 1024x768 but that's only a problem for the PSP screen, not  for my monitor.

Beaglebone Capes are recognized by the kernel via their eeprom. This memory holds identification and configuration data for each Cape. In order to impersonate the DVI Cape I used an ATmega32 to talk to Beagle's I2C bus and mimicking that very specific eeprom. The actual memory contents for the DVI Cape eeprom can be downloaded from the website.

It appears the kernel reads 268 bytes in three bursts. Not entirely sure why since the configuration data is only 244 bytes long. It did not seem to make much of a difference.

That ATmega32L is running at 3.3V and doesn't cause any level-shifting-headaches when talking to the beagle.

Once a few glitches and unknowns in the I2C conversation were ironed out the kernel cheerfully announced that it found a DVI Cape on port 0x54. It also didn't mind loading the frame buffer driver up for me. Lucky for me the driver either didn't  look too closely at the presented hardware or it didn't care (it would have ruined my day if it had attempted to talk to the DVI line driver over the I2C bus).

A quick scope of the pins revealed indeed the presence of sync signals so the only thing left to do was to hook up 12 of the color lines to my VGA connector. (Note that the pin numbers are assigned a bit creatively from LCD_DATA9 upwards!)

After that, and a reboot of the board a splash screen of a 12-bit beagle rewarded my efforts.

Finally, a few words of caution:
The Linux guys are likely frowning on my lack of guru-ishness while the BeagleBone guys are probably counting how long it will take for my setup to catch on fire.
This is definitely not the best way to do this. There is very likely a reason for the buffers for every line on the original DVI Cape.
I'm sure there's also a sort-of-simple way to get a suitable LCD driver installed on Ångström that is easily configured for any desired resolution and without the need to impersonate a Cape. I'd be very happy if someone would point me in the right direction there.

Update: Beaglebone + Android = Beaglebone & PSP screen

After leaving the beagle sulk in a drawer for a very long time I decided to give it another try. 
This time I went the Android route and it turned out that this was a very (coincidentally) good decision.
While I was building and installing TI's (or row-boat's) Android JB on the beagle I noticed some fragments in the board initialization code that indicated that the kernel will first test for daughterboards and if it doesn't find any it will initialize the lcd controller with a default 320x200 dummy lcd. 

( TI-Android-JB-4.1.2_AM335x_4.0.1/kernel/arch/arm/mach-omap2/board-am335xevm.c : line 3018 )
static void bone_setup_daughter_board(struct memory_accessor *m, void *c)

    /* Display needs to be initialized even if display daughter card is not found so as
    * to enable framebuffer driver which is needed for successful Android bootup
    pr_info("No daughter card found on BeagleBone\n");
    vnc_lcdc_init (DEV_ON_BASEBOARD, PROFILE_NONE);    

and then in...

( TI-Android-JB-4.1.2_AM335x_4.0.1/kernel/arch/arm/mach-omap2/board-am335xevm.c : line 1476)
static void vnc_lcdc_init(int evm_id, int profile)

    if (am33xx_register_lcdc(&Sharp_LCD035Q3DG01_pdata))
    	pr_info("Failed to register LCDC device\n");

I suppose this is done because Android is mainly based on it's graphical user interface and without it not of much use. The androidvnc server seems to also rely on this frame buffer.
Dumbfounded by this I grabbed an oscilloscope probe and indeed the beagle was outputting video signals. Out of the box !

Now, this default driver is not going to generate the proper signals for the higher res PSP screen, but while digging a bit deeper I discovered that the driver knows about a whole bunch of different screens, one of them, LK043T1DG01, is the PSP screen (or a very similar incarnation). 

This can be found in:

( TI-Android-JB-4.1.2_AM335x_4.0.1/kernel/drivers/video/da8xx-fb.c : line 233 )
static struct da8xx_panel known_lcd_panels[] = {
    /* Sharp LCD035Q3DG01 */
    [0] = {
    /* Sharp LK043T1DG01 */
    [1] = {
        .name = "Sharp_LK043T1DG01",
	.width = 480,
	.height = 272,
	.hfp = 2,
	.hbp = 2,
	.hsw = 41,
	.vfp = 3,
	.vbp = 3,
	.vsw = 10,
	.pxl_clk = 7833600,
	.invert_pxl_clk = 0

So I made a copy of the Sharp_LCD035blah.. struct in the board-am355xevm.c file and changed the .file member to the name of the desired PSP screen.

struct da8xx_lcdc_platform_data Sharp_LK043T1DG01_pdata = {
	.manu_name		= "Sharp",
	.controller_data	= &lcd_cfg,
	.type			= "Sharp_LK043T1DG01",

Now all that remained to be done is register the new screen instead of the old 320x200 one:

static void vnc_lcdc_init(int evm_id, int profile)
    //if (am33xx_register_lcdc(&Sharp_LCD035Q3DG01_pdata))
    if (am33xx_register_lcdc(&Sharp_LK043T1DG01_pdata))	
    	pr_info("Failed to register LCDC device\n");

And voilà, Android on a PSP screen !

And yeah, the wiring is a bit tedious.
3V, 5V, GND are connected to the beagle power rails, DISP is always high (3V).
The 5R 6G 5B most significant bits of the LCD's color lines are connected to the beagle's LCD bus just like the DVI shield.
Don't forget VSync and HSync.
The rest of the unused LCD color pins are tied to GND.

Looks pretty wild.

Other projects you might like

DE0-Nano | PSP Screen
Etch tank