Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSD1608 Custom Lookup table #160

Open
lbarnard86 opened this issue Mar 17, 2023 · 2 comments
Open

SSD1608 Custom Lookup table #160

lbarnard86 opened this issue Mar 17, 2023 · 2 comments

Comments

@lbarnard86
Copy link

It would seem that it's not possible to create custom luts for the new SSD1608 display variant. It's not possible to even get the red display to register as a black and white display as Pimoroni's own website indicates.

Does this problem require dev intervention or am I missing something when it comes to creating custom luts for quicker redraw rates?

@iso2013
Copy link

iso2013 commented Apr 29, 2023

I'm wondering this too - I bought the wHAT display under the impression that it could be updated monochromatically as the website states, but I haven't had any luck in getting that to actually happen.

@Gadgetoid
Copy link
Member

I believe the text on the website is a holdout from an older version of wHAT that used the original (old pHAT notwithstanding) driver. New wHAT uses the SSD1683 (not SSD1608) . This has a "luts" table defined in code as a holdout from SSD1608 but it does not attempt to write them to the display.

That said the display datasheet seems to suggest a Black/White mode is possible, though from some experimentation I can't seem to get it to actually trigger. Red can be omitted by setting the DISP_CTRL1 register to 0x40, 0x00, which - when combined with some changes elsewhere- turns it into a black/white display. But it seems to take the same amount of time to update.

Writing to the "temperature" register to tell the display that it's warmer than it is doesn't seem to get much speed advantage, either.

Looks like it would involve dumping the existing LUTs and hacking them manually to get any faster, but from experience that's a great way to destroy a display (or a few dozen).

For posterity, here's what I tried:

diff --git a/inky/inky_ssd1683.py b/inky/inky_ssd1683.py
index f299be1..ea4e6ce 100644
--- a/inky/inky_ssd1683.py
+++ b/inky/inky_ssd1683.py
@@ -88,6 +88,7 @@ class Inky:
         self.cs_pin = cs_pin
         self.h_flip = h_flip
         self.v_flip = v_flip
+        self.fast_mode = True
 
         self._gpio = gpio
         self._gpio_setup = False
@@ -199,11 +200,21 @@ class Inky:
         self._send_command(ssd1683.SET_RAMXCOUNT, [0x00])
         self._send_command(ssd1683.SET_RAMYCOUNT, [0x00, 0x00])
 
-        for data in ((ssd1683.WRITE_RAM, buf_a), (ssd1683.WRITE_ALTRAM, buf_b)):
-            cmd, buf = data
-            self._send_command(cmd, buf)
+        if self.fast_mode:
+            # buf_a and buf_b should both be the same in fast mode
+            self._send_command(ssd1683.WRITE_RAM, buf_a)
+        else:
+            for data in ((ssd1683.WRITE_RAM, buf_a), (ssd1683.WRITE_ALTRAM, buf_b)):
+                cmd, buf = data
+                self._send_command(cmd, buf)
 
         self._busy_wait()
+
+        if self.fast_mode:
+            self._send_command(ssd1683.DISP_CTRL1, [0x40, 0x00])  # Skip updating the red
+            self._send_command(ssd1683.TEMP_WRITE, 0x7F)    # Tell the display it's really warm so it uses faster LUTs
+            self._send_command(ssd1683.DISP_CTRL2, [0xD4])  # Datasheet says 0xFF is POR but only 0xF7/0xD4/0xD7 work??
+
         self._send_command(ssd1683.MASTER_ACTIVATE)
 
     def set_pixel(self, x, y, v):
@@ -234,10 +245,13 @@ class Inky:
         if self.rotation:
             region = numpy.rot90(region, self.rotation // 90)
 
-        buf_a = numpy.packbits(numpy.where(region == BLACK, 0, 1)).tolist()
-        buf_b = numpy.packbits(numpy.where(region == RED, 1, 0)).tolist()
+        if self.fast_mode:
+            buf_b = buf_a = numpy.packbits(numpy.where(region != WHITE, 0, 1))
+        else:
+            buf_a = numpy.packbits(numpy.where(region == BLACK, 0, 1))
+            buf_b = numpy.packbits(numpy.where(region == RED, 1, 0))
 
-        self._update(buf_a, buf_b, busy_wait=busy_wait)
+        self._update(buf_a.tolist(), buf_b.tolist(), busy_wait=busy_wait)
 
     def set_border(self, colour):
         """Set the border colour."""
diff --git a/inky/ssd1683.py b/inky/ssd1683.py
index a48ea60..9aaa04f 100644
--- a/inky/ssd1683.py
+++ b/inky/ssd1683.py
@@ -24,6 +24,7 @@ VCOM_DURATION = 0x2C
 WRITE_VCOM = 0x2C
 READ_OTP = 0x2D
 WRITE_LUT = 0x32
+WRITE_DISPLAY_OPTION = 0x37
 WRITE_DUMMY = 0x3A
 WRITE_GATELINE = 0x3B
 WRITE_BORDER = 0x3C

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants