LCD HD44780 Test Coverage Report


src/
File: lcd_hd44780.c
Date: 2025-03-01 19:02:50
Lines:
248/251
98.8%
Functions:
38/38
100.0%
Branches:
50/53
94.3%

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