]> git.webhop.me Git - lcd4linux.git/commitdiff
keypad and firmware support for Cwlinux (patch from Volker Gering)
authormichael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 20 Apr 2007 04:53:19 +0000 (04:53 +0000)
committermichael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 20 Apr 2007 04:53:19 +0000 (04:53 +0000)
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@785 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

drv_Cwlinux.c

index 151140c91b6553a8bfaa6cb20f72da0317419da7..35a7a206b5c0bdaae54a4c0f4d4c74acf28db40f 100644 (file)
 #include "debug.h"
 #include "cfg.h"
 #include "qprintf.h"
+#include "timer.h"
 #include "plugin.h"
 #include "widget.h"
 #include "widget_text.h"
 #include "widget_icon.h"
 #include "widget_bar.h"
+#include "widget_keypad.h"
 #include "drv.h"
 #include "drv_generic_text.h"
 #include "drv_generic_gpio.h"
 #include "drv_generic_serial.h"
+#include "drv_generic_keypad.h"
 
 
 static char Name[] = "Cwlinux";
@@ -58,13 +61,21 @@ static char Name[] = "Cwlinux";
 static int Model;
 static int Protocol;
 
+/* ring buffer for bytes received from the display */
+static unsigned char RingBuffer[256];
+static unsigned int RingRPos = 0;
+static unsigned int RingWPos = 0;
+
 typedef struct {
     int type;
     char *name;
     int rows;
     int cols;
-    int xres;
+    int xres;                  /* pixel width of one char */
+    int yres;                  /* pixel height of one char */
     int gpos;
+    int gpis;
+    int chars;                 /* number of user definable chars */
     int protocol;
 } MODEL;
 
@@ -72,9 +83,9 @@ typedef struct {
 /* Fixme: number of gpo's should be verified */
 
 static MODEL Models[] = {
-    {0x01, "CW1602", 2, 16, 5, 0, 1},
-    {0x02, "CW12232", 4, 20, 6, 0, 2},
-    {0xff, "Unknown", -1, -1, -1, -1, -1}
+    {0x01, "CW1602", 2, 16, 5, 7, 2, 2, 8, 1},
+    {0x02, "CW12232", 4, 20, 6, 8, 2, 2, 16, 2},
+    {0xff, "Unknown", -1, -1, -1, -1, -1, -1, -1, -1}
 };
 
 
@@ -82,10 +93,55 @@ static MODEL Models[] = {
 /***  hardware dependant functions    ***/
 /****************************************/
 
+static void drv_CW_process_input(void)
+{
+    while (RingRPos != RingWPos) {
+       drv_generic_keypad_press(RingBuffer[RingRPos++]);
+       if (RingRPos >= sizeof(RingBuffer))
+           RingRPos = 0;
+    }
+}
+
+
+static int drv_CW_poll(void)
+{
+    while (1) {
+       char buffer[32];
+       int num, n;
+
+       num = drv_generic_serial_poll(buffer, sizeof(buffer));
+       if (num <= 0)
+           break;              /* no more input */
+
+       /* put result into RingBuffer */
+       for (n = 0; n < num; n++) {
+           RingBuffer[RingWPos++] = (unsigned char) buffer[n];
+           if (RingWPos >= sizeof(RingBuffer))
+               RingWPos = 0;
+       }
+    }
+
+    if (RingRPos != RingWPos)
+       return 1;
+    else
+       return 0;
+}
+
+
+static void drv_CW_timer(void __attribute__ ((unused)) * notused)
+{
+    while (drv_CW_poll()) {
+       drv_CW_process_input();
+    }
+}
+
+
 static void drv_CW_send(const char *string, const int len)
 {
     drv_generic_serial_write(string, len);
     usleep(20);
+    if (drv_CW_poll())
+       drv_CW_process_input();
 }
 
 
@@ -145,6 +201,16 @@ static int drv_CW_GPO(const int num, const int val)
 }
 
 
+static int drv_CW_GPI(const int num)
+{
+    if (num < 0 || num > GPIS) {
+       return 0;
+    }
+    error("%s: GPI's not yet implemented!", Name);
+    return num;
+}
+
+
 static void drv_CW_clear(void)
 {
 #if 1
@@ -194,10 +260,43 @@ static int drv_CW_brightness(int brightness)
 }
 
 
+static int drv_CW_keypad(const int num)
+{
+    int val = WIDGET_KEY_PRESSED;
+
+    switch (num) {
+    case 65:
+       val += WIDGET_KEY_UP;
+       break;
+    case 66:
+       val += WIDGET_KEY_DOWN;
+       break;
+    case 67:
+       val += WIDGET_KEY_LEFT;
+       break;
+    case 68:
+       val += WIDGET_KEY_RIGHT;
+       break;
+    case 69:
+       val += WIDGET_KEY_CONFIRM;
+       break;
+    case 70:
+       val += WIDGET_KEY_CANCEL;
+       break;
+    default:
+       error("%s: unknown keypad value %d", Name, num);
+    }
+
+    debug("%s: key %c (0x%x) pressed", Name, num, num);
+    return val;
+}
+
+
 static int drv_CW_start(const char *section)
 {
     int i;
     char *model;
+    char buffer[16];
 
     model = cfg_get(section, "Model", NULL);
     if (model != NULL && *model != '\0') {
@@ -220,28 +319,37 @@ static int drv_CW_start(const char *section)
     if (drv_generic_serial_open(section, Name, 0) < 0)
        return -1;
 
-    /* this does not work as I'd expect it... */
-#if 0
     /* read firmware version */
-    generic_serial_read(buffer, sizeof(buffer));
-    usleep(100000);
-    generic_serial_write("\3761", 2);
-    usleep(100000);
-    generic_serial_write("\375", 1);
+    drv_generic_serial_write("\3761\375", 3);
     usleep(100000);
-    if (generic_serial_read(buffer, 2) != 2) {
+    if (drv_generic_serial_read(buffer, 2) != 2) {
        info("unable to read firmware version!");
+    } else {
+       info("Cwlinux Firmware V%d.%d", (int) buffer[0], (int) buffer[1]);
+    }
+
+    /* read model mumber */
+    drv_generic_serial_write("\3760\375", 3);
+    usleep(100000);
+    if (drv_generic_serial_read(buffer, 2) != 2) {
+       info("unable to read model number!");
+    } else {
+       info("Cwlinux model CW%d%d", (int) buffer[0], (int) buffer[1]);
     }
-    info("Cwlinux Firmware %d.%d", (int) buffer[0], (int) buffer[1]);
-#endif
 
     /* initialize global variables */
     DROWS = Models[Model].rows;
     DCOLS = Models[Model].cols;
     XRES = Models[Model].xres;
+    YRES = Models[Model].yres;
     GPOS = Models[Model].gpos;
+    GPIS = Models[Model].gpis;
+    CHARS = Models[Model].chars;
     Protocol = Models[Model].protocol;
 
+    /* regularly process display input */
+    timer_add(drv_CW_timer, NULL, 250, 0);
+
     drv_CW_clear();
 
     drv_CW_send("\376D\375", 3);       /* auto line wrap off */
@@ -291,6 +399,7 @@ static void plugin_brightness(RESULT * result, const int argc, RESULT * argv[])
 /* using drv_generic_text_icon_draw(W) */
 /* using drv_generic_text_bar_draw(W) */
 /* using drv_generic_gpio_draw(W) */
+/* using drv_generic_keypad_draw(W) */
 
 
 /****************************************/
@@ -319,9 +428,6 @@ int drv_CW_init(const char *section, const int quiet)
     info("%s: %s", Name, "$Rev$");
 
     /* display preferences */
-    XRES = 6;                  /* pixel width of one char  */
-    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 */
     INVALIDATE = 1;            /* re-defined chars must be re-sent to the display */
@@ -333,6 +439,8 @@ int drv_CW_init(const char *section, const int quiet)
     /* real worker functions */
     drv_generic_text_real_write = drv_CW_write;
     drv_generic_gpio_real_set = drv_CW_GPO;
+    drv_generic_gpio_real_get = drv_CW_GPI;
+    drv_generic_keypad_real_press = drv_CW_keypad;
 
     switch (Protocol) {
     case 1:
@@ -371,6 +479,10 @@ int drv_CW_init(const char *section, const int quiet)
     if ((ret = drv_generic_gpio_init(section, Name)) != 0)
        return ret;
 
+    /* initialize generic key pad driver */
+    if ((ret = drv_generic_keypad_init(section, Name)) != 0)
+       return ret;
+
     /* register text widget */
     wc = Widget_Text;
     wc.draw = drv_generic_text_draw;
@@ -400,6 +512,7 @@ int drv_CW_quit(const int quiet)
     info("%s: shutting down.", Name);
     drv_generic_text_quit();
     drv_generic_gpio_quit();
+    drv_generic_keypad_quit();
 
     /* clear display */
     drv_CW_clear();