summaryrefslogtreecommitdiff
path: root/peripheral/libupm/src/lcd/lcm1602.h
blob: 6c2608270b95cb307c8c6d50a0d88c6e3f4fb41a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
/*
 * The MIT License (MIT)
 *
 * Author: Daniel Mosquera
 * Copyright (c) 2013 Daniel Mosquera
 *
 * Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
 * Copyright (c) 2014 Intel Corporation.
 *
 * Contributions: Jon Trulson <jtrulson@ics.com>
 *                Sergey Kiselev <sergey.kiselev@intel.com> 
 *
 * Permission is hereby granted, free of uint8_tge, 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.
 */

#pragma once

#include <string>
#include <mraa/i2c.hpp>

#include <mraa/gpio.hpp>

#include "lcd.h"

namespace upm
{
/**
 * @library i2clcd
 * @sensor lcm1602
 * @comname LCM1602 Display
 * @type display
 * @man adafruit sparkfun seeed
 * @web https://www.adafruit.com/datasheets/TC1602A-01T.pdf
 * @con i2c gpio
 *
 * @brief API for the LCM1602 I2C controller for HD44780-based displays
 *
 * This supports all sizes of HD44780 displays, from 16x2 to 4x20. The
 * controller has no idea of the actual display hardware, so it lets you write
 * farther than you can see. These displays with such controllers are available
 * from various manufacturers with different I2C addresses. Adafruit*
 * TC1602A-01T seems to be a well-documented example. The driver also supports
 * parallel GPIO connections directly to the HD44780 in case you are not using
 * an I2C expander/backpack.
 *
 * @image html lcm1602.jpeg
 * Example for LCM1602 displays that use the I2C bus
 * @snippet lcm1602-i2c.cxx Interesting
 * Code sample for GPIO based LCM1602 displays
 * @snippet lcm1602-parallel.cxx Interesting
 */
class Lcm1602 : public LCD
{
  public:
    /**
     * Lcm1602 constructor; calls libmraa initialisation functions
     *
     * @param bus I2C bus to use
     * @param address Slave address the LCD is registered on
     * @param isExpander True if we are dealing with an I2C expander,
     * false otherwise. Default is true.
     */
  Lcm1602(int bus, int address, bool isExpander=true,
          uint8_t numColumns = 16, uint8_t numRows = 4);

    /**
     * Lcm1602 alternate constructor, used for GPIO based HD44780
     * controllers supporting RS, Enable, and 4 data pins in 4-bit
     * mode.
     *
     * @param rs Register select pin
     * @param enable Enable pin
     * @param d0 Data 0 pin
     * @param d1 Data 1 pin
     * @param d2 Data 2 pin
     * @param d3 Data 3 pin
     */
    Lcm1602(uint8_t rs,  uint8_t enable,
            uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
            uint8_t numColumns = 16, uint8_t numRows = 4);

    /**
     * Lcm1602 destructor
     */
    ~Lcm1602();
    /**
     * Writes a string to the LCD
     *
     * @param msg std::string to write to the display; note: only ASCII
     * characters are supported
     * @return Result of the operation
     */
    mraa::Result write(std::string msg);
    /**
     * Sets the cursor to specified coordinates
     *
     * @param row Row to set the cursor to
     * @param column Column to set the cursor to
     * @return Result of the operation
     */
    mraa::Result setCursor(int row, int column);
    /**
     * Clears the display of all characters
     *
     * @return Result of the operation
     */
    mraa::Result clear();
    /**
     * Returns to the original coordinates (0,0)
     *
     * @return Result of the operation
     */
    mraa::Result home();

    /**
     * Create a custom character
     *
     * @param charSlot the character slot to write, only 8 are available
     * @param charData The character data (8 bytes) making up the character
     * @return Result of operation
     */
    mraa::Result createChar(uint8_t charSlot, uint8_t charData[]);

    /**
     * Turn the display on
     *
     * @return Result of operation
     */
    mraa::Result displayOn();

    /**
     * Turn the display off
     *
     * @return Result of operation
     */
    mraa::Result displayOff();

    /**
     * Turn the cursor on
     *
     * @return Result of operation
     */
    mraa::Result cursorOn();

    /**
     * Turn the cursor off
     *
     * @return Result of operation
     */
    mraa::Result cursorOff();

    /**
     * Turn cursor blink on
     *
     * @return Result of operation
     */
    mraa::Result cursorBlinkOn();

    /**
     * Turn cursor blink off
     *
     * @return Result of operation
     */
    mraa::Result cursorBlinkOff();

    /**
     * Scroll the display left, without changing the character RAM
     *
     * @return Result of operation
     */
    mraa::Result scrollDisplayLeft();

    /**
     * Scroll the display right, without changing the character RAM
     *
     * @return Result of operation
     */
    mraa::Result scrollDisplayRight();

    /**
     * set the entry mode so that characters are added left to right
     *
     * @return Result of operation
     */
    mraa::Result entryLeftToRight();

    /**
     * set the entry mode so that characters are added right to left
     *
     * @return Result of operation
     */
    mraa::Result entryRightToLeft();

    /**
     * Right justify text entered from the cursor
     *
     * @return Result of operation
     */
    mraa::Result autoscrollOn();

    /**
     * Left justify text entered from the cursor
     *
     * @return Result of operation
     */
    mraa::Result autoscrollOff();


  protected:
    mraa::Result send(uint8_t value, int mode);
    mraa::Result write4bits(uint8_t value);
    mraa::Result expandWrite(uint8_t value);
    mraa::Result pulseEnable(uint8_t value);

    uint8_t m_displayControl;
    uint8_t m_entryDisplayMode;

    // Display size
    uint8_t m_numColumns;
    uint8_t m_numRows;

    // Add a command() and data() virtual member functions, with a
    // default implementation in lcm1602.  This is expected to be
    // implemented by derived classes with different needs (Jhd1313m1,
    // for example).
    virtual mraa::Result command(uint8_t cmd);
    virtual mraa::Result data(uint8_t data);

    int m_lcd_control_address;
    mraa::I2c* m_i2c_lcd_control;

  private:

    // true if using i2c, false otherwise (gpio)
    bool m_isI2C;

    // gpio operation
    mraa::Gpio* m_gpioRS;
    mraa::Gpio* m_gpioEnable;
    mraa::Gpio* m_gpioD0;
    mraa::Gpio* m_gpioD1;
    mraa::Gpio* m_gpioD2;
    mraa::Gpio* m_gpioD3;
};
}