-
Notifications
You must be signed in to change notification settings - Fork 14
/
HT1621.h
315 lines (285 loc) · 13.7 KB
/
HT1621.h
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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/**
* \mainpage Holtek HT1621
*
* \author Enrico Formenti
* \date 31 january 2015
* \version 1.0
* \tableofcontents
* \section sec_intro Introduction
* The Holtek HT1621 is multi-function LCD driver with a 32x4 memory mapping capability. It has a simple
* interface with microprocessors (3-wire serial communication) and a built-in tone generator with two
* frequences (2kHz and 4kHz). It supports both internal oscillator (256kHz) or external (256kHz). With
* 1/2, 1/3 bias and 1/2, 1/3, 1/4 duty cycle is suitable for many general purpose LCD applications.
*
* \section sec_dispmem Display memory
* The RAM is organized into an array of 32 cells of 4 bits each as illustrated by Figure 1.
* The content of the RAM is directly mapped to the content of the LCD driver and may be affected by the
* commands \c READ, \c WRITE, \c READ-MODIFY-WRITE.
*
* \image latex HT1621mem.png "Figure 1. Memory structure of the HT1621. Remark that we have restructure the adresses so to be able to take care of a full digit."
* \image html HT1621mem.png "Figure 1. Memory structure of the HT1621. Remark that we have restructure the adresses so to be able to take care of a full digit."
*
* \section sec_osc System oscillator
* The system clock is used in a variety of tasks included LCD driving clock and tone frequency generation.
* HT1621 has a built-in RC oscillator (256kHZ) and a crystal oscillator (32768Hz). An external 256KHz
* oscillator can also be used. The type of oscillator used can be selecting by issuing \c XTAL32K,
* \c RC256K or \c EXT256K commands.
*
* Issuing a \c SYS_DIS command stops the system clock, the LCD bias generator and the time base/WDT.
* The LCD screen will appear blank.
*
* An \c LCD_OFF command will turn off the bias generator but not the system clock. Issuing a
* \c SYS_DIS command will power down the system reducing power consumption.
*
* \warning The \c SYS_DIS command affects the system only when the internal RC 256kHZ or the
* 32.768kHz crystal clocks are used.
*
* \section sec_tone Tone output
* The HT1621 can provide a tone output at the pins \c BZ and \c \f$\bar{BZ}\f$. There are only two tone
* frequencies, namely: 2kHz and 4kHz that can be selected using the \c TONE2K or \c TONE4K, respectively.
* Then, the buzzer (if connected to \c BZ and \c \f$\bar{BZ}\f$) start playing at the
* \c TONE_ON command. Sound is stopped issuing the \c TONE_OFF command.
*
* \section sec_powon Power-on
* At power-on the system is in \c SYS_DIS state. A generic LCD initialization sequence will consist of the following steps:
* - System Enable
* - Oscillator configuration
* - Bias/com configuration
* - Bias generator start (LCD_ON)
*
* \section sec_history History
* \subsection subsec_v1_0 Version 1.0
* This the first public version.
*
* \section sec_todo Todo list
* - Improve the overall documentation.
* - Optimize delays in both writing and reading functions
* - Overload \c HT1621::sendCommand() function to send several commands in a row
* - Test reading functions which use the internal RAM of HT1621 not the simulated RAM.
*/
/**
* \file HT1621.h
* \brief A class for dealing with the Holtek HT1621 chip.
* \author Enrico Formenti
* \date 31 january 2015
* \version 1.0
* \copyright BSD license, check the License page on the blog for more information. All this text must be
* included in any redistribution.
* <br><br>
* See macduino.blogspot.com for more details.
*
*/
#ifndef _HT1621_h
#define _HT1621_h
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#define TAKE_CS() digitalWrite(_CS_pin, LOW)
#define RELEASE_CS() digitalWrite(_CS_pin, HIGH)
// Uncomment the line below if you can read from the HT1621 directly
// #define __HT1621_READ
#define DECIMAL B00000001
/*
* a
* -
* f | | b
* - <-g
* e | | c
* - . <-h
* d
*
* f g e d a b c h
* 1 1 1 1 1 1 1 1 (all on)
*
*
*/
const word charMap[] = {
B10111110, //0
B00000110, //1
B01111100, //2
B01011110, //3
B11000110, //4
B11011010, //5
B11110010, //6
B00001110, //7
B11111110, //8
B11001110, //9
B00000001, //10 '.'
B01000000, //11 '-'
B11001100, //12 'deg' (top o)
B01110010, //13 'c'
};
byte setDigits( long number, byte *d, byte len );
class HT1621 {
private:
uint8_t _CS_pin;
uint8_t _DATA_pin;
uint8_t _RW_pin;
protected:
#ifndef __HT1621_READ
/**
* \var ram[16]
* This array is used to simulate the HT1621 internal ram whenever the read operations are not possible.
* \warning Define the label __HT1621 to disable this feature and use standard read procedures.
*/
uint8_t ram[16];
#endif
public:
/*!
* \enum Modes
* Operating modes for the HT1621.
*/
enum Modes : uint8_t {
COMMAND_MODE = 0b10000000, /*!< This is used for sending standard commands. */
READ_MODE = 0b11000000, /*!< This instructs the HT1621 to prepare for reading the internal RAM. */
WRITE_MODE = 0b10100000, /*!< This instructs the HT1621 to prepare for writing the internal RAM. */
READ_MODIFY_WRITE_MODE = 0b10100000, /*!< This instructs the HT1621 to prepare for reading/modifying batch of internal RAM adresses. */
SPECIAL_MODE = 0b10010000 /*!< This instructs the HT1621 to prepare for executing a special command. */
};
/*!
* \enum Commands
*
* This is an enum of available commands for the HT1621.
*
*/
enum Commands : uint8_t {
SYS_DIS = 0b00000000, /*!< System disable. It stops the bias generator and the system oscillator. */
SYS_EN = 0b00000010, /*!< System enable. It starts the bias generator and the system oscillator. */
LCD_OFF = 0b00000100, /*!< Turn off the bias generator. */
LCD_ON = 0b00000110, /*!< Turn on the bias generator. */
TIMER_DIS = 0b00001000, /*!< Disable time base output. */
WDT_DIS = 0b00001010, /*!< Watch-dog timer disable. */
TIMER_EN = 0b00001100, /*!< Enable time base output. */
WDT_EN = 0b00001110, /*!< Watch-dog timer enable. The timer is reset. */
CLR_TIMER = 0b00011000, /*!< Clear the contents of the time base generator. */
CLR_WDT = 0b00011100, /*!< Clear the contents of the watch-dog stage. */
TONE_OFF = 0b00010000, /*!< Stop emitting the tone signal at the tone pin. \sa TONE2K, TONE4K */
TONE_ON = 0b00010010, /*!< Start emitting tone signal at the tone pin. Tone frequency is selected using commands TONE2K or TONE4K. \sa TONE2K, TONE4K */
TONE2K = 0b11000000, /*!< Output tone is at 2kHz. */
TONE4K = 0b10000000, /*!< Output tone is at 4kHz. */
RC256K = 0b00110000, /*!< System oscillator is the internal RC oscillator at 256kHz. */
XTAL32K = 0b00101000, /*!< System oscillator is the crystal oscillator at 32768Hz. */
EXT256K = 0b00111000, /*!< System oscillator is an external oscillator at 256kHz. */
//Set bias to 1/2 or 1/3 cycle
//Set to 2,3 or 4 connected COM lines
BIAS_HALF_2_COM = 0b01000000, /*!< Use 1/2 bias and 2 commons. */
BIAS_HALF_3_COM = 0b01001000, /*!< Use 1/2 bias and 3 commons. */
BIAS_HALF_4_COM = 0b01010000, /*!< Use 1/2 bias and 4 commons. */
BIAS_THIRD_2_COM = 0b01000010, /*!< Use 1/3 bias and 2 commons. */
BIAS_THIRD_3_COM = 0b01001010, /*!< Use 1/3 bias and 3 commons. */
BIAS_THIRD_4_COM = 0b01010010, /*!< Use 1/3 bias and 4 commons. */
IRQ_EN = 0b00010000, /*!< Enables IRQ output. This needs to be excuted in SPECIAL_MODE. */
IRQ_DIS = 0b00010000, /*!< Disables IRQ output. This needs to be excuted in SPECIAL_MODE. */
// WDT configuration commands
F1 = 0b01000000, /*!< Time base/WDT clock. Output = 1Hz. Time-out = 4s. This needs to be excuted in SPECIAL_MODE. */
F2 = 0b01000010, /*!< Time base/WDT clock. Output = 2Hz. Time-out = 2s. This needs to be excuted in SPECIAL_MODE. */
F4 = 0b01000100, /*!< Time base/WDT clock. Output = 4Hz. Time-out = 1s. This needs to be excuted in SPECIAL_MODE. */
F8 = 0b01000110, /*!< Time base/WDT clock. Output = 8Hz. Time-out = .5s. This needs to be excuted in SPECIAL_MODE. */
F16 = 0b01001000, /*!< Time base/WDT clock. Output = 16Hz. Time-out = .25s. This needs to be excuted in SPECIAL_MODE. */
F32 = 0b01001010, /*!< Time base/WDT clock. Output = 32Hz. Time-out = .125s. This needs to be excuted in SPECIAL_MODE. */
F64 = 0b01001100, /*!< Time base/WDT clock. Output = 64Hz. Time-out = .0625s. This needs to be excuted in SPECIAL_MODE. */
F128 = 0b01001110, /*!< Time base/WDT clock. Output = 128Hz. Time-out = .03125s. This needs to be excuted in SPECIAL_MODE. */
//Don't use
TEST_ON = 0b11000000, /*!< Don't use! Only for manifacturers. This needs SPECIAL_MODE. */
TEST_OFF = 0b11000110 /*!< Don't use! Only for manifacturers. This needs SPECIAL_MODE. */
};
/**
* \fn HT1621(uint8_t CSpin, uint8_t RWpin, uint8_t DATApin)
* \brief Constructor. Use begin() to complete the initialization of the chip.
* @param \c CSpin Channel select pin.
* @param \c RWpin Read/Write signal pin
* @param \c DATApin Data pin both for reading or writing data.
*/
HT1621(uint8_t CSpin, uint8_t RWpin, uint8_t DATApin) : _CS_pin(CSpin), _DATA_pin(DATApin), _RW_pin(RWpin) {};
/**
* \fn void begin(void)
* \brief Init the HT1621. It inits the control bus. Moreover, it clears the (simulated) ram if \c __HT1621_READ is defined.
*/
void begin(void);
/**
* \fn void writeBits(uint8_t data, uint8_t cnt)
* \brief Send bits to the HT1621.
* @param data Data to be sent to the HT1621 seen as an array of bits.
* @param cnt Number of bits to send to the HT1621.
* \warning In order to allow series of data to be sent CS is not taken by this function, so several writes can be issued in a row. You need to control CS by your own.
* \warning There is no check on the size of cnt. Hence avoid ask to send more than 7 bits per time.
* \sa readBits()
*/
void writeBits(uint8_t data, uint8_t cnt);
/**
* \fn uint8_t readBits(uint8_t cnt)
* \brief Reads bits from the HT1621.
* @param cnt Number of bits to read. Maximal number of bits that can be read is 8.
* \return uint8_t A byte containing the bits read. Last bit is the leftmost one.
* \warning There is no check if too much bits are read. 0nly the last batch of 8 will be sent back.
* \sa writeBits()
*/
uint8_t readBits(uint8_t cnt);
/**
* \fn void sendCommand(uint8_t cmd, bool first = true, bool last = true)
* \brief Sends a command to the HT1621.
* @param cmd Id of the command to send.
* @param first If true CS is taken.
* @param last If true CS is relased.
* \warning There is no check on the command id.
*/
void sendCommand(uint8_t cmd, bool first = true, bool last = true);
/**
* \fn void write(uint8_t address, uint8_t data)
* \brief Write \c data at the given address.
* @param address Address to which write the data. Max address is 128.
* @param data Data to be written. Remark that only the 4 less significative bits are used.
* \warning There is no check to verify if the address is valid.
*/
void write(uint8_t address, uint8_t data);
/**
* \fn void write(uint8_t address, uint8_t data, uint8_t cnt)
* \brief Write \c data at the given address and at the \c cnt successive addresses.
* @param address Address to which write the data. Max address is 128.
* @param data Data to be written. Remark that only the 4 less significative bits are used.
* @param cnt Number of times that \c data has to be written
* \warning There is no check to verify if the address is valid. Moreover, pay attention that
* the address \c (address+cnt) has also to be valid.
*/
void write(uint8_t address, uint8_t data, uint8_t cnt);
/**
* \fn void write(uint8_t address, uint8_t *data, uint8_t cnt)
* \brief Write \c cnt bytes starting at \c address and take data from buffer \c data.
* @param address Address to which start writing data. Max address is 128.
* @param data Buffer to be written.
* @param cnt Length of the buffer.
* \warning The buffer is byte aligned, so it is not very efficient. Indeed, only the 4 less significant
* bits are written.
* \warning There is no check that the buffer is of suitable length.
*/
void write(uint8_t address, uint8_t *data, uint8_t cnt);
/**
* \fn read(uint8_t address)
* \brief Read memory content at address \c address
* @param address Memory address to read from.
* \return uint8_t A byte contained the date read.
* \warning There is no check to verify if the address is valid.
*/
uint8_t read(uint8_t address);
/**
* \fn void read(uint8_t address, uint8_t *data, uint8_t cnt)
* \brief Read \c cnt bytes starting from \c address into buffer \c data.
* @param address Memory address to read from.
* @param *data Buffer in which to store data read.
* @param cnt Number of bytes to read.
* \warning There is no check to verify if the address is valid.
* \warning There is no check that the buffer is of suitable length.
*/
void read(uint8_t address, uint8_t *data, uint8_t cnt);
/*
* write bytes
*/
void writeChar(uint8_t address, uint8_t c, bool decimal = false);
void printNumber(long number, int places, int dec = 0, bool flushdisplay = true);
void printFloat(double number, int places, int decimalplaces = 2, bool flushdisplay = true);
void clear(int places = 16);
void flush();
};
#endif