diff --git a/server/drivers/tyan_lcdm.c b/server/drivers/tyan_lcdm.c index 796fbed..a0bec7b 100644 --- a/server/drivers/tyan_lcdm.c +++ b/server/drivers/tyan_lcdm.c @@ -65,8 +65,8 @@ typedef enum { } custom_type; static int fd; -static char *framebuf = NULL; -static char *old = NULL; +static unsigned char *framebuf = NULL; +static unsigned char *old = NULL; static int width = 0; static int height = 0; static int cellwidth = DEFAULT_CELL_WIDTH; @@ -85,7 +85,7 @@ static void tyan_lcdm_switch_mode (); static void tyan_lcdm_hardware_clear (Driver * drvthis); static void tyan_lcdm_set_rampos(unsigned char pos); -static void tyan_lcdm_write_str(char *str,unsigned char start_addr, int length); +static void tyan_lcdm_write_str(unsigned char *str, unsigned char start_addr, int length); #if 0 static void tyan_lcdm_set_cursor(unsigned char start_addr, int pos); #endif @@ -104,52 +104,55 @@ tyan_lcdm_init (Driver * drvthis, char *args) int speed = DEFAULT_SPEED; char size[200] = DEFAULT_SIZE; - debug(RPT_INFO, "tyan_lcdm: init(%p,%s)", drvthis, args ); + debug(RPT_INFO, "tyan_lcdm: init(%p,%s)", drvthis, args); /* Read config file */ /* Which serial device should be used */ - strncpy(device, drvthis->config_get_string ( drvthis->name , "Device" , 0 , DEFAULT_DEVICE),sizeof(device)); - device[sizeof(device)-1]=0; - debug (RPT_INFO,"tyan_lcdm: Using device: %s", device); + strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); + device[sizeof(device)-1] = '\0'; + debug(RPT_INFO,"%s: using Device %s", drvthis->name, device); /* Which size */ - strncpy(size, drvthis->config_get_string ( drvthis->name , "Size" , 0 , DEFAULT_SIZE),sizeof(size)); - size[sizeof(size)-1]=0; - if( sscanf(size , "%dx%d", &w, &h ) != 2 - || (w <= 0) || (w > LCD_MAX_WIDTH) - || (h <= 0) || (h > LCD_MAX_HEIGHT)) { - report (RPT_WARNING, "tyan_lcdm_init: Cannot read size: %s. Using default value.\n", size); - sscanf( DEFAULT_SIZE , "%dx%d", &w, &h ); - } else { - width = w; - height = h; + strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); + size[sizeof(size)-1] = '\0'; + if ((sscanf(size , "%dx%d", &w, &h) != 2) + || (w <= 0) || (w > LCD_MAX_WIDTH) + || (h <= 0) || (h > LCD_MAX_HEIGHT)) { + report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", + drvthis->name, size, DEFAULT_SIZE); + sscanf(DEFAULT_SIZE , "%dx%d", &w, &h); } + width = w; + height = h; /* Which speed */ - tmp = drvthis->config_get_int ( drvthis->name , "Speed" , 0 , DEFAULT_SPEED); + tmp = drvthis->config_get_int(drvthis->name , "Speed", 0, DEFAULT_SPEED); if (tmp == 4800) speed = B4800; else if (tmp == 9600) speed = B9600; - else { report (RPT_WARNING, "tyan_lcdm_init: Speed must be 4800 or 9600. Using default value.\n", speed); + else { + report(RPT_WARNING, "%s: Speed must be 4800 or 9600; using default %d", + drvthis->name, DEFAULT_SPEED); + speed = 9600; } /* Set up io port correctly, and open it... */ - debug( RPT_DEBUG, "tyan_lcdm: Opening serial device: %s", device); - - fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY); + debug(RPT_DEBUG, "tyan_lcdm: Opening serial device: %s", device); + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { - report (RPT_ERR, "tyan_lcdm_init: failed (%s)\n", strerror (errno)); + report(RPT_ERR, "%s: open(%s) failed (%s)", + drvthis->name, device, strerror(errno)); return -1; } - tcgetattr (fd, &portset); + tcgetattr(fd, &portset); /* We use RAW mode */ #ifdef HAVE_CFMAKERAW - /* The easy way */ - cfmakeraw( &portset ); + /* The easy way */ + cfmakeraw(&portset); #else - /* The hard way */ + /* The hard way */ portset.c_cflag = CS8 | CREAD | CLOCAL; portset.c_iflag = IXON | IXOFF | IGNBRK | IGNCR; portset.c_oflag &= ~ONLCR; @@ -160,22 +163,26 @@ tyan_lcdm_init (Driver * drvthis, char *args) #endif /* Set port speed */ - cfsetospeed (&portset, speed); - cfsetispeed (&portset, speed); + cfsetospeed(&portset, speed); + cfsetispeed(&portset, speed); /* Do it... */ - tcsetattr (fd, TCSANOW, &portset); + tcsetattr(fd, TCSANOW, &portset); /* Make sure the frame buffer is there... */ - framebuf = (unsigned char *) malloc (width * height); - memset (framebuf, ' ', width * height); + framebuf = (unsigned char *) malloc(width * height); + if (framebuf == NULL) { + report(RPT_ERR, "%s: unable to create framebuffer", drvthis->name); + return -1; + } + memset(framebuf, ' ', width * height); /* Set display-specific stuff.. */ - tyan_lcdm_switch_mode (); + tyan_lcdm_switch_mode(); - report (RPT_DEBUG, "tyan_lcdm_init: done\n"); + report(RPT_DEBUG, "%s: init() done", drvthis->name); - return 0; + return 1; } /* @@ -184,12 +191,14 @@ tyan_lcdm_init (Driver * drvthis, char *args) MODULE_EXPORT void tyan_lcdm_close (Driver * drvthis) { - close (fd); + close(fd); - if(framebuf) free (framebuf); + if (framebuf) + free(framebuf); framebuf = NULL; - if(old) free (old); + if (old) + free(old); old = NULL; } @@ -218,41 +227,40 @@ MODULE_EXPORT void tyan_lcdm_flush (Driver * drvthis) { int i; - char *xp, *xq; + unsigned char *xp, *xq; /* * We don't use delta update yet. * It is possible but not easy, we can only update a line, full or begining. */ - if (old==NULL) { - old = (unsigned char *) malloc (width * height); - memset (old, ' ', width * height); - tyan_lcdm_hardware_clear (drvthis); + if (old == NULL) { + old = (unsigned char *) malloc(width * height); + memset(old, ' ', width * height); + tyan_lcdm_hardware_clear(drvthis); } -xp = framebuf; -xq = old; + xp = framebuf; + xq = old; -for (i=0; iname, key); return NULL; break; } @@ -302,7 +308,8 @@ tyan_lcdm_chr (Driver * drvthis, int x, int y, char c) y--; x--; - framebuf[(y * width) + x] = c; + if ((x >= 0) && (y >= 0) && (x < width) && (y < height)) + framebuf[(y * width) + x] = c; } /* @@ -322,18 +329,19 @@ static void tyan_lcdm_switch_mode (Driver * drvthis) { char lcdcmd[4]; + //set os selection - lcdcmd[0]=TYAN_LCDM_CMD_BEGIN; - lcdcmd[1]=0x73; - lcdcmd[2]=0x01; - lcdcmd[3]=TYAN_LCDM_CMD_END; - write(fd,lcdcmd,4); + lcdcmd[0] = TYAN_LCDM_CMD_BEGIN; + lcdcmd[1] = 0x73; + lcdcmd[2] = 0x01; + lcdcmd[3] = TYAN_LCDM_CMD_END; + write(fd, lcdcmd, 4); sleep(1); //send "LCD Ready" cmd - lcdcmd[1]=0x6c; - lcdcmd[2]=TYAN_LCDM_CMD_END; - write(fd,lcdcmd,3); + lcdcmd[1] = 0x6c; + lcdcmd[2] = TYAN_LCDM_CMD_END; + write(fd, lcdcmd, 3); sleep(1); } @@ -418,14 +426,13 @@ tyan_lcdm_init_vbar (Driver * drvthis) }; if (custom != vbar) { - // printf("+++ vbar +++\n"); - tyan_lcdm_set_char (drvthis, 1, a); - tyan_lcdm_set_char (drvthis, 2, b); - tyan_lcdm_set_char (drvthis, 3, c); - tyan_lcdm_set_char (drvthis, 4, d); - tyan_lcdm_set_char (drvthis, 5, e); - tyan_lcdm_set_char (drvthis, 6, f); - tyan_lcdm_set_char (drvthis, 7, g); + tyan_lcdm_set_char(drvthis, 1, a); + tyan_lcdm_set_char(drvthis, 2, b); + tyan_lcdm_set_char(drvthis, 3, c); + tyan_lcdm_set_char(drvthis, 4, d); + tyan_lcdm_set_char(drvthis, 5, e); + tyan_lcdm_set_char(drvthis, 6, f); + tyan_lcdm_set_char(drvthis, 7, g); custom = vbar; } } @@ -499,12 +506,12 @@ tyan_lcdm_init_hbar (Driver * drvthis) }; if (custom != hbar) { - tyan_lcdm_set_char (drvthis, 1, a); - tyan_lcdm_set_char (drvthis, 2, b); - tyan_lcdm_set_char (drvthis, 3, c); - tyan_lcdm_set_char (drvthis, 4, d); - tyan_lcdm_set_char (drvthis, 5, e); - tyan_lcdm_set_char (drvthis, 6, f); + tyan_lcdm_set_char(drvthis, 1, a); + tyan_lcdm_set_char(drvthis, 2, b); + tyan_lcdm_set_char(drvthis, 3, c); + tyan_lcdm_set_char(drvthis, 4, d); + tyan_lcdm_set_char(drvthis, 5, e); + tyan_lcdm_set_char(drvthis, 6, f); custom = hbar; } } @@ -557,8 +564,9 @@ tyan_lcdm_num (Driver * drvthis, int x, int num) { /* char out[5]; - snprintf (out, sizeof(out), "%c%c%c", 28, x, num); - write (fd, out, 3); + + snprintf(out, sizeof(out), "%c%c%c", 28, x, num); + write(fd, out, 3); */ } @@ -572,32 +580,32 @@ tyan_lcdm_num (Driver * drvthis, int x, int num) MODULE_EXPORT void tyan_lcdm_set_char (Driver * drvthis, int n, char *dat) { - char out[8]; + unsigned char out[8]; int row, col; - int letter; - if (n < 0 || n > 7) + if ((n < 0) || (n > 7)) return; if (!dat) return; for (row = 0; row < cellheight; row++) { - letter = 0; + int letter = 0; + for (col = 0; col < cellwidth; col++) { letter <<= 1; letter |= (dat[(row * cellwidth) + col] > 0); - /* I should remove that debug code. */ - // if (dat[(row * cellheight) + col] == 0) printf("."); - // if (dat[(row * cellheight) + col] == 1) printf("+"); - // if (dat[(row * cellheight) + col] == 2) printf("x"); - // if (dat[(row * cellheight) + col] == 3) printf("*"); - // printf("'%1d'", dat[(row * cellwidth) + col]); - // printf("%3d ", letter); + /* I should remove that debug code. */ + //if (dat[(row * cellheight) + col] == 0) printf("."); + //if (dat[(row * cellheight) + col] == 1) printf("+"); + //if (dat[(row * cellheight) + col] == 2) printf("x"); + //if (dat[(row * cellheight) + col] == 3) printf("*"); + //printf("'%1d'", dat[(row * cellwidth) + col]); + //printf("%3d ", letter); } - out[row+1]=letter; - // printf(": %d\n", letter); + out[row+1] = letter; + //printf(": %d\n", letter); } - tyan_lcdm_write_str(out,(unsigned char)(0x40+n*8),8); + tyan_lcdm_write_str(out, (unsigned char) (0x40 + n * 8), 8); } /* @@ -698,50 +706,50 @@ tyan_lcdm_icon (Driver * drvthis, int x, int y, int icon) }; /* Yes we know, this is a VERY BAD implementation :-) */ - switch( icon ) { + switch (icon) { case ICON_BLOCK_FILLED: - tyan_lcdm_chr( drvthis, x, y, 255 ); + tyan_lcdm_chr(drvthis, x, y, 255); break; case ICON_HEART_FILLED: custom = cust; - tyan_lcdm_set_char( drvthis, 0, icons[1] ); - tyan_lcdm_chr( drvthis, x, y, 0 ); + tyan_lcdm_set_char(drvthis, 0, icons[1]); + tyan_lcdm_chr(drvthis, x, y, 0); break; case ICON_HEART_OPEN: custom = cust; - tyan_lcdm_set_char( drvthis, 0, icons[0] ); - tyan_lcdm_chr( drvthis, x, y, 0 ); + tyan_lcdm_set_char(drvthis, 0, icons[0]); + tyan_lcdm_chr(drvthis, x, y, 0); break; case ICON_ARROW_UP: custom = cust; - tyan_lcdm_set_char( drvthis, 1, icons[2] ); - tyan_lcdm_chr( drvthis, x, y, 1 ); + tyan_lcdm_set_char(drvthis, 1, icons[2]); + tyan_lcdm_chr(drvthis, x, y, 1); break; case ICON_ARROW_DOWN: custom = cust; - tyan_lcdm_set_char( drvthis, 2, icons[3] ); - tyan_lcdm_chr( drvthis, x, y, 2 ); + tyan_lcdm_set_char(drvthis, 2, icons[3]); + tyan_lcdm_chr(drvthis, x, y, 2); break; case ICON_ARROW_LEFT: - tyan_lcdm_chr( drvthis, x, y, 0x7F ); + tyan_lcdm_chr(drvthis, x, y, 0x7F); break; case ICON_ARROW_RIGHT: - tyan_lcdm_chr( drvthis, x, y, 0x7E ); + tyan_lcdm_chr(drvthis, x, y, 0x7E); break; case ICON_CHECKBOX_OFF: custom = cust; - tyan_lcdm_set_char( drvthis, 3, icons[4] ); - tyan_lcdm_chr( drvthis, x, y, 3 ); + tyan_lcdm_set_char(drvthis, 3, icons[4]); + tyan_lcdm_chr(drvthis, x, y, 3); break; case ICON_CHECKBOX_ON: custom = cust; - tyan_lcdm_set_char( drvthis, 4, icons[5] ); - tyan_lcdm_chr( drvthis, x, y, 4 ); + tyan_lcdm_set_char(drvthis, 4, icons[5]); + tyan_lcdm_chr(drvthis, x, y, 4); break; case ICON_CHECKBOX_GRAY: custom = cust; - tyan_lcdm_set_char( drvthis, 5, icons[6] ); - tyan_lcdm_chr( drvthis, x, y, 5 ); + tyan_lcdm_set_char(drvthis, 5, icons[6]); + tyan_lcdm_chr(drvthis, x, y, 5); break; default: return -1; /* Let the core do other icons */ @@ -756,7 +764,7 @@ tyan_lcdm_icon (Driver * drvthis, int x, int y, int icon) MODULE_EXPORT void tyan_lcdm_clear (Driver * drvthis) { - memset (framebuf, ' ', width * height); + memset(framebuf, ' ', width * height); } /* @@ -766,13 +774,14 @@ static void tyan_lcdm_hardware_clear (Driver * drvthis) { char lcdcmd[5]; + //set os selection - lcdcmd[0]=TYAN_LCDM_CMD_BEGIN; - lcdcmd[1]=0x70; - lcdcmd[2]=0x00; - lcdcmd[3]=0x01; - lcdcmd[4]=TYAN_LCDM_CMD_END; - write(fd,lcdcmd,5); + lcdcmd[0] = TYAN_LCDM_CMD_BEGIN; + lcdcmd[1] = 0x70; + lcdcmd[2] = 0x00; + lcdcmd[3] = 0x01; + lcdcmd[4] = TYAN_LCDM_CMD_END; + write(fd, lcdcmd, 5); } @@ -786,15 +795,16 @@ tyan_lcdm_string (Driver * drvthis, int x, int y, char string[]) int i; /* Convert 1-based coords to 0-based... */ - x -= 1; - y -= 1; + x--; + y--; - for (i = 0; string[i]; i++) { + if ((y < 0) || (y >= height)) + return; + for (i = 0; (string[i] != '\0') && (x < width); i++, x++) { /* Check for buffer overflows... */ - if ((y * width) + x + i > (width * height)) - break; - framebuf[(y * width) + x + i] = string[i]; + if (x >= 0) + framebuf[(y * width) + x] = string[i]; } } @@ -802,35 +812,38 @@ static void tyan_lcdm_set_rampos(unsigned char pos) { char cmd_str[5]; - cmd_str[0]=TYAN_LCDM_CMD_BEGIN; - cmd_str[1]=0x70; - cmd_str[2]=0x00; - cmd_str[3]=pos; - cmd_str[4]=TYAN_LCDM_CMD_END; - write( fd,cmd_str,5); + + cmd_str[0] = TYAN_LCDM_CMD_BEGIN; + cmd_str[1] = 0x70; + cmd_str[2] = 0x00; + cmd_str[3] = pos; + cmd_str[4] = TYAN_LCDM_CMD_END; + write(fd, cmd_str, 5); } static -void tyan_lcdm_write_str(char *str,unsigned char start_addr, int length) +void tyan_lcdm_write_str(unsigned char *str,unsigned char start_addr, int length) { //CGRAM 0x40, 0x48,.... //if Line 1: start_addr = 0x80 //if Line 2: start_addr = 0xc0 // 1<= length <=16 - char cmd_str[20]; + unsigned char cmd_str[20]; + tyan_lcdm_set_rampos(start_addr); - memset(cmd_str,' ', 20); + memset(cmd_str, ' ', 20); cmd_str[0] = TYAN_LCDM_CMD_BEGIN; cmd_str[1] = 0x70; cmd_str[2] = 0x02; cmd_str[19] = TYAN_LCDM_CMD_END; - memcpy(cmd_str+3,str,length); - write(fd,cmd_str,20); + memcpy(cmd_str+3, str, length); + write(fd, cmd_str, 20); } #if 0 static void tyan_lcdm_set_cursor(unsigned char start_addr, int pos){ char cmd_str[5]; + tyan_lcdm_set_rampos(pos+start_addr); cmd_str[0] = TYAN_LCDM_CMD_BEGIN; cmd_str[1] = 0x70; @@ -843,13 +856,17 @@ void tyan_lcdm_set_cursor(unsigned char start_addr, int pos){ #endif static -unsigned char tyan_lcdm_read_key(){ - int count=0; +unsigned char tyan_lcdm_read_key() +{ + int count = 0; char key_str[4]; - memset(key_str,0,4); - count=read(fd,key_str,4); - if( key_str[0] == (char)TYAN_LCDM_CMD_BEGIN && key_str[1]==(char)0x72 && key_str[3]==(char)TYAN_LCDM_CMD_END){ + + memset(key_str, 0, 4); + count = read(fd, key_str, 4); + if ((key_str[0] == (char) TYAN_LCDM_CMD_BEGIN) + && (key_str[1] == (char) 0x72) + && (key_str[3] == (char) TYAN_LCDM_CMD_END)) { return key_str[2]; } - return 0xf4; //error + return 0xF4; //error } diff --git a/server/drivers/tyan_lcdm.h b/server/drivers/tyan_lcdm.h index 7945f9c..e99d27e 100644 --- a/server/drivers/tyan_lcdm.h +++ b/server/drivers/tyan_lcdm.h @@ -25,7 +25,7 @@ #define DEFAULT_CELL_WIDTH 5 #define DEFAULT_CELL_HEIGHT 8 #define DEFAULT_DEVICE "/dev/lcd" -#define DEFAULT_SPEED B9600 +#define DEFAULT_SPEED 9600 #define DEFAULT_SIZE "16x2" MODULE_EXPORT int tyan_lcdm_init (Driver * drvthis, char *device);