From bfdcf10d5aeda000809ecf139f8de78d3d63ac51 Mon Sep 17 00:00:00 2001 From: Vasily Davydov Date: Tue, 20 Sep 2022 19:22:23 +0300 Subject: [PATCH] lcd: resolve #4 --- LiquidCrystal/.cproject | 242 +++++++++++++++++++++++++ LiquidCrystal/inc/LiquidCrystal.h | 97 ++++++++++ LiquidCrystal/liblinks.xml | 32 ++++ LiquidCrystal/src/LiquidCrystal.cpp | 268 ++++++++++++++++++++++++++++ esp-vent-main/.cproject | 10 ++ esp-vent-main/.project | 1 + 6 files changed, 650 insertions(+) create mode 100644 LiquidCrystal/.cproject create mode 100644 LiquidCrystal/inc/LiquidCrystal.h create mode 100644 LiquidCrystal/liblinks.xml create mode 100644 LiquidCrystal/src/LiquidCrystal.cpp diff --git a/LiquidCrystal/.cproject b/LiquidCrystal/.cproject new file mode 100644 index 0000000..e77af50 --- /dev/null +++ b/LiquidCrystal/.cproject @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_2="LPC15xx_256K.cfx" property_3="NXP" property_4="LPC1549" property_count="5" version="100300"/> +<infoList vendor="NXP"> +<info chip="LPC1549" connectscript="LPC15RunBootRomConnect.scp" flash_driver="LPC15xx_256K.cfx" match_id="0x0" name="LPC1549" resetscript="LPC15RunBootRomReset.scp" stub="crt_emu_cm3_gen"> +<chip> +<name>LPC1549</name> +<family>LPC15xx</family> +<vendor>NXP (formerly Philips)</vendor> +<reset board="None" core="Real" sys="Real"/> +<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/> +<memory can_program="true" id="Flash" is_ro="true" type="Flash"/> +<memory id="RAM" type="RAM"/> +<memory id="Periph" is_volatile="true" type="Peripheral"/> +<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/> +<memoryInstance derived_from="RAM" id="Ram0_16" location="0x2000000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram1_16" location="0x2004000" size="0x4000"/> +<memoryInstance derived_from="RAM" id="Ram2_4" location="0x2008000" size="0x1000"/> +</chip> +<processor> +<name gcc_name="cortex-m3">Cortex-M3</name> +<family>Cortex-M</family> +</processor> +</info> +</infoList> +</TargetConfig> + + + LPCXpresso1549 + + \ No newline at end of file diff --git a/LiquidCrystal/inc/LiquidCrystal.h b/LiquidCrystal/inc/LiquidCrystal.h new file mode 100644 index 0000000..89690b1 --- /dev/null +++ b/LiquidCrystal/inc/LiquidCrystal.h @@ -0,0 +1,97 @@ +#ifndef LiquidCrystal_h +#define LiquidCrystal_h + + +#include +#include +#include "chip.h" +#include "DigitalIoPin.h" + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +class LiquidCrystal { +public: + + LiquidCrystal(DigitalIoPin *rs, DigitalIoPin *enable, + DigitalIoPin *d0, DigitalIoPin *d1, DigitalIoPin *d2, DigitalIoPin *d3); + + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); + + void clear(); + void home(); + + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void leftToRight(); + void rightToLeft(); + void autoscroll(); + void noAutoscroll(); + + void createChar(uint8_t, uint8_t[]); + void setCursor(uint8_t, uint8_t); + virtual size_t write(uint8_t); + void command(uint8_t); + void print(std::string const &s); + void print(const char *s); + +private: + void send(uint8_t, uint8_t); + void write4bits(uint8_t); + void pulseEnable(); + + DigitalIoPin *rs_pin; // LOW(false): command. HIGH(true): character. + DigitalIoPin *enable_pin; // activated by a HIGH pulse. + DigitalIoPin *data_pins[4]; + + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + + uint8_t _initialized; + + uint8_t _numlines,_currline; +}; + +#endif diff --git a/LiquidCrystal/liblinks.xml b/LiquidCrystal/liblinks.xml new file mode 100644 index 0000000..1dc1803 --- /dev/null +++ b/LiquidCrystal/liblinks.xml @@ -0,0 +1,32 @@ + + + + + ${MacroStart}workspace_loc:/${ProjName}/inc${MacroEnd} + + + ${MacroStart}workspace_loc:/${ProjName}/inc${MacroEnd} + + + ${ProjName} + + + ${MacroStart}workspace_loc:/${ProjName}/Debug${MacroEnd} + + + ${MacroStart}workspace_loc:/${ProjName}/Release${MacroEnd} + + + ${ProjName} + + + diff --git a/LiquidCrystal/src/LiquidCrystal.cpp b/LiquidCrystal/src/LiquidCrystal.cpp new file mode 100644 index 0000000..a90728c --- /dev/null +++ b/LiquidCrystal/src/LiquidCrystal.cpp @@ -0,0 +1,268 @@ +#include "LiquidCrystal.h" + +#include +#include "chip.h" + +#define LOW 0 +#define HIGH 1 + + + +void delayMicroseconds(unsigned int us) +{ + // implement with RIT +} + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + + + + +LiquidCrystal::LiquidCrystal(DigitalIoPin *rs, DigitalIoPin *enable, + DigitalIoPin *d0, DigitalIoPin *d1, DigitalIoPin *d2, DigitalIoPin *d3) +{ + rs_pin = rs; + enable_pin = enable; + + data_pins[0] = d0; + data_pins[1] = d1; + data_pins[2] = d2; + data_pins[3] = d3; + + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + + begin(16, 2); // default to 16x2 display +} + +void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { + if (lines > 1) { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + _currline = 0; + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != 0) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + delayMicroseconds(50000); + // Now we pull both RS and R/W low to begin commands + rs_pin->write(false); //digitalWrite(_rs_pin, LOW); + enable_pin->write(false); //digitalWrite(_enable_pin, LOW); + + // note: this port supports only 4 bit mode + //put the LCD into 4 bit or 8 bit mode + if (! (_displayfunction & LCD_8BITMODE)) { + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x03); + delayMicroseconds(150); + + // finally, set to 4-bit interface + write4bits(0x02); + } else { + // this is according to the hitachi HD44780 datasheet + // page 45 figure 23 + + // Send function set command sequence + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(4500); // wait more than 4.1ms + + // second try + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(150); + + // third go + command(LCD_FUNCTIONSET | _displayfunction); + } + + // finally, set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for romance languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + +} + +/********** high level commands, for the user! */ +void LiquidCrystal::clear() +{ + command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::home() +{ + command(LCD_RETURNHOME); // set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + + +void LiquidCrystal::print(std::string const &s) +{ +} + +void LiquidCrystal::print(const char *s) +{ +} + +void LiquidCrystal::setCursor(uint8_t col, uint8_t row) +{ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + if ( row >= _numlines ) { + row = _numlines-1; // we count rows starting w/0 + } + + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal::command(uint8_t value) { + send(value, LOW); +} + +inline size_t LiquidCrystal::write(uint8_t value) { + send(value, HIGH); + return 1; // assume sucess +} + +/************ low level data pushing commands **********/ + +// write either command or data +void LiquidCrystal::send(uint8_t value, uint8_t mode) { + rs_pin->write(mode); //digitalWrite(_rs_pin, mode); + + write4bits(value>>4); + write4bits(value); +} + +void LiquidCrystal::pulseEnable(void) { + enable_pin->write(false); //digitalWrite(_enable_pin, LOW); + delayMicroseconds(1); + enable_pin->write(true); //digitalWrite(_enable_pin, HIGH); + delayMicroseconds(1); // enable pulse must be >450ns + enable_pin->write(false); //digitalWrite(_enable_pin, LOW); + delayMicroseconds(100); // commands need > 37us to settle +} + +void LiquidCrystal::write4bits(uint8_t value) { + for (int i = 0; i < 4; i++) { + data_pins[i]->write((value >> i) & 0x01); //digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} + diff --git a/esp-vent-main/.cproject b/esp-vent-main/.cproject index fa1ef8e..cbc0616 100644 --- a/esp-vent-main/.cproject +++ b/esp-vent-main/.cproject @@ -42,6 +42,7 @@ + @@ -110,11 +113,13 @@ + @@ -244,11 +252,13 @@ +