-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNokia5110_LCD_IT.c
267 lines (234 loc) · 10.4 KB
/
Nokia5110_LCD_IT.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
#include "Nokia5110_LCD_IT.h"
#define LCD_ASCII_OFFSET 0x20 //0x20, ASCII character for Space
#define LCD_ASCII_OFFSET_ZERO 0x2E // ASCII code for . is 0X2E (. / 0 1 etc)
#define LCD_X_ADDRESS_LENGTH 84
#define LCD_Y_ADDRESS_LENGTH 6
#define LCD_TOTAL_ADDRESS_LINES (LCD_X_ADDRESS_LENGTH * LCD_Y_ADDRESS_LENGTH)
#define TOTAL_FONT_COUNT 9
#define MAX_LCD_CHARACTER_CAPACITY 70
// Size width of fonts in pixels, add 2 for padding 1-6
#define LCD_DEFAULT_FONT_WIDTH 5
#define LCD_THICK_FONT_WIDTH 7
#define LCD_AUREBESH_FONT_WIDTH 5
#define LCD_SEVEN_SEGMENT_FONT_WIDTH 4
#define LCD_WIDE_FONT_WIDTH 8
#define LCD_TINY_FONT_WIDTH 3
#define LCD_LARGE_FONT_WIDTH 12 // No padding, no lowercase letters
#define LCD_HUGE_FONT_WIDTH 16 // No padding, numbers only
#define LCD_MEGA_FONT_WIDTH 16 // No padding, numbers only
static SPI_IT *SPIPointer;
static uint8_t lcdFont = N5110_FONT_DEFAULT;
static uint8_t rowPosition = 0;
static uint8_t columnPosition = 0;
static TextColor textColor = BLACK;
static const uint8_t ZERO_VALUES_ARRAY[LCD_TOTAL_ADDRESS_LINES] = { [0 ... LCD_TOTAL_ADDRESS_LINES - 1] = 0x00 };
static void printChar(char character);
static void printLargeFontCharacter(char character);
static void printHugeFontCharacter(char character);
static void printMegaFontCharacter(char character);
static void transmitFontDataLCD(void *fontArray, char character, uint8_t columnLength);
void initN5110(SPI_TypeDef *SPIx) {
SPIPointer = initBufferedSPI(SPIx, N5110_CHIP_SELECT_PORT, N5110_CHIP_SELECT_PIN, 0, LCD_TOTAL_ADDRESS_LINES); // only transmit data enabled
resetN5110(); // reset the display
commandN5110(H_EXTENDED_INSTRUCTION_SET);
commandN5110(VOP_BIAS_VOLTAGE_HIGH_CONTRAST);
commandN5110(TEMPERATURE_COEFFICIENT_3);
commandN5110(BIAS_VALUE_MUX_RATE_1X48);
commandN5110(H_BASIC_INSTRUCTION_SET); // for setting display mode switch to basic instructions
commandN5110(DISPLAY_NORMAL_MODE);
clearN5110();
}
void printCharN5110(char character) {
chipSelectSetBufferedSPI(SPIPointer);
printChar(character);
chipSelectResetBufferedSPI(SPIPointer);
}
void printStringN5110(const char *string) {
if (textColor == WHITE) {
transmit8BitsBufferedSPI(SPIPointer, 0xFF);
}
for (uint16_t i = 0; string[i] != '\0'; i++) {
printChar(string[i]);
}
if (textColor == WHITE) {
transmit8BitsBufferedSPI(SPIPointer, 0xFF);
}
chipSelectResetBufferedSPI(SPIPointer);
}
void printfStringN5110(char *format, ...) {
static char formatBuffer[MAX_LCD_CHARACTER_CAPACITY];
memset(formatBuffer, 0, MAX_LCD_CHARACTER_CAPACITY);
va_list args;
va_start(args, format);
vsnprintf(formatBuffer, MAX_LCD_CHARACTER_CAPACITY, format, args);
va_end(args);
printStringN5110(formatBuffer);
}
void printImageN5110(const uint8_t *imageData) {
transmit8BitDataBufferedSPI(SPIPointer, imageData, LCD_TOTAL_ADDRESS_LINES);
}
void fillBlockN5110(uint8_t fillData, uint8_t rowBlockNum) {
while(!LL_SPI_IsActiveFlag_TXE(SPIPointer->SPIx)); // wait if line is busy
goToXYN5110(0, rowBlockNum);
for (uint8_t i = 0; i < LCD_X_ADDRESS_LENGTH; i++) {
addByte(SPIPointer->TxBuffer, fillData);
}
chipSelectSetBufferedSPI(SPIPointer);
LL_SPI_EnableIT_TXE(SPIPointer->SPIx);
}
void printCustomCharacter(const unsigned char characterData[], uint16_t length, CustomCharacterPadding padding) {
if (padding == PADDING_LEFT || padding == PADDING_ALL) {
transmit8BitsBufferedSPI(SPIPointer, 0x00); //Blank vertical line padding, LHS
}
transmit8BitDataBufferedSPI(SPIPointer, characterData, length);
if (padding == PADDING_RIGHT || padding == PADDING_ALL) {
transmit8BitsBufferedSPI(SPIPointer, 0x00); //Blank vertical line padding, RHS
}
}
void goToXYN5110(uint8_t x, uint8_t y) {
if (x < LCD_X_ADDRESS_LENGTH && y < LCD_Y_ADDRESS_LENGTH) {
commandN5110(SET_X_ADDRESS_OF_RAM_COMMAND_REGISTER | x);
commandN5110(SET_Y_ADDRESS_OF_RAM_COMMAND_REGISTER | y);
columnPosition = x;
rowPosition = y;
}
}
void setPixelN5110(uint8_t column, uint8_t row) {
uint8_t rowBlock = row / 8; // from 0 to 5
goToXYN5110(column, rowBlock);
transmit8BitsBufferedSPI(SPIPointer, (1 << (row - (rowBlock * 8))));
}
void setFontN5110(uint8_t font) {
if (font <= TOTAL_FONT_COUNT) {
lcdFont = font;
}
}
void setTextColorN5110(TextColor color) {
textColor = color;
}
void clearN5110() {
LL_GPIO_SetOutputPin(N5110_DC_GPIO_PORT, N5110_DC_PIN);
transmit8BitDataBufferedSPI(SPIPointer, ZERO_VALUES_ARRAY, LCD_TOTAL_ADDRESS_LINES);
goToXYN5110(0, 0);
}
void commandN5110(char command) {
LL_GPIO_ResetOutputPin(N5110_DC_GPIO_PORT, N5110_DC_PIN);// make DC pin to logic zero for command operation
transmit8BitsBufferedSPI(SPIPointer, command);
LL_GPIO_SetOutputPin(N5110_DC_GPIO_PORT, N5110_DC_PIN); // make DC pint to logic high for data operation
}
void resetN5110() { // reset the Display at the beginning of initialization
LL_GPIO_ResetOutputPin(N5110_RESET_GPIO_PORT, N5110_RESET_PIN);
LL_mDelay(100);
LL_GPIO_SetOutputPin(N5110_RESET_GPIO_PORT, N5110_RESET_PIN);
}
void printChar(char character) {
switch (lcdFont) {
#ifdef N5110_FONT_DEFAULT
case N5110_FONT_DEFAULT:
if (character >= 0xC0) break; // cyrillic symbols workaround
transmitFontDataLCD((const unsigned char **) ASCII_CYRILLIC, character, LCD_DEFAULT_FONT_WIDTH);
break;
#endif
#ifdef N5110_FONT_THICK
case N5110_FONT_THICK:
transmitFontDataLCD((const unsigned char **) ASCII_THICK, character, LCD_THICK_FONT_WIDTH);
break;
#endif
#ifdef N5110_FONT_AUREBESH
case N5110_FONT_AUREBESH:
transmitFontDataLCD((const unsigned char **) ASCII_AUREBESH, character, LCD_AUREBESH_FONT_WIDTH);
break;
#endif
#ifdef N5110_FONT_SEVEN_SEGMENT
case N5110_FONT_SEVEN_SEGMENT:
transmitFontDataLCD((const unsigned char **) ASCII_SEVEN_SEGMENT, character, LCD_SEVEN_SEGMENT_FONT_WIDTH);
break;
#endif
#ifdef N5110_FONT_WIDE
case N5110_FONT_WIDE:
transmitFontDataLCD((const unsigned char **) ASCII_WIDE, character, LCD_WIDE_FONT_WIDTH);
break;
#endif
#ifdef N5110_FONT_TINY
case N5110_FONT_TINY:
transmitFontDataLCD((const unsigned char **) ASCII_TINY, character, LCD_TINY_FONT_WIDTH);
break;
#endif
#ifdef N5110_FONT_LARGE
case N5110_FONT_LARGE:
printLargeFontCharacter(character);
break;
#endif
#ifdef N5110_FONT_HUGE
case N5110_FONT_HUGE:
printHugeFontCharacter(character);
break;
#endif
#ifdef N5110_FONT_MEGA
case N5110_FONT_MEGA:
printMegaFontCharacter(character);
break;
#endif
default:
break;
}
}
#ifdef N5110_FONT_LARGE
static void printLargeFontCharacter(char character) {
for (uint8_t column = 0; column < LCD_LARGE_FONT_WIDTH; column++) { //print upper byte
transmit8BitsBufferedSPI(SPIPointer, ASCII_LARGE[character - LCD_ASCII_OFFSET][column]);
}
goToXYN5110(columnPosition, ++rowPosition); // move to next block
for (uint8_t column = 0; column < LCD_LARGE_FONT_WIDTH; column++) { //print lower byte
transmit8BitsBufferedSPI(SPIPointer, ((ASCII_LARGE[character - LCD_ASCII_OFFSET][column]) >> 8));
}
goToXYN5110((columnPosition + LCD_LARGE_FONT_WIDTH), --rowPosition);//move back to upper block
}
#endif
#ifdef N5110_FONT_HUGE
static void printHugeFontCharacter(char character) {
for (uint8_t column = 0; column < LCD_HUGE_FONT_WIDTH; column++) {//print upper byte DD
transmit8BitsBufferedSPI(SPIPointer, ASCII_HUGE[character - LCD_ASCII_OFFSET_ZERO][column]);
}
goToXYN5110(columnPosition, ++rowPosition); // move to next block
for (uint8_t column = 0; column < LCD_HUGE_FONT_WIDTH; column++) {// print middle upper byte CC
transmit8BitsBufferedSPI(SPIPointer, ((ASCII_HUGE[character - LCD_ASCII_OFFSET_ZERO][column]) >> 8));
}
goToXYN5110(columnPosition, ++rowPosition); // move to next block
for (uint8_t column = 0; column < LCD_HUGE_FONT_WIDTH; column++) {// print middle upper byte BB
transmit8BitsBufferedSPI(SPIPointer, ((ASCII_HUGE[character - LCD_ASCII_OFFSET_ZERO][column]) >> 16));
}
goToXYN5110(columnPosition + LCD_HUGE_FONT_WIDTH, rowPosition - 2); //move back for next character
}
#endif
#ifdef N5110_FONT_MEGA
static void printMegaFontCharacter(char character) {
for (uint8_t column = 0; column < LCD_MEGA_FONT_WIDTH; column++) {//print upper byte DD
transmit8BitsBufferedSPI(SPIPointer, ASCII_MEGA[character - LCD_ASCII_OFFSET_ZERO][column]);
}
goToXYN5110(columnPosition, ++rowPosition); // move to next block
for (uint8_t column = 0; column < LCD_MEGA_FONT_WIDTH; column++) {// print middle upper byte CC
transmit8BitsBufferedSPI(SPIPointer, ((ASCII_MEGA[character - LCD_ASCII_OFFSET_ZERO][column]) >> 8));
}
goToXYN5110(columnPosition, ++rowPosition); // move to next block
for (uint8_t column = 0; column < LCD_MEGA_FONT_WIDTH; column++) {// print middle upper byte BB
transmit8BitsBufferedSPI(SPIPointer, ((ASCII_MEGA[character - LCD_ASCII_OFFSET_ZERO][column]) >> 16));
}
goToXYN5110(columnPosition, ++rowPosition); // move to next block
for (uint8_t column = 0; column < LCD_MEGA_FONT_WIDTH; column++) {// print middle upper byte AA
transmit8BitsBufferedSPI(SPIPointer, ((ASCII_MEGA[character - LCD_ASCII_OFFSET_ZERO][column]) >> 24));
}
goToXYN5110(columnPosition + LCD_HUGE_FONT_WIDTH, rowPosition - 3); //move back for next character
}
#endif
static void transmitFontDataLCD(void *fontArray, char character, uint8_t columnLength) {
uint8_t dataByte;
unsigned char (*arrayOfChars)[columnLength] = fontArray;
for (int column = 0; column < columnLength; column++) {
dataByte = arrayOfChars[character - LCD_ASCII_OFFSET][column];
addByte(SPIPointer->TxBuffer, textColor == BLACK ? dataByte : ~dataByte);
}
addByte(SPIPointer->TxBuffer, textColor == BLACK ? 0x00 : 0xFF); // Blank vertical line padding RHS
chipSelectSetBufferedSPI(SPIPointer);
LL_SPI_EnableIT_TXE(SPIPointer->SPIx);
}