Friday, 21 November 2008

More on Writing to MusicPal Display

I've made some progress on writing to the MusicPal display now.
This is all written in C - haven't got as far as trying to make Python work yet.
I downloaded the Embedded Linux Development Kit and the MusicPal Linux source code from the FreeCom web site by clicking on the 'Legal Notice' link.
The source code included a directory .../alinux/linux-2.6.16.16/arch/arm/mach-mv88w8xx8/lcd_framebuffer which appears to be the framebuffer driver source code for the MusicPal LCD Display.
It included an example file "mvlcd_test.c" which did not work, but I managed to comment out the errors to get it to compile and run on the MusicPal - I transferred the executable to the MusicPal using wget on the MusicPal to download it from my web server. Most of the options to do with filling in the screen did not work, but the 'Write String' one did once I realised that you have to do 'manually refresh display' afterwards to see what you have done. It is also best to kill the MusicPal main application with:

/etc/init.d/watching stop
/etc/init.d/mainapp stop

Otherwise it overwrites the things you have written.

I have got a simple example running which shows text in three different fonts. The example program is:

#include
#include "glcd.h"
main() {
lcd_clear_screen();
lcd_set_font(0);
lcd_write_string("font0",0,0);
lcd_set_font(1);
lcd_write_string("font1",0,10);
lcd_set_font(2);
lcd_write_string("22:00",0,20);
lcd_redraw_screen();
}


This in turn relies on a simple library that I have started - glcd.c and glcd.h:
glcd.h

/*
* glcd.h
* Desc: Graham's simple interface to display text on the MusicPal LCD
* Display.
* HIST: 21nov2008 GJ ORIGINAL VERSIO
*/

extern int lcd_font_number; /* Default font - 0,1 or 2 */

int lcd_set_font(int);
int lcd_write_string(char *str,int x,int y);
int lcd_clear_screen(void);
int lcd_redraw_screen(void);
int lcd_poll_buttons(void);



glcd.c


#include
#include
#include "lcdwrite.h"
#include "glcd.h"

int lcd_font = 0;

int lcd_write_string(char *str, int x, int y) {
int fbfd = 0;
int retval = 0;
struct disp_string_lcd disp_lcd;
strcpy(disp_lcd.str,str);
disp_lcd.x = x;
disp_lcd.y = y;

switch (lcd_font) {
case 0:
disp_lcd.flags = STR_FLAG_FONT_6X8;
break;
case 1:
disp_lcd.flags = STR_FLAG_FONT_8X8;
break;
case 2:
disp_lcd.flags = STR_FLAG_FONT_24X24;
break;
default:
disp_lcd.flags = STR_FLAG_FONT_6X8;
}

printf("write_string: str=%s, x=%d, y=%d, flags=%d\n",
disp_lcd.str, disp_lcd.x, disp_lcd.y, disp_lcd.flags);
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
retval = -1;
} else {
if (ioctl(fbfd, MVLCD_DISP_STRING, &disp_lcd)) {
printf("Error refreshing.\n");
return 1;
}
}
close(fbfd);
return 0;
}


int lcd_clear_screen() {
int fbfd = 0;
int retval = 0;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
retval = -1;
} else {
if (ioctl(fbfd, MVLCD_CLEAR_SCREEN, 0)) {
printf("Error refreshing.\n");
return 1;
}
}
close(fbfd);
return 0;

}

int lcd_redraw_screen() {
int fbfd = 0;
int retval = 0;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
retval = -1;
} else {
if (ioctl(fbfd, MVLCD_REFRESH, 0)) {
printf("Error refreshing.\n");
return 1;
}
}
close(fbfd);
return 0;

}

int poll_buttons() {
int fbfd = 0;
int retval = 0;
int buttons;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
retval = -1;
} else {
if (ioctl(fbfd, MVLCD_POLL_BUTTONS, &buttons)) {
printf("Error refreshing.\n");
return 1;
}
}
close(fbfd);
return buttons;

}


int lcd_set_font(int font) {
if (font<0>2) {
fprintf(stderr,"WARNING: Font Number %d is an odd number - this might not work\n", font);
}
lcd_font = font;
}




This doesn't do much, but I can now display text on the MusicPal display, so I am progressing towards a replacement firmware for it - just a little way to go still!

NT

2 comments:

Anonymous said...

rather than using wget to transfer files why not simply use netcat

e.g.

nc -l -p 1234 < mvlcd_test

on your server and

nc <ServerIP> 1234 > mvlcd_test

on your MusicPal (you will have to ctrl+C when you think the file has transfered and check the file size)

Graham Jones said...

There is a really simple reason for not using netcat - I had never heard of it!

I'll have a play - it looks like a simple way of doing it if you do not have a handy web server to do the transfers.

The 'best' way would be to get NFS working on the MusicPal so I can just mount the whole directory of my other computer. I have compiled a new kernel with NFS enabled, but haven't dared load it yet because I haven't tested the 'emergency re-flash' facility on the MusicPal, and I could easily have messed it up!