summaryrefslogtreecommitdiff
path: root/src/driver/pervasive_aurora_mb.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/driver/pervasive_aurora_mb.cc')
-rw-r--r--src/driver/pervasive_aurora_mb.cc126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/driver/pervasive_aurora_mb.cc b/src/driver/pervasive_aurora_mb.cc
new file mode 100644
index 0000000..c244a72
--- /dev/null
+++ b/src/driver/pervasive_aurora_mb.cc
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2021 Daniel Friesel
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Driver for Pervasive Aurora Mb E-Paper displays with internal Timing
+ * Controller (iTC). Configured for the 300x400px 4.2" variant.
+ */
+#include "driver/pervasive_aurora_mb.h"
+#include "driver/spi.h"
+#include "driver/gpio.h"
+#include "arch.h"
+
+void PervasiveAuroraMb::setup()
+{
+ gpio.output(PERVASIVE_AURORA_RESET_PIN, 0);
+ gpio.output(PERVASIVE_AURORA_CS_PIN, 0);
+ gpio.output(PERVASIVE_AURORA_DC_PIN, 0);
+ gpio.output(PERVASIVE_AURORA_VCC_PIN, 0);
+ gpio.input(PERVASIVE_AURORA_BUSY_PIN);
+}
+
+void PervasiveAuroraMb::powerOn()
+{
+ gpio.write(PERVASIVE_AURORA_VCC_PIN, 1);
+ arch.delay_ms(5);
+ gpio.write(PERVASIVE_AURORA_RESET_PIN, 1);
+ arch.delay_ms(1);
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 1);
+}
+
+void PervasiveAuroraMb::initialize(signed char temperature)
+{
+ // "Input Temperature"
+ spiWrite(0xe5, (const unsigned char*)&temperature, 1);
+
+ // "Active Temperature"
+ spiWrite(0xe0, (const unsigned char[]){0x02}, 1);
+
+ // "Panel Settings"
+ spiWrite(0x00, (const unsigned char[]){0x0f}, 1);
+
+ // "Panel Settings"
+ spiWrite(0x00, (const unsigned char[]){0x0f}, 1);
+
+ // "Booster soft start settings"
+ spiWrite(0x06, (const unsigned char[]){0x17, 0x17, 0x27}, 3);
+
+ // "Resolution settings": 300 x 400 -> 0x12c x 0x190
+ spiWrite(0x61, (const unsigned char[]){0x01, 0x90, 0x01, 0x2c}, 4);
+
+ // "Vcom and data interval setting"
+ spiWrite(0x50, (const unsigned char[]){0x87}, 1);
+
+ // "Power Saving"
+ spiWrite(0xe3, (const unsigned char[]){0x88}, 1);
+}
+
+void PervasiveAuroraMb::sendImage(unsigned char *frame)
+{
+ unsigned char null_int[2] = {0x00, 0x00};
+ spiWrite(0x10, 0, 0);
+
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 0);
+ spi.xmit(300*(400/8), frame, 0, frame);
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 1);
+
+ /*
+ * Second Pass: All zeroes (-> update entire display).
+ * A 1 bit indicates that the corresponding pixel should be skipped.
+ */
+ spiWrite(0x13, 0, 0);
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 0);
+ for (unsigned int i = 0; i < 300*(400/16); i++) {
+ spi.xmit(2, null_int, 0, frame);
+ }
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 1);
+}
+
+void PervasiveAuroraMb::sendUpdate()
+{
+ while (isBusy()) ;
+
+ spiWrite(0x04, 0, 0);
+
+ while (isBusy()) ;
+
+ spiWrite(0x12, 0, 0);
+
+ while (isBusy()) ;
+}
+
+void PervasiveAuroraMb::powerOff()
+{
+ spiWrite(0x02, 0, 0);
+ while (isBusy()) ;
+ gpio.output(PERVASIVE_AURORA_RESET_PIN, 0);
+ gpio.output(PERVASIVE_AURORA_CS_PIN, 0);
+ gpio.output(PERVASIVE_AURORA_DC_PIN, 0);
+ gpio.output(PERVASIVE_AURORA_VCC_PIN, 0);
+}
+
+bool PervasiveAuroraMb::isBusy()
+{
+ return !gpio.read(PERVASIVE_AURORA_BUSY_PIN);
+}
+
+void PervasiveAuroraMb::spiWrite(unsigned char reg, const unsigned char *txbuf, unsigned int length)
+{
+ gpio.write(PERVASIVE_AURORA_DC_PIN, 0);
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 0);
+
+ spi.xmit(1, &reg, 0, 0);
+
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 1);
+ gpio.write(PERVASIVE_AURORA_DC_PIN, 1);
+
+ if (length) {
+ arch.delay_us(1);
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 0);
+ spi.xmit(length, (unsigned char*)txbuf, 0, 0);
+ gpio.write(PERVASIVE_AURORA_CS_PIN, 1);
+ }
+}
+
+PervasiveAuroraMb pervasiveAuroraMb;