This driver supports display modules based on the Mitsubishi M50530 chip. These displays are made by different manufactures, and come in various sizes. The main difference between the M50530 and the HD44780 is that the M50530 can control much larger displays (mine has 8 rows and 24 columns).

The displays are connected to the parallel board (see “Wiring” below), and are quite timing-critical. There's no way to delay a usermode program under Linux for e.g. 40 usec, so we have to do busy-waiting. This has been done in a delay loop, which had to be calibrated. Since 0.98 there are two new delay loops, one based on the processor's TSC (Time Stamp Counter), one based on gettimeofday(). LCD4Linux decides automatically which one to use (it prefers the TSC method, but falls back to gettimeofday() if neither the TSC flag nor the MHz value is set in /proc/cpuinfo). Calibration is no longer necessary!

The driver knows of two ways of controlling the parallel port: The (old, ugly and unportable) raw programming of ports, and the new, cool, great ppdev() style. You decide which one to use by specifying either a hexadecimal value or a device file with the 'Port' entry in the config file.

Note that the old port programming only works with standard ports (0x3f8, 0x2f8,…), but not with PCI parallel port cards. Also, some secured linux systems (LEAF kernels with the grsecurity patches being one) do not allow a userspace program to do raw I/O (not even if running as root), so you have to use ppdev there anyway.

Using ppdev requires kernel 2.4 or newer, and the ppdev kernel module loaded. The configure script detects if you have the required include files, and deactivates ppdev if they are not there. You should use ppdev whenever possible! Raw port access may be dropped someday.

Note that you have to use parport devices (usually /dev/parports/* or /dev/parport* with major number 99), the printer devices (/dev/printers/* with major number 6) do NOT work! If you are using devfs or udev, these devices may become visible as soon as you load the ppdev kernel module.

The driver fully supports the text, bar and icon widgets.

Display <name> {
    Driver 'M50530'
    Model  'M50530'
    Port   <string>
    Size   <string>
    Font   <string>
    Duty   <number>
    UseBusy <0|1>
    Icons  <number>
    GPOs   <number>
    Wire {
	RW   <string>
	EX   <string>
	IOC1 <string>
	IOC2 <string>
	GPO  <string>
    Timing {
        fuzz      <percentage>
        SU        <number of nanoseconds>
        W         <number of nanoseconds>
        D         <number of nanoseconds>
        H         <number of nanoseconds>
        GPO_ST    <number of nanoseconds>
        GPO_PW    <number of nanoseconds>
        EXEC      <number of microseconds>
        CLEAR     <number of microseconds>
        INIT      <number of microseconds>

Model'M50530' (maybe someday we'll find other models)
Porteither the hexadecimal address of the parallel port ('0x378') or a ppdev device ('/dev/parports/0')
Size<columns>x<rows> e.g. '16×2'
Fonteither '5×7' (the default) or '5×11', according to your display
Dutydescribes the internal layout, if the default (2) does not work for you, try 0 or 1
!UseBusy0 (don't use Busy-Flag checking, default) or 1 (use Busy-Flag checking)
IconsNumber of user-defined chars reserved for Icons (default: 0)
GPOsnumber of general purpose outputs, use 0 (zero, which is the default) to deactivate this feature
Wire.*see below
Timing.*see below

Display M50530-24x8 {
    Driver    'M50530'
    Model     'M50530'
    Port      '/dev/parport0'	
    Size      '24x8'
    Font      '5x7'
    Duty       2
    UseBusy    0
    Wire.RW   'GND'
    Wire.EX   'STROBE'
    Wire.IOC1 'SLCTIN'
    Wire.IOC2 'AUTOFD'
    Wire.GPO  'GND'

My M50530-based display has 16 pins. Power (+5V) must be supplied via pins 15 (VCC) and 16 (GND), be careful not to change polarity, you will destroy your display! Pin 14 is used to control the contrast, it needs a positive voltage of about 10 V (it really needs more than 5V! It took me weeks to find out that my display is not dead :-) I used a potentiometer (10k) between GND and +12V, and connect VFF (pin 14) to the slider.

Starting with lcd4linux 0.9.9, there's a parallel port abstraction layer which makes the wiring completely configurable! (this is what the Wire.xy entries in the configuration are for). If you use a different wiring scheme, you have to change these lines accordingly.

The wiring configuration uses abstract signal names (e.g. STROBE) instead of pin numbers on the parallel port. So here's a translation table:


My M50530 display has 16 pins:

1SHIELDShield, usually connected to GND
2DB0Data Bit 0
3DB1Data Bit 1
4DB2Data Bit 2
5DB3Data Bit 3
6DB4Data Bit 4
7DB5Data Bit 5
8DB6Data Bit 6
9DB7Data Bit 7
10EXExecute (instruction start signal)
12I/OC2Input/Output control signal 2
13I/OC1Input/Output control signal 1
14VFFcontrast voltage 0..10V
15VCCsupply voltage +5V

Now for the wiring details:

  • The data lines (DB0..DB7 on the display, DB0..DB7 on the parallel port) are connected directly.
  • The “RW” signal from the display may be harwired to GND, we do not read anything from the display. If you want to use busy-flag checking, you have to connect it to a control signal, which must be specified with the Wire.RW line. LCD4Linux's default is GND
  • The “EX” signal has to be connected to one of the control signals (STROBE, SLCTIN, AUTOFD or INIT). LCD4Linux's default is STROBE.
  • The “IOC1” and “IOC2” (kind of 9th and 10th data bit) signals have to be connected to one of the control signals. LCD4Linux's default is SLCTIN for IOC1 and AUTOFD for IOC2.

You can connect up to 8 digital output lines to the parallel port with a simple additional circuit (see the HD44780 page for the circuit). These lines can be controlled by lcd4linux, and need an additional control signal from the parallel port. You have to specify this signal with the Wire.GPO entry in the config file (the default is GND, i.e. not connected).

As I said above, M50530 is quite timing-critial. First, there is the low-level timing on the parallel port, second is the execution time needed for various commands (especially if you're not using busy-flag checking). In the past, we tried to use worst-case values, as the timings differ from datasheet to datasheet. But this did not always work, some displays really need smaller values…

So I decided to make the timings configurable. That's what the Timing section in the lcd4linux.conf is for. Note that under normal circumstances you won't need such a section, lcd4linux uses default values which should work with most displays.

You should consult the datasheet of your display before messing around with these values!

To make it easier to play with the timing values, I invented a fuzz factor, which modifies all other timing values. This factor is interpreted as a percentage, with a default of 100% (meaning no modification). If you specify a fuzz factor of 150, this leads to all timings being multiplied by 1.5 (so the default 1000 ns Enable Cycle Time will be 1500 ns).

SUcontrol data setup time200ns
WEX signal pulse width500ns
DData output delay time300ns
HData hold time100ns
EXECnormal execution time20us
CLEARClear Display1250us
INITmysterious initialization time2000us

If you're using a 74HCT573 or similar as a latch to control one or more GPO's, you may specify the timing, too:

GPO_ST74HCT573 set-up time20ns
GPO_PW74HCT573 enable pulse width230ns
 Timing {
    SU     200  
    W      500  
    D      300  
    H      100  
    GPO_ST  20
    GPO_PW 230
    EXEC    20
    CLEAR 1250
    INIT  2000

I built a little interface board to my M50530 display. It consists of a stabilized voltage regulator to create the +5V, a potentiometer to control the contrast (supplied with +12V) and a connector to the parallel port. The whole board needs +12V supply voltage. Here's the schematic and board (designed with eagle):

  • m50530.txt
  • Last modified: 2020/07/17 18:33
  • (external edit)