summaryrefslogtreecommitdiff
path: root/ucoo/dev
diff options
context:
space:
mode:
authorNicolas Schodet2015-05-04 16:57:10 +0200
committerNicolas Schodet2019-10-07 00:44:50 +0200
commit7bd977afc2d1f833ca6adb10b742527df43d3370 (patch)
treefd44090542c766214a163c9505c1310aaa6025cd /ucoo/dev
parente43de81bf8c58029521fd8eaeaa9c2b7cd638244 (diff)
ucoo/{intf,dev/lcd}: add text LCD support
Diffstat (limited to 'ucoo/dev')
-rw-r--r--ucoo/dev/lcd/Module1
-rw-r--r--ucoo/dev/lcd/lcd_spi.cc189
-rw-r--r--ucoo/dev/lcd/lcd_spi.hh81
-rw-r--r--ucoo/dev/lcd/test/Makefile9
-rw-r--r--ucoo/dev/lcd/test/test_lcd.cc58
5 files changed, 338 insertions, 0 deletions
diff --git a/ucoo/dev/lcd/Module b/ucoo/dev/lcd/Module
new file mode 100644
index 0000000..1934cc8
--- /dev/null
+++ b/ucoo/dev/lcd/Module
@@ -0,0 +1 @@
+dev_lcd_SOURCES := lcd_spi.cc
diff --git a/ucoo/dev/lcd/lcd_spi.cc b/ucoo/dev/lcd/lcd_spi.cc
new file mode 100644
index 0000000..f8f05d0
--- /dev/null
+++ b/ucoo/dev/lcd/lcd_spi.cc
@@ -0,0 +1,189 @@
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2015 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/dev/lcd/lcd_spi.hh"
+
+#include "ucoo/common.hh"
+#include "ucoo/utils/delay.hh"
+
+#include <cstring>
+
+namespace ucoo {
+
+enum
+{
+ LCD_CLEAR = 0x01,
+ LCD_HOME = 0x02,
+ LCD_ENTRY_MODE = 0x04,
+ LCD_ENTRY_MODE__INCR = 0x02,
+ LCD_ENTRY_MODE__SHIFT = 0x01,
+ LCD_DISPLAY_ON_OFF = 0x08,
+ LCD_DISPLAY_ON_OFF__ON = 0x04,
+ LCD_DISPLAY_ON_OFF__CURSOR = 0x02,
+ LCD_DISPLAY_ON_OFF__BLINK = 0x01,
+ LCD_SHIFT = 0x10,
+ LCD_SHIFT__DISPLAY = 0x08,
+ LCD_SHIFT__RIGHT = 0x04,
+ LCD_FUNCTION_SET = 0x20,
+ LCD_FUNCTION_SET__8BIT = 0x10,
+ LCD_FUNCTION_SET__2LINES = 0x08,
+ LCD_FUNCTION_SET__FONT = 0x04,
+ LCD_FUNCTION_SET__INSTRUCTION_TABLE_1 = 0x01,
+ LCD_SET_CGRAM_ADDRESS = 0x40,
+ LCD_SET_DDRAM_ADDRESS = 0x80,
+
+ LCD_IS1_BIAS_SET = 0x14,
+ LCD_IS1_BIAS_SET__1_4_BIAS = 0x08,
+ LCD_IS1_BIAS_SET__1_5_BIAS = 0x00,
+ LCD_IS1_POWER_CONTROL = 0x50,
+ LCD_IS1_POWER_CONTROL__BOOST_ON = 0x04,
+ LCD_IS1_POWER_CONTROL__CONTRAST_C5 = 0x02,
+ LCD_IS1_POWER_CONTROL__CONTRAST_C4 = 0x01,
+ LCD_IS1_FOLLOWER_CONTROL = 0x60,
+ LCD_IS1_FOLLOWER_CONTROL__ON = 0x08,
+ LCD_IS1_CONTRAST_SET = 0x70,
+ LCD_IS1_CONTRAST_SET__CONTRAST_C3 = 0x08,
+ LCD_IS1_CONTRAST_SET__CONTRAST_C2 = 0x04,
+ LCD_IS1_CONTRAST_SET__CONTRAST_C1 = 0x02,
+ LCD_IS1_CONTRAST_SET__CONTRAST_C0 = 0x01,
+};
+
+LcdSpi::~LcdSpi ()
+{
+ disable ();
+}
+
+void
+LcdSpi::enable ()
+{
+ enabled_ = true;
+ // Enable bus.
+ cs_.output ();
+ cs_.set ();
+ rs_.output ();
+ spi_.enable (spi_speed_hz_, SPI_MODE_3);
+ // Initialise display.
+ char buf[] = {
+ LCD_FUNCTION_SET | LCD_FUNCTION_SET__8BIT | LCD_FUNCTION_SET__2LINES
+ | LCD_FUNCTION_SET__INSTRUCTION_TABLE_1,
+ LCD_IS1_BIAS_SET | LCD_IS1_BIAS_SET__1_5_BIAS,
+ LCD_IS1_POWER_CONTROL | LCD_IS1_POWER_CONTROL__BOOST_ON | 0x1,
+ LCD_IS1_FOLLOWER_CONTROL | LCD_IS1_FOLLOWER_CONTROL__ON | 5,
+ LCD_IS1_CONTRAST_SET | 0x8,
+ LCD_FUNCTION_SET | LCD_FUNCTION_SET__8BIT | LCD_FUNCTION_SET__2LINES,
+ LCD_DISPLAY_ON_OFF | LCD_DISPLAY_ON_OFF__ON,
+ LCD_CLEAR,
+ LCD_ENTRY_MODE | LCD_ENTRY_MODE__INCR,
+ };
+ send (buf, sizeof (buf), true, true);
+ cur_line_ = 0;
+}
+
+void
+LcdSpi::disable ()
+{
+ if (enabled_)
+ {
+ enabled_ = false;
+ // Turn off display.
+ char buf[] = { LCD_DISPLAY_ON_OFF };
+ send (buf, sizeof (buf), true);
+ // Disable bus.
+ spi_.disable ();
+ rs_.input ();
+ cs_.input ();
+ }
+}
+
+void
+LcdSpi::puts (const char *str)
+{
+ while (*str)
+ {
+ const char *end = str + strcspn (str, "\n\r");
+ if (end != str)
+ send (str, end - str);
+ str = end;
+ switch (*str)
+ {
+ case '\n':
+ go (cur_line_ + 1, 0);
+ str++;
+ break;
+ case '\r':
+ go (cur_line_, 0);
+ str++;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void
+LcdSpi::go (int line, int column)
+{
+ line = line % lines_;
+ int addr = line * 0x40 + column;
+ char buf[] = { static_cast<char> (LCD_SET_DDRAM_ADDRESS | addr) };
+ send (buf, sizeof (buf), true);
+ cur_line_ = line;
+}
+
+void
+LcdSpi::clear ()
+{
+ char buf[] = { LCD_CLEAR };
+ send (buf, sizeof (buf), true, true);
+}
+
+int
+LcdSpi::get_lines () const
+{
+ return lines_;
+}
+
+int
+LcdSpi::get_columns () const
+{
+ return columns_;
+}
+
+void
+LcdSpi::send (const char *buf, int count, bool command, bool long_delay)
+{
+ assert (enabled_);
+ rs_.set (!command);
+ cs_.reset ();
+ spi_.send (buf, count);
+ cs_.set ();
+ if (command)
+ {
+ if (long_delay)
+ delay_ms (3);
+ else
+ delay_us (60);
+ }
+}
+
+} // namespace ucoo
diff --git a/ucoo/dev/lcd/lcd_spi.hh b/ucoo/dev/lcd/lcd_spi.hh
new file mode 100644
index 0000000..b0f4368
--- /dev/null
+++ b/ucoo/dev/lcd/lcd_spi.hh
@@ -0,0 +1,81 @@
+#ifndef ucoo_dev_lcd_lcd_spi_hh
+#define ucoo_dev_lcd_lcd_spi_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2015 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/intf/lcd.hh"
+#include "ucoo/intf/spi_master.hh"
+#include "ucoo/intf/io.hh"
+
+// TODO: support several LCD and buses using subclassing.
+
+namespace ucoo {
+
+/// Typical character based LCD using SPI connection.
+class LcdSpi : public Lcd
+{
+ public:
+ /// Constructor.
+ LcdSpi (SpiMaster &spi, Io &cs, Io &rs);
+ /// Destructor.
+ ~LcdSpi ();
+ /// Enable, initialise display.
+ void enable ();
+ /// Disable, clear display and shutdown if possible.
+ void disable ();
+ /// See Lcd::puts.
+ void puts (const char *str);
+ /// See Lcd::go.
+ void go (int line, int column);
+ /// See Lcd::clear.
+ void clear ();
+ /// See Lcd::get_lines.
+ int get_lines () const;
+ /// See Lcd::get_columns.
+ int get_columns () const;
+ protected:
+ /// Send commands or data to LCD.
+ void send (const char *buf, int count, bool command = false,
+ bool long_delay = false);
+ private:
+ SpiMaster &spi_;
+ Io &cs_, &rs_;
+ /// Number of lines, columns and current line.
+ int lines_, columns_, cur_line_;
+ /// Is it enabled?
+ bool enabled_;
+ /// SPI frequency.
+ static const int spi_speed_hz_ = 250000;
+};
+
+inline
+LcdSpi::LcdSpi (SpiMaster &spi, Io &cs, Io &rs)
+ : spi_ (spi), cs_ (cs), rs_ (rs),
+ lines_ (2), columns_ (16),
+ cur_line_ (0), enabled_ (false)
+{
+}
+
+} // namespace ucoo
+
+#endif // ucoo_dev_lcd_lcd_spi_hh
diff --git a/ucoo/dev/lcd/test/Makefile b/ucoo/dev/lcd/test/Makefile
new file mode 100644
index 0000000..f8bef65
--- /dev/null
+++ b/ucoo/dev/lcd/test/Makefile
@@ -0,0 +1,9 @@
+BASE = ../../../..
+
+TARGETS = stm32f1
+PROGS = test_lcd
+test_lcd_SOURCES = test_lcd.cc
+
+MODULES = intf utils hal/gpio hal/spi dev/lcd
+
+include $(BASE)/build/top.mk
diff --git a/ucoo/dev/lcd/test/test_lcd.cc b/ucoo/dev/lcd/test/test_lcd.cc
new file mode 100644
index 0000000..c654287
--- /dev/null
+++ b/ucoo/dev/lcd/test/test_lcd.cc
@@ -0,0 +1,58 @@
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2015 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/hal/spi/spi_soft.hh"
+#include "ucoo/hal/gpio/gpio.hh"
+#include "ucoo/utils/delay.hh"
+
+#include "ucoo/dev/lcd/lcd_spi.hh"
+
+#include "ucoo/arch/arch.hh"
+
+#include <libopencm3/stm32/rcc.h>
+
+int
+main (int argc, const char **argv)
+{
+ ucoo::arch_init (argc, argv);
+ rcc_periph_clock_enable (RCC_GPIOB);
+ ucoo::Gpio rw (GPIOB, 10);
+ ucoo::Gpio rs (GPIOB, 11);
+ ucoo::Gpio cs (GPIOB, 12);
+ ucoo::Gpio sck (GPIOB, 13);
+ ucoo::Gpio miso (GPIOB, 14);
+ ucoo::Gpio mosi (GPIOB, 15);
+ ucoo::SpiSoftMaster spi (sck, mosi, miso);
+ rw.reset ();
+ rw.output ();
+ ucoo::LcdSpi lcd (spi, cs, rs);
+ ucoo::delay (1);
+ lcd.enable ();
+ int i = 0;
+ while (1)
+ {
+ lcd.printf ("Hello world!\n%02d:%02d\n", i / 60, i % 60);
+ i++;
+ ucoo::delay (1);
+ }
+}