62 enum class Dimensions {
DIM_8x1,
DIM_8x2,
DIM_8x4,
DIM_16x1_1,
DIM_16x1_2,
DIM_16x2,
DIM_16x4,
DIM_20x1,
DIM_20x2,
DIM_20x4,
DIM_24x1,
DIM_24x2,
DIM_40x1,
DIM_40x2,
80 #define HD44780_ERRORS_LIMIT 16
82 #define HD44780_ERRORS_BASE 48
108 uint8_t ddramCharRowBreak;
110 uint8_t ddramLineEnd;
122 static const uint8_t CLEAR = BIT_0;
123 static const uint8_t RET_HOME = BIT_1;
124 static const uint8_t ENTRY_MODE_SET = BIT_2;
125 static const uint8_t DISPLAY_CTRL = BIT_3;
126 static const uint8_t SHIFT = BIT_4;
127 static const uint8_t FUNCTION_SET = BIT_5;
128 static const uint8_t SET_CGRAM_ADDR = BIT_6;
129 static const uint8_t SET_DDRAM_ADDR = BIT_7;
136 static const uint8_t SHIFT_INC = BIT_1;
137 static const uint8_t SHIFT_EN = BIT_0;
144 static const uint8_t DISPLAY_PWR = BIT_2;
145 static const uint8_t CURSOR = BIT_1;
146 static const uint8_t BLINK = BIT_0;
153 static const uint8_t SHIFT_DISPLAY = BIT_3;
154 static const uint8_t SHIFT_RIGHT = BIT_2;
191 : m_dataPort(lsbDataPin, static_cast<uint8_t>(bitMode),
Port::Dir::OUT),
192 m_rs(rs,
Pin::Dir::OUT),
193 m_rw(rw,
Pin::Dir::OUT),
194 m_en(en,
Pin::Dir::OUT),
196 m_dimensions(dimensions) {
197 this->m_curPos.row = 0;
198 this->m_curPos.col = 0;
206 this->generate_mem_map();
230 this->m_dataPort.
write(arg);
241 this->m_dataPort.
write(0x2);
246 arg = PropWare::HD44780::FUNCTION_SET;
254 arg = PropWare::HD44780::SHIFT;
258 arg = PropWare::HD44780::DISPLAY_CTRL
259 | PropWare::HD44780::DISPLAY_PWR;
263 arg = PropWare::HD44780::ENTRY_MODE_SET
264 | PropWare::HD44780::SHIFT_INC;
274 this->
cmd(PropWare::HD44780::CLEAR);
275 this->m_curPos.row = 0;
276 this->m_curPos.col = 0;
286 void move (
const uint8_t row,
const uint8_t col) {
287 uint8_t ddramLine, addr = 0;
291 if (this->m_memMap.ddramCharRowBreak > this->m_memMap.ddramLineEnd) {
292 ddramLine = col / this->m_memMap.ddramLineEnd;
295 addr |= col % this->m_memMap.ddramLineEnd;
296 }
else if (4 == this->m_memMap.charRows) {
301 addr += this->m_memMap.ddramCharRowBreak;
302 addr += col % this->m_memMap.ddramCharRowBreak;
310 this->
cmd(addr | PropWare::HD44780::SET_DDRAM_ADDR);
311 this->m_curPos.row = row;
312 this->m_curPos.col = col;
315 void puts (
const char string[]) {
316 const char *s = (
char *)
string;
327 this->m_curPos.row++;
328 if (this->m_curPos.row == this->m_memMap.charRows)
329 this->m_curPos.row = 0;
330 this->m_curPos.col = 0;
331 this->
move(this->m_curPos.row, this->m_curPos.col);
332 }
else if (
'\t' == c) {
336 }
else if (
'\r' == c)
337 this->
move(this->m_curPos.row, 0);
342 this->write((
const uint8_t) c);
345 ++this->m_curPos.col;
346 if (this->m_memMap.charColumns == this->m_curPos.col)
351 if (this->m_memMap.ddramCharRowBreak
352 > this->m_memMap.ddramLineEnd)
353 this->
move(this->m_curPos.row, this->m_curPos.col);
362 void cmd (
const uint8_t command)
const {
365 this->write(command);
369 static const char str[] =
"HD44780 Error ";
374 printer <<
"invalid control signal\n";
377 printer <<
"invalid LCD dimension; please choose from the HD44780::Dimensions type\n";
380 printer <<
"unknown error code\n";
394 void write (
const uint8_t val)
const {
400 this->m_dataPort.
write(val >> 4);
404 this->m_dataPort.
write(val);
408 this->m_dataPort.
write(val);
416 void clock_pulse (
void)
const {
425 void generate_mem_map () {
427 switch (this->m_dimensions) {
429 this->m_memMap.charRows = 1;
430 this->m_memMap.charColumns = 8;
431 this->m_memMap.ddramCharRowBreak = 8;
432 this->m_memMap.ddramLineEnd = 8;
435 this->m_memMap.charRows = 2;
436 this->m_memMap.charColumns = 8;
437 this->m_memMap.ddramCharRowBreak = 8;
438 this->m_memMap.ddramLineEnd = 8;
441 this->m_memMap.charRows = 4;
442 this->m_memMap.charColumns = 8;
443 this->m_memMap.ddramCharRowBreak = 8;
444 this->m_memMap.ddramLineEnd = 16;
447 this->m_memMap.charRows = 1;
448 this->m_memMap.charColumns = 16;
449 this->m_memMap.ddramCharRowBreak = 8;
450 this->m_memMap.ddramLineEnd = 8;
453 this->m_memMap.charRows = 1;
454 this->m_memMap.charColumns = 16;
455 this->m_memMap.ddramCharRowBreak = 16;
456 this->m_memMap.ddramLineEnd = 16;
459 this->m_memMap.charRows = 2;
460 this->m_memMap.charColumns = 16;
461 this->m_memMap.ddramCharRowBreak = 16;
462 this->m_memMap.ddramLineEnd = 16;
465 this->m_memMap.charRows = 4;
466 this->m_memMap.charColumns = 16;
467 this->m_memMap.ddramCharRowBreak = 16;
468 this->m_memMap.ddramLineEnd = 32;
471 this->m_memMap.charRows = 1;
472 this->m_memMap.charColumns = 20;
473 this->m_memMap.ddramCharRowBreak = 20;
474 this->m_memMap.ddramLineEnd = 20;
477 this->m_memMap.charRows = 2;
478 this->m_memMap.charColumns = 20;
479 this->m_memMap.ddramCharRowBreak = 20;
480 this->m_memMap.ddramLineEnd = 20;
483 this->m_memMap.charRows = 4;
484 this->m_memMap.charColumns = 20;
485 this->m_memMap.ddramCharRowBreak = 20;
486 this->m_memMap.ddramLineEnd = 40;
489 this->m_memMap.charRows = 1;
490 this->m_memMap.charColumns = 24;
491 this->m_memMap.ddramCharRowBreak = 24;
492 this->m_memMap.ddramLineEnd = 24;
495 this->m_memMap.charRows = 2;
496 this->m_memMap.charColumns = 24;
497 this->m_memMap.ddramCharRowBreak = 24;
498 this->m_memMap.ddramLineEnd = 24;
501 this->m_memMap.charRows = 1;
502 this->m_memMap.charColumns = 40;
503 this->m_memMap.ddramCharRowBreak = 40;
504 this->m_memMap.ddramLineEnd = 40;
507 this->m_memMap.charRows = 2;
508 this->m_memMap.charColumns = 40;
509 this->m_memMap.ddramCharRowBreak = 40;
510 this->m_memMap.ddramLineEnd = 40;
522 HD44780::MemMap m_memMap;
525 const SimplePort m_dataPort;