diff options
Diffstat (limited to 'FPGA/vhdl/lcd_controller.vhd')
-rw-r--r-- | FPGA/vhdl/lcd_controller.vhd | 363 |
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 | |||
10 | library ieee; | ||
11 | use 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 | |||
32 | Entity 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 | |||
57 | end LCD_Controller; | ||
58 | |||
59 | |||
60 | |||
61 | Architecture 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 | |||
133 | process (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 | |||
172 | test_EN <= '1' when Count = En_delay else '0'; | ||
173 | test_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 |