OpenCores
URL https://opencores.org/ocsvn/hd44780_driver/hd44780_driver/trunk

Subversion Repositories hd44780_driver

[/] [hd44780_driver/] [trunk/] [lcd_driver_hd44780_module.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jodb
-- Filename:     lcd_driver_hd44780_module.vhd
2
-- Filetype:     VHDL Source Code
3
-- Date:         26 oct 2012
4
-- Update:       -
5
-- Description:  VHDL Description for driving an HD44780 based LCD driver
6
-- Author:       J. op den Brouw
7
-- State:        Demo
8
-- Error:        -
9
-- Version:      1.2alpha
10
-- Copyright:    (c)2012, De Haagse Hogeschool
11
 
12
-- This file contains a VHDL description for driving an HD44780 based LCD
13
-- driver, see for a standard information of such a display:
14
-- https://decibel.ni.com/content/servlet/JiveServlet/download/2741-3-3217/hd44780.pdf
15
--
16
-- Currently, this driver uses the 8-bit databus mode. This is not a big problem
17
-- for most FPGA's because of the numerous pins.
18
--
19
-- Please note that there are a lot of almost-the-same displays available, so
20
-- it's not guaranteed to work with all displays available. Also, timing may differ.
21
--
22
-- This code is tested on a Terasic DE0-board with an optional
23
-- LCD display. See the weblinks
24
-- http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=56&No=364
25
-- http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=78&No=396
26
-- for more info. The display used has only two lines.
27
--
28 3 jodb
-- This VHDL description can both be simulated and synthesized.
29 2 jodb
--
30
-- This driver has a User Side and a LCD Side. The user is to interface at the User Side
31
-- and has a number of "routines" at her disposal. The User Side implements the following
32
-- inputs/routines in order of priority:
33
--
34
-- Command inputs:
35
--     init:   a logic 1 initializes the display
36
--     cls:    a logic 1 clears the display (and goes to home)
37
--     home:   a logic 1 sets the cursor to row 0, column 0
38
--     goto10: a logic 1 sets the cursor to row 1, column 0
39
--     goto20: a logic 1 sets the cursor to row 2, column 0
40
--     goto30: a logic 1 sets the cursor to row 3, column 0
41
--     wr:     a logic 1 writes a character to the display
42
--
43
-- Data inputs:
44
--
45
--     data:   an 8-bit data to be written to the display
46
--
47
-- The user has one observable output:
48
--
49
--     busy:   a logic 1 indicates that the driver is currently
50
--             busy driving the display, a logic 0 indicates that
51
--             the driver waits for the next command.
52
--
53
-- The user can supply the next generics, which are processed at
54
-- instantiation of the module:
55
--
56
--          freq:   the clock frequency at which the hardware has to run.
57
--             this frequency is mandatory because of internal delays
58
--             calculated, defaults to 50 MHz.
59
--     areset_pol:
60
--             the polarity of the reset signal, defaults to High (1)
61
--     time_init1:
62
--             the time to wait after Vcc > 4.5 V 
63
--     time_init2:
64
--             the time to wait after first "contact"
65
--     time_init3:
66
--             the time to wait after the second contact
67
--     time_tas:
68
--             the RW and RS signal setup time with respect to the positive
69
--             edge of the E pulse
70
--     time_cycle_e:
71
--             the complete cycle time
72
--     time_pweh:
73
--             the E pulse width high time
74
--     time_no_bf:
75
--             time to wait before command completion if no Busy Flag reading is done,
76
--             some designs connect RW to logic 0, so reading from the LCD is not
77
--             possible, saves a pin.
78
--     cursor_on:
79
--             true to set the cursor on at the display, false for no cursor
80
--     blink_on:
81
--             true to let the cursor blink, false for no blink (just a underscore)
82
--     use_bf: true if Busy Flag reading is to be used, false for no BF reading
83
--
84
-- Note: it's not possible to write command codes to the display.
85
--
86
-- Changes to v1.0:  LCD_E is renamed to LCD_EN
87
--                   LCD_DB is renamed to LCD_DATA
88
--                   busy is now registered
89
--                   removed hardware simulation architecture
90
--
91
-- Changes to v1.1:  added timing generics for better steering of the E pulse cycle
92
--                   implemented cursor on/off/blink with generic parameters
93
--
94
-- Changes to v1.2:  added Busy Flag reading mode, selectable at instantiation time
95
--                   LCD_EN changes back to LCD_E
96
--                   LCD_DATA changed back to LCD_DB
97
--
98
-- To do:            use 4-bit mode or 8-bit mode at instantiation time
99
--
100
 
101
-- The libraries to use.
102
library ieee;
103
use ieee.std_logic_1164.all;
104
 
105
-- The entity of the LCD Driver Module.
106
entity lcd_driver_hd44780_module is
107
        generic (freq         : integer := 50000000;
108
                                areset_pol   : std_logic := '1';
109
                                time_init1   : time := 40 ms;
110
                                time_init2   : time := 4100 us;
111
                                time_init3   : time := 100 us;
112
                                time_tas     : time := 60 ns;
113
                                time_cycle_e : time := 1000 ns;
114
                                time_pweh    : time := 500 ns;
115
                                time_no_bf   : time := 2 ms;
116
                                cursor_on    : boolean := false;
117
                                blink_on     : boolean := false;
118
                                use_bf       : boolean := true
119
                          );
120
        port      (clk      : in std_logic;
121
                           areset   : in std_logic;
122
                           -- User site
123
                           init     : in std_logic;
124
                           data     : in std_logic_vector(7 downto 0);
125
                           wr       : in std_logic;
126
                           cls      : in std_logic;
127
                           home     : in std_logic;
128
                           goto10   : in std_logic;
129
                           goto20   : in std_logic;
130
                           goto30   : in std_logic;
131
                           busy     : out std_logic;
132
                           -- LCD side
133
                           LCD_E    : out std_logic;
134
                           LCD_RS   : out std_logic;
135
                           LCD_RW   : out std_logic;
136
                           LCD_DB   : inout std_logic_vector(7 downto 0)
137
                          );
138
end entity lcd_driver_hd44780_module;
139
 
140
-- This architecture drives the LCD.
141
architecture hardware_driver of lcd_driver_hd44780_module is
142
 
143
-- Delays... Please note that if the frequency is (too) low,
144
-- some of the delays will 0. The code will take care of that.
145
-- Converting time to integer is problematic. Please note the use of
146
-- the simulator time step in the calculations.
147
-- The simulator timestep
148
constant simulator_timestep : time := 1 ns;
149
-- Number of simulator timesteps per second.
150
constant sim_steps_per_sec : real := real(1 sec/simulator_timestep);
151
 
152
constant delay_init1   : integer := integer( real(freq) * real(time_init1/simulator_timestep) / sim_steps_per_sec);
153
constant delay_init2   : integer := integer( real(freq) * real(time_init2/simulator_timestep) / sim_steps_per_sec);
154
constant delay_init3   : integer := integer( real(freq) * real(time_init3/simulator_timestep) / sim_steps_per_sec);
155
constant delay_tas     : integer := integer( real(freq) * real(time_tas/simulator_timestep) / sim_steps_per_sec);
156
constant delay_cycle_e : integer := integer( real(freq) * real(time_cycle_e/simulator_timestep) / sim_steps_per_sec);
157
constant delay_pweh    : integer := integer( real(freq) * real(time_pweh/simulator_timestep) / sim_steps_per_sec);
158
constant delay_no_bf   : integer := integer( real(freq) * real(time_no_bf/simulator_timestep) / sim_steps_per_sec);
159
 
160
-- The next statements do work in Quartus but not in (32 bit) ModelSim...
161
--constant delay_init1   : integer := integer(real(freq)*real(time'pos(time_init1)) / real(time'pos(1 sec)));
162
--constant delay_init2   : integer := integer(real(freq)*real(time'pos(time_init2)) / real(time'pos(1 sec)));
163
--constant delay_init3   : integer := integer(real(freq)*real(time'pos(time_init3)) / real(time'pos(1 sec)));
164
--constant delay_tas     : integer := integer(real(freq)*real(time'pos(time_tas)) / real(time'pos(1 sec)));
165
--constant delay_cycle_e : integer := integer(real(freq)*real(time'pos(time_cycle_e)) / real(time'pos(1 sec)));
166
--constant delay_pweh    : integer := integer(real(freq)*real(time'pos(time_pweh)) / real(time'pos(1 sec)));
167
--constant delay_no_bf   : integer := integer(real(freq)*real(time'pos(time_no_bf)) / real(time'pos(1 sec)));
168
 
169
-- Time the E signal must be low following E high
170
constant delay_pwel    : integer := delay_cycle_e-delay_pweh;
171
 
172
-- Counter for the delays. Timer would be a better choice.
173
-- Range should be to the longest delay.
174
signal delay_counter : integer range 0 to delay_init1;
175
 
176
-- Should we use Busy Flag reading?
177
signal use_bf_int : std_logic;
178
 
179
-- The states of the state machine.
180
type state_type is (reset, command_init, command_init_1, command_init_2, command_init_3,
181
                                                  command_init_4, command_init_5, command_init_6, command_init_7, command_init_8,
182
                                                  command_init_9, command_init_10, command_init_11, command_init12,
183
                                                  wait_for_command,
184
                                                  command_cls, command_home,
185
                                                  command_goto10, command_goto20, command_goto30, command_wr,
186
                                                  pulse_e, pulse_e_1, pulse_e_2, pulse_e_3, pulse_e_4,
187
                                                  pulse_busy_flag, pulse_busy_flag_1, pulse_busy_flag_2, pulse_busy_flag_3,
188
                                                  pulse_busy_flag_4, pulse_busy_flag_5);
189
 
190
 
191
-- The current state and one for the return state (to facilitate return to the caller).
192
signal current_state, return_state : state_type;
193
begin
194
 
195
        -- The state machine ;-)
