Line |
Branch |
Exec |
Source |
1 |
|
|
/** |
2 |
|
|
* @file lcd_hd44780.c |
3 |
|
|
* @author niwciu (niwciu@gmail.com) |
4 |
|
|
* @brief |
5 |
|
|
* @version 1.0.2 |
6 |
|
|
* @date 2024-02-25 |
7 |
|
|
* |
8 |
|
|
* @copyright Copyright (c) 2024 |
9 |
|
|
|
10 |
|
|
*/ |
11 |
|
|
#include "lcd_hd44780_GPIO_interface.h" |
12 |
|
|
#include "lcd_hd44780.h" |
13 |
|
|
#include "lcd_hd44780_driver_commands.h" |
14 |
|
|
#ifdef AVR |
15 |
|
|
#include "lcd_hd44780_avr_specific.h" |
16 |
|
|
#endif |
17 |
|
|
#include <stddef.h> |
18 |
|
|
#include <stdio.h> |
19 |
|
|
#include <string.h> |
20 |
|
|
|
21 |
|
|
#define BUSY_FLAG 1 << 7 |
22 |
|
|
#define VAL_PREFIX_LENGHT 2U |
23 |
|
|
|
24 |
|
|
#ifndef UNIT_TEST |
25 |
|
|
#define PRIVATE static |
26 |
|
|
#else |
27 |
|
|
#define PRIVATE |
28 |
|
|
#endif |
29 |
|
|
|
30 |
|
|
#if LCD_BUFFERING == ON |
31 |
|
|
#define LAST_CHAR_IN_LCD_LINE (LCD_X - 1) |
32 |
|
|
#define LAST_LCD_LINE (LCD_Y - 1) |
33 |
|
|
|
34 |
|
|
typedef char lcd_pos_t; |
35 |
|
|
static lcd_pos_t *lcd_buf_position_ptr; |
36 |
|
|
PRIVATE char lcd_buffer[LCD_Y][LCD_X]; |
37 |
|
|
PRIVATE char prev_lcd_buffer[LCD_Y][LCD_X]; |
38 |
|
|
#endif |
39 |
|
|
|
40 |
|
|
static const struct LCD_IO_driver_interface_struct *LCD = NULL; |
41 |
|
|
#if USE_DEF_CHAR_FUNCTION == ON |
42 |
|
|
static const lcd_char_mapping_struct_t *char_mapping_tab = NULL; |
43 |
|
|
#endif |
44 |
|
|
PRIVATE bool LCD_BUFFER_UPDATE_FLAG = false; |
45 |
|
|
|
46 |
|
|
static void register_LCD_IO_driver(void); |
47 |
|
|
static void lcd_set_all_SIG(void); |
48 |
|
|
static void lcd_reset_all_SIG(void); |
49 |
|
|
static void lcd_write_4bit_data(uint8_t data); |
50 |
|
|
static void lcd_write_cmd(uint8_t cmd); |
51 |
|
|
static void lcd_write_data(uint8_t data); |
52 |
|
|
static void lcd_write_byte(uint8_t byte); |
53 |
|
|
|
54 |
|
|
#if USE_RW_PIN == ON |
55 |
|
|
static uint8_t lcd_read_byte(void); |
56 |
|
|
static uint8_t lcd_read_4bit_data(void); |
57 |
|
|
#endif |
58 |
|
|
|
59 |
|
|
#ifndef AVR |
60 |
|
|
#if (USE_LCD_BIN == ON || ((LCD_BUFFERING == ON) && (LCD_USE_BUF_BIN == ON))) |
61 |
|
|
static void fill_bin_value_buffer(int val, char *bin_val_buffer); |
62 |
|
|
static void fill_zeros_buffer(const char *buffer, uint8_t width, char *zeros_buf); |
63 |
|
|
#endif |
64 |
|
|
#endif |
65 |
|
|
|
66 |
|
|
#if LCD_BUFFERING == ON |
67 |
|
|
static void check_lcd_buf_possition_ptr_overflow(void); |
68 |
|
|
static void copy_lcd_buf_2_prev_lcd_buf(void); |
69 |
|
|
static void update_lcd_curosr_possition(uint8_t *lcd_cursor_position, uint8_t *lcd_line, uint8_t *missed_char_counter_in_LCD_line); |
70 |
|
|
static void write_lcd_buf_2_lcd(const uint8_t *lcd_cursor_position, const uint8_t *lcd_line, uint8_t *missed_char_counter_in_LCD_line, const lcd_pos_t *prev_lcd_buff_pos_ptr); |
71 |
|
|
#endif |
72 |
|
|
#if USE_DEF_CHAR_FUNCTION == ON |
73 |
|
|
char lcd_translate_char(char c); |
74 |
|
|
#endif |
75 |
|
|
|
76 |
|
57 |
static void register_LCD_IO_driver(void) |
77 |
|
|
{ |
78 |
|
57 |
LCD = LCD_IO_driver_interface_get(); |
79 |
|
57 |
} |
80 |
|
|
|
81 |
|
57 |
static void lcd_set_all_SIG(void) |
82 |
|
|
{ |
83 |
|
57 |
LCD->set_LCD_E(); |
84 |
|
57 |
LCD->set_LCD_RS(); |
85 |
|
|
#if USE_RW_PIN == ON |
86 |
|
|
LCD->set_LCD_RW(); |
87 |
|
|
#endif |
88 |
|
57 |
} |
89 |
|
|
|
90 |
|
57 |
static void lcd_reset_all_SIG(void) |
91 |
|
|
{ |
92 |
|
|
#if USE_RW_PIN == ON |
93 |
|
|
LCD->reset_LCD_RW(); |
94 |
|
|
#endif |
95 |
|
57 |
LCD->reset_LCD_RS(); |
96 |
|
57 |
LCD->reset_LCD_E(); |
97 |
|
57 |
} |
98 |
|
|
|
99 |
|
1150 |
void lcd_write_4bit_data(uint8_t data) |
100 |
|
|
{ |
101 |
|
1150 |
LCD->set_LCD_E(); |
102 |
|
|
; |
103 |
|
1150 |
data &= 0x0F; |
104 |
|
1150 |
LCD->write_data(data); |
105 |
|
1150 |
LCD->reset_LCD_E(); |
106 |
|
|
; |
107 |
|
1150 |
} |
108 |
|
|
|
109 |
|
286 |
static void lcd_write_cmd(uint8_t cmd) |
110 |
|
|
{ |
111 |
|
286 |
LCD->reset_LCD_RS(); |
112 |
|
|
; |
113 |
|
286 |
lcd_write_byte(cmd); |
114 |
|
286 |
} |
115 |
|
|
|
116 |
|
175 |
void lcd_write_data(uint8_t data) |
117 |
|
|
{ |
118 |
|
175 |
LCD->set_LCD_RS(); |
119 |
|
|
; |
120 |
|
175 |
lcd_write_byte(data); |
121 |
|
175 |
} |
122 |
|
|
|
123 |
|
461 |
void lcd_write_byte(uint8_t byte) |
124 |
|
|
{ |
125 |
|
|
#if USE_RW_PIN == ON |
126 |
|
|
LCD->reset_LCD_RW(); |
127 |
|
|
; |
128 |
|
|
#endif |
129 |
|
461 |
lcd_write_4bit_data((byte) >> 4); |
130 |
|
461 |
lcd_write_4bit_data((byte) & 0x0F); |
131 |
|
|
#if USE_RW_PIN == ON |
132 |
|
|
// check_BUSSY_FALG |
133 |
|
|
LCD->set_data_pins_as_inputs(); |
134 |
|
|
LCD->reset_LCD_RS(); |
135 |
|
|
; |
136 |
|
|
LCD->set_LCD_RW(); |
137 |
|
|
; |
138 |
|
|
while (lcd_read_byte() & BUSY_FLAG) |
139 |
|
|
{ |
140 |
|
|
} |
141 |
|
|
LCD->reset_LCD_RW(); |
142 |
|
|
; |
143 |
|
|
LCD->set_data_pins_as_outputs(); |
144 |
|
|
|
145 |
|
|
#else |
146 |
|
461 |
LCD->delay_us(120); |
147 |
|
|
#endif |
148 |
|
461 |
} |
149 |
|
|
|
150 |
|
|
#if USE_RW_PIN == ON |
151 |
|
|
uint8_t lcd_read_byte(void) |
152 |
|
|
{ |
153 |
|
|
uint8_t data; |
154 |
|
|
// read 4 MSB |
155 |
|
|
data = (lcd_read_4bit_data() << 4); |
156 |
|
|
// read 4 LSB |
157 |
|
|
data |= (lcd_read_4bit_data() & 0x0F); |
158 |
|
|
return data; |
159 |
|
|
} |
160 |
|
|
|
161 |
|
|
uint8_t lcd_read_4bit_data(void) |
162 |
|
|
{ |
163 |
|
|
uint8_t data; |
164 |
|
|
LCD->set_LCD_E(); |
165 |
|
|
; |
166 |
|
|
data = LCD->read_data(); |
167 |
|
|
LCD->reset_LCD_E(); |
168 |
|
|
; |
169 |
|
|
return data; |
170 |
|
|
} |
171 |
|
|
#endif |
172 |
|
|
#ifndef AVR |
173 |
|
|
#if USE_LCD_BIN == ON |
174 |
|
4 |
static void fill_bin_value_buffer(int val, char *bin_val_buffer) |
175 |
|
|
{ |
176 |
|
4 |
uint32_t bit_mask = 0x80000000; |
177 |
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 4 times.
|
132 |
while (bit_mask != 0) |
178 |
|
|
{ |
179 |
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 120 times.
|
128 |
if ((bit_mask & val) != 0) |
180 |
|
|
{ |
181 |
|
8 |
strcat(bin_val_buffer, "1"); |
182 |
|
|
} |
183 |
|
|
else |
184 |
|
|
{ |
185 |
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 116 times.
|
120 |
if (strlen(bin_val_buffer) != 0) |
186 |
|
|
{ |
187 |
|
4 |
strcat(bin_val_buffer, "0"); |
188 |
|
|
} |
189 |
|
|
} |
190 |
|
128 |
bit_mask = bit_mask >> 1; |
191 |
|
|
} |
192 |
|
4 |
} |
193 |
|
|
|
194 |
|
4 |
static void fill_zeros_buffer(const char *buffer, uint8_t width, char *zeros_buf) |
195 |
|
|
{ |
196 |
|
4 |
uint8_t buf_len = strlen(buffer); |
197 |
|
4 |
uint8_t total_str_width = width + VAL_PREFIX_LENGHT; |
198 |
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 |
if (buf_len < (total_str_width)) |
199 |
|
|
{ |
200 |
|
2 |
uint8_t zeros_qty = width - ((strlen(buffer) + VAL_PREFIX_LENGHT)); |
201 |
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 |
for (uint8_t j = 0; j < zeros_qty; j++) |
202 |
|
|
{ |
203 |
|
2 |
strcat(zeros_buf, "0"); |
204 |
|
|
} |
205 |
|
|
} |
206 |
|
4 |
} |
207 |
|
|
#endif |
208 |
|
|
#endif |
209 |
|
|
|
210 |
|
|
#if LCD_BUFFERING == ON |
211 |
|
126 |
static void check_lcd_buf_possition_ptr_overflow(void) |
212 |
|
|
{ |
213 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 123 times.
|
126 |
if (lcd_buf_position_ptr > &lcd_buffer[LAST_LCD_LINE][LAST_CHAR_IN_LCD_LINE]) |
214 |
|
|
{ |
215 |
|
3 |
lcd_buf_position_ptr = &lcd_buffer[LINE_1][C1]; |
216 |
|
|
} |
217 |
|
126 |
} |
218 |
|
71 |
static void copy_lcd_buf_2_prev_lcd_buf(void) |
219 |
|
|
{ |
220 |
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 71 times.
|
213 |
for (uint8_t y = 0; y < LCD_Y; y++) |
221 |
|
|
{ |
222 |
2/2
✓ Branch 0 taken 2272 times.
✓ Branch 1 taken 142 times.
|
2414 |
for (uint8_t x = 0; x < LCD_X; x++) |
223 |
|
|
{ |
224 |
|
2272 |
prev_lcd_buffer[y][x] = lcd_buffer[y][x]; |
225 |
|
|
} |
226 |
|
|
} |
227 |
|
71 |
} |
228 |
|
448 |
static void update_lcd_curosr_possition(uint8_t *lcd_cursor_position, uint8_t *lcd_line, uint8_t *missed_char_counter_in_LCD_line) |
229 |
|
|
{ |
230 |
|
448 |
(*lcd_cursor_position)++; |
231 |
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 420 times.
|
448 |
if ((*lcd_cursor_position) >= LCD_X) |
232 |
|
|
{ |
233 |
|
28 |
*lcd_cursor_position = 0; |
234 |
|
28 |
(*lcd_line)++; |
235 |
|
28 |
*missed_char_counter_in_LCD_line = 0; |
236 |
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
|
28 |
if (*lcd_line == LCD_Y) |
237 |
|
|
{ |
238 |
|
14 |
*lcd_line = LINE_1; |
239 |
|
|
} |
240 |
|
28 |
lcd_locate(*lcd_line, *lcd_cursor_position); |
241 |
|
|
} |
242 |
|
448 |
} |
243 |
|
|
|
244 |
|
448 |
static void write_lcd_buf_2_lcd(const uint8_t *lcd_cursor_position, const uint8_t *lcd_line, uint8_t *missed_char_counter_in_LCD_line, const lcd_pos_t *prev_lcd_buff_pos_ptr) |
245 |
|
|
{ |
246 |
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 397 times.
|
448 |
if ((*lcd_buf_position_ptr) != (*prev_lcd_buff_pos_ptr)) |
247 |
|
|
{ |
248 |
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 47 times.
|
51 |
if (*missed_char_counter_in_LCD_line != 0) |
249 |
|
|
{ |
250 |
|
4 |
lcd_locate(*lcd_line, *lcd_cursor_position); |
251 |
|
4 |
*missed_char_counter_in_LCD_line = 0; |
252 |
|
|
} |
253 |
|
51 |
lcd_char(*lcd_buf_position_ptr); |
254 |
|
|
} |
255 |
|
|
else |
256 |
|
|
{ |
257 |
|
397 |
(*missed_char_counter_in_LCD_line)++; |
258 |
|
|
} |
259 |
|
448 |
} |
260 |
|
|
|
261 |
|
|
#endif |
262 |
|
|
|
263 |
|
|
#if USE_DEF_CHAR_FUNCTION == ON |
264 |
|
|
|
265 |
|
103 |
char lcd_translate_char(char c) |
266 |
|
|
{ |
267 |
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 1 times.
|
103 |
if (char_mapping_tab != NULL) |
268 |
|
|
{ |
269 |
|
102 |
int i = 0; |
270 |
2/2
✓ Branch 0 taken 1020 times.
✓ Branch 1 taken 102 times.
|
1122 |
while (char_mapping_tab[i].ascii_char != '\0') |
271 |
|
|
{ // Iteracja przez mapowanie |
272 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1020 times.
|
1020 |
if (char_mapping_tab[i].ascii_char == c) |
273 |
|
|
{ |
274 |
|
✗ |
return char_mapping_tab[i].lcd_def_char_addr; // Zwrócenie odpowiednika LCD |
275 |
|
|
} |
276 |
|
1020 |
i++; |
277 |
|
|
} |
278 |
|
|
} |
279 |
|
103 |
return c; // Jeśli brak mapowania, zwróć oryginalny znak |
280 |
|
|
} |
281 |
|
|
|
282 |
|
|
#endif |
283 |
|
|
|
284 |
|
57 |
void lcd_init(void) |
285 |
|
|
{ |
286 |
|
57 |
register_LCD_IO_driver(); |
287 |
|
57 |
LCD->init_LCD_pins(); |
288 |
|
57 |
lcd_disable_backlight(); |
289 |
|
|
/**************************BASIC LCD INIT - basing on DS init procedure***************************************/ |
290 |
|
|
// set all LCD signals to High for more than 15ms ->bit different than in DS based on other implementations from the internet |
291 |
|
57 |
lcd_set_all_SIG(); |
292 |
|
57 |
LCD->delay_us(15000); |
293 |
|
57 |
lcd_reset_all_SIG(); |
294 |
|
|
// send 0x03 & wait more then 4,1ms |
295 |
|
57 |
lcd_write_4bit_data(0x03); |
296 |
|
57 |
LCD->delay_us(4500); |
297 |
|
|
// send 0x03 & wait more then 100us |
298 |
|
57 |
lcd_write_4bit_data(0x03); |
299 |
|
57 |
LCD->delay_us(110); |
300 |
|
|
// send 0x03 & wait more then 100us |
301 |
|
57 |
lcd_write_4bit_data(0x03); |
302 |
|
57 |
LCD->delay_us(110); |
303 |
|
|
// send 0x02 & wait more then 100us |
304 |
|
57 |
lcd_write_4bit_data(0x02); |
305 |
|
57 |
LCD->delay_us(110); |
306 |
|
|
// FUNCTION SET ->send cmd -> LCD in 4-bit mode, 2 rows, char size 5x7 |
307 |
|
57 |
lcd_write_cmd(LCDC_FUNC | LCDC_FUNC4B | LCDC_FUNC2L | LCDC_FUNC5x7); |
308 |
|
|
// DISPLAY_ON_OFF send cmd -> enable lcd |
309 |
|
57 |
lcd_write_cmd(LCDC_ONOFF | LCDC_CURSOROFF | LCDC_DISPLAYON); |
310 |
|
|
// LCD clear screen |
311 |
|
57 |
lcd_cls(); |
312 |
|
|
// ENTRY MODe SET do not shift the LCD shift cursor right after placing a char |
313 |
|
57 |
lcd_write_cmd(LCDC_ENTRY_MODE | LCDC_ENTRYR); |
314 |
|
|
/*********************************END of BASIC LCD INIT***************************************/ |
315 |
|
|
#if LCD_BUFFERING == ON |
316 |
|
|
// clear lcd_buffer by putting spaces inside of the buffer |
317 |
|
57 |
lcd_buf_cls(); |
318 |
|
|
// copy lcd_buffer with spaces to prev_lcd_buffer |
319 |
|
57 |
copy_lcd_buf_2_prev_lcd_buf(); |
320 |
|
|
// clear flag due to init procedure that reset LCD screen and buffers |
321 |
|
57 |
LCD_BUFFER_UPDATE_FLAG = false; |
322 |
|
|
#endif |
323 |
|
57 |
} |
324 |
|
|
/** |
325 |
|
|
* @brief Function for disabling backlight od the LCD |
326 |
|
|
*/ |
327 |
|
2 |
void lcd_enable_backlight(void) |
328 |
|
|
{ |
329 |
|
|
#if LCD_BCKL_PIN_EN_STATE == HIGH |
330 |
|
2 |
LCD->set_LCD_BCKL(); |
331 |
|
|
#else |
332 |
|
|
LCD->reset_LCD_BCKL(); |
333 |
|
|
#endif |
334 |
|
2 |
} |
335 |
|
|
|
336 |
|
|
/** |
337 |
|
|
* @brief Function that disable backlight of the LCD. |
338 |
|
|
* This function change the backlight GPIO pin state to inactive. |
339 |
|
|
* Active state of the GPIO backlight pin is defined by @ lcd_init() |
340 |
|
|
*/ |
341 |
|
58 |
void lcd_disable_backlight(void) |
342 |
|
|
{ |
343 |
|
|
#if LCD_BCKL_PIN_EN_STATE == HIGH |
344 |
|
58 |
LCD->reset_LCD_BCKL(); |
345 |
|
|
#else |
346 |
|
|
LCD->set_LCD_BCKL(); |
347 |
|
|
#endif |
348 |
|
58 |
} |
349 |
|
|
|
350 |
|
|
/** |
351 |
|
|
* @brief Function that clears the LCD screen and sets the cursor on the position of the first character in the first line of the LCD |
352 |
|
|
* screen. |
353 |
|
|
*/ |
354 |
|
58 |
void lcd_cls(void) |
355 |
|
|
{ |
356 |
|
58 |
lcd_write_cmd(LCDC_CLS); |
357 |
|
|
#if USE_RW_PIN == OFF |
358 |
|
58 |
LCD->delay_us(4900); |
359 |
|
|
#endif |
360 |
|
58 |
} |
361 |
|
|
|
362 |
|
|
#if USE_DEF_CHAR_FUNCTION == ON |
363 |
|
|
/** |
364 |
|
|
* @brief Function for defining custom user characters in CGRAM of the LCD. |
365 |
|
|
* |
366 |
|
|
* @param CGRAM_char_index Position/address of the character in CGRAM of the LCD where defined char should be written. |
367 |
|
|
* For the predefined example of special characters, taken values are defined in the type enum LCD_CGRAM_BANK_1_e that is declared |
368 |
|
|
* in lcd-hd44780.h |
369 |
|
|
* |
370 |
|
|
* @param def_char Pointer to the predefined special character. |
371 |
|
|
* |
372 |
|
|
* @note CGRAM_char_index - This Parameter can take values from 0 to 7. For the predefined example of special |
373 |
|
|
* characters, taken values are defined in the type enum LCD_CGRAM that is defined in lcd_hd44780_def_char.h |
374 |
|
|
*/ |
375 |
|
9 |
void lcd_def_char(const uint8_t CGRAM_bank_x_char_adr, const uint8_t *def_char) |
376 |
|
|
{ |
377 |
|
9 |
lcd_write_cmd(LCDC_SET_CGRAM | ((DEF_CHAR_ADR_MASK & CGRAM_bank_x_char_adr) * LCD_CGRAM_BYTES_PER_CHAR)); |
378 |
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 9 times.
|
81 |
for (uint8_t j = 0; j < LCD_CGRAM_BYTES_PER_CHAR; j++) |
379 |
|
|
{ |
380 |
|
72 |
lcd_write_data(def_char[j]); |
381 |
|
|
} |
382 |
|
9 |
lcd_write_cmd(LCDC_SET_DDRAM); |
383 |
|
9 |
} |
384 |
|
|
|
385 |
|
|
/** |
386 |
|
|
* @brief Function that loads to LCD_CGRAM predefined characters form specific user char_bank |
387 |
|
|
* |
388 |
|
|
* @param char_bank - pointer to selected user char bank that function should load to LCD_CGRAM. Char banks are defined in lcd_hd44780_def_char.h |
389 |
|
|
*/ |
390 |
|
1 |
void lcd_load_char_bank(const lcd_bank_load_struct_t *char_bank_data) |
391 |
|
|
{ |
392 |
|
1 |
lcd_def_char(0, char_bank_data->char_bank->char_0); |
393 |
|
1 |
lcd_def_char(1, char_bank_data->char_bank->char_1); |
394 |
|
1 |
lcd_def_char(2, char_bank_data->char_bank->char_2); |
395 |
|
1 |
lcd_def_char(3, char_bank_data->char_bank->char_3); |
396 |
|
1 |
lcd_def_char(4, char_bank_data->char_bank->char_4); |
397 |
|
1 |
lcd_def_char(5, char_bank_data->char_bank->char_5); |
398 |
|
1 |
lcd_def_char(6, char_bank_data->char_bank->char_6); |
399 |
|
1 |
lcd_def_char(7, char_bank_data->char_bank->char_7); |
400 |
|
1 |
char_mapping_tab = char_bank_data->char_mapping_tab; |
401 |
|
1 |
} |
402 |
|
|
#endif |
403 |
|
|
#if USE_DEF_CHAR_FUNCTION == ON |
404 |
|
|
/** |
405 |
|
|
* @brief Function for printing the char on the LCD screen under the current position of the LCD cursor. |
406 |
|
|
* @param C char (for example '1') or its ASCI code (0x31). |
407 |
|
|
* @note For user-defined char, place CGRAM_char_index (Position/address of the character in CGRAM of the LCD where |
408 |
|
|
* defined char was written). |
409 |
|
|
*/ |
410 |
|
103 |
void lcd_char(const char C) |
411 |
|
|
{ |
412 |
|
103 |
uint8_t data = (uint8_t)(lcd_translate_char(C)); |
413 |
|
103 |
lcd_write_data(data); |
414 |
|
103 |
} |
415 |
|
|
#else |
416 |
|
|
/** |
417 |
|
|
* @brief Function for printing the char on the LCD screen under the current position of the LCD cursor. |
418 |
|
|
* @param C char (for example '1') or its ASCI code (0x31). |
419 |
|
|
* @note For user-defined char, place CGRAM_char_index (Position/address of the character in CGRAM of the LCD where |
420 |
|
|
* defined char was written). |
421 |
|
|
*/ |
422 |
|
|
void lcd_char(const char C) |
423 |
|
|
{ |
424 |
|
|
uint8_t data = (uint8_t)(C); |
425 |
|
|
lcd_write_data(data); |
426 |
|
|
} |
427 |
|
|
#endif |
428 |
|
|
/** |
429 |
|
|
* @brief Function for printing/writing the string on the LCD screen starting from the current LCD cursor position. |
430 |
|
|
* @param str string that should be printed/written on the LCD screen |
431 |
|
|
*/ |
432 |
|
11 |
void lcd_str(const char *str) |
433 |
|
|
{ |
434 |
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 11 times.
|
62 |
while ((*str) != '\0') |
435 |
|
|
{ |
436 |
|
51 |
lcd_char(*str); |
437 |
|
51 |
str++; |
438 |
|
|
} |
439 |
|
11 |
} |
440 |
|
|
|
441 |
|
|
#if USE_LCD_INT == ON |
442 |
|
|
/** |
443 |
|
|
* @brief Function for printing the integer value on the LCD screen under the current position of the LCD cursor. |
444 |
|
|
* @param val int type value to print on LCD screen |
445 |
|
|
* @param width Minimum number of characters to be printed. If the value to be printed is shorter than this number, the |
446 |
|
|
* result is padded with blank spaces. The value is not truncated even if the result is larger. |
447 |
|
|
* @param alignment This parameter can only accept values defined in ::LCD_alignment_e. If the value to be printed is shorter than the width, this parameter will specify the alignment of the |
448 |
|
|
* printed text value. |
449 |
|
|
* @attention to compile for AVR ucontrollers definition of flag AVR is required. |
450 |
|
|
*/ |
451 |
|
4 |
void lcd_int(int val, uint8_t width, enum LCD_alignment_e alignment) |
452 |
|
|
{ |
453 |
|
|
#ifdef AVR |
454 |
|
|
lcd_int_AVR(val, width, alignment); |
455 |
|
|
#else |
456 |
|
|
char buffer[20]; // 19chars for 64 bit int + end char '\0' |
457 |
|
4 |
buffer[0] = '\0'; |
458 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
|
4 |
if (alignment == right) |
459 |
|
3 |
sprintf(buffer, "%*i", width, val); |
460 |
|
|
else |
461 |
|
1 |
sprintf(buffer, "%-*i", width, val); |
462 |
|
4 |
lcd_str(buffer); |
463 |
|
|
#endif |
464 |
|
4 |
} |
465 |
|
|
#endif |
466 |
|
|
|
467 |
|
|
#if USE_LCD_HEX == ON |
468 |
|
|
/** |
469 |
|
|
* @brief Function for printing the integer value in hexadecimal format on the LCD screen under the current position of the LCD |
470 |
|
|
* cursor. |
471 |
|
|
* @param val int type value to print on LCD screen in hexadecimal format |
472 |
|
|
* @param width Minimum number of characters to be printed. If the value to be printed is shorter than this number, the |
473 |
|
|
* result is padded with blank spaces. The value is not truncated even if the result is larger. The width should contain |
474 |
|
|
* additional 2 characters for '0x' at the beginning of the printed value. |
475 |
|
|
* @param alignment This parameter can only accept values defined in ::LCD_alignment_e. If the value to be printed is shorter than the width, this parameter will specify the alignment of the |
476 |
|
|
* printed text value. |
477 |
|
|
* @attention to compile for AVR ucontrollers definition of flag AVR is required. |
478 |
|
|
*/ |
479 |
|
4 |
void lcd_hex(int val, uint8_t width, enum LCD_alignment_e alignment) |
480 |
|
|
{ |
481 |
|
|
#ifdef AVR |
482 |
|
|
lcd_hex_AVR(val, width, alignment); |
483 |
|
|
#else |
484 |
|
|
char buffer[17]; |
485 |
|
4 |
buffer[0] = '\0'; |
486 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
|
4 |
if (alignment == right) |
487 |
|
3 |
sprintf(buffer, "%#*x", width, val); |
488 |
|
|
else |
489 |
|
1 |
sprintf(buffer, "%-#*x", width, val); |
490 |
|
4 |
lcd_str(buffer); |
491 |
|
|
#endif |
492 |
|
4 |
} |
493 |
|
|
#endif |
494 |
|
|
|
495 |
|
|
#if USE_LCD_BIN == ON |
496 |
|
|
/** |
497 |
|
|
* @brief Function for printing the integer value in hexadecimal format on the LCD screen under the current position of the LCD |
498 |
|
|
* cursor. |
499 |
|
|
* @param val int type value to print on LCD screen in hexadecimal format |
500 |
|
|
* @param width Minimum number of characters to be printed. If the value to be printed is shorter than this number, the |
501 |
|
|
* result is padded with blank spaces. The value is not truncated even if the result is larger. The width should contain |
502 |
|
|
* additional 2 characters for '0x' at the beginning of the printed value. |
503 |
|
|
* @attention to compile for AVR ucontrollers definition of flag AVR is required. |
504 |
|
|
*/ |
505 |
|
2 |
void lcd_bin(int val, uint8_t width) |
506 |
|
|
{ |
507 |
|
|
#ifdef AVR |
508 |
|
|
lcd_bin_AVR(val, width); |
509 |
|
|
#else |
510 |
|
|
char buffer[35]; |
511 |
|
|
char bin_val_buffer[35]; |
512 |
|
|
char zeros_buf[35]; |
513 |
|
2 |
buffer[0] = '\0'; |
514 |
|
2 |
bin_val_buffer[0] = '\0'; |
515 |
|
2 |
zeros_buf[0] = '\0'; |
516 |
|
|
|
517 |
|
2 |
fill_bin_value_buffer(val, bin_val_buffer); |
518 |
|
2 |
fill_zeros_buffer(bin_val_buffer, width, zeros_buf); |
519 |
|
2 |
strcat(buffer, "0b"); |
520 |
|
2 |
strcat(buffer, zeros_buf); |
521 |
|
2 |
strcat(buffer, bin_val_buffer); |
522 |
|
2 |
lcd_str(buffer); |
523 |
|
|
#endif |
524 |
|
2 |
} |
525 |
|
|
|
526 |
|
|
#endif |
527 |
|
|
|
528 |
|
|
/** |
529 |
|
|
* @brief Function that moves LCD cursor to a specific position located under the x and y coordinate |
530 |
|
|
* @param y LCD row/line number. This parameter can only accept values defined in ::LCD_LINES_e. |
531 |
|
|
* @param x LCD column number. This parameter can only accept values defined in ::LCD_COLUMNS_e. |
532 |
|
|
*/ |
533 |
|
35 |
void lcd_locate(enum LCD_LINES_e y, enum LCD_COLUMNS_e x) |
534 |
|
|
{ |
535 |
2/3
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
35 |
switch (y) |
536 |
|
|
{ |
537 |
|
18 |
case 0: |
538 |
|
18 |
y = LCD_LINE1_ADR; |
539 |
|
18 |
break; |
540 |
|
|
|
541 |
|
|
#if (LCD_Y > 1) |
542 |
|
17 |
case 1: |
543 |
|
17 |
y = LCD_LINE2_ADR; |
544 |
|
17 |
break; |
545 |
|
|
#endif |
546 |
|
|
#if (LCD_Y > 2) |
547 |
|
|
case 2: |
548 |
|
|
y = LCD_LINE3_ADR; |
549 |
|
|
break; |
550 |
|
|
#endif |
551 |
|
|
#if (LCD_Y > 3) |
552 |
|
|
case 3: |
553 |
|
|
y = LCD_LINE4_ADR; |
554 |
|
|
break; |
555 |
|
|
#endif |
556 |
|
✗ |
default: |
557 |
|
✗ |
break; |
558 |
|
|
} |
559 |
|
35 |
lcd_write_cmd((uint8_t)(LCDC_SET_DDRAM + y + x)); |
560 |
|
35 |
} |
561 |
|
|
#if USE_LCD_CURSOR_HOME == ON |
562 |
|
|
/** |
563 |
|
|
* @brief Function that moves LCD cursor to the first position at the first row of the LCD screen |
564 |
|
|
*/ |
565 |
|
1 |
void lcd_home(void) |
566 |
|
|
{ |
567 |
|
1 |
lcd_write_cmd(LCDC_CLS | LCDC_HOME); |
568 |
|
|
#if USE_RW_PIN == OFF |
569 |
|
1 |
LCD->delay_us(4900); |
570 |
|
|
#endif |
571 |
|
1 |
} |
572 |
|
|
#endif |
573 |
|
|
|
574 |
|
|
#if USE_LCD_CURSOR_ON == ON |
575 |
|
|
/** |
576 |
|
|
* @brief Function that activates the visibility of the LCD cursor. |
577 |
|
|
*/ |
578 |
|
1 |
void lcd_cursor_on(void) |
579 |
|
|
{ |
580 |
|
1 |
lcd_write_cmd(LCDC_ONOFF | LCDC_DISPLAYON | LCDC_CURSORON); |
581 |
|
1 |
} |
582 |
|
|
#endif |
583 |
|
|
|
584 |
|
|
#if USE_LCD_CURSOR_OFF == ON |
585 |
|
|
/** |
586 |
|
|
* @brief Function that deactivates the visibility and blinking of the LCD cursor. |
587 |
|
|
*/ |
588 |
|
1 |
void lcd_cursor_off(void) |
589 |
|
|
{ |
590 |
|
1 |
lcd_write_cmd(LCDC_ONOFF | LCDC_DISPLAYON); |
591 |
|
1 |
} |
592 |
|
|
#endif |
593 |
|
|
#if USE_LCD_BLINKING_CURSOR_ON == ON |
594 |
|
|
/** |
595 |
|
|
* @brief Function that activates the visibility and blinking of the LCD cursor. |
596 |
|
|
*/ |
597 |
|
1 |
void lcd_blinking_cursor_on(void) |
598 |
|
|
{ |
599 |
|
1 |
lcd_write_cmd(LCDC_ONOFF | LCDC_DISPLAYON | LCDC_CURSORON | LCDC_BLINKON); |
600 |
|
1 |
} |
601 |
|
|
#endif |
602 |
|
|
|
603 |
|
|
#if LCD_BUFFERING == ON |
604 |
|
|
/** |
605 |
|
|
* @brief Function that puts spaces(0x32) in the whole LCD buffer and sets the cursor on the position of the first character in the first line of the LCD |
606 |
|
|
* buffer. |
607 |
|
|
*/ |
608 |
|
58 |
void lcd_buf_cls(void) |
609 |
|
|
{ |
610 |
2/2
✓ Branch 0 taken 1856 times.
✓ Branch 1 taken 58 times.
|
1914 |
for (lcd_buf_position_ptr = &lcd_buffer[LINE_1][C1]; lcd_buf_position_ptr <= &lcd_buffer[LAST_LCD_LINE][LAST_CHAR_IN_LCD_LINE]; lcd_buf_position_ptr++) |
611 |
|
|
{ |
612 |
|
1856 |
*lcd_buf_position_ptr = ' '; |
613 |
|
|
} |
614 |
|
58 |
lcd_buf_position_ptr = &lcd_buffer[LINE_1][C1]; |
615 |
|
58 |
LCD_BUFFER_UPDATE_FLAG = true; |
616 |
|
58 |
} |
617 |
|
|
|
618 |
|
|
/** |
619 |
|
|
* @brief Function for adding the char to the LCD buffer under the current position of the LCD buffer. |
620 |
|
|
* @param C char (for example '1') or its ASCI code (0x31). |
621 |
|
|
* @note For user-defined char, place LCD_CGRAM_BANK_x_e (Position/address of the character in CGRAM of the LCD where |
622 |
|
|
* defined char was written). |
623 |
|
|
*/ |
624 |
|
9 |
void lcd_buf_char(const char c) |
625 |
|
|
{ |
626 |
|
9 |
*lcd_buf_position_ptr = c; |
627 |
|
9 |
lcd_buf_position_ptr++; |
628 |
|
9 |
check_lcd_buf_possition_ptr_overflow(); |
629 |
|
9 |
LCD_BUFFER_UPDATE_FLAG = true; |
630 |
|
9 |
} |
631 |
|
|
|
632 |
|
|
/** |
633 |
|
|
* @brief Function that changes the current LCD buffer position pointer to a specific position located under the x and y coordinate |
634 |
|
|
* @param y LCD row/line number. This parameter can only accept values defined in ::LCD_LINES_e. |
635 |
|
|
* @param x LCD column number. This parameter can only accept values defined in ::LCD_COLUMNS_e. |
636 |
|
|
*/ |
637 |
|
13 |
void lcd_buf_locate(enum LCD_LINES_e y, enum LCD_COLUMNS_e x) |
638 |
|
|
{ |
639 |
|
13 |
lcd_buf_position_ptr = &lcd_buffer[y][x]; |
640 |
|
13 |
} |
641 |
|
|
|
642 |
|
|
/** |
643 |
|
|
* @brief Function for placing the string in the LCD buffer starts from the current LCD buffer position pointer. |
644 |
|
|
* @param str string that should be placed in the LCD buffer |
645 |
|
|
*/ |
646 |
|
24 |
void lcd_buf_str(const char *str) |
647 |
|
|
{ |
648 |
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 24 times.
|
141 |
while (*str) |
649 |
|
|
{ |
650 |
|
117 |
*(lcd_buf_position_ptr++) = *(str++); |
651 |
|
117 |
check_lcd_buf_possition_ptr_overflow(); |
652 |
|
|
} |
653 |
|
24 |
LCD_BUFFER_UPDATE_FLAG = true; |
654 |
|
24 |
} |
655 |
|
|
|
656 |
|
|
/** |
657 |
|
|
* @brief Function that prints on the LCD screen the content of The LCD buffer. |
658 |
|
|
* The function sets also The LCD buffer position pointer to the First line's first character. |
659 |
|
|
*/ |
660 |
|
14 |
void lcd_update(void) |
661 |
|
|
{ |
662 |
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 |
if (LCD_BUFFER_UPDATE_FLAG == true) |
663 |
|
|
{ |
664 |
|
14 |
uint8_t lcd_cursor_position = 0; |
665 |
|
14 |
uint8_t lcd_line = 0; |
666 |
|
14 |
uint8_t missed_char_counter_in_LCD_line = 0; |
667 |
|
14 |
const lcd_pos_t *prev_lcd_buff_pos_ptr = &prev_lcd_buffer[LINE_1][C1]; |
668 |
|
|
|
669 |
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 14 times.
|
462 |
for (lcd_buf_position_ptr = &lcd_buffer[LINE_1][C1]; lcd_buf_position_ptr <= &lcd_buffer[LAST_LCD_LINE][LAST_CHAR_IN_LCD_LINE]; lcd_buf_position_ptr++) |
670 |
|
|
{ |
671 |
|
448 |
write_lcd_buf_2_lcd(&lcd_cursor_position, &lcd_line, &missed_char_counter_in_LCD_line, prev_lcd_buff_pos_ptr); |
672 |
|
448 |
update_lcd_curosr_possition(&lcd_cursor_position, &lcd_line, &missed_char_counter_in_LCD_line); |
673 |
|
448 |
prev_lcd_buff_pos_ptr++; |
674 |
|
|
} |
675 |
|
|
|
676 |
|
14 |
lcd_buf_position_ptr = &lcd_buffer[LINE_1][C1]; |
677 |
|
14 |
copy_lcd_buf_2_prev_lcd_buf(); |
678 |
|
14 |
LCD_BUFFER_UPDATE_FLAG = false; |
679 |
|
|
} |
680 |
|
14 |
} |
681 |
|
|
|
682 |
|
|
#if USE_LCD_BUF_INT == ON |
683 |
|
|
/** |
684 |
|
|
* @brief Function for adding integer value as string to the LCD buffer under the current position of the LCD buffer pointer. |
685 |
|
|
* @param val int type value to add to LCD buffer |
686 |
|
|
* @param width Minimum number of characters to be added to LCD buffer. If the value to be added to the LCD buffer is shorter than width, the |
687 |
|
|
* result is padded with blank spaces. The value to be added to the buffer as a string is not truncated if the string length is larger than the width value. |
688 |
|
|
* @param alignment This parameter can only accept values defined in ::LCD_alignment_e. If the value to be printed is shorter than the width, this parameter will specify the alignment of the |
689 |
|
|
* printed text value. |
690 |
|
|
* @attention to compile for AVR ucontrollers, definition of flag AVR is required. |
691 |
|
|
*/ |
692 |
|
4 |
void lcd_buf_int(int val, uint8_t width, enum LCD_alignment_e alignment) |
693 |
|
|
{ |
694 |
|
|
#ifdef AVR |
695 |
|
|
lcd_buf_int_AVR(val, width, alignment); |
696 |
|
|
#else |
697 |
|
|
char buffer[20]; // 19chars for 64 bit int + end char '\0' |
698 |
|
4 |
buffer[0] = '\0'; |
699 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
|
4 |
if (alignment == right) |
700 |
|
3 |
sprintf(buffer, "%*i", width, val); |
701 |
|
|
else |
702 |
|
1 |
sprintf(buffer, "%-*i", width, val); |
703 |
|
4 |
lcd_buf_str(buffer); |
704 |
|
|
#endif |
705 |
|
4 |
} |
706 |
|
|
#endif |
707 |
|
|
|
708 |
|
|
#if USE_LCD_BUF_HEX == ON |
709 |
|
|
/** |
710 |
|
|
* @brief Function for adding integer value in hexadecimal format as a string to the LCD buffer under the current position of the LCD buffer pointer. |
711 |
|
|
* @param val int type value to add to LCD buffer as a string in hexadecimal format |
712 |
|
|
* @param width Minimum number of characters to be added to lcd buffer. If the value to be added to the buffer is shorter than the width, the |
713 |
|
|
* result is padded with blank spaces. The value to be added to the buffer as a string is not truncated if the string length is larger than the width value. Width should contain |
714 |
|
|
* additional 2 characters for "0x" at the beginning of the value represented as a string. example: 0x01-> width=4 |
715 |
|
|
* @param alignment This parameter can only accept values defined in ::LCD_alignment_e. If the value to be printed is shorter than the width, this parameter will specify the alignment of the |
716 |
|
|
* printed text value. |
717 |
|
|
* @attention to compile for AVR ucontrollers, definition of flag AVR is required. |
718 |
|
|
*/ |
719 |
|
5 |
void lcd_buf_hex(int val, uint8_t width, enum LCD_alignment_e alignment) |
720 |
|
|
{ |
721 |
|
|
#ifdef AVR |
722 |
|
|
lcd_buf_hex_AVR(val, width, alignment); |
723 |
|
|
#else |
724 |
|
|
char buffer[17]; |
725 |
|
5 |
buffer[0] = '\0'; |
726 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
5 |
if (alignment == right) |
727 |
|
3 |
sprintf(buffer, "%#*x", width, val); |
728 |
|
|
else |
729 |
|
2 |
sprintf(buffer, "%-#*x", width, val); |
730 |
|
5 |
lcd_buf_str(buffer); |
731 |
|
|
#endif |
732 |
|
5 |
} |
733 |
|
|
#endif |
734 |
|
|
|
735 |
|
|
#if USE_LCD_BUF_BIN == ON |
736 |
|
|
/** |
737 |
|
|
* @brief Function for adding to the LCD buffer the integer value in binary format as a string under the current position of the LCD buffer pointer |
738 |
|
|
* @param val int type value to be added to the LCD buffer as a string in hexadecimal format |
739 |
|
|
* @param width Minimum number of characters to be added to LCD buffer. If the value to be added to the buffer as string length is shorter than width, the |
740 |
|
|
* result is padded with blank spaces. The value to be added to the buffer as a string is not truncated if the string length represents the value in binary format length |
741 |
|
|
* is larger than the width value. The width should contain an additional 2 characters for "0b" at the beginning of the value represented as a string. example: 0b01-> width=4 |
742 |
|
|
* @attention to compile for AVR ucontrollers, definition of flag AVR is required. |
743 |
|
|
*/ |
744 |
|
2 |
void lcd_buf_bin(int val, uint8_t width) |
745 |
|
|
{ |
746 |
|
|
#ifdef AVR |
747 |
|
|
lcd_buf_bin_AVR(val, width); |
748 |
|
|
#else |
749 |
|
|
char buffer[35]; |
750 |
|
|
char bin_val_buffer[35]; |
751 |
|
|
char zeros_buf[35]; |
752 |
|
2 |
buffer[0] = '\0'; |
753 |
|
2 |
bin_val_buffer[0] = '\0'; |
754 |
|
2 |
zeros_buf[0] = '\0'; |
755 |
|
|
|
756 |
|
2 |
fill_bin_value_buffer(val, bin_val_buffer); |
757 |
|
2 |
fill_zeros_buffer(bin_val_buffer, width, zeros_buf); |
758 |
|
2 |
strcat(buffer, "0b"); |
759 |
|
2 |
strcat(buffer, zeros_buf); |
760 |
|
2 |
strcat(buffer, bin_val_buffer); |
761 |
|
2 |
lcd_buf_str(buffer); |
762 |
|
|
#endif |
763 |
|
2 |
} |
764 |
|
|
|
765 |
|
|
#endif |
766 |
|
|
#endif |
767 |
|
|
|