From f6d399ec08e90d328d617e248293f6280f0d7a6d Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 15 Jun 2023 18:34:20 +0200 Subject: [PATCH] ili9341: st7789: fix SetScrollArea The existing code was broken in a few ways: - It didn't use the correct operator precedence for the VSCRDEF VSA variable: it needed some extra parentheses to be correct. - It used the configured height instead of the actual display height for calculating VSA, which is incorrect. TFA+VSA+BFA must always be exactly 320, even if a lower value is configured. - If a lower than 320 pixel height is configured, the bottomFixedArea parameter applied to the whole 320 pixel screen height. Because this seems counter intuitive (and relies on properties of any given screen), I've changed it to work from the actual visible bottom of the screen (which may be smaller than 320 pixels). TODO: this doesn't take RowOffset into account, while it probably should. I haven't fixed the st7735 implementation, because I didn't have example code on hand that would easily work on a st7735 screen. This is left as a TODO for the future. --- ili9341/ili9341.go | 10 ++++++++-- st7735/st7735.go | 2 ++ st7789/st7789.go | 9 ++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ili9341/ili9341.go b/ili9341/ili9341.go index 4b8f133..421b3d2 100644 --- a/ili9341/ili9341.go +++ b/ili9341/ili9341.go @@ -320,10 +320,16 @@ func (d *Device) SetRotation(rotation drivers.Rotation) error { // SetScrollArea sets an area to scroll with fixed top/bottom or left/right parts of the display // Rotation affects scroll direction func (d *Device) SetScrollArea(topFixedArea, bottomFixedArea int16) { + if d.height < 320 { + // The screen doesn't use the full 320 pixel height. + // Enlarge the bottom fixed area to fill the 320 pixel height, so that + // bottomFixedArea starts from the visible bottom of the screen. + bottomFixedArea += 320 - d.height + } cmdBuf[0] = uint8(topFixedArea >> 8) cmdBuf[1] = uint8(topFixedArea) - cmdBuf[2] = uint8(d.height - topFixedArea - bottomFixedArea>>8) - cmdBuf[3] = uint8(d.height - topFixedArea - bottomFixedArea) + cmdBuf[2] = uint8((320 - topFixedArea - bottomFixedArea) >> 8) + cmdBuf[3] = uint8(320 - topFixedArea - bottomFixedArea) cmdBuf[4] = uint8(bottomFixedArea >> 8) cmdBuf[5] = uint8(bottomFixedArea) d.sendCommand(VSCRDEF, cmdBuf[:6]) diff --git a/st7735/st7735.go b/st7735/st7735.go index fd0829b..f9521cd 100644 --- a/st7735/st7735.go +++ b/st7735/st7735.go @@ -235,6 +235,8 @@ func (d *Device) setWindow(x, y, w, h int16) { // SetScrollWindow sets an area to scroll with fixed top and bottom parts of the display func (d *Device) SetScrollArea(topFixedArea, bottomFixedArea int16) { + // TODO: this code is broken, see the st7789 and ili9341 implementations for + // how to do this correctly. d.Command(VSCRDEF) d.Tx([]uint8{ uint8(topFixedArea >> 8), uint8(topFixedArea), diff --git a/st7789/st7789.go b/st7789/st7789.go index 8a145e4..96b1232 100644 --- a/st7789/st7789.go +++ b/st7789/st7789.go @@ -554,9 +554,16 @@ func (d *Device) IsBGR(bgr bool) { // SetScrollArea sets an area to scroll with fixed top and bottom parts of the display. func (d *Device) SetScrollArea(topFixedArea, bottomFixedArea int16) { + if d.height < 320 { + // The screen doesn't use the full 320 pixel height. + // Enlarge the bottom fixed area to fill the 320 pixel height, so that + // bottomFixedArea starts from the visible bottom of the screen. + bottomFixedArea += 320 - d.height + } + verticalScrollArea := 320 - topFixedArea - bottomFixedArea copy(d.buf[:6], []uint8{ uint8(topFixedArea >> 8), uint8(topFixedArea), - uint8(d.height - topFixedArea - bottomFixedArea>>8), uint8(d.height - topFixedArea - bottomFixedArea), + uint8(verticalScrollArea >> 8), uint8(verticalScrollArea), uint8(bottomFixedArea >> 8), uint8(bottomFixedArea)}) d.startWrite() d.sendCommand(VSCRDEF, d.buf[:6])