forked from DanielBretts/Spaceship-Game
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lcd.c
520 lines (477 loc) · 13.7 KB
/
lcd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
/* ************************************************************************** */
/** Descriptive File Name
@Company
Digilent
@File Name
lcd.c
@Description
This file groups the functions that implement the LCD library.
The library implements control of the LCD device.
It is accessed in a "parallel like" approach.
Library provides functions for simple commands, displaying characters, handling user characters.
Include the file together with config.h, utils.c and utils.h in the project when this library is needed.
@Author
Cristian Fatu
cristian.fatu@digilent.ro
*/
/* ************************************************************************** */
/* ************************************************************************** */
/* ************************************************************************** */
/* Section: Included Files */
/* ************************************************************************** */
#include <xc.h>
#include <sys/attribs.h>
#include <string.h>
#include "config.h"
#include "lcd.h"
/* ************************************************************************** */
/* ------------------------------------------------------------ */
/*** LCD_Init
**
** Parameters:
**
**
** Return Value:
**
**
** Description:
** This function initializes the hardware used in the LCD module:
** The following digital pins are configured as digital outputs: LCD_DISP_RS, LCD_DISP_RW, LCD_DISP_EN
** The following digital pins are configured as digital inputs: LCD_DISP_RS.
** The LCD initialization sequence is performed, the LCD is turned on.
**
*/
void LCD_Init()
{
LCD_ConfigurePins();
LCD_InitSequence(displaySetOptionDisplayOn);
}
/* ------------------------------------------------------------ */
/*** LCD_ConfigurePins
**
** Parameters:
**
**
** Return Value:
**
**
** Description:
** This function configures the digital pins involved in the LCD module:
** The following digital pins are configured as digital outputs: LCD_DISP_RS, LCD_DISP_RW, LCD_DISP_EN
** The following digital pins are configured as digital inputs: LCD_DISP_RS.
** The function uses pin related definitions from config.h file.
** This is a low-level function called by LCD_Init(), so user should avoid calling it directly.
**
**
*/
void LCD_ConfigurePins()
{
// set control pins as digital outputs.
tris_LCD_DISP_RS = 0;
tris_LCD_DISP_RW = 0;
tris_LCD_DISP_EN = 0;
// disable analog (set pins as digital))
ansel_LCD_DISP_RS = 0;
// default (IO) function for remapable pins
rp_LCD_DISP_RS = 0;
rp_LCD_DISP_RW = 0;
rp_LCD_DISP_EN = 0;
// make data pins digital (disable analog)
ansel_LCD_DB2 = 0;
ansel_LCD_DB4 = 0;
ansel_LCD_DB5 = 0;
ansel_LCD_DB6 = 0;
ansel_LCD_DB7 = 0;
}
/* ------------------------------------------------------------ */
/*** LCD_WriteByte
**
** Parameters:
** unsigned char bData - the data to be written to LCD, over the parallel interface
**
** Return Value:
**
**
** Description:
** This function writes a byte to the LCD.
** It implements the parallel write using LCD_DISP_RS, LCD_DISP_RW, LCD_DISP_EN,
** LCD_DISP_RS pins, and data pins.
** For a better performance, the data pins are accessed using a pointer to
** the register byte where they are allocated.
** This is a low-level function called by LCD write functions, so user should avoid calling it directly.
** The function uses pin related definitions from config.h file.
**
**
*/
void LCD_WriteByte(unsigned char bData)
{
DelayAprox10Us(5);
// Configure IO Port data pins as output.
tris_LCD_DATA &= ~msk_LCD_DATA;
DelayAprox10Us(5);
// clear RW
lat_LCD_DISP_RW = 0;
// access data as contiguous 8 bits, using pointer to the LSB byte of LATE register
unsigned char *pLCDData = (unsigned char *)(0xBF886430);
*pLCDData = bData;
DelayAprox10Us(10);
// Set En
lat_LCD_DISP_EN = 1;
DelayAprox10Us(5);
// Clear En
lat_LCD_DISP_EN = 0;
DelayAprox10Us(5);
// Set RW
lat_LCD_DISP_RW = 1;
}
/* ------------------------------------------------------------ */
/*** LCD_ReadByte
**
** Parameters:
**
**
** Return Value:
** unsigned char - the data read from LCD, over the parallel interface
**
** Description:
** This function reads a byte from the LCD.
** It implements the parallel read using LCD_DISP_RS, LCD_DISP_RW, LCD_DISP_EN,
** LCD_DISP_RS pins, and data pins.
** This is a low-level function called by LCD_ReadStatus function, so user should avoid calling it directly.
** The function uses pin related definitions from config.h file.
**
**
*/
unsigned char LCD_ReadByte()
{
unsigned char bData;
// Configure IO Port data pins as input.
tris_LCD_DATA |= msk_LCD_DATA;
// Set RW
lat_LCD_DISP_RW = 1;
// set RW
lat_LCD_DISP_RW = 1;
// Set En
lat_LCD_DISP_EN = 1;
DelayAprox10Us(50);
// Clear En
lat_LCD_DISP_EN = 0;
bData = (unsigned char)(prt_LCD_DATA & (unsigned int)msk_LCD_DATA);
return bData;
}
/* ------------------------------------------------------------ */
/*** LCD_ReadStatus
**
** Parameters:
**
**
** Return Value:
** unsigned char - the status byte that was read.
**
** Description:
** Reads the status of the LCD.
** It clears the RS and calls LCD_ReadByte() function.
** The function uses pin related definitions from config.h file.
**
*/
unsigned char LCD_ReadStatus()
{
// Clear RS
lat_LCD_DISP_RS = 0;
unsigned char bStatus = LCD_ReadByte();
return bStatus;
}
/* ------------------------------------------------------------ */
/*** LCD_WriteCommand
**
** Parameters:
** unsigned char bCmd - the command code byte to be written to LCD
**
** Return Value:
**
**
** Description:
** Writes the specified byte as command.
** It clears the RS and writes the byte to LCD.
** The function uses pin related definitions from config.h file.
**
**
*/
void LCD_WriteCommand(unsigned char bCmd)
{
// Clear RS
lat_LCD_DISP_RS = 0;
// Write command byte
LCD_WriteByte(bCmd);
}
/* ------------------------------------------------------------ */
/*** LCD_WriteDataByte
**
** Parameters:
** unsigned char bData - the data byte to be written to LCD
**
** Return Value:
**
**
** Description:
** Writes the specified byte as data.
** It sets the RS and writes the byte to LCD.
** The function uses pin related definitions from config.h file.
** This is a low-level function called by LCD write functions, so user should avoid calling it directly.
**
**
*/
void LCD_WriteDataByte(unsigned char bData)
{
// Set RS
lat_LCD_DISP_RS = 1;
// Write data byte
LCD_WriteByte(bData);
}
/* ------------------------------------------------------------ */
/*** LCD_InitSequence
**
** Synopsis:
** LCD_InitSequence(displaySetOptionDisplayOn);//set the display on
**
** Parameters:
** unsigned char bDisplaySetOptions - display options
** Possible options (to be OR-ed)
** displaySetOptionDisplayOn - display ON
** displaySetOptionCursorOn - cursor ON
** displaySetBlinkOn - cursor blink ON
**
** Return Value:
**
**
** Description:
** This function performs the initializing (startup) sequence.
** The LCD is initialized according to the parameter bDisplaySetOptions.
**
**
*/
void LCD_InitSequence(unsigned char bDisplaySetOptions)
{
// wait 40 ms
DelayAprox10Us(40000);
// Function Set
LCD_WriteCommand(cmdLcdFcnInit);
// Wait ~100 us
DelayAprox10Us(10);
// Function Set
LCD_WriteCommand(cmdLcdFcnInit);
// Wait ~100 us
DelayAprox10Us(10); // Display Set
LCD_DisplaySet(bDisplaySetOptions);
// Wait ~100 us
DelayAprox10Us(10);
// Display Clear
LCD_DisplayClear();
// Wait 1.52 ms
DelayAprox10Us(160);
// Entry mode set
LCD_WriteCommand(cmdLcdEntryMode);
// Wait 1.52 ms
DelayAprox10Us(160);
}
/* ------------------------------------------------------------ */
/*** LCD_DisplaySet
**
** Synopsis:
** LCD_DisplaySet(displaySetOptionDisplayOn | displaySetOptionCursorOn);
**
** Parameters:
** unsigned char bDisplaySetOptions - display options
** Possible options (to be OR-ed)
** displaySetOptionDisplayOn - display ON
** displaySetOptionCursorOn - cursor ON
** displaySetBlinkOn - cursor blink ON
**
** Return Value:
**
**
** Description:
** The LCD is initialized according to the parameter bDisplaySetOptions.
** If one of the above mentioned optios is not OR-ed,
** it means that the OFF action is performed for it.
**
**
*/
void LCD_DisplaySet(unsigned char bDisplaySetOptions)
{
LCD_WriteCommand(cmdLcdCtlInit | bDisplaySetOptions);
}
/* ------------------------------------------------------------ */
/*** LCD_DisplayClear
**
** Parameters:
**
** Return Value:
**
** Description:
** Clears the display and returns the cursor home (upper left corner, position 0 on row 0).
**
**
*/
void LCD_DisplayClear()
{
LCD_WriteCommand(cmdLcdClear);
}
/* ------------------------------------------------------------ */
/*** LCD_ReturnHome
**
**
** Parameters:
**
** Return Value:
**
** Description:
** Returns the cursor home (upper left corner, position 0 on row 0).
**
**
*/
void LCD_ReturnHome()
{
LCD_WriteCommand(cmdLcdRetHome);
}
/* ------------------------------------------------------------ */
/*** LCD_DisplayShift
** Parameters:
** unsigned char fRight - specifies display shift direction:
** - 1 in order to shift right
** - 0 in order to shift left
**
** Return Value:
**
** Description:
** Shifts the display one position right or left, depending on the fRight parameter.
**
**
*/
void LCD_DisplayShift(unsigned char fRight)
{
unsigned char bCmd = cmdLcdDisplayShift | (fRight ? mskShiftRL: 0);
LCD_WriteCommand(bCmd);
}
/* ------------------------------------------------------------ */
/*** LCD_CursorShift
**
** Parameters:
** unsigned char fRight
** - 1 in order to shift right
** - 0 in order to shift left
**
** Return Value:
**
** Description:
** Shifts the cursor one position right or left, depending on the fRight parameter.
**
**
*/
void LCD_CursorShift(unsigned char fRight)
{
unsigned char bCmd = cmdLcdCursorShift | (fRight ? mskShiftRL: 0);
LCD_WriteCommand(bCmd);
}
/* ------------------------------------------------------------ */
/*** LCD_WriteStringAtPos
**
** Synopsis:
** LCD_WriteStringAtPos("Demo", 0, 0);
**
** Parameters:
** char *szLn - string to be written to LCD
** int idxLine - line where the string will be displayed
** 0 - first line of LCD
** 1 - second line of LCD
** unsigned char idxPos - the starting position of the string within the line.
** The value must be between:
** 0 - first position from left
** 39 - last position for DDRAM for one line
**
**
** Return Value:
**
** Description:
** Displays the specified string at the specified position on the specified line.
** It sets the corresponding write position and then writes data bytes when the device is ready.
** Strings longer than 40 characters are trimmed.
** It is possible that not all the characters will be visualized, as the display only visualizes 16 characters for one line.
**
**
*/
void LCD_WriteStringAtPos(char *szLn, unsigned char idxLine, unsigned char idxPos)
{
// crop string to 0x27 chars
int len = strlen(szLn);
if(len > 0x27)
{
szLn[0x27] = 0; // trim the string so it contains 40 characters
len = 0x27;
}
// Set write position
unsigned char bAddrOffset = (idxLine == 0 ? 0: 0x40) + idxPos;
LCD_SetWriteDdramPosition(bAddrOffset);
unsigned char bIdx = 0;
while(bIdx < len)
{
LCD_WriteDataByte(szLn[bIdx]);
bIdx++;
}
}
/* ------------------------------------------------------------ */
/*** LCD_SetWriteCgramPosition
**
**
** Parameters:
** unsigned char bAdr - the write location. The position in CGRAM where the next data write operations will put bytes.
**
** Return Value:
**
** Description:
** Sets the DDRAM write position. This is the location where the next data write operation will be performed.
** Writing to a location auto-increments the write location.
** This is a low-level function called by LCD_WriteBytesAtPosCgram(), so user should avoid calling it directly.
**
**
*/
void LCD_SetWriteCgramPosition(unsigned char bAdr)
{
unsigned char bCmd = cmdLcdSetCgramPos | bAdr;
LCD_WriteCommand(bCmd);
}
/* ------------------------------------------------------------ */
/*** LCD_WriteBytesAtPosCgram
**
** Synopsis:
** LCD_WriteBytesAtPosCgram(userDefArrow, 8, posCgramChar0);
**
** Parameters:
** unsigned char *pBytes - pointer to the string of bytes
** unsigned char len - the number of bytes to be written
** unsigned char bAdr - the position in CGRAM where bytes will be written
**
** Return Value:
**
** Description:
** Writes the specified number of bytes to CGRAM starting at the specified position.
** This allows user characters to be defined.
** It sets the corresponding write position and then writes data bytes when the device is ready.
**
**
*/
void LCD_WriteBytesAtPosCgram(unsigned char *pBytes, unsigned char len, unsigned char bAdr)
{
// Set write position
LCD_SetWriteCgramPosition(bAdr);
// Write the string of bytes that define the character to CGRAM
unsigned char idx = 0;
while(idx < len)
{
LCD_WriteDataByte(pBytes[idx]);
idx++;
}
}
/* *****************************************************************************
End of File
*/