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

Subversion Repositories lcd_block

[/] [lcd_block/] [trunk/] [hdl/] [iseProject/] [lcd_controller.v] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 leonardoar
`timescale 1ns / 1ps
2
 
3
module lcd_controller(
4
    input rst,
5
    input clk,
6 8 leonardoar
    input rs_in,
7
         input [7:0] data_in,
8 5 leonardoar
    input strobe_in,
9
    input [7:0] period_clk_ns,
10
    output lcd_e,
11
    output [3:0] lcd_nibble,
12
    output lcd_rs,
13
    output lcd_rw,
14
    output disable_flash,
15
    output done
16
    );
17
 
18
        // States for FSM that initialize the LCD
19
        localparam lcd_init_rst = 1;
20
        localparam lcd_init_wait = 2;
21
        localparam lcd_init_write_03_01 = 3;
22
        localparam lcd_init_wait_4ms = 4;
23
        localparam lcd_init_write_03_02 = 5;
24
        localparam lcd_init_wait_100us = 6;
25
        localparam lcd_init_write_03_03 = 7;
26
        localparam lcd_init_wait_40us = 8;
27
        localparam lcd_init_write_02 = 9;
28
        localparam lcd_init_wait_50us = 10;
29 8 leonardoar
        localparam lcd_init_state_done = 11;
30
        localparam lcd_init_strobe = 12;
31 6 leonardoar
        reg [3:0] lcd_init_states, lcd_init_state_next; // Declare two variables of 4 bits to hold the FSM states
32 8 leonardoar
        reg [23:0] counter_wait_lcd_init;
33
        reg [8:0] counter_wait_strobe_lcd_init, counter_wait_stabilize_lcd_init;
34
        reg [23:0] time_wait_lcd_init;
35 6 leonardoar
        reg [3:0] lcd_init_data_out;  // FSM output LCD_DATA
36
        reg lcd_init_e_out;           // FSM output LCD_E
37
        reg lcd_init_done;
38 5 leonardoar
 
39 6 leonardoar
        // States for FSM that send data to LCD
40
        localparam lcd_data_rst = 1;
41 8 leonardoar
        localparam lcd_data_wait_1us = 2;
42 6 leonardoar
        localparam lcd_data_wr_nibble_high = 3;
43
        localparam lcd_data_wr_nibble_low = 4;
44
        localparam lcd_data_strobe = 5;
45 8 leonardoar
        localparam lcd_data_wait_40us = 6;
46
        localparam lcd_data_done = 7;
47
        reg [19:0] time_wait_lcd_data;
48
        reg [19:0] counter_wait_lcd_data;
49
        reg [8:0] counter_wait_strobe_lcd_data, counter_wait_stabilize_lcd_data;
50 6 leonardoar
        reg [3:0] lcd_data_states, lcd_data_state_next;  // Declare two variables of 4 bits to hold the FSM states
51
        reg [3:0] lcd_data_data_out;     // FSM output LCD_DATA
52
        reg lcd_data_e_out;                             // FSM output LCD_E
53 8 leonardoar
        reg done;
54 5 leonardoar
 
55 6 leonardoar
 
56 5 leonardoar
        /*
57
                Initialize LCD...
58
        */
59
        always @ (posedge clk)
60
        begin
61
                if (rst)        // Reset synchronous
62
                        begin
63
                                lcd_init_states <= lcd_init_rst;
64
                                counter_wait_lcd_init <= 0;
65
                                counter_wait_strobe_lcd_init <= 0;
66 8 leonardoar
                                counter_wait_stabilize_lcd_init <= 0;
67 6 leonardoar
                                lcd_init_e_out <= 0;
68
                                lcd_init_done <= 0;
69 8 leonardoar
                                lcd_init_data_out <= 0;
70 5 leonardoar
                        end
71
                else
72
                        begin
73
                                case (lcd_init_states)
74
                                        lcd_init_rst:
75
                                                begin
76
                                                        // Wait for 15ms to power-up LCD
77
                                                        time_wait_lcd_init <= 15000000;
78
                                                        lcd_init_states <= lcd_init_wait;
79
                                                        lcd_init_state_next <= lcd_init_write_03_01;
80
                                                end
81
 
82
                                        // Wait for a configured time in (ns) and go to other state in (lcd_init_state_next)
83
                                        lcd_init_wait:
84
                                                begin
85
                                                        counter_wait_lcd_init <= counter_wait_lcd_init + period_clk_ns;
86 8 leonardoar
                                                        if (counter_wait_lcd_init >= time_wait_lcd_init)
87
                                                                begin
88
                                                                        lcd_init_states <= lcd_init_state_next;
89
                                                                        counter_wait_lcd_init <= 0;
90
                                                                end
91 5 leonardoar
                                                end
92
 
93
                                        // Strobe the LCD for at least 240 ns
94
                                        lcd_init_strobe:
95
                                                begin
96 8 leonardoar
                                                        // We need to wait at least 40ns to stabilize the data before strobing the data... 
97
                                                        counter_wait_stabilize_lcd_init <= counter_wait_stabilize_lcd_init + period_clk_ns;
98
                                                        if (counter_wait_stabilize_lcd_init >= 40)
99 5 leonardoar
                                                                begin
100 8 leonardoar
                                                                        lcd_init_e_out <= 1;
101
 
102
                                                                        // After we got a strobe high hold for more 240 ns
103
                                                                        counter_wait_strobe_lcd_init <= counter_wait_strobe_lcd_init + period_clk_ns;
104
                                                                        if (counter_wait_strobe_lcd_init >= 240)
105
                                                                                begin
106
                                                                                        lcd_init_states <= lcd_init_state_next;
107
                                                                                        counter_wait_stabilize_lcd_init <= 0;
108
                                                                                        counter_wait_strobe_lcd_init <= 0;
109
                                                                                        lcd_init_e_out <= 0;
110
                                                                                end
111
                                                                end
112 5 leonardoar
                                                end
113
 
114
                                        lcd_init_write_03_01:
115
                                                // Send 0x3 and pulse LCD_E for 240ns 
116
                                                begin
117
                                                        lcd_init_data_out <= 4'h3;
118
                                                        lcd_init_states <= lcd_init_strobe;     // Strobe for at least 230 ns                                           
119
                                                        lcd_init_state_next <= lcd_init_wait_4ms;
120
                                                end
121
 
122
                                        lcd_init_wait_4ms:
123
                                                begin
124
                                                        time_wait_lcd_init <= 4100000;  // Wait for 4.1ms
125
                                                        lcd_init_states <= lcd_init_wait;
126
                                                        lcd_init_state_next <= lcd_init_write_03_02;
127
                                                end
128
 
129
                                        lcd_init_write_03_02:
130
                                                // Send 0x3 and pulse LCD_E for 240ns 
131
                                                begin
132
                                                        lcd_init_data_out <= 4'h3;
133
                                                        lcd_init_states <= lcd_init_strobe;     // Strobe for at least 230 ns                                           
134
                                                        lcd_init_state_next <= lcd_init_wait_100us;
135
                                                end
136
 
137
                                        lcd_init_wait_100us:
138
                                                begin
139
                                                        time_wait_lcd_init <= 100000;   // Wait for 100us
140
                                                        lcd_init_states <= lcd_init_wait;
141
                                                        lcd_init_state_next <= lcd_init_write_03_03;
142
                                                end
143
 
144
                                        lcd_init_write_03_03:
145
                                                // Send 0x3 and pulse LCD_E for 240ns 
146
                                                begin
147
                                                        lcd_init_data_out <= 4'h3;
148
                                                        lcd_init_states <= lcd_init_strobe;     // Strobe for at least 230 ns                                           
149
                                                        lcd_init_state_next <= lcd_init_wait_40us;
150
                                                end
151
 
152
                                        lcd_init_wait_40us:
153
                                                begin
154 8 leonardoar
                                                        time_wait_lcd_init <= 40000;    // Wait for 40us
155 5 leonardoar
                                                        lcd_init_states <= lcd_init_wait;
156
                                                        lcd_init_state_next <= lcd_init_write_02;
157
                                                end
158
 
159
                                        lcd_init_write_02:
160 8 leonardoar
                                                // Send 0x2 and pulse LCD_E for 240ns 
161 5 leonardoar
                                                begin
162
                                                        lcd_init_data_out <= 4'h2;
163
                                                        lcd_init_states <= lcd_init_strobe;     // Strobe for at least 230 ns                                           
164
                                                        lcd_init_state_next <= lcd_init_wait_50us;
165
                                                end
166
 
167
                                        lcd_init_wait_50us:
168
                                                begin
169 8 leonardoar
                                                        time_wait_lcd_init <= 50000;    // Wait for 50us
170 5 leonardoar
                                                        lcd_init_states <= lcd_init_wait;
171 8 leonardoar
                                                        lcd_init_state_next <= lcd_init_state_done;
172
                                                end
173
 
174
                                        lcd_init_state_done:
175
                                                begin
176 6 leonardoar
                                                        lcd_init_done <= 1;
177 8 leonardoar
                                                        lcd_init_state_next <= lcd_init_state_done;
178 5 leonardoar
                                                end
179
                                endcase;
180
                        end;
181
        end;
182
 
183 8 leonardoar
        assign lcd_rw = 0;
184 6 leonardoar
 
185 8 leonardoar
        // Will assign the output of the FSM init or the FSM data depending if initialization is already done
186
        assign lcd_e = (!lcd_init_done) ? lcd_init_e_out : lcd_data_e_out;
187
        assign lcd_nibble = (!lcd_init_done) ? lcd_init_data_out : lcd_data_data_out ;
188
 
189 6 leonardoar
        /*
190
                FSM that deals to send data to the LCD (nibble High + nibble Low)
191
        */
192
        always @ (posedge clk)
193
        begin
194
                if (~lcd_init_done)
195
                        begin
196 8 leonardoar
                                lcd_data_e_out <= 0;
197
                                lcd_data_data_out <= 0;
198
                                lcd_data_states <= lcd_data_rst;
199
                                done <= 0;
200
                                counter_wait_stabilize_lcd_data <= 0;
201
                                counter_wait_lcd_data <= 0;
202
                                counter_wait_strobe_lcd_data <= 0;
203 6 leonardoar
                        end
204 8 leonardoar
                else
205
                        begin
206
                                case (lcd_data_states)
207
                                        lcd_data_rst:
208
                                                begin
209
                                                        done <= 0;
210
                                                        // Start to send data when strobe_in =1
211
                                                        if (strobe_in == 1)
212
                                                                begin
213
                                                                        lcd_data_states <= lcd_data_wr_nibble_high;
214
                                                                end
215
                                                        else
216
                                                                lcd_data_states <= lcd_data_rst;
217
                                                end
218
 
219
                                        lcd_data_wr_nibble_high:
220
                                                begin
221
                                                        // First send the high nibble
222
                                                        lcd_data_data_out <= data_in[7:4];
223
                                                        lcd_data_states <= lcd_data_strobe;
224
                                                        lcd_data_state_next <= lcd_data_wait_1us;
225
                                                end
226
 
227
                                        lcd_data_strobe:
228
                                                begin
229
                                                        // We need to wait at least 40ns to stabilize the data before strobing the data... 
230
                                                        counter_wait_stabilize_lcd_data <= counter_wait_stabilize_lcd_data + period_clk_ns;
231
                                                        if (counter_wait_stabilize_lcd_data >= 40)
232
                                                                begin
233
                                                                        lcd_data_e_out <= 1;
234
 
235
                                                                        // After we got a strobe high hold for more 240 ns
236
                                                                        counter_wait_strobe_lcd_data <= counter_wait_strobe_lcd_data + period_clk_ns;
237
                                                                        if (counter_wait_strobe_lcd_data >= 240)
238
                                                                                begin
239
                                                                                        lcd_data_states <= lcd_data_state_next;
240
                                                                                        counter_wait_stabilize_lcd_data <= 0;
241
                                                                                        counter_wait_strobe_lcd_data <= 0;
242
                                                                                        lcd_data_e_out <= 0;
243
                                                                                end
244
                                                                end
245
                                                end
246
 
247
                                        // Wait for 1us before sending the low nibble
248
                                        lcd_data_wait_1us:
249
                                                begin
250
                                                        counter_wait_lcd_data <= counter_wait_lcd_data + period_clk_ns;
251
                                                        if (counter_wait_lcd_data >= 1000)
252
                                                                begin
253
                                                                        lcd_data_states <= lcd_data_wr_nibble_low;
254
                                                                        counter_wait_lcd_data <= 0;
255
                                                                end
256
                                                end
257
 
258
                                        lcd_data_wr_nibble_low:
259
                                                begin
260
                                                        // After send the low nibble
261
                                                        lcd_data_data_out <= data_in[3:0];
262
                                                        lcd_data_states <= lcd_data_strobe;
263
                                                        lcd_data_state_next <= lcd_data_wait_40us;
264
                                                end
265
 
266
                                        // Wait for 40us before sending the next byte
267
                                        lcd_data_wait_40us:
268
                                                begin
269
                                                        counter_wait_lcd_data <= counter_wait_lcd_data + period_clk_ns;
270
                                                        if (counter_wait_lcd_data >= 40000)
271
                                                                begin
272
                                                                        lcd_data_states <= lcd_data_done;
273
                                                                        counter_wait_lcd_data <= 0;
274
                                                                end
275
                                                end
276
 
277
                                        lcd_data_done:
278
                                                begin
279
                                                        // Signal that we done sending the data
280
                                                        done <= 1;
281
                                                        lcd_data_states <= lcd_data_rst;
282
                                                end
283
 
284
                                endcase
285
                        end
286 6 leonardoar
        end;
287 5 leonardoar
 
288
endmodule

powered by: WebSVN 2.1.0

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