summaryrefslogtreecommitdiff
path: root/FPGA/vhdl/lcd_controller.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'FPGA/vhdl/lcd_controller.vhd')
-rw-r--r--FPGA/vhdl/lcd_controller.vhd363
1 files changed, 363 insertions, 0 deletions
diff --git a/FPGA/vhdl/lcd_controller.vhd b/FPGA/vhdl/lcd_controller.vhd
new file mode 100644
index 0000000..0818db2
--- /dev/null
+++ b/FPGA/vhdl/lcd_controller.vhd
@@ -0,0 +1,363 @@
1----------------------------------------------------------
2-- LCD 2 lines controller
3--
4-- 8 bits interface --
5----------------------------------------------------------
6-- ESIEE
7-- Creation : A. Exertier, mars 2008
8----------------------------------------------------------
9
10library ieee;
11use ieee.std_logic_1164.all;
12 use ieee.numeric_std.all;
13
14----------------------------------------------------------
15-- INPUTS
16----------------------------------------------------------
17-- clk : system clock
18-- resetn : aynchronous active low reset
19-- en_250kHz : enable at 250 kHz (lasts 1 clock cycle)
20-- char : input ASCII character
21-- write_char : write character command
22-- ready : set to 1 when device is ready for a writing
23----------------------------------------------------------
24-- OUTPUTS
25----------------------------------------------------------
26-- LCD_DATA : ASCII data to LCD
27-- LCD_RS : RS to LCD
28-- LCD_RW : Read/write to LCD
29-- LCD_EN : Enable to LCD
30------------------------------------------------------------
31
32Entity LCD_controller is
33
34 port(
35 clk : in std_logic;
36 resetn : in std_logic;
37 en_250kHz : in std_logic;
38
39 mode : in std_logic_vector(1 downto 0);
40 char : in std_logic_vector (7 downto 0);
41 address : in std_logic_vector(6 downto 0);
42 write_char : in std_logic;
43 write_address : in std_logic;
44 ready : out std_logic;
45 D : in std_logic;
46 C : in std_logic;
47 B : in std_logic;
48
49 -- LCD signals
50
51 LCD_data : inout std_logic_vector(7 downto 0);
52 LCD_RS : out std_logic;
53 LCD_RW : out std_logic;
54 LCD_EN : out std_logic
55 );
56
57end LCD_Controller;
58
59
60
61Architecture RTL of LCD_Controller is
62
63 type State_type is (Boot, FunctionSet, DisplayControl, EntryModeSet, Clear,
64 Address_set, Waiting, Verify, Putchar, Homecursor,
65 WriteAddress, WriteData);
66 signal present : State_type;
67
68 signal future : State_type;
69
70
71-- Timing Constants :
72
73 constant T_30ms : integer := 30_000/4; -- 7500; -- 30 ms
74
75 constant T_2ms : integer := 2_000/4; --500; -- 2 ms
76
77 constant T_40us : integer := 12; -- > 39 us after E down
78
79 constant En_delay : integer := 1; -- 8 us
80
81 constant LastPosition : integer := 16;
82
83
84-- CLEAR DisplayControl
85 constant CLR : std_logic_vector(7 downto 0) := "00000001";
86-- RETURN HOME
87 constant RET_HOME : std_logic_vector(7 downto 0) := "00000010"; -- 0000001x
88 -- DDRAM address to 0 (beginning of first line)
89
90-- ENTRY MODE SET
91 constant ENTRY_MODE : std_logic_vector(7 downto 0) := "00000110"; -- 0000 01 I/D S
92 -- I/D : 1 => Increment, 0 => Decrement
93 -- S : 1 => DisplayControl shift
94
95-- FUNCTION SET
96 constant FUNC_SET : std_logic_vector(7 downto 0) := "00111100"; -- 001 DL N F xx
97 -- DL : 1 => 8 bits, 0 => 4 bits
98 -- N : 1 => 2 lines, 0 => 1 line
99 -- F : 1 => 5x10 dots, 0 => 5x8 dots
100
101-- DisplayControl ON/OFF CONTROL
102 constant DON : std_logic_vector(7 downto 0) := "00001110"; -- 0000 1 D C B
103 -- D : 1 => Display on
104 -- C : 1 => Cursor on
105 -- B : 1 => Cursor blink on
106
107 constant RET_LINE2 : std_logic_vector(7 downto 0) := "11000000";
108 -- set DDRAM address to 32 (beginning of second line)
109 constant RET_LINE1 : std_logic_vector(7 downto 0) := "10000000";
110 -- set DDRAM address to 0 (beginning of first line)
111
112
113
114 signal Position : natural range 0 to 2*LastPosition;
115
116 signal Count : natural range 0 to T_30ms;
117 signal inc_C : std_logic;
118
119 signal cmd_P : std_logic_vector(1 downto 0);
120 --signal reset_P : std_logic;
121
122 signal test_EN : std_logic;
123 signal test_T_40us : std_logic;
124
125
126
127 begin
128
129
130 LCD_RW <= '0';
131
132
133process (Clk, resetn)
134
135 begin
136
137 if resetn = '0' then
138
139 present <= Boot;
140 position <= 0;
141 count <= 0;
142
143 elsif rising_edge(clk) then
144
145 if en_250kHz = '1' then
146
147 present <= future;
148
149 if inc_C = '1' then count <= count+1;
150
151 else count <= 0;
152
153 end if;
154 case cmd_P is
155 when "00" => position <= 0;
156 when "01" => if position >= 31 then position <= 0;
157 else position <= position+1;
158 end if;
159 when "10" => if address(6 downto 4) = "000" then position <= to_integer(unsigned(address(3 downto 0)));
160 elsif address(6 downto 4) = "100" then position <= to_integer(unsigned(address(3 downto 0)))+16;
161 else position <= 0;
162 end if;
163 when others => null;
164 end case;
165
166 end if;
167
168 end if;
169 end process;
170
171
172test_EN <= '1' when Count = En_delay else '0';
173test_T_40us <= '1' when count >= T_40us else '0';
174
175 process(present, Write_char, mode, write_address, count, Position,char,
176 address,test_EN, test_T_40us , D, C, b) is
177
178 begin
179
180 future <= present;
181
182 inc_C <= '1';
183
184 cmd_P <= "11";
185
186 ready <= '0';
187
188 LCD_RS <= '0';
189
190 LCD_EN <= '0';
191
192 LCD_data <= X"00";
193
194
195
196 case present is
197
198
199 when Boot => -- Wait for 30 ms
200
201 if Count = T_30ms then
202 future <= FunctionSet;
203 inc_C <= '0';
204 end if;
205 cmd_P <= "00";
206
207
208
209 when FunctionSet => -- Function Set
210 LCD_data <= FUNC_SET;
211
212 LCD_EN <= test_EN;
213
214 if test_T_40us = '1' then
215 future <= EntryModeSet;
216 inc_C <= '0';
217 end if;
218 cmd_P <= "00";
219
220
221
222
223 when EntryModeSet => -- Entry Mode Set
224
225 LCD_data <= ENTRY_MODE;
226
227 LCD_EN <= test_EN;
228
229 if test_T_40us = '1' then
230 future <= DisplayControl;
231 inc_C <= '0';
232