1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
2 | ;; ;;
|
3 | ;; information ;;
|
4 | ;; ;;
|
5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
6 | ;;
|
7 | ;; This code is used for picoblaze to initialize a LCD and to write on it.
|
8 | ;; It is tested on a Spartan 3E starter kit. The LCD data and command port is
|
9 | ;; connected to picoblaze port 0x10:
|
10 | ;;
|
11 | ;; case port_id is
|
12 | ;; when x"10" => lcd_output_data <= out_port(7 downto 4);
|
13 | ;; lcd_drive <= out_port(3);
|
14 | ;; Lcd_rs <= out_port(2);
|
15 | ;; Lcd_e <= out_port(0);
|
16 | ;;
|
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
18 | ;; ;;
|
19 | ;; header ;;
|
20 | ;; ;;
|
21 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
22 |
|
23 | ;
|
24 | ; output ports
|
25 | CONSTANT LCD_PORT, 10
|
26 |
|
27 | ;
|
28 | ; constants
|
29 | CONSTANT DELAY_1US_CONSTANT, 0B
|
30 |
|
31 | ;
|
32 | ; bitfields
|
33 | CONSTANT LCD_E, 01
|
34 | CONSTANT LCD_DRIVE, 08
|
35 |
|
36 | ;
|
37 | ; adresses in scratchpad RAM
|
38 | CONSTANT STRING_RAM, 22 ; 22-2B - string for comand
|
39 |
|
40 | ;
|
41 | ; registers
|
42 | NAMEREG s0, US_REG ; wait registers
|
43 | NAMEREG s1, 40US_REG ;
|
44 | NAMEREG s2, MS_REG ;
|
45 | NAMEREG s3, 20MS_REG ;
|
46 | NAMEREG s4, LCD_INST_REG ; LCD registers
|
47 | NAMEREG s5, LCD_DATA_REG ;
|
48 | NAMEREG s6, LCD_ROW_COUNTER ;
|
49 |
|
50 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
51 | ;; ;;
|
52 | ;; LCD control functions ;;
|
53 | ;; ;;
|
54 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
55 |
|
56 | lcd_init:
|
57 | CALL delay_20ms ; wait more that 15ms for display to be ready
|
58 | LOAD LCD_INST_REG, 30
|
59 | CALL lcd_write_inst4 ; send '3'
|
60 | CALL delay_20ms ; wait >4.1ms
|
61 | CALL lcd_write_inst4 ; send '3'
|
62 | CALL delay_1ms ; wait >100us
|
63 | CALL lcd_write_inst4 ; send '3'
|
64 | CALL delay_40us ; wait >40us
|
65 | LOAD LCD_INST_REG, 20
|
66 | CALL lcd_write_inst4 ; send '2'
|
67 | CALL delay_40us ; wait >40us
|
68 | LOAD LCD_DATA_REG, 28 ; function set
|
69 | CALL lcd_write_inst8
|
70 | LOAD LCD_DATA_REG, 06 ; entry mode
|
71 | CALL lcd_write_inst8
|
72 | LOAD LCD_DATA_REG, 0C ; display control
|
73 | CALL lcd_write_inst8
|
74 | LOAD LCD_ROW_COUNTER, 10 ; 16 chars per line
|
75 | lcd_clear:
|
76 | LOAD LCD_DATA_REG, 01 ; display clear
|
77 | CALL lcd_write_inst8
|
78 | CALL delay_1ms ; wait >1.64ms for display to clear
|
79 | CALL delay_1ms
|
80 | RETURN
|
81 |
|
82 | lcd_pulse_e:
|
83 | XOR LCD_INST_REG, LCD_E
|
84 | OUTPUT LCD_INST_REG, LCD_PORT
|
85 | CALL wait_1us
|
86 | XOR LCD_INST_REG, LCD_E
|
87 | OUTPUT LCD_INST_REG, LCD_PORT
|
88 | RETURN
|
89 |
|
90 | lcd_write_inst4:
|
91 | AND LCD_INST_REG, F8 ; RS=0, E=0, master=1
|
92 | OUTPUT LCD_INST_REG, LCD_PORT
|
93 | CALL lcd_pulse_e
|
94 | RETURN
|
95 |
|
96 | lcd_write_inst8:
|
97 | LOAD LCD_INST_REG, LCD_DATA_REG
|
98 | AND LCD_INST_REG, F0 ; master=0 RS=0 instruction, E=0
|
99 | OR LCD_INST_REG, LCD_DRIVE ; master=1
|
100 | CALL lcd_write_inst4 ; write upper nibble
|
101 | CALL delay_1us
|
102 | LOAD LCD_INST_REG, LCD_DATA_REG ; select lower nibble with
|
103 | SL1 LCD_INST_REG ; master=1
|
104 | SL0 LCD_INST_REG ; RS=0
|
105 | SL0 LCD_INST_REG
|
106 | SL0 LCD_INST_REG ; E=0
|
107 | CALL lcd_write_inst4 ; write lower nibble
|
108 | CALL delay_40us ; wait >40us
|
109 | LOAD LCD_INST_REG, F0 ; master=0 RS=0 instruction, RW=0 write, E=0
|
110 | OUTPUT LCD_INST_REG, LCD_PORT ; release master enable
|
111 | RETURN
|
112 |
|
113 | lcd_cursor_home:
|
114 | LOAD LCD_DATA_REG, 80
|
115 | CALL lcd_write_inst8
|
116 | LOAD LCD_ROW_COUNTER, 10
|
117 | RETURN
|
118 |
|
119 | lcd_write_data:
|
120 | LOAD LCD_INST_REG, LCD_DATA_REG
|
121 | AND LCD_INST_REG, F0 ; master=0, RS=0 Instruction, E=0
|
122 | OR LCD_INST_REG, 0C ; master=1, RS=1 Data, E=0
|
123 | OUTPUT LCD_INST_REG, LCD_PORT ; set up RS and RW >40ns before enable pulse
|
124 | CALL lcd_pulse_e
|
125 | CALL delay_1us ; wait >1us
|
126 | LOAD LCD_INST_REG, LCD_DATA_REG ; select higher nibble with
|
127 | SL1 LCD_INST_REG ; master=1
|
128 | SL1 LCD_INST_REG ; RS=1 Data
|
129 | SL0 LCD_INST_REG ; RW=0 Write
|
130 | SL0 LCD_INST_REG ; E=0
|
131 | OUTPUT LCD_INST_REG, LCD_PORT ; set up RS and RW >40ns before enable pulse
|
132 | CALL lcd_pulse_e ; write lower nibble
|
133 | CALL delay_40us ; wait >40us
|
134 | LOAD LCD_INST_REG, F0 ; master=0, RS=0 Instruction, E=0
|
135 | OUTPUT LCD_INST_REG, LCD_PORT ; release master enable
|
136 | SUB LCD_ROW_COUNTER, 01 ; if eol => cursor home
|
137 | CALL Z, lcd_cursor_home
|
138 | RETURN
|
139 |
|
140 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
141 | ;; ;;
|
142 | ;; delay functions ;;
|
143 | ;; ;;
|
144 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
145 |
|
146 | delay_1us:
|
147 | LOAD US_REG, DELAY_1US_CONSTANT
|
148 | wait_1us: SUB US_REG, 01
|
149 | JUMP NZ, wait_1us
|
150 | RETURN
|
151 |
|
152 | delay_40us:
|
153 | LOAD 40US_REG, 28 ; 40 x 1us = 40us
|
154 | wait_40us:CALL delay_1us
|
155 | SUB 40US_REG, 01
|
156 | JUMP NZ, wait_40us
|
157 | RETURN
|
158 |
|
159 | delay_1ms:
|
160 | LOAD MS_REG, 19 ; 25 x 40us = 1ms
|
161 | wait_1ms: CALL delay_40us
|
162 | SUB MS_REG, 01
|
163 | JUMP NZ, wait_1ms
|
164 | RETURN
|
165 |
|
166 | delay_20ms:
|
167 | LOAD 20MS_REG, 14 ; 20 x 1ms = 20ms
|
168 | wait_20ms:CALL delay_1ms
|
169 | SUB 20MS_REG, 01
|
170 | JUMP NZ, wait_20ms
|
171 | RETURN
|