166 lines
3.5 KiB
C
166 lines
3.5 KiB
C
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
/*
|
|
* lcd_emulator.c
|
|
*
|
|
* Created on: Apr 1, 2019
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include "lcd.h"
|
|
|
|
#define CR 13 // \r
|
|
#define TAB 9 // \n
|
|
|
|
static uint8_t lcd_row, lcd_col;
|
|
static char lcd_buf[MAX_ROWS][MAX_CHARS_PER_LINE];
|
|
|
|
static char enable_checks = 1;
|
|
|
|
const char* get_lcd_buf(void){
|
|
return &lcd_buf[0][0];
|
|
}
|
|
|
|
void print_lcd(void){
|
|
printf("(row,col)=(%d,%d)\n", lcd_row, lcd_col);
|
|
printf("|---|---|---|---|\n");
|
|
for (int i = 0; i < MAX_ROWS; i++){
|
|
printf("|");
|
|
for (int j = 0; j < MAX_CHARS_PER_LINE; j++){
|
|
printf("%c", lcd_buf[i][j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
printf("|---|---|---|---|\n");
|
|
}
|
|
|
|
void LCD_Open(void){
|
|
LCD_Clear();
|
|
}
|
|
|
|
void LCD_Clear(void){
|
|
for (int i = 0; i < MAX_ROWS; i++){
|
|
for (int j = 0; j < MAX_CHARS_PER_LINE; j++){
|
|
lcd_buf[i][j] = ' ';
|
|
}
|
|
}
|
|
lcd_row=0;
|
|
lcd_col=0;
|
|
}
|
|
|
|
void LCD_GoTo(uint8_t row, uint8_t col){
|
|
if (row < MAX_ROWS && col < MAX_CHARS_PER_LINE){
|
|
lcd_row = row;
|
|
lcd_col = col;
|
|
} else {
|
|
printf("LCD_GoTo(%u, %u) out of range\n", lcd_row, lcd_col);
|
|
}
|
|
}
|
|
|
|
static void to_row(unsigned char row_to){
|
|
if (row_to == 0){
|
|
lcd_row = 0;
|
|
} else {
|
|
lcd_row = 1;
|
|
}
|
|
lcd_col = 0;
|
|
}
|
|
|
|
void LCD_OutString(const char *string, uint8_t max_chars) {
|
|
const char *s;
|
|
for (s = string; *s && max_chars > 0; s++, max_chars--) {
|
|
TERMIO_PutChar(*s);
|
|
}
|
|
}
|
|
|
|
void LCD_OutString_Initial(const char *string) {
|
|
enable_checks = 0;
|
|
assert(strlen(string) <= 32);
|
|
LCD_OutString(string, 32);
|
|
enable_checks = 1;
|
|
}
|
|
|
|
static int is_valid_character(char letter){
|
|
if (isdigit(letter)){
|
|
return 1;
|
|
} else if(letter == CGRAM_EXP || letter == CGRAM_EXP_NEG){
|
|
return 1;
|
|
} else if(letter == '.' || letter == ' ' || letter == '-'){
|
|
return 1;
|
|
} else if(letter == '^'){
|
|
return 1;
|
|
} else if(letter == 'E' || letter == 'r' || letter == 'o'){
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
short TERMIO_PutChar(unsigned char letter) {
|
|
if (letter == CR || letter == '\n') {
|
|
LCD_Clear();
|
|
} else if (letter == TAB || letter == '\t') {
|
|
if (lcd_row == 0) {
|
|
to_row(1);
|
|
} else {
|
|
to_row(0);
|
|
}
|
|
}
|
|
//warn if unknown character
|
|
if (!is_valid_character(letter) && enable_checks) {
|
|
printf("\nerror @%d,%d, invalid character %d\n",
|
|
lcd_row, lcd_col, letter);
|
|
}
|
|
//add character to buf
|
|
if (letter == CGRAM_EXP){
|
|
lcd_buf[lcd_row][lcd_col] = 'E';
|
|
} else if (letter == CGRAM_EXP_NEG) {
|
|
lcd_buf[lcd_row][lcd_col] = '-';
|
|
} else if (letter == CGRAM_DOWN) {
|
|
lcd_buf[lcd_row][lcd_col] = 'V';
|
|
} else {
|
|
lcd_buf[lcd_row][lcd_col] = letter;
|
|
}
|
|
lcd_col++;
|
|
//check if new line
|
|
if (lcd_col >= MAX_CHARS_PER_LINE) {
|
|
if (lcd_row == 0) {
|
|
to_row(1);
|
|
} else {
|
|
to_row(0);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void LCD_ClearToEnd(uint8_t curr_row){
|
|
while (lcd_col != 0 && lcd_row == curr_row){
|
|
TERMIO_PutChar(' ');
|
|
}
|
|
}
|
|
|
|
void LCD_OutNibble(uint8_t x){
|
|
x &= 0xf; //ensure only bottom nibble
|
|
if (x <= 9){
|
|
TERMIO_PutChar(x + '0');
|
|
} else {
|
|
TERMIO_PutChar(x - 10 + 'a');
|
|
}
|
|
}
|