196
        nsl_state: process (clk, areset) is
197
                -- Function to translate a boolean to std_logic
198
                function bool_to_stdlogic(l: boolean) return std_logic is
199
                begin
200
        if l then
201
                                return('1');
202
                        else
203
                                return('0');
204
                        end if;
205
                end function bool_to_stdlogic;
206
        begin
207
                if (areset = '1' and areset_pol = '1') or (areset = '0' and areset_pol = '0') then
208
                        current_state <= reset;
209
                        delay_counter <= 0;
210
                        busy <= '1';
211
                        LCD_DB <= (others => 'Z');
212
                        LCD_E  <= '0';
213
                        LCD_RS <= '0';
214
                        LCD_RW <= '0';
215
                        use_bf_int <= '0';
216
                elsif rising_edge(clk) then
217
                        -- Default is busy
218
                        busy <= '1';
219
                        -- Default values of the LCD side
220
                        LCD_E  <= '0';
221
                        LCD_RW <= '0';
222
                        case current_state is
223
                                when reset|command_init =>
224
                                        -- The logic is reset. Start initialization routine.
225
                                        LCD_DB <= (others => 'Z');
226
                                        LCD_RS <= '0';
227
                                        use_bf_int <= '0';
228
                                        delay_counter <= delay_init1;
229
                                        current_state <= command_init_1;
230
                                when command_init_1 =>
231
                                        -- Wait until Vcc > 4.5 V...
232
                                        LCD_DB <= (others => 'Z');
233
                                        LCD_RS <= '0';
234
                                        use_bf_int <= '0';
235
                                        -- If done write 0x30 to the LCD
236
                                        if delay_counter = 0 or delay_counter = 1 then
237
                                                LCD_DB <= "00110000";  -- 0x30
238
                                                current_state <= pulse_e;
239
                                                return_state <= command_init_2;
240
                                        else
241
                                                delay_counter <= delay_counter-1;
242
                                        end if;
243
                                when command_init_2 =>
244
                                        -- Next, set up wait for 4.1 ms
245
                                        LCD_DB <= (others => 'Z');
246
                                        LCD_RS <= '0';
247
                                        use_bf_int <= '0';
248
                                        delay_counter <= delay_init2;
249
                                        current_state <= command_init_3;
250
                                when command_init_3 =>
251
                                        -- Wait...
252
                                        LCD_DB <= (others => 'Z');
253
                                        LCD_RS <= '0';
254
                                        use_bf_int <= '0';
255
                                        -- If done write 0x30 to the LCD
256
                                        if delay_counter = 0 or delay_counter = 1 then
257
                                                LCD_DB <= "00110000";  -- 0x30
258
                                                current_state <= pulse_e;
259
                                                return_state <= command_init_4;
260
                                        else
261
                                                delay_counter <= delay_counter-1;
262
                                        end if;
263
                                when command_init_4 =>
264
                                        -- Next, set up wait for 100 us
265
                                        LCD_DB <= (others => 'Z');
266
                                        LCD_RS <= '0';
267
                                        use_bf_int <= '0';
268
                                        delay_counter <= delay_init3;
269
                                        current_state <= command_init_5;
270
                                when command_init_5 =>
271
                                        -- Wait...
272
                                        LCD_DB <= (others => 'Z');
273
                                        LCD_RS <= '0';
274
                                        use_bf_int <= '0';
275
                                        -- If done write 0x30 to the LCD
276
                                        if delay_counter = 0 or delay_counter = 1 then
277
                                                LCD_DB <= "00110000";  -- 0x30
278
                                                current_state <= pulse_e;
279
                                                return_state <= command_init_6;
280
                                        else
281
                                                delay_counter <= delay_counter-1;
282
                                        end if;
283
                                when command_init_6 =>
284
                                        -- Power up is now done, so let's enter some reasonable values...
285
                                        LCD_DB <= "00110000";
286
                                        LCD_RS <= '0';
287
                                        use_bf_int <= bool_to_stdlogic(use_bf);
288
                                        current_state <= pulse_e;
289
                                        return_state <= command_init_7;
290
                                when command_init_7 =>
291
                                        -- 8-bit bus, 2(?) lines, 5x7 characters
292
                                        LCD_DB <= "00111100";  -- 0x3C
293
                                        LCD_RS <= '0';
294
                                        current_state <= pulse_e;
295
                                        return_state <= command_init_8;
296
                                when command_init_8 =>
297
                                        -- Display off
298
                                        LCD_DB <= "00001000";  -- 0x08
299
                                        LCD_RS <= '0';
300
                                        current_state <= pulse_e;
301
                                        return_state <= command_init_9;
302
                                when command_init_9 =>
303
                                        -- Display clear
304
                                        LCD_DB <= "00000001";  -- 0x01
305
                                        LCD_RS <= '0';
306
                                        current_state <= pulse_e;
307
                                        return_state <= command_init_10;
308
                                when command_init_10 =>
309
                                        -- Display on, cursor and blink...
310
                                        LCD_DB <= "000011" & bool_to_stdlogic(cursor_on) & bool_to_stdlogic(blink_on);  -- 0x0C + ...
311
                                        LCD_RS <= '0';
312
                                        current_state <= pulse_e;
313
                                        return_state <= command_init_11;
314
                                when command_init_11 =>
315
                                        -- Mode set, increment cursor address, cursor shift
316
                                        LCD_DB <= "00000110";  -- 0x06
317
                                        LCD_RS <= '0';
318
                                        current_state <= pulse_e;
319
                                        return_state <= wait_for_command;
320
 
321
                                -- The command dispatcher! This state waits for one of
322
                                -- the command inputs to be logic '1' and 'starts' the
323
                                -- accompanying routine. Note the priority encoding!
324
                                when wait_for_command =>
325
                                        LCD_DB <= (others => 'Z');
326
                                        LCD_RS <= '0';
327
                                        busy <= '0';
328
                                        if init = '1' then
329
                                                busy <= '1';
330
                                                current_state <= command_init;
331
                                        elsif cls = '1' then
332
                                                busy <= '1';
333
                                                current_state <= command_cls;
334
                                        elsif home = '1' then
335
                                                busy <= '1';
336
                                                current_state <= command_home;
337
                                        elsif goto10 = '1' then
338
                                                busy <= '1';
339
                                                current_state <= command_goto10;
340
                                        elsif goto20 = '1' then
341
                                                busy <= '1';
342
                                                current_state <= command_goto20;
343
                                        elsif goto30 = '1' then
344
                                                busy <= '1';
345
                                                current_state <= command_goto30;
346
                                        elsif wr = '1' then
347
                                                -- Read in data! Do NOT forget that here!
348
                                                LCD_DB <= data;
349
                                                busy <= '1';
350
                                                current_state <= command_wr;
351
                                        end if;
352
 
353
                                when command_cls =>
354
                                        -- Display clear
355
                                        LCD_DB <= "00000001";
356
                                        LCD_RS <= '0';
357
                                        current_state <= pulse_e;
358
                                        return_state <= wait_for_command;
359
 
360
                                when command_home =>
361
                                        -- Cursor home
362
                                        LCD_DB <= "00000010";
363
                                        LCD_RS <= '0';
364
                                        current_state <= pulse_e;
365
                                        return_state <= wait_for_command;
366
 
367
                                when command_goto10 =>
368
                                        -- Cursor to beginning of line 2nd line...
369
                                        LCD_DB <= "11000000";   --0x80+0x40;
370
                                        LCD_RS <= '0';
371
                                        current_state <= pulse_e;
372
                                        return_state <= wait_for_command;
373
 
374
                                when command_goto20 =>
375
                                        -- Cursor to beginning of line 3rd line...
376
                                        LCD_DB <= "10010000";   --0x80+0x10;
377
                                        LCD_RS <= '0';
378
                                        current_state <= pulse_e;
379
                                        return_state <= wait_for_command;
380
 
381
                                when command_goto30 =>
382
                                        -- Cursor to beginning of line 4th line...
383
                                        LCD_DB <= "11010000";   --0x80+0x50;
384
                                        LCD_RS <= '0';
385
                                        current_state <= pulse_e;
386
                                        return_state <= wait_for_command;
387
 
388
                                when command_wr =>
389
                                        -- Start character write cycle
390
                                        -- Do NOT set data here!
391
                                        LCD_RS <= '1';
392
                                        current_state <= pulse_e;
