Displaytronic (Xiamen Zettler)'s I2C text LCD driver

Dependents:   IsuProject_LPC1768 robottt

Revision:
0:f81621685b23
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ACM1602.cpp	Wed Mar 19 01:08:18 2014 +0000
@@ -0,0 +1,115 @@
+// ==================================================== Mar 19 2014, kayeks ==
+// ACM1602.cpp
+// ===========================================================================
+// Displaytronic (Xiamen Zettler)'s I2C text LCD driver
+
+#include <stdlib.h>
+#include "mbed.h"
+#include "ACM1602.h"
+
+/** Constructor of class ACM1602. */
+ACM1602::ACM1602(PinName sda, PinName scl, uint8_t address)
+:
+    i2c(sda, scl)
+{
+    i2c.frequency(100000);
+    this->address = address & 0xfe;
+}
+
+/** Initialize LCD. */
+void ACM1602::init() {
+    cls();
+    command(0x38);  // 8-bit mode, double-line
+    command(0x0c);  // Display on, cursor off
+    command(0x06);  // Enable DDRAM address increment
+}
+
+/** Clear display and reset DDRAM address. */
+void ACM1602::cls() {
+    command(0x01);
+    wait(0.01);
+    memset(lineBuffer[0], ' ', 16);
+    memset(lineBuffer[1], ' ', 16);
+    this->col = 0;
+    this->row = 0;
+}
+
+/** Locate the cursor position. */
+void ACM1602::locate(int col, int row) {
+    if (col < 0 || col > 15 || row < 0 || row > 1) {
+        return;
+    }
+    command(0x80 | (row << 6) | col);
+    this->col = col;
+    this->row = row;
+}
+
+/** Implementation of putc from Stream class. */
+int ACM1602::_putc(int c) {
+    switch (c) {
+    case '\r':
+        this->col = 0;
+        locate(this->col, this->row);
+        break;
+    case '\n':
+        if (this->row == 1) {
+            shiftUp();
+        } else {
+            locate(this->col, ++this->row);
+        }
+        break;
+    default:
+        if (this->col > 15) {
+            shiftUp();
+            this->col = 0;
+            this->row = 1;
+            locate(this->col, this->row);
+        }
+        data(c);
+        lineBuffer[this->row][this->col] = c;
+        this->col++;
+        break;
+    }
+    return 0;
+}
+
+/** Implementation of getc from Stream class. */
+int ACM1602::_getc() {
+    return EOF;
+}
+
+/** Shift up the lower line for scroll. */
+void ACM1602::shiftUp() {
+    memcpy(lineBuffer[0], lineBuffer[1], 16);
+    memset(lineBuffer[1], ' ', 16);
+    
+    locate(0, 0);
+    for (uint8_t i = 0; i < 16; i++) {
+        data(lineBuffer[0][i]);
+    }
+    locate(0, 1);
+    for (uint8_t i = 0; i < 16; i++) {
+        data(' ');
+    }
+    locate(0, 1);
+}
+
+/** Send a command byte to LCD. */
+void ACM1602::command(uint8_t b) {
+    wait_us(25); i2c.start();
+    wait_us(25); i2c.write(this->address);
+    wait_us(25); i2c.write(0x00);
+    wait_us(25); i2c.write(b);
+    wait_us(25); i2c.stop();
+    wait_us(40);
+}
+
+/** Send a data byte to LCD. */
+void ACM1602::data(uint8_t b) {
+    wait_us(25); i2c.start();
+    wait_us(25); i2c.write(this->address);
+    wait_us(25); i2c.write(0x80);
+    wait_us(25); i2c.write(b);
+    wait_us(25); i2c.stop();
+    wait_us(40);
+}