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 10

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 10 leonardoar
                                endcase
178
                        end
179
        end
180 5 leonardoar
 
181 10 leonardoar
        // On the most cases you can only write to the display...
182 8 leonardoar
        assign lcd_rw = 0;
183 10 leonardoar
        assign lcd_rs = rs_in;
184
        assign disable_flash = 1;
185 6 leonardoar
 
186 8 leonardoar
        // Will assign the output of the FSM init or the FSM data depending if initialization is already done
187
        assign lcd_e = (!lcd_init_done) ? lcd_init_e_out : lcd_data_e_out;
188 10 leonardoar
        assign lcd_nibble = (!lcd_init_done) ? lcd_init_data_out : lcd_data_data_out ;
189 8 leonardoar
 
190 6 leonardoar
        /*
191
                FSM that deals to send data to the LCD (nibble High + nibble Low)
192
        */
193
        always @ (posedge clk)
194
        begin
195
                if (~lcd_init_done)
196
                        begin
197 8 leonardoar
                                lcd_data_e_out <= 0;
198
                                lcd_data_data_out <= 0;
199
                                lcd_data_states <= lcd_data_rst;
200
                                done <= 0;
201
                                counter_wait_stabilize_lcd_data <= 0;
202
                                counter_wait_lcd_data <= 0;
203
                                counter_wait_strobe_lcd_data <= 0;
204 6 leonardoar
                        end
205 8 leonardoar
                else
206
                        begin
207
                                case (lcd_data_states)
208
                                        lcd_data_rst:
209
                                                begin
210
                                                        done <= 0;
211
                                                        // Start to send data when strobe_in =1
212
                                                        if (strobe_in == 1)
213
                                                                begin
214
                                                                        lcd_data_states <= lcd_data_wr_nibble_high;
215
                                                                end
216
                                                        else
217
                                                                lcd_data_states <= lcd_data_rst;
218
                                                end
219
 
220
                                        lcd_data_wr_nibble_high:
221
                                                begin
222
                                                        // First send the high nibble
223
                                                        lcd_data_data_out <= data_in[7:4];
224
                                                        lcd_data_states <= lcd_data_strobe;
225
                                                        lcd_data_state_next <= lcd_data_wait_1us;
226
                                                end
227
 
228
                                        lcd_data_strobe:
229
                                                begin
230
                                                        // We need to wait at least 40ns to stabilize the data before strobing the data... 
231
                                                        counter_wait_stabilize_lcd_data <= counter_wait_stabilize_lcd_data + period_clk_ns;
232
                                                        if (counter_wait_stabilize_lcd_data >= 40)
233
                                                                begin
234
                                                                        lcd_data_e_out <= 1;
235
 
236
                                                                        // After we got a strobe high hold for more 240 ns
237
                                                                        counter_wait_strobe_lcd_data <= counter_wait_strobe_lcd_data + period_clk_ns;
238
                                                                        if (counter_wait_strobe_lcd_data >= 240)
239
                                                                                begin
240
                                                                                        lcd_data_states <= lcd_data_state_next;
241
                                                                                        counter_wait_stabilize_lcd_data <= 0;
242
                                                                                        counter_wait_strobe_lcd_data <= 0;
243
                                                                                        lcd_data_e_out <= 0;
244
                                                                                end
245
                                                                end
246
                                                end
247
 
248
                                        // Wait for 1us before sending the low nibble
249
                                        lcd_data_wait_1us:
250
                                                begin
251
                                                        counter_wait_lcd_data <= counter_wait_lcd_data + period_clk_ns;
252
                                                        if (counter_wait_lcd_data >= 1000)
253
                                                                begin
254
                                                                        lcd_data_states <= lcd_data_wr_nibble_low;
255
                                                                        counter_wait_lcd_data <= 0;
256
                                                                end
257
                                                end
258
 
259
                                        lcd_data_wr_nibble_low:
260
                                                begin
261
                                                        // After send the low nibble
262
                                                        lcd_data_data_out <= data_in[3:0];
263
                                                        lcd_data_states <= lcd_data_strobe;
264
                                                        lcd_data_state_next <= lcd_data_wait_40us;
265
                                                end
266
 
267
                                        // Wait for 40us before sending the next byte
268
                                        lcd_data_wait_40us:
269
                                                begin
270
                                                        counter_wait_lcd_data <= counter_wait_lcd_data + period_clk_ns;
271
                                                        if (counter_wait_lcd_data >= 40000)
272
                                                                begin
273
                                                                        lcd_data_states <= lcd_data_done;
274
                                                                        counter_wait_lcd_data <= 0;
275
                                                                end
276
                                                end
277
 
278
                                        lcd_data_done:
279
                                                begin
280
                                                        // Signal that we done sending the data
281
                                                        done <= 1;
282
                                                        lcd_data_states <= lcd_data_rst;
283
                                                end
284
 
285
                                endcase
286
                        end
287 10 leonardoar
        end
288 5 leonardoar
 
289
endmodule

powered by: WebSVN 2.1.0

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