diff --git a/ChangeLog b/ChangeLog index 50f72c3..d74b49e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,6 +37,7 @@ v.0.5dev (ongoing development) * server core: display values in menu for all input MenuEntry types * hd44780 driver: reorganize ConnectionType recognition + hd44780 driver: new ConnectionType mplay + + hd44780 driver: get/set contrast & brightness support for lcd2usb (M. Dolze) v.0.5.2 * fix switching on/off the Load screen in lcdproc client using the menu diff --git a/LCDd.conf b/LCDd.conf index f787e89..841cbe9 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -443,6 +443,7 @@ Contrast=0 # Set brightness of the backlight (lcd2usb only) [default: 0; legal 0 - 1000] #Brightness=1000 +#OffBrightness=0 # If you have a switchable backlight. Backlight=no diff --git a/docs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook index c82a3e3..6f3ac77 100644 --- a/docs/lcdproc-user/drivers/hd44780.docbook +++ b/docs/lcdproc-user/drivers/hd44780.docbook @@ -1882,9 +1882,10 @@ One for each key and one if the keys are pressed simultaneously. With this menus Besides the standard configuration options for hd44780 displays, the -lcd2usb connection type supports two additional options: -Contrast= to set the display's contrast and -Brightness= to set the display's brightness. +lcd2usb connection type supports three additional options: +Contrast= to set the display's contrast, +Brightness= to set the display's brightness when is backlight is switched on and +OffBrightness= to set the display's brightness when is backlight is switched off. Both options expect a number in the range from 0 to 1000. @@ -1901,7 +1902,9 @@ DownKey=Down ConnectionType=lcd2usb Contrast=850 Brightness=800 +OffBrightness=0 Keypad=yes +Backlight=yes Size=20x2 KeyDirect_1=Enter KeyDirect_2=Down diff --git a/server/drivers/hd44780-lcd2usb.c b/server/drivers/hd44780-lcd2usb.c index 55bc08c..6509859 100644 --- a/server/drivers/hd44780-lcd2usb.c +++ b/server/drivers/hd44780-lcd2usb.c @@ -5,6 +5,7 @@ */ /* Copyright (C) 2007 Peter Marschall + * 2007 Markus Dolze * * This file is released under the GNU General Public License. Refer to the * COPYING file distributed with this package. @@ -28,26 +29,25 @@ static usb_dev_handle *lcd2usb; -// initialize the driver +/** + * Initialize the driver. + * \param drvthis Pointer to driver structure. + * \retval 0 Success. + * \retval -1 Error. + */ int hd_init_lcd2usb(Driver *drvthis) { PrivateData *p = (PrivateData*) drvthis->private_data; struct usb_bus *bus; - //char device_manufacturer[LCD_MAX_WIDTH+1] = ""; - int contrast = -1; /* illegal contrast value (to detect errors) */ - int brightness = -1; /* illegal brightness value (to detect errors) */ p->hd44780_functions->senddata = lcd2usb_HD44780_senddata; p->hd44780_functions->backlight = lcd2usb_HD44780_backlight; p->hd44780_functions->scankeypad = lcd2usb_HD44780_scankeypad; p->hd44780_functions->close = lcd2usb_HD44780_close; - - /* Read config file's contents: contrast */ - - contrast = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST); - brightness = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); + drvthis->set_contrast = lcd2usb_set_contrast; + drvthis->set_brightness = lcd2usb_set_brightness; /* try to find USB device */ #if 0 @@ -72,22 +72,14 @@ hd_init_lcd2usb(Driver *drvthis) lcd2usb = usb_open(dev); if (lcd2usb == NULL) { report(RPT_WARNING, "hd_init_lcd2usb: unable to open device"); - // return -1; /* it's better to continue */ } else { - /* get device information & check for serial number */ - //if (usb_get_string_simple(lcd2usb, dev->descriptor.iManufacturer, - // manufacturer, LCD_MAX_WIDTH) <= 0) - // *manufacturer = '\0'; - //manufacturer[sizeof(manufacturer)-1] = '\0'; + /* read firmware version */ + unsigned char buffer[2]; - //if (usb_get_string_simple(lcd2usb, dev->descriptor.iProduct, - // product, LCD_MAX_WIDTH) <= 0) - // *product = '\0'; - //product[sizeof(product)-1] = '\0'; - - //usb_close(lcd2usb); - //lcd2usb = NULL; + if (usb_control_msg(lcd2usb, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + LCD2USB_GET_FWVER, 0, 0, (char *)buffer, sizeof(buffer), 1000) == 2) + report(RPT_INFO, "hd_init_lcd2usb: device with firmware version %d.%02d found", buffer[0], buffer[1]); } } } @@ -95,7 +87,6 @@ hd_init_lcd2usb(Driver *drvthis) if (lcd2usb != NULL) { debug(RPT_DEBUG, "hd_init_lcd2usb: opening device succeeded"); - } else { report(RPT_ERR, "hd_init_lcd2usb: no (matching) LCD2USB device found"); @@ -104,48 +95,102 @@ hd_init_lcd2usb(Driver *drvthis) common_init(p, IF_4BIT); - /* set contrast */ - if ((0 <= contrast) && (contrast <= 1000)) { - int res = usb_control_msg(lcd2usb, USB_TYPE_VENDOR, LCD2USB_SET_CONTRAST, - (contrast * 255) / 1000, 0, NULL, 0, 1000); - if (res < 0) - report(RPT_WARNING, "hd_init_lcd2usb: setting contrast failed"); - } else { - report(RPT_INFO, "hd_init_lcd2usb: Using default contrast value"); - } - - /* set brightness */ - if ((0 <= brightness) && (brightness <= 1000)) { - int res = usb_control_msg(lcd2usb, USB_TYPE_VENDOR, LCD2USB_SET_BRIGHTNESS, - (brightness * 255) / 1000, 0, NULL, 0, 1000); - if (res < 0) - report(RPT_WARNING, "hd_init_lcd2usb: setting brightness failed"); - } else { - report(RPT_INFO, "hd_init_lcd2usb: Using default brightness value"); - } + /* set contrast: value comes from global hd44780 init */ + lcd2usb_set_contrast(drvthis, p->contrast); return 0; } -// lcd2usb_HD44780_senddata +/** + * Send data or commands to the display. + * \param p Pointer to driver's data structure. + * \param displayID ID of the display (or 0 for all) to send data to. + * \param flags Defines whether to end a command or data. + * \param ch The value to send. + */ void lcd2usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { -int type = (flags == RS_DATA) ? LCD2USB_DATA : LCD2USB_CMD; -int id = (displayID == 0) ? LCD2USB_CTRL_BOTH + int type = (flags == RS_DATA) ? LCD2USB_DATA : LCD2USB_CMD; + int id = (displayID == 0) ? LCD2USB_CTRL_BOTH : ((displayID == 1) ? LCD2USB_CTRL_0 : LCD2USB_CTRL_1); - usb_control_msg(lcd2usb, USB_TYPE_VENDOR, (type | id), ch, 0, NULL, 0, 1000); + usb_control_msg(lcd2usb, USB_TYPE_VENDOR, (type | id), ch, 0, NULL, 0, 1000); } +/** + * Turn the LCD backlight on or off. + * \param p Pointer to driver's data structure. + * \param state New backlight status. + */ void lcd2usb_HD44780_backlight(PrivateData *p, unsigned char state) { + // Get backlight brightness. + int promille = (state == BACKLIGHT_ON) ? p->brightness : p->offbrightness; + + // And set it (converted from [0,1000] -> [0,255]). + usb_control_msg(lcd2usb, USB_TYPE_VENDOR, LCD2USB_SET_BRIGHTNESS, + (promille * 255) / 1000, 0, NULL, 0, 1000); } +/** + * Change LCD contrast. + * \param drvthis Pointer to driver structure. + * \param promille New contrast value in promille. + */ +void +lcd2usb_set_contrast(Driver *drvthis, int promille) +{ + PrivateData *p = drvthis->private_data; + + // Check if value within range + if ((promille < 0) || (promille > 1000)) + return; + + // And set it (converted from [0,1000] -> [0,255]). + // If successful, update the local value. + if (usb_control_msg(lcd2usb, USB_TYPE_VENDOR, LCD2USB_SET_CONTRAST, + (promille * 255) / 1000, 0, NULL, 0, 1000) < 0) + report(RPT_WARNING, "hd_init_lcd2usb: setting contrast failed"); + else + p->contrast = promille; +} + + +/** + * Set on/off brightness. + * The value is not actually transmitted to the display. lcd2usb_hd44780_backlight + * has to be called to do this. + * \param drvthis Pointer to driver structure. + * \param state Brightness state (on/off) for which we want to store the value. + * \param promille New brightness in promille. + */ +void +lcd2usb_set_brightness(Driver *drvthis, int state, int promille) +{ + PrivateData *p = drvthis->private_data; + + // Check if value within range + if (promille < 0 || promille > 1000) + return; + + /* store the software value */ + if (state == BACKLIGHT_ON) + p->brightness = promille; + else + p->offbrightness = promille; +} + + +/** + * Read keypress. + * \param p Pointer to driver's data structure. + * \return Bitmap of the pressed keys. + */ unsigned char lcd2usb_HD44780_scankeypad(PrivateData *p) { @@ -164,6 +209,11 @@ lcd2usb_HD44780_scankeypad(PrivateData *p) return '\0'; } + +/** + * Close the driver (do necessary clean-up). + * \param p Pointer to driver's data structure. + */ void lcd2usb_HD44780_close(PrivateData *p) { diff --git a/server/drivers/hd44780-lcd2usb.h b/server/drivers/hd44780-lcd2usb.h index 27d5e66..bf5e3ad 100644 --- a/server/drivers/hd44780-lcd2usb.h +++ b/server/drivers/hd44780-lcd2usb.h @@ -31,10 +31,6 @@ #define LCD2USB_GET_CTRL (LCD2USB_GET | (2<<3)) #define LCD2USB_GET_RESERVED1 (LCD2USB_GET | (3<<3)) -#define DEFAULT_CONTRAST 300 -#define DEFAULT_BRIGHTNESS 600 -#define DEFAULT_OFFBRIGHTNESS 300 - // initialise this particular driver int hd_init_lcd2usb(Driver *drvthis); @@ -42,5 +38,8 @@ void lcd2usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned void lcd2usb_HD44780_backlight(PrivateData *p, unsigned char state); unsigned char lcd2usb_HD44780_scankeypad(PrivateData *p); void lcd2usb_HD44780_close(PrivateData *p); +void lcd2usb_set_contrast(Driver *drvthis, int promille); +void lcd2usb_set_brightness(Driver *drvthis, int state, int promille); + #endif