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 9

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

powered by: WebSVN 2.1.0

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