1 ;fuction: print 'PicoBlaze' on the screen
2 ;LCD interface ports
3 ;
4 ;The master enable signal is not used by the LCD display itself
5 ;but may be required to confirm that LCD communication is active.
6 ;This is required on the Spartan-3E Starter Kit if the StrataFLASH
7 ;is used because it shares the same data pins and conflicts must be avoided.
8 ;
9 CONSTANT LCD_output_port, 40 ;LCD character module output data and control
10 CONSTANT LCD_E, 01 ; active High Enable E - bit0
11 CONSTANT LCD_RW, 02 ; Read=1 Write=0 RW - bit1
12 CONSTANT LCD_RS, 04 ; Instruction=0 Data=1 RS - bit2
13 CONSTANT LCD_drive, 08 ; Master enable (active High) - bit3
14 CONSTANT LCD_DB4, 10 ; 4-bit Data DB4 - bit4
15 CONSTANT LCD_DB5, 20 ; interface Data DB5 - bit5
16 CONSTANT LCD_DB6, 40 ; Data DB6 - bit6
17 CONSTANT LCD_DB7, 80 ; Data DB7 - bit7
18 ;
19 ;
20 CONSTANT LCD_input_port, 02 ;LCD character module input data
21 CONSTANT LCD_read_spare0, 01 ; Spare bits - bit0
22 CONSTANT LCD_read_spare1, 02 ; are zero - bit1
23 CONSTANT LCD_read_spare2, 04 ; - bit2
24 CONSTANT LCD_read_spare3, 08 ; - bit3
25 CONSTANT LCD_read_DB4, 10 ; 4-bit Data DB4 - bit4
26 CONSTANT LCD_read_DB5, 20 ; interface Data DB5 - bit5
27 CONSTANT LCD_read_DB6, 40 ; Data DB6 - bit6
28 CONSTANT LCD_read_DB7, 80 ; Data DB7 - bit7
29 ;
30 ;
31
32 ;Constant to define a software delay of 1us. This must be adjusted to reflect the
33 ;clock applied to KCPSM3. Every instruction executes in 2 clock cycles making the
34 ;calculation highly predictable. The '6' in the following equation even allows for
35 ;'CALL delay_1us' instruction in the initiating code.
36 ;
37 ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
38 ;
39 ;Example: For a 50MHz clock the constant value is (10-6)/4 = 11 (0B Hex).
40 ;For clock rates below 10MHz the value of 1 must be used and the operation will
41 ;become lower than intended.
42 ;
43 CONSTANT delay_1us_constant, 0B
44 ;
45 ;
46 ;
47 ;ASCII table
48 ;
49 CONSTANT character_a, 61
50 CONSTANT character_b, 62
51 CONSTANT character_c, 63
52 CONSTANT character_d, 64
53 CONSTANT character_e, 65
54 CONSTANT character_f, 66
55 CONSTANT character_g, 67
56 CONSTANT character_h, 68
57 CONSTANT character_i, 69
58 CONSTANT character_j, 6A
59 CONSTANT character_k, 6B
60 CONSTANT character_l, 6C
61 CONSTANT character_m, 6D
62 CONSTANT character_n, 6E
63 CONSTANT character_o, 6F
64 CONSTANT character_p, 70
65 CONSTANT character_q, 71
66 CONSTANT character_r, 72
67 CONSTANT character_s, 73
68 CONSTANT character_t, 74
69 CONSTANT character_u, 75
70 CONSTANT character_v, 76
71 CONSTANT character_w, 77
72 CONSTANT character_x, 78
73 CONSTANT character_y, 79
74 CONSTANT character_z, 7A
75 CONSTANT character_A, 41
76 CONSTANT character_B, 42
77 CONSTANT character_C, 43
78 CONSTANT character_D, 44
79 CONSTANT character_E, 45
80 CONSTANT character_F, 46
81 CONSTANT character_G, 47
82 CONSTANT character_H, 48
83 CONSTANT character_I, 49
84 CONSTANT character_J, 4A
85 CONSTANT character_K, 4B
86 CONSTANT character_L, 4C
87 CONSTANT character_M, 4D
88 CONSTANT character_N, 4E
89 CONSTANT character_O, 4F
90 CONSTANT character_P, 50
91 CONSTANT character_Q, 51
92 CONSTANT character_R, 52
93 CONSTANT character_S, 53
94 CONSTANT character_T, 54
95 CONSTANT character_U, 55
96 CONSTANT character_V, 56
97 CONSTANT character_W, 57
98 CONSTANT character_X, 58
99 CONSTANT character_Y, 59
100 CONSTANT character_Z, 5A
101 CONSTANT character_0, 30
102 CONSTANT character_1, 31
103 CONSTANT character_2, 32
104 CONSTANT character_3, 33
105 CONSTANT character_4, 34
106 CONSTANT character_5, 35
107 CONSTANT character_6, 36
108 CONSTANT character_7, 37
109 CONSTANT character_8, 38
110 CONSTANT character_9, 39
111 CONSTANT character_colon, 3A
112 CONSTANT character_stop, 2E
113 CONSTANT character_semi_colon, 3B
114 CONSTANT character_minus, 2D
115 CONSTANT character_divide, 2F ;'/'
116 CONSTANT character_plus, 2B
117 CONSTANT character_comma, 2C
118 CONSTANT character_less_than, 3C
119 CONSTANT character_greater_than, 3E
120 CONSTANT character_equals, 3D
121 CONSTANT character_space, 20
122 CONSTANT character_CR, 0D ;carriage return
123 CONSTANT character_question, 3F ;'?'
124 CONSTANT character_dollar, 24
125 CONSTANT character_exclaim, 21 ;'!'
126 CONSTANT character_BS, 08 ;Back Space command character
127 ;
128
129 ;routine
130 ;initializaion
131 ;print
132
133 cold_start: call LCD_reset ;initialise LCD display
134 ;Write welcome message to LCD display
135 ;
136 LOAD s5, 10 ;Line 1 position 0
137 CALL LCD_cursor
138 CALL disp_PicoBlaze ;Display 'PicoBlaze Inside'
139 stop:load s0,s0 ;
140 jump stop
141 ;**************************************************************************************
142 ;LCD text messages
143 ;**************************************************************************************
144 ;
145 ;
146 ;Display 'PicoBlaze' on LCD at current cursor position
147 ;
148 ;
149 disp_PicoBlaze: LOAD s5, character_P
150 CALL LCD_write_data
151 LOAD s5, character_i
152 CALL LCD_write_data
153 LOAD s5, character_c
154 CALL LCD_write_data
155 LOAD s5, character_o
156 CALL LCD_write_data
157 LOAD s5, character_B
158 CALL LCD_write_data
159 LOAD s5, character_l
160 CALL LCD_write_data
161 LOAD s5, character_a
162 CALL LCD_write_data
163 LOAD s5, character_z
164 CALL LCD_write_data
165 LOAD s5, character_e
166 CALL LCD_write_data
167 RETURN
168 ;
169 ;**************************************************************************************
170 ;Software delay routines
171 ;**************************************************************************************
172 ;
173 ;
174 ;
175 ;Delay of 1us.
176 ;
177 ;Constant value defines reflects the clock applied to KCPSM3. Every instruction
178 ;executes in 2 clock cycles making the calculation highly predictable. The '6' in
179 ;the following equation even allows for 'CALL delay_1us' instruction in the initiating code.
180 ;
181 ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
182 ;
183 ;Registers used s0
184 ;
185 delay_1us: LOAD s0, delay_1us_constant
186 wait_1us: SUB s0, 01
187 JUMP NZ, wait_1us
188 RETURN
189 ;
190 ;Delay of 40us.
191 ;
192 ;Registers used s0, s1
193 ;
194 delay_40us: LOAD s1, 28 ;40 x 1us = 40us
195 wait_40us: CALL delay_1us
196 SUB s1, 01
197 JUMP NZ, wait_40us
198 RETURN
199 ;
200 ;
201 ;Delay of 1ms.
202 ;
203 ;Registers used s0, s1, s2
204 ;
205 delay_1ms: LOAD s2, 19 ;25 x 40us = 1ms
206 wait_1ms: CALL delay_40us
207 SUB s2, 01
208 JUMP NZ, wait_1ms
209 RETURN
210 ;
211 ;Delay of 20ms.
212 ;
213 ;Delay of 20ms used during initialisation.
214 ;
215 ;Registers used s0, s1, s2, s3
216 ;
217 delay_20ms: LOAD s3, 14 ;20 x 1ms = 20ms
218 wait_20ms: CALL delay_1ms
219 SUB s3, 01
220 JUMP NZ, wait_20ms
221 RETURN
222 ;
223 ;Delay of approximately 1 second.
224 ;
225 ;Registers used s0, s1, s2, s3, s4
226 ;
227 delay_1s: LOAD s4, 32 ;50 x 20ms = 1000ms
228 wait_1s: CALL delay_20ms
229 SUB s4, 01
230 JUMP NZ, wait_1s
231 RETURN
232 ;
233 ;
234 ;
235 ;**************************************************************************************
236 ;LCD Character Module Routines
237 ;**************************************************************************************
238 ;
239 ;LCD module is a 16 character by 2 line display but all displays are very similar
240 ;The 4-wire data interface will be used (DB4 to DB7).
241 ;
242 ;The LCD modules are relatively slow and software delay loops are used to slow down
243 ;KCPSM3 adequately for the LCD to communicate. The delay routines are provided in
244 ;a different section (see above in this case).
245 ;
246 ;
247 ;Pulse LCD enable signal 'E' high for greater than 230ns (1us is used).
248 ;
249 ;Register s4 should define the current state of the LCD output port.
250 ;
251 ;Registers used s0, s4
252 ;
253 LCD_pulse_E: XOR s4, LCD_E ;E=1
254 OUTPUT s4, LCD_output_port
255 CALL delay_1us
256 XOR s4, LCD_E ;E=0
257 OUTPUT s4, LCD_output_port
258 RETURN
259 ;
260 ;Write 4-bit instruction to LCD display.
261 ;
262 ;The 4-bit instruction should be provided in the upper 4-bits of register s4.
263 ;Note that this routine does not release the master enable but as it is only
264 ;used during initialisation and as part of the 8-bit instruction write it
265 ;should be acceptable.
266 ;
267 ;Registers used s4
268 ;
269 LCD_write_inst4: AND s4, F8 ;Enable=1 RS=0 Instruction, RW=0 Write, E=0
270 OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
271 CALL LCD_pulse_E
272 RETURN
273 ;
274 ;
275 ;Write 8-bit instruction to LCD display.
276 ;
277 ;The 8-bit instruction should be provided in register s5.
278 ;Instructions are written using the following sequence
279 ; Upper nibble
280 ; wait >1us
281 ; Lower nibble
282 ; wait >40us
283 ;
284 ;Registers used s0, s1, s4, s5
285 ;
286 LCD_write_inst8: LOAD s4, s5
287 AND s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
288 OR s4, LCD_drive ;Enable=1
289 CALL LCD_write_inst4 ;write upper nibble
290 CALL delay_1us ;wait >1us
291 LOAD s4, s5 ;select lower nibble with
292 SL1 s4 ;Enable=1
293 SL0 s4 ;RS=0 Instruction
294 SL0 s4 ;RW=0 Write
295 SL0 s4 ;E=0
296 CALL LCD_write_inst4 ;write lower nibble
297 CALL delay_40us ;wait >40us
298 LOAD s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
299 OUTPUT s4, LCD_output_port ;Release master enable
300 RETURN
301 ;
302 ;
303 ;
304 ;Write 8-bit data to LCD display.
305 ;
306 ;The 8-bit data should be provided in register s5.
307 ;Data bytes are written using the following sequence
308 ; Upper nibble
309 ; wait >1us
310 ; Lower nibble
311 ; wait >40us
312 ;
313 ;Registers used s0, s1, s4, s5
314 ;
315 LCD_write_data: LOAD s4, s5
316 AND s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
317 OR s4, 0C ;Enable=1 RS=1 Data, RW=0 Write, E=0
318 OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
319 CALL LCD_pulse_E ;write upper nibble
320 CALL delay_1us ;wait >1us
321 LOAD s4, s5 ;select lower nibble with
322 SL1 s4 ;Enable=1
323 SL1 s4 ;RS=1 Data
324 SL0 s4 ;RW=0 Write
325 SL0 s4 ;E=0
326 OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
327 CALL LCD_pulse_E ;write lower nibble
328 CALL delay_40us ;wait >40us
329 LOAD s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
330 OUTPUT s4, LCD_output_port ;Release master enable
331 RETURN
332 ;
333 ;
334 ;
335 ;
336 ;Read 8-bit data from LCD display.
337 ;
338 ;The 8-bit data will be read from the current LCD memory address
339 ;and will be returned in register s5.
340 ;It is advisable to set the LCD address (cursor position) before
341 ;using the data read for the first time otherwise the display may
342 ;generate invalid data on the first read.
343 ;
344 ;Data bytes are read using the following sequence
345 ; Upper nibble
346 ; wait >1us
347 ; Lower nibble
348 ; wait >40us
349 ;
350 ;Registers used s0, s1, s4, s5
351 ;
352 LCD_read_data8: LOAD s4, 0E ;Enable=1 RS=1 Data, RW=1 Read, E=0
353 OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
354 XOR s4, LCD_E ;E=1
355 OUTPUT s4, LCD_output_port
356 CALL delay_1us ;wait >260ns to access data
357 INPUT s5, LCD_input_port ;read upper nibble
358 XOR s4, LCD_E ;E=0
359 OUTPUT s4, LCD_output_port
360 CALL delay_1us ;wait >1us
361 XOR s4, LCD_E ;E=1
362 OUTPUT s4, LCD_output_port
363 CALL delay_1us ;wait >260ns to access data
364 INPUT s0, LCD_input_port ;read lower nibble
365 XOR s4, LCD_E ;E=0
366 OUTPUT s4, LCD_output_port
367 AND s5, F0 ;merge upper and lower nibbles
368 SR0 s0
369 SR0 s0
370 SR0 s0
371 SR0 s0
372 OR s5, s0
373 LOAD s4, 04 ;Enable=0 RS=1 Data, RW=0 Write, E=0
374 OUTPUT s4, LCD_output_port ;Stop reading 5V device and release master enable
375 CALL delay_40us ;wait >40us
376 RETURN
377 ;
378 ;
379 ;Reset and initialise display to communicate using 4-bit data mode
380 ;Includes routine to clear the display.
381 ;
382 ;Requires the 4-bit instructions 3,3,3,2 to be sent with suitable delays
383 ;following by the 8-bit instructions to set up the display.
384 ;
385 ; 28 = '001' Function set, '0' 4-bit mode, '1' 2-line, '0' 5x7 dot matrix, 'xx'
386 ; 06 = '000001' Entry mode, '1' increment, '0' no display shift
387 ; 0C = '00001' Display control, '1' display on, '0' cursor off, '0' cursor blink off
388 ; 01 = '00000001' Display clear
389 ;
390 ;Registers used s0, s1, s2, s3, s4
391 ;
392 LCD_reset: CALL delay_20ms ;wait more that 15ms for display to be ready
393 LOAD s4, 30
394 CALL LCD_write_inst4 ;send '3'
395 CALL delay_20ms ;wait >4.1ms
396 CALL LCD_write_inst4 ;send '3'
397 CALL delay_1ms ;wait >100us
398 CALL LCD_write_inst4 ;send '3'
399 CALL delay_40us ;wait >40us
400 LOAD s4, 20
401 CALL LCD_write_inst4 ;send '2'
402 CALL delay_40us ;wait >40us
403 LOAD s5, 28 ;Function set
404 CALL LCD_write_inst8
405 LOAD s5, 06 ;Entry mode
406 CALL LCD_write_inst8
407 LOAD s5, 0C ;Display control
408 CALL LCD_write_inst8
409 LCD_clear: LOAD s5, 01 ;Display clear
410 CALL LCD_write_inst8
411 CALL delay_1ms ;wait >1.64ms for display to clear
412 CALL delay_1ms
413 RETURN
414 ;
415 ;Position the cursor ready for characters to be written.
416 ;The display is formed of 2 lines of 16 characters and each
417 ;position has a corresponding address as indicated below.
418 ;
419 ; Character position
420 ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
421 ;
422 ; Line 1 - 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
423 ; Line 2 - C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
424 ;
425 ;This routine will set the cursor position using the value provided
426 ;in register s5. The upper nibble will define the line and the lower
427 ;nibble the character position on the line.
428 ; Example s5 = 2B will position the cursor on line 2 position 11
429 ;
430 ;Registers used s0, s1, s2, s3, s4
431 ;
432 LCD_cursor: TEST s5, 10 ;test for line 1
433 JUMP Z, set_line2
434 AND s5, 0F ;make address in range 80 to 8F for line 1
435 OR s5, 80
436 CALL LCD_write_inst8 ;instruction write to set cursor
437 RETURN
438 set_line2: AND s5, 0F ;make address in range C0 to CF for line 2
439 OR s5, C0
440 CALL LCD_write_inst8 ;instruction write to set cursor
441 RETURN
442 ;
443 ;