From cc759e3d55d871dace980414790bd30e477f8ec7 Mon Sep 17 00:00:00 2001 From: Oskar Senft Date: Thu, 25 Jul 2024 18:02:19 -0400 Subject: [PATCH 1/2] Add support for Arduino LiquidCrystal LED displays (Hitachi HD44780) --- Display_Implementation.h | 10 +++++++ LiquidCrystal_Parallel.cpp | 61 ++++++++++++++++++++++++++++++++++++++ LiquidCrystal_Parallel.h | 52 ++++++++++++++++++++++++++++++++ config.example.h | 4 +++ 4 files changed, 127 insertions(+) create mode 100644 LiquidCrystal_Parallel.cpp create mode 100644 LiquidCrystal_Parallel.h diff --git a/Display_Implementation.h b/Display_Implementation.h index 6a3c995..de9b4c8 100644 --- a/Display_Implementation.h +++ b/Display_Implementation.h @@ -30,6 +30,7 @@ #include "DisplayInterface.h" #include "SSD1306Ascii.h" #include "LiquidCrystal_I2C.h" +#include "LiquidCrystal_Parallel.h" // Implement the Display shim class as a singleton. @@ -38,6 +39,7 @@ // Then Display class talks to the specific device type classes: // SSD1306AsciiWire for I2C OLED driver with SSD1306 or SH1106 controllers; // LiquidCrystal_I2C for I2C LCD driver for HD44780 with PCF8574 'backpack'. +// LiquidCrystal_Parallel for HD44780 in parallel mode. #if defined(OLED_DRIVER) #define DISPLAY_START(xxx) { \ @@ -53,6 +55,14 @@ t->begin(); \ xxx; \ t->refresh();} + +#elif defined(PARALLEL_LCD_DRIVER) + #define DISPLAY_START(xxx) { \ + DisplayInterface *t = new Display( \ + new LiquidCrystal_Parallel(PARALLEL_LCD_DRIVER)); \ + t->begin(); \ + xxx; \ + t->refresh();} #else #define DISPLAY_START(xxx) { \ xxx; \ diff --git a/LiquidCrystal_Parallel.cpp b/LiquidCrystal_Parallel.cpp new file mode 100644 index 0000000..1b475bf --- /dev/null +++ b/LiquidCrystal_Parallel.cpp @@ -0,0 +1,61 @@ +/* + * © 2024, Oskar Senft. All rights reserved. + * + * This file is part of CommandStation-EX + * + * This 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. + * + * It 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 CommandStation-EX. If not, see . + */ + +#include +#include "LiquidCrystal_Parallel.h" +#include "DIAG.h" + +LiquidCrystal_Parallel::LiquidCrystal_Parallel( + uint16_t cols, uint16_t rows, + uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) + : _cols(cols), _rows(rows), lcd(rs, rw, enable, d4, d5, d6, d7) +{ +} + +bool LiquidCrystal_Parallel::begin() +{ + lcd.begin(getNumCols(), getNumRows()); + lcd.noCursor(); + return true; +} + +void LiquidCrystal_Parallel::clearNative() +{ + lcd.clear(); +} + +void LiquidCrystal_Parallel::setRowNative(byte row) +{ + if (row >= getNumRows()) + { + row = getNumRows() - 1; // we count rows starting w/0 + } + lcd.setCursor(0, row); +} + +size_t LiquidCrystal_Parallel::writeNative(uint8_t value) +{ + return lcd.write(value); +} + +bool LiquidCrystal_Parallel::isBusy() +{ + return false; +} diff --git a/LiquidCrystal_Parallel.h b/LiquidCrystal_Parallel.h new file mode 100644 index 0000000..afba6c2 --- /dev/null +++ b/LiquidCrystal_Parallel.h @@ -0,0 +1,52 @@ +/* + * © 2024, Oskar Senft. All rights reserved. + * + * This file is part of CommandStation-EX + * + * This 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. + * + * It 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 CommandStation. If not, see . + */ + +#ifndef LiquidCrystal_Parallel_h +#define LiquidCrystal_Parallel_h + +#include +#include +#include "Display.h" + +// Support for an LCD based on the Hitachi HD44780 (or a compatible) chipset +// as supported by Arduino's LiquidCrystal library. +class LiquidCrystal_Parallel : public DisplayDevice +{ +public: + // Specify the display's number of columns and rows as well + // as Arduino pins numbers for the display's pins (4-bit mode) + LiquidCrystal_Parallel(uint16_t cols, uint16_t rows, + uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); + bool begin() override; + void clearNative() override; + void setRowNative(byte line) override; + size_t writeNative(uint8_t c) override; + bool isBusy() override; + + uint16_t getNumCols() override { return _cols; } + uint16_t getNumRows() override { return _rows; } + +private: + LiquidCrystal lcd; + const uint16_t _cols; + const uint16_t _rows; +}; + +#endif diff --git a/config.example.h b/config.example.h index 7c4e254..4bab32f 100644 --- a/config.example.h +++ b/config.example.h @@ -161,6 +161,10 @@ The configuration file for DCC-EX Command Station // Use 132,64 for a SH1106-based I2C device with a 128x64 display. // #define OLED_DRIVER 0x3c,128,32 +//OR define PARALLEL_LCD_DRIVER COLS,ROWS,RS,RW,ENABLE,D4,D5,D6,D7 +// using Arduino pin numbers for RS,RW,ENABLE,D4,D5,D6,D7 +// #define PARALLEL_LCD_DRIVER 20, 4, 26, 27, 28, 22, 23, 24, 25 + // Define scroll mode as 0, 1 or 2 // * #define SCROLLMODE 0 is scroll continuous (fill screen if poss), // * #define SCROLLMODE 1 is by page (alternate between pages), From b36fb352b6e0276cc849fe9cfe98629f9d4d608d Mon Sep 17 00:00:00 2001 From: Oskar Senft Date: Fri, 26 Jul 2024 10:48:57 -0400 Subject: [PATCH 2/2] Reference LiquidCrystal library only if driver is enabled --- LiquidCrystal_Parallel.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/LiquidCrystal_Parallel.h b/LiquidCrystal_Parallel.h index afba6c2..3b00da8 100644 --- a/LiquidCrystal_Parallel.h +++ b/LiquidCrystal_Parallel.h @@ -21,9 +21,26 @@ #define LiquidCrystal_Parallel_h #include -#include #include "Display.h" +#ifdef PARALLEL_LCD_DRIVER +// Only use the Arduino library if the driver is actually enabled. +#include +#else +// If the driver is not enabled, use a dummy version instead. +class LiquidCrystal +{ +public: + LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) {}; + void begin(uint16_t cols, uint16_t rows) {}; + void noCursor() {}; + void setCursor(uint16_t col, uint16_t row) {}; + void clear() {}; + size_t write(uint8_t val) { return 0; }; +}; +#endif + // Support for an LCD based on the Hitachi HD44780 (or a compatible) chipset // as supported by Arduino's LiquidCrystal library. class LiquidCrystal_Parallel : public DisplayDevice