diff --git a/lib/cube/sh1106.py b/lib/cube/sh1106.py index 1945dac00f1c0bb257fed5d8e667c3911599b870..7bd091720a460421868963d4dc692167e134cbe2 100644 --- a/lib/cube/sh1106.py +++ b/lib/cube/sh1106.py @@ -30,10 +30,17 @@ from micropython import const +import machine +import rp2 from math import sin, cos import utime as time import framebuf +_WRITE_SIZE = const(135) +_I2C1_BASE = const(0x40048000) +_IC_TAR = const(_I2C1_BASE + 0x04) # Offset 0x04 +_IC_ENABLE = const(_I2C1_BASE + 0x6C) # _IC_ENABLE register address +DMA = False # Register definitions _SET_CONTRAST = const(0x81) @@ -69,6 +76,8 @@ class SH1106(framebuf.FrameBuffer): self.bufsize = self.pages * self.width self.renderbuf = bytearray(self.bufsize) self.pages_to_update = 0 + + self.init_memoryview() if self.rotate90: self.displaybuf = bytearray(self.bufsize) @@ -94,10 +103,22 @@ class SH1106(framebuf.FrameBuffer): self.pry = 0 self.data_points = 0 #no of data points in continuous chart + def init_memoryview(self): + buffer = bytearray(_WRITE_SIZE*2) + self.disp_send_memoryview = memoryview(buffer) + self.disp_send_memoryview[1] = 0x04 + self.disp_send_memoryview[_WRITE_SIZE*2-1] =0x02 + self.disp_send_memoryview[0] = 0x80 + # self.disp_send_memoryview[2] page address + self.disp_send_memoryview[4] = 0x80 + self.disp_send_memoryview[6] = 0x02 + self.disp_send_memoryview[8] = 0x80 + self.disp_send_memoryview[10] = 0x10 + self.disp_send_memoryview[12] = 0x40 + def init_display(self): self.reset() - self.fill(0) - self.show() + self.fill(1) self.poweron() # rotate90 requires a call to flip() for setting up. self.flip(self.flip_en) @@ -140,13 +161,9 @@ class SH1106(framebuf.FrameBuffer): pages_to_update = (1 << self.pages) - 1 else: pages_to_update = self.pages_to_update - #print("Updating pages: {:08b}".format(pages_to_update)) for page in range(self.pages): if (pages_to_update & (1 << page)): - self.write_cmd(_SET_PAGE_ADDRESS | page) - self.write_cmd(_LOW_COLUMN_ADDRESS | 2) - self.write_cmd(_HIGH_COLUMN_ADDRESS | 0) - self.write_data(db[(w*page):(w*page+w)]) + self.write_at_once(page, db[(w*page):(w*page+w)]) self.pages_to_update = 0 def register_updates(self, y0, y1=None): @@ -524,6 +541,14 @@ class SH1106_I2C(SH1106): self.temp = bytearray(2) if res is not None: res.init(res.OUT, value=1) + self.dma = rp2.DMA() + self.dma_config = self.dma.pack_ctrl(size=0, inc_write=False) + self.dma_buffer = bytearray(1) + self.dma_ctrl = self.dma.pack_ctrl( + size=1, + inc_read=True, + inc_write=False, + treq_sel=34) super().__init__(width, height, external_vcc, rotate) def write_cmd(self, cmd): @@ -536,6 +561,21 @@ class SH1106_I2C(SH1106): with self.i2c_lock: self.i2c.writeto(self.addr, b'\x40'+buf) + def write_at_once(self, page, buf): + with self.i2c_lock: + if DMA: + self.disp_send_memoryview[2] = (_SET_PAGE_ADDRESS | page) + for i in range(len(buf)): + self.disp_send_memoryview[14+i*2] = buf[i] + machine.mem32[_IC_ENABLE] = 0 # Disable I2C0 + machine.mem32[_IC_TAR] = self.addr + machine.mem32[_IC_ENABLE] = 1 # Disable I2C0 + self.dma.config(read=self.disp_send_memoryview,write=self.i2c ,count=_WRITE_SIZE,ctrl=self.dma_ctrl,trigger=True) + while self.dma.active(): + continue + else: + self.i2c.writeto(self.addr, b'\x80'+(_SET_PAGE_ADDRESS | page).to_bytes(1, 'little')+b'\x80\x02'+b'\x80\x10'+b'\x40'+buf) + def reset(self): super().reset(self.res)