From da0b35b5b6d5431b8a01373cd4fc0e40357dc6c5 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Sun, 28 Nov 2004 15:50:24 +0000 Subject: [lcd4linux @ 2004-11-28 15:50:24 by reinelt] Cwlinux fixes (invalidation of user-defined chars) --- drv_Cwlinux.c | 54 ++++--- drv_generic_text.c | 402 +++++++++++++++++++++++++++----------------------- drv_generic_text.h | 8 +- lcd4linux.conf.sample | 8 +- widget_icon.c | 10 +- 5 files changed, 265 insertions(+), 217 deletions(-) diff --git a/drv_Cwlinux.c b/drv_Cwlinux.c index ccfd667..c533b3f 100644 --- a/drv_Cwlinux.c +++ b/drv_Cwlinux.c @@ -1,4 +1,4 @@ -/* $Id: drv_Cwlinux.c,v 1.19 2004/06/26 12:04:59 reinelt Exp $ +/* $Id: drv_Cwlinux.c,v 1.20 2004/11/28 15:50:24 reinelt Exp $ * * new style driver for Cwlinux display modules * @@ -23,6 +23,9 @@ * * * $Log: drv_Cwlinux.c,v $ + * Revision 1.20 2004/11/28 15:50:24 reinelt + * Cwlinux fixes (invalidation of user-defined chars) + * * Revision 1.19 2004/06/26 12:04:59 reinelt * * uh-oh... the last CVS log message messed up things a lot... @@ -160,6 +163,7 @@ typedef struct { int protocol; } MODEL; + /* Fixme: number of gpo's should be verified */ static MODEL Models[] = { @@ -173,15 +177,21 @@ static MODEL Models[] = { /*** hardware dependant functions ***/ /****************************************/ +static void drv_CW_send (const char *string, const int len) +{ + drv_generic_serial_write (string, len); + usleep (20); +} + + static void drv_CW_write (const int row, const int col, const char *data, const int len) { char cmd[6]="\376Gxy\375"; cmd[2]=(char)col; cmd[3]=(char)row; - drv_generic_serial_write (cmd, 5); - - drv_generic_serial_write (data, len); + drv_CW_send (cmd, 5); + drv_CW_send (data, len); } @@ -195,8 +205,7 @@ static void drv_CW1602_defchar (const int ascii, const unsigned char *buffer) for (i=0; i<8; i++) { cmd[3+i] = buffer[i] & 0x1f; } - drv_generic_serial_write(cmd,12); - usleep(20); /* delay for cw1602 to settle the character defined! */ + drv_CW_send(cmd,12); } @@ -218,22 +227,20 @@ static void drv_CW12232_defchar (const int ascii, const unsigned char *buffer) } } } - drv_generic_serial_write (cmd, 10); + drv_CW_send (cmd, 10); } static void drv_CW_clear (void) { -#if 0 - drv_generic_serial_write("\376X\375",3); /* Clear Display */ +#if 1 + drv_CW_send("\376X\375",3); /* Clear Display */ + usleep(500000); #else /* for some mysterious reason, we have to sleep after */ /* the command _and_ after the CMD_END... */ - usleep(20); - drv_generic_serial_write("\376X",2); /* Clear Display */ - usleep(20); - drv_generic_serial_write("\375",1); /* Command End */ - usleep(20); + drv_CW_send("\376X",2); /* Clear Display */ + drv_CW_send("\375",1); /* Command End */ #endif } @@ -253,16 +260,16 @@ static int drv_CW_brightness (int brightness) switch (Brightness) { case 0: /* backlight off */ - drv_generic_serial_write ("\376F\375", 3); + drv_CW_send ("\376F\375", 3); break; case 8: /* backlight on */ - drv_generic_serial_write ("\376B\375", 3); + drv_CW_send ("\376B\375", 3); break; default: /* backlight level */ cmd[2] = (char)Brightness; - drv_generic_serial_write (cmd, 4); + drv_CW_send (cmd, 4); break; } @@ -318,10 +325,10 @@ static int drv_CW_start (const char *section) drv_CW_clear(); - drv_generic_serial_write ("\376D\375", 3); /* auto line wrap off */ - drv_generic_serial_write ("\376R\375", 3); /* auto scroll off */ - drv_generic_serial_write ("\376K\375", 3); /* underline cursor off */ - drv_generic_serial_write ("\376B\375", 3); /* backlight on */ + drv_CW_send ("\376D\375", 3); /* auto line wrap off */ + drv_CW_send ("\376R\375", 3); /* auto scroll off */ + drv_CW_send ("\376K\375", 3); /* underline cursor off */ + drv_CW_send ("\376B\375", 3); /* backlight on */ /* set brightness */ if (cfg_number(section, "Brightness", 0, 0, 8, &i) > 0) { @@ -394,7 +401,8 @@ int drv_CW_init (const char *section, const int quiet) YRES = 8; /* pixel height of one char */ CHARS = 16; /* number of user-defineable characters */ CHAR0 = 1; /* ASCII of first user-defineable char */ - GOTO_COST = 3; /* number of bytes a goto command requires */ + GOTO_COST = 3; /* number of bytes a goto command requires */ + INVALIDATE = 1; /* re-defined chars must be re-sent to the display */ /* start display */ if ((ret=drv_CW_start (section))!=0) @@ -464,7 +472,7 @@ int drv_CW_quit (const int quiet) { info("%s: shutting down.", Name); drv_generic_text_quit(); - /* clear *both* displays */ + /* clear display */ drv_CW_clear(); /* say goodbye... */ diff --git a/drv_generic_text.c b/drv_generic_text.c index 336c782..db1e03e 100644 --- a/drv_generic_text.c +++ b/drv_generic_text.c @@ -1,4 +1,4 @@ -/* $Id: drv_generic_text.c,v 1.21 2004/06/26 12:04:59 reinelt Exp $ +/* $Id: drv_generic_text.c,v 1.22 2004/11/28 15:50:24 reinelt Exp $ * * generic driver helper for text-based displays * @@ -23,6 +23,9 @@ * * * $Log: drv_generic_text.c,v $ + * Revision 1.22 2004/11/28 15:50:24 reinelt + * Cwlinux fixes (invalidation of user-defined chars) + * * Revision 1.21 2004/06/26 12:04:59 reinelt * * uh-oh... the last CVS log message messed up things a lot... @@ -125,9 +128,10 @@ * extern int DROWS, DCOLS; display size * extern int LROWS, LCOLS; layout size * extern int XRES, YRES; pixel width/height of one char - * extern int GOTO_COST; number of bytes a goto command requires * extern int CHARS, CHAR0; number of user-defineable characters, ASCII of first char * extern int ICONS; number of user-defineable characters reserved for icons + * extern int GOTO_COST; number of bytes a goto command requires + * extern int INVALIDATE; re-send a modified userdefined char? * * * these functions must be implemented by the real driver: @@ -200,6 +204,7 @@ typedef struct { int val2; DIRECTION dir; int segment; + int invalid; } BAR; typedef struct { @@ -214,12 +219,18 @@ static char *Section=NULL; static char *Driver=NULL; -int DROWS, DCOLS; /* display size */ -int LROWS, LCOLS; /* layout size */ -int XRES, YRES; /* pixels of one char cell */ -int GOTO_COST; /* number of bytes a goto command requires */ -int CHARS, CHAR0; /* number of user-defineable characters, ASCII of first char */ -int ICONS; /* number of user-defineable characters reserved for icons */ +int DROWS = 20; /* display size: rows */ +int DCOLS = 4; /* display size: columns */ +int LROWS = 20; /* layout size: rows */ +int LCOLS = 4; /* layout size: columns */ +int XRES = 6; /* pixels of one char cell */ +int YRES = 8; /* pixels of one char cell */ +int CHARS = 0; /* number of user-defineable characters */ +int CHAR0 = 0; /* ASCII of first user-defineable char */ +int ICONS = 0; /* number of user-defineable characters reserved for icons */ + +int GOTO_COST = 0; /* number of bytes a goto command requires */ +int INVALIDATE = 0; /* re-send a modified userdefined char? */ static char *LayoutFB = NULL; @@ -245,22 +256,22 @@ static void drv_generic_text_resizeFB (int rows, int cols) int i, row, col; /* Layout FB is large enough */ - if (rows<=LROWS && cols<=LCOLS) + if (rows <= LROWS && cols <= LCOLS) return; /* get maximum values */ - if (rows= 2) { for (i = 0; line2[i]; i++) { if (strlen(line2[i]) <= (unsigned)DCOLS) { - drv_generic_text_real_write (1, (DCOLS-strlen(line2[i]))/2, line2[i], strlen(line2[i])); + drv_generic_text_real_write (1, (DCOLS - strlen(line2[i])) / 2, line2[i], strlen(line2[i])); flag = 1; break; } @@ -367,7 +379,7 @@ int drv_generic_text_greet (const char *msg1, const char *msg2) if (msg1 && DROWS >= 3) { int len = strlen(msg1); if ( len <= DCOLS) { - drv_generic_text_real_write (2, (DCOLS-len)/2, msg1, len); + drv_generic_text_real_write (2, (DCOLS-len) / 2, msg1, len); flag = 1; } } @@ -375,7 +387,7 @@ int drv_generic_text_greet (const char *msg1, const char *msg2) if (msg2 && DROWS >= 4) { int len = strlen(msg2); if ( len <= DCOLS) { - drv_generic_text_real_write (3, (DCOLS-len)/2, msg2, len); + drv_generic_text_real_write (3, (DCOLS-len) / 2, msg2, len); flag = 1; } } @@ -386,15 +398,15 @@ int drv_generic_text_greet (const char *msg1, const char *msg2) int drv_generic_text_draw (WIDGET *W) { - WIDGET_TEXT *Text=W->data; + WIDGET_TEXT *Text = W->data; char *txt, *fb1, *fb2; int row, col, col0, len, end; - row=W->row; - col=W->col; - txt=Text->buffer; - len=strlen(txt); - end=col+len; + row = W->row; + col = W->col; + txt = Text->buffer; + len = strlen(txt); + end = col + len; /* maybe grow layout framebuffer */ drv_generic_text_resizeFB (row+1, col+len); @@ -403,21 +415,21 @@ int drv_generic_text_draw (WIDGET *W) fb2 = DisplayFB + row*DCOLS; /* transfer new text into layout buffer */ - memcpy (fb1+col, txt, len); + memcpy (fb1 + col, txt, len); if (rowGOTO_COST) break; + if (++equal > GOTO_COST) break; } else { - pos2=col; - equal=0; + pos2 = col; + equal = 0; } } memcpy ( fb2+pos1, fb1+pos1, pos2-pos1+1); @@ -433,17 +445,17 @@ int drv_generic_text_quit (void) { if (LayoutFB) { free(LayoutFB); - LayoutFB=NULL; + LayoutFB = NULL; } if (DisplayFB) { free(DisplayFB); - DisplayFB=NULL; + DisplayFB = NULL; } if (BarFB) { free (BarFB); - BarFB=NULL; + BarFB = NULL; } widget_unregister(); @@ -457,7 +469,7 @@ int drv_generic_text_quit (void) { int drv_generic_text_icon_init (void) { - if (cfg_number(Section, "Icons", 0, 0, CHARS, &ICONS)<0) return -1; + if (cfg_number(Section, "Icons", 0, 0, CHARS, &ICONS) < 0) return -1; if (ICONS>0) { info ("%s: reserving %d of %d user-defined characters for icons", Driver, ICONS, CHARS); } @@ -467,9 +479,11 @@ int drv_generic_text_icon_init (void) int drv_generic_text_icon_draw (WIDGET *W) { - static int icon_counter=0; + static int icon_counter = 0; WIDGET_ICON *Icon = W->data; int row, col; + int l_idx, d_idx; + int invalidate = 0; unsigned char ascii; row = W->row; @@ -479,34 +493,40 @@ int drv_generic_text_icon_draw (WIDGET *W) drv_generic_text_resizeFB (row+1, col+1); /* icon deactivated? */ - if (Icon->ascii==-2) return 0; + if (Icon->ascii == -2) return 0; /* ASCII already assigned? */ - if (Icon->ascii==-1) { - if (icon_counter>=ICONS) { + if (Icon->ascii == -1) { + if (icon_counter >= ICONS) { error ("cannot process icon '%s': out of icons", W->name); - Icon->ascii=-2; + Icon->ascii = -2; return -1; } icon_counter++; - Icon->ascii=CHAR0+CHARS-icon_counter; + Icon->ascii = CHAR0 + CHARS - icon_counter; } /* maybe redefine icon */ - if (Icon->curmap!=Icon->prvmap) { - drv_generic_text_real_defchar(Icon->ascii, Icon->bitmap+YRES*Icon->curmap); + if (Icon->curmap != Icon->prvmap && Icon->visible) { + Icon->prvmap = Icon->curmap; + drv_generic_text_real_defchar(Icon->ascii, Icon->bitmap + YRES * Icon->curmap); + invalidate = INVALIDATE; } /* use blank if invisible */ - ascii=Icon->visible?Icon->ascii:' '; + ascii = Icon->visible ? Icon->ascii : ' '; + /* index into the two framebuffers */ + l_idx = row * LCOLS + col; + d_idx = row * DCOLS + col; + /* transfer icon into layout buffer */ - LayoutFB[row*LCOLS+col]=ascii; + LayoutFB[l_idx] = ascii; /* maybe send icon to the display */ - if (row < DROWS && col < DCOLS && DisplayFB[row*DCOLS+col] != ascii) { - DisplayFB[row*DCOLS+col]=ascii; - drv_generic_text_real_write (row, col, DisplayFB+row*DCOLS+col, 1); + if (row < DROWS && col < DCOLS && (DisplayFB[d_idx] != ascii || invalidate)) { + DisplayFB[d_idx] = ascii; + drv_generic_text_real_write (row, col, DisplayFB + d_idx, 1); } return 0; @@ -522,14 +542,15 @@ static void drv_generic_text_bar_clear(void) { int i; - for (i=0; i 0 && col < LCOLS) { - BarFB[row*LCOLS+col].dir=dir; - BarFB[row*LCOLS+col].segment=-1; + BarFB[row*LCOLS+col].dir = dir; + BarFB[row*LCOLS+col].segment = -1; if (val1 >= XRES) { - BarFB[row*LCOLS+col].val1 = rev?0:XRES; + BarFB[row*LCOLS+col].val1 = rev ? 0 : XRES; val1 -= XRES; } else { - BarFB[row*LCOLS+col].val1 = rev?XRES-val1:val1; + BarFB[row*LCOLS+col].val1 = rev ? XRES-val1 : val1; val1 = 0; } if (val2 >= XRES) { - BarFB[row*LCOLS+col].val2 = rev?0:XRES; + BarFB[row*LCOLS+col].val2 = rev ? 0 : XRES; val2 -= XRES; } else { - BarFB[row*LCOLS+col].val2 = rev?XRES-val2:val2; + BarFB[row*LCOLS+col].val2 = rev ? XRES-val2 : val2; val2 = 0; } len--; @@ -608,27 +629,26 @@ static void drv_generic_text_bar_create_bar (int row, int col, const DIRECTION d case DIR_NORTH: while (len > 0 && row < LROWS) { - BarFB[row*LCOLS+col].dir=dir; - BarFB[row*LCOLS+col].segment=-1; + BarFB[row*LCOLS+col].dir = dir; + BarFB[row*LCOLS+col].segment = -1; if (val1 >= YRES) { - BarFB[row*LCOLS+col].val1 = rev?0:YRES; + BarFB[row*LCOLS+col].val1 = rev ? 0 : YRES; val1 -= YRES; } else { - BarFB[row*LCOLS+col].val1 = rev?YRES-val1:val1; + BarFB[row*LCOLS+col].val1 = rev ? YRES-val1 : val1; val1 = 0; } if (val2 >= YRES) { - BarFB[row*LCOLS+col].val2 = rev?0:YRES; + BarFB[row*LCOLS+col].val2 = rev ? 0 : YRES; val2 -= YRES; } else { - BarFB[row*LCOLS+col].val2 = rev?YRES-val2:val2; + BarFB[row*LCOLS+col].val2 = rev ? YRES - val2 : val2; val2 = 0; } len--; row++; } break; - } } @@ -639,35 +659,35 @@ static void drv_generic_text_bar_create_segments (void) int res, l1, l2; /* find first unused segment */ - for (i=fSegment; ires) l1=res; - l2 = Segment[i].val2; if (l2>res) l2=res; + l1 = Segment[i].val1; if (l1 > res) l1=res; + l2 = Segment[i].val2; if (l2 > res) l2=res; if (l1 == BarFB[n].val1 && l2 == BarFB[n].val2) break; } } - if (i==nSegment) { + if (i == nSegment) { nSegment++; - Segment[i].val1=BarFB[n].val1; - Segment[i].val2=BarFB[n].val2; - Segment[i].dir=BarFB[n].dir; - Segment[i].used=0; - Segment[i].ascii=-1; + Segment[i].val1 = BarFB[n].val1; + Segment[i].val2 = BarFB[n].val2; + Segment[i].dir = BarFB[n].dir; + Segment[i].used = 0; + Segment[i].ascii = -1; } - BarFB[n].segment=i; + BarFB[n].segment = i; } } @@ -677,25 +697,25 @@ static int drv_generic_text_bar_segment_error (const int i, const int j) int res; int i1, i2, j1, j2; - if (i==j) return 65535; + if (i == j) return 65535; if (!(Segment[i].dir & Segment[j].dir)) return 65535; res = Segment[i].dir&(DIR_EAST|DIR_WEST) ? XRES:YRES; - i1=Segment[i].val1; if (i1>res) i1=res; - i2=Segment[i].val2; if (i2>res) i2=res; - j1=Segment[j].val1; if (j1>res) j1=res; - j2=Segment[j].val2; if (j2>res) j2=res; + i1 = Segment[i].val1; if (i1 > res) i1 = res; + i2 = Segment[i].val2; if (i2 > res) i2 = res; + j1 = Segment[j].val1; if (j1 > res) j1 = res; + j2 = Segment[j].val2; if (j2 > res) j2 = res; - if (i1==0 && j1!=0) return 65535; - if (i2==0 && j2!=0) return 65535; - if (i1==res && j1 0) return 65535; - if (i2==1 && j2!=1 && j1 > 0) return 65535; - if (i1==i2 && j1!=j2) return 65535; + if (i1 == 0 && j1 != 0) return 65535; + if (i2 == 0 && j2 != 0) return 65535; + if (i1 == res && j1 < res) return 65535; + if (i2 == res && j2 < res) return 65535; + if (i1 == 1 && j1 != 1 && i2 > 0) return 65535; + if (i2 == 1 && j2 != 1 && j1 > 0) return 65535; + if (i1 == i2 && j1 != j2) return 65535; - return (i1-j1)*(i1-j1)+(i2-j2)*(i2-j2); + return (i1-j1)*(i1-j1) + (i2-j2)*(i2-j2); } @@ -710,30 +730,30 @@ static void drv_generic_text_bar_pack_segments (void) return; } - for (i=0; ifSegment+CHARS-ICONS) { + while (nSegment > fSegment + CHARS - ICONS) { - min=65535; - pack_i=-1; - pack_j=-1; - for (i=fSegment; i=fSegment) c+=CHAR0; /* ascii offset for user-defineable chars */ - if(c==LayoutFB[n]) continue; - LayoutFB[n]=c; + for (row = 0; row < LROWS; row++) { + for (col = 0; col < LCOLS; col++) { + n = row*LCOLS+col; + s = BarFB[n].segment; + if (s == -1) continue; + c = Segment[s].ascii; + if (c == -1) continue; + if (s >= fSegment) c += CHAR0; /* ascii offset for user-defineable chars */ + LayoutFB[n] = c; + /* maybe invalidate display framebuffer */ + if (BarFB[n].invalid) { + BarFB[n].invalid = 0; + DisplayFB[row*DCOLS+col] = ~LayoutFB[n]; + } + } } /* transfer differences to the display */ - for (row=0; rowGOTO_COST) break; + if (++equal > GOTO_COST) break; } else { - pos2=col; - equal=0; + pos2 = col; + equal = 0; } } memcpy ( DisplayFB+row*DCOLS+pos1, LayoutFB+row*LCOLS+pos1, pos2-pos1+1); diff --git a/drv_generic_text.h b/drv_generic_text.h index f45f055..572ea9f 100644 --- a/drv_generic_text.h +++ b/drv_generic_text.h @@ -1,4 +1,4 @@ -/* $Id: drv_generic_text.h,v 1.15 2004/06/26 12:04:59 reinelt Exp $ +/* $Id: drv_generic_text.h,v 1.16 2004/11/28 15:50:24 reinelt Exp $ * * generic driver helper for text-based displays * @@ -23,6 +23,9 @@ * * * $Log: drv_generic_text.h,v $ + * Revision 1.16 2004/11/28 15:50:24 reinelt + * Cwlinux fixes (invalidation of user-defined chars) + * * Revision 1.15 2004/06/26 12:04:59 reinelt * * uh-oh... the last CVS log message messed up things a lot... @@ -100,9 +103,10 @@ extern int DROWS, DCOLS; /* display size */ extern int LROWS, LCOLS; /* layout size */ extern int XRES, YRES; /* pixel width/height of one char */ -extern int GOTO_COST; /* number of bytes a goto command requires */ extern int CHARS, CHAR0; /* number of user-defineable characters, ASCII of first char */ extern int ICONS; /* number of user-defineable characters reserved for icons */ +extern int GOTO_COST; /* number of bytes a goto command requires */ +extern int INVALIDATE; /* re-send a modified userdefined char? */ /* these functions must be implemented by the real driver */ void (*drv_generic_text_real_write)(const int row, const int col, const char *data, const int len); diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample index 06e84f6..09ea972 100644 --- a/lcd4linux.conf.sample +++ b/lcd4linux.conf.sample @@ -32,16 +32,16 @@ Display CF631 { Port '/dev/tts/USB0' Speed 115200 Contrast 95 - Backlight 100 + Backlight 255 Icons 1 } Display CF632 { - Icons 7 Driver 'Crystalfontz' Model '632' Port '/dev/tts/0' Speed 19200 + Icons 1 } Display CF633 { @@ -687,14 +687,14 @@ Layout testMySQL { #Display 'SC1602D' #Display 'LCM-162' #Display 'CF631' -#Display 'CF632' +Display 'CF632' #Display 'CF633' #Display 'Curses' #Display 'M50530-24x8' #Display 'CT20x4' #Display 'T6963-240x64' #Display 'XWindow' -Display 'USBLCD' +#Display 'USBLCD' #Display 'BWCT' #Display 'Image' diff --git a/widget_icon.c b/widget_icon.c index 294a95e..f858ae5 100644 --- a/widget_icon.c +++ b/widget_icon.c @@ -1,4 +1,4 @@ -/* $Id: widget_icon.c,v 1.14 2004/06/26 12:05:00 reinelt Exp $ +/* $Id: widget_icon.c,v 1.15 2004/11/28 15:50:24 reinelt Exp $ * * icon widget handling * @@ -21,6 +21,9 @@ * * * $Log: widget_icon.c,v $ + * Revision 1.15 2004/11/28 15:50:24 reinelt + * Cwlinux fixes (invalidation of user-defined chars) + * * Revision 1.14 2004/06/26 12:05:00 reinelt * * uh-oh... the last CVS log message messed up things a lot... @@ -181,15 +184,12 @@ void widget_icon_update (void *Self) /* rotate icon bitmap */ Icon->curmap++; if (Icon->curmap >= Icon->maxmap) - Icon->curmap=0; + Icon->curmap = 0; /* finally, draw it! */ if (W->class->draw) W->class->draw(W); - /* store currently visible bitmap */ - Icon->prvmap=Icon->curmap; - /* add a new one-shot timer */ timer_add (widget_icon_update, Self, Icon->speed, 1); -- cgit v1.2.3