Add a flush method to the hardware depended functions. It is called whenever
a sequence of characters or commands have to be terminated (common_init, position, flush). Modify the lcd2usb subdriver to implement a small command buffer and implement flush().
This commit is contained in:
@@ -21,6 +21,7 @@ v.0.5dev (ongoing development)
|
|||||||
* hd44780: Change mapping for spanish 'n with tilde' characters
|
* hd44780: Change mapping for spanish 'n with tilde' characters
|
||||||
* hd44780: Exclude pin for switchable backlight from keypad scanning
|
* hd44780: Exclude pin for switchable backlight from keypad scanning
|
||||||
* server core: New network input buffering
|
* server core: New network input buffering
|
||||||
|
* hd44780: Extended subdriver API and performance improvement for lcd2usb
|
||||||
|
|
||||||
v0.5.3
|
v0.5.3
|
||||||
+ lcdexec: notification when called program finishes
|
+ lcdexec: notification when called program finishes
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ void lcd2usb_HD44780_backlight(PrivateData *p, unsigned char state);
|
|||||||
unsigned char lcd2usb_HD44780_scankeypad(PrivateData *p);
|
unsigned char lcd2usb_HD44780_scankeypad(PrivateData *p);
|
||||||
void lcd2usb_HD44780_close(PrivateData *p);
|
void lcd2usb_HD44780_close(PrivateData *p);
|
||||||
void lcd2usb_HD44780_set_contrast(PrivateData *p, unsigned char value);
|
void lcd2usb_HD44780_set_contrast(PrivateData *p, unsigned char value);
|
||||||
|
void lcd2usb_HD44780_flush(PrivateData *p);
|
||||||
|
|
||||||
|
/* small data buffer */
|
||||||
|
unsigned char buffer[LCD2USB_MAX_CMD];
|
||||||
|
int buffer_current_type_id = -1;
|
||||||
|
int buffer_current_use = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,6 +69,7 @@ hd_init_lcd2usb(Driver *drvthis)
|
|||||||
p->hd44780_functions->scankeypad = lcd2usb_HD44780_scankeypad;
|
p->hd44780_functions->scankeypad = lcd2usb_HD44780_scankeypad;
|
||||||
p->hd44780_functions->close = lcd2usb_HD44780_close;
|
p->hd44780_functions->close = lcd2usb_HD44780_close;
|
||||||
p->hd44780_functions->set_contrast = lcd2usb_HD44780_set_contrast;
|
p->hd44780_functions->set_contrast = lcd2usb_HD44780_set_contrast;
|
||||||
|
p->hd44780_functions->flush = lcd2usb_HD44780_flush;
|
||||||
|
|
||||||
/* try to find USB device */
|
/* try to find USB device */
|
||||||
#if 0
|
#if 0
|
||||||
@@ -116,9 +123,9 @@ hd_init_lcd2usb(Driver *drvthis)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send data or commands to the display.
|
* Send data or command to the display. The data/command is internally
|
||||||
|
* queued.
|
||||||
* \param p Pointer to driver's private data structure.
|
* \param p Pointer to driver's private data structure.
|
||||||
* \param displayID ID of the display (or 0 for all) to send data to.
|
* \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 flags Defines whether to end a command or data.
|
||||||
@@ -131,9 +138,41 @@ lcd2usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char
|
|||||||
int id = (displayID == 0) ? LCD2USB_CTRL_BOTH
|
int id = (displayID == 0) ? LCD2USB_CTRL_BOTH
|
||||||
: ((displayID == 1) ? LCD2USB_CTRL_0 : LCD2USB_CTRL_1);
|
: ((displayID == 1) ? LCD2USB_CTRL_0 : LCD2USB_CTRL_1);
|
||||||
|
|
||||||
usb_control_msg(p->usbHandle, USB_TYPE_VENDOR, (type | id), ch, 0, NULL, 0, 1000);
|
/* flush current buffer if target or command type are different */
|
||||||
|
if ((buffer_current_type_id >= 0) && (buffer_current_type_id != (type | id)))
|
||||||
|
lcd2usb_HD44780_flush(p);
|
||||||
|
|
||||||
|
/* add new item to buffer */
|
||||||
|
buffer_current_type_id = (type | id);
|
||||||
|
buffer[buffer_current_use++] = ch;
|
||||||
|
|
||||||
|
/* flush buffer if it's full */
|
||||||
|
if (buffer_current_use == LCD2USB_MAX_CMD)
|
||||||
|
lcd2usb_HD44780_flush(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually send data or command to the display.
|
||||||
|
* \param p Pointer to driver's private data structure.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lcd2usb_HD44780_flush(PrivateData *p)
|
||||||
|
{
|
||||||
|
/* only if some data available */
|
||||||
|
if (buffer_current_use == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* construct and send message */
|
||||||
|
usb_control_msg(p->usbHandle, USB_TYPE_VENDOR,
|
||||||
|
buffer_current_type_id | (buffer_current_use - 1),
|
||||||
|
buffer[0] | (buffer[1] << 8),
|
||||||
|
buffer[2] | (buffer[3] << 8),
|
||||||
|
NULL, 0, 1000);
|
||||||
|
|
||||||
|
/* buffer is now free again. Not necessary to clear what's in it. */
|
||||||
|
buffer_current_type_id = -1;
|
||||||
|
buffer_current_use = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn display backlight on or off.
|
* Turn display backlight on or off.
|
||||||
@@ -171,31 +210,6 @@ lcd2usb_HD44780_set_contrast(PrivateData *p, unsigned char value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Read keypress.
|
||||||
* \param p Pointer to driver's private data structure.
|
* \param p Pointer to driver's private data structure.
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
#define LCD2USB_VENDORID 0x0403
|
#define LCD2USB_VENDORID 0x0403
|
||||||
#define LCD2USB_PRODUCTID 0xc630
|
#define LCD2USB_PRODUCTID 0xc630
|
||||||
|
|
||||||
|
/* current protocol supports up to 4 bytes */
|
||||||
|
#define LCD2USB_MAX_CMD 4
|
||||||
|
|
||||||
/* target is a bit map for CMD/DATA */
|
/* target is a bit map for CMD/DATA */
|
||||||
#define LCD2USB_CTRL_0 (1<<3)
|
#define LCD2USB_CTRL_0 (1<<3)
|
||||||
#define LCD2USB_CTRL_1 (1<<4)
|
#define LCD2USB_CTRL_1 (1<<4)
|
||||||
|
|||||||
@@ -216,6 +216,10 @@ typedef struct hwDependentFns {
|
|||||||
// ch - character to display or instruction value
|
// ch - character to display or instruction value
|
||||||
void (*senddata)(PrivateData *p, unsigned char dispID, unsigned char flags, unsigned char ch);
|
void (*senddata)(PrivateData *p, unsigned char dispID, unsigned char flags, unsigned char ch);
|
||||||
|
|
||||||
|
// Flush data to the display. To be used by subdrivers that
|
||||||
|
// queue from senddata internally.
|
||||||
|
void (*flush)(PrivateData *p);
|
||||||
|
|
||||||
// Switch the backlight on or off
|
// Switch the backlight on or off
|
||||||
// state - to be or not to be on
|
// state - to be or not to be on
|
||||||
void (*backlight)(PrivateData *p, unsigned char state);
|
void (*backlight)(PrivateData *p, unsigned char state);
|
||||||
@@ -242,6 +246,7 @@ typedef struct hwDependentFns {
|
|||||||
// Close the interface on shutdown
|
// Close the interface on shutdown
|
||||||
void (*close)(PrivateData *p);
|
void (*close)(PrivateData *p);
|
||||||
|
|
||||||
|
|
||||||
} HD44780_functions; /* for want of a better name :-) */
|
} HD44780_functions; /* for want of a better name :-) */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -387,6 +387,7 @@ HD44780_init(Driver *drvthis)
|
|||||||
p->hd44780_functions->scankeypad = NULL;
|
p->hd44780_functions->scankeypad = NULL;
|
||||||
p->hd44780_functions->output = NULL;
|
p->hd44780_functions->output = NULL;
|
||||||
p->hd44780_functions->close = NULL;
|
p->hd44780_functions->close = NULL;
|
||||||
|
p->hd44780_functions->flush = NULL;
|
||||||
|
|
||||||
// Do local (=connection type specific) display init
|
// Do local (=connection type specific) display init
|
||||||
if (init_fn(drvthis) != 0)
|
if (init_fn(drvthis) != 0)
|
||||||
@@ -499,6 +500,8 @@ common_init(PrivateData *p, unsigned char if_bit)
|
|||||||
p->hd44780_functions->uPause(p, 40);
|
p->hd44780_functions->uPause(p, 40);
|
||||||
p->hd44780_functions->senddata(p, 0, RS_INSTR, HOMECURSOR);
|
p->hd44780_functions->senddata(p, 0, RS_INSTR, HOMECURSOR);
|
||||||
p->hd44780_functions->uPause(p, 1600);
|
p->hd44780_functions->uPause(p, 1600);
|
||||||
|
if (p->hd44780_functions->flush != NULL)
|
||||||
|
p->hd44780_functions->flush(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -627,6 +630,8 @@ HD44780_position(Driver *drvthis, int x, int y)
|
|||||||
}
|
}
|
||||||
p->hd44780_functions->senddata(p, dispID, RS_INSTR, POSITION | DDaddr);
|
p->hd44780_functions->senddata(p, dispID, RS_INSTR, POSITION | DDaddr);
|
||||||
p->hd44780_functions->uPause(p, 40); // Minimum exec time for all commands
|
p->hd44780_functions->uPause(p, 40); // Minimum exec time for all commands
|
||||||
|
if (p->hd44780_functions->flush != NULL)
|
||||||
|
p->hd44780_functions->flush(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -703,6 +708,8 @@ HD44780_flush(Driver *drvthis)
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (p->hd44780_functions->flush != NULL)
|
||||||
|
p->hd44780_functions->flush(p);
|
||||||
debug(RPT_DEBUG, "%s: flushed %d custom chars", drvthis->name, count);
|
debug(RPT_DEBUG, "%s: flushed %d custom chars", drvthis->name, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user