393
                                        return_state <= wait_for_command;
394
 
395
                                -- --   
396
                                -- Provide E strobing for data transfer.
397
                                -- Writes data byte to the LCD.
398
                                -- Please note, DATA and RS are set by the caller!
399
                                when pulse_e =>
400
                                        -- wait 60 ns before E -> 1 (tAS)
401
                                        delay_counter <= delay_tas;
402
                                        current_state <= pulse_e_1;
403
                                when pulse_e_1 =>
404
                                        if delay_counter = 0 or delay_counter = 1 then
405
                                                -- timer set: E = 1 for 500 ns (PWeh)
406
                                                delay_counter <= delay_pweh;
407
                                                current_state <= pulse_e_2;
408
                                        else
409
                                                delay_counter <= delay_counter-1;
410
                                        end if;
411
                                when pulse_e_2 =>
412
                                        LCD_E <= '1';
413
                                        if delay_counter = 0 or delay_counter = 1 then
414
                                                -- timer set: E = 0 for 500 ns (tCycleE-PWeh)
415
                                                delay_counter <= delay_pwel;
416
                                                current_state <= pulse_e_3;
417
                                        else
418
                                                delay_counter <= delay_counter-1;
419
                                        end if;
420
                                when pulse_e_3 =>
421
                                        LCD_E <= '0';
422
                                        -- Command completion, check for use busy flag
423
                                        if delay_counter = 0 or delay_counter = 1 then
424
                                                -- If no busy flag used, wait for a amount of time.
425
                                                if use_bf_int = '0' then
426
                                                        delay_counter <= delay_no_bf;
427
                                                        current_state <= pulse_e_4;
428
                                                else -- BF used
429
                                                        current_state <= pulse_busy_flag;
430
                                                end if;
431
                                        else
432
                                                delay_counter <= delay_counter-1;
433
                                        end if;
434
                                when pulse_e_4 =>
435
                                        -- Wait for the delay to finsh and then return to the caller.
436
                                        if delay_counter = 0 or delay_counter = 1 then
437
                                                current_state <= return_state;
438
                                        else
439
                                                delay_counter <= delay_counter-1;
440
                                        end if;
441
 
442
                                -- Let's read the busy flag, see if the module is busy...
443
                                when pulse_busy_flag =>
444
                                        LCD_DB <= (others => 'Z');
445
                                        LCD_RW <= '1';
446
                                        LCD_RS <= '0';
447
                                        -- wait 60 ns before E -> 1 (tAS)
448
                                        delay_counter <= delay_tas;
449
                                        current_state <= pulse_busy_flag_1;
450
                                when pulse_busy_flag_1 =>
451
                                        LCD_RW <= '1';
452
                                        if delay_counter = 0 or delay_counter = 1 then
453
                                                -- timer set: E = 1 for 500 ns (tPWeh)
454
                                                delay_counter <= delay_pweh;
455
                                                current_state <= pulse_busy_flag_2;
456
                                        else
457
                                                delay_counter <= delay_counter-1;
458
                                        end if;
459
                                when pulse_busy_flag_2 =>
460
                                        LCD_E <= '1';
461
                                        LCD_RW <= '1';
462
                                        if delay_counter = 0 or delay_counter = 1 then
463
                                                -- timer set: E = 0 for 500 ns (tPWel)
464
                                                delay_counter <= delay_pwel;
465
                                                current_state <= pulse_busy_flag_3;
466
                                        else
467
                                                delay_counter <= delay_counter-1;
468
                                        end if;
469
                                when pulse_busy_flag_3 =>
470
                                        LCD_E <= '0';
471
                                        LCD_RW <= '1';
472
                                        if LCD_DB(7) = '0' then
473
                                                -- operation ended
474
                                                current_state <= pulse_busy_flag_4;
475
                                        else
476
                                                -- operation in progress
477
                                                current_state <= pulse_busy_flag_5;
478
                                        end if;
479
                                when pulse_busy_flag_4 =>
480
                                        if delay_counter = 0 or delay_counter = 1 then
481
                                                -- Operation ended, return caller
482
                                                current_state <= return_state;
483
                                        else
484
                                                delay_counter <= delay_counter-1;
485
                                        end if;
486
                                when pulse_busy_flag_5 =>
487
                                        if delay_counter = 0 or delay_counter = 1 then
488
                                                -- Operation in progress, read BF again
489
                                                current_state <= pulse_busy_flag;
490
                                        else
491
                                                delay_counter <= delay_counter-1;
492
                                        end if;
493
 
494
                                when others => null;
495
                        end case;
496
                end if;
497
 
498
        end process;
499
 
500
end architecture hardware_driver;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.