You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devices/waveshare2in13v3/controller.go

166 lines
4.1 KiB
Go

// Copyright 2021 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package waveshare2in13v3
type controller interface {
sendCommand(byte)
sendData([]byte)
waitUntilIdle()
}
func initDisplay(ctrl controller, opts *Opts) {
ctrl.waitUntilIdle()
ctrl.sendCommand(swReset)
ctrl.waitUntilIdle()
ctrl.sendCommand(driverOutputControl)
ctrl.sendData([]byte{0xf9, 0x00, 0x00})
ctrl.sendCommand(dataEntryModeSetting)
ctrl.sendData([]byte{0x03})
setWindow(ctrl, 0, 0, opts.Width-1, opts.Height-1)
setCursor(ctrl, 0, 0)
ctrl.sendCommand(borderWaveformControl)
ctrl.sendData([]byte{0x05})
ctrl.sendCommand(displayUpdateControl1)
ctrl.sendData([]byte{0x00, 0x80})
ctrl.sendCommand(tempSensorSelect)
ctrl.sendData([]byte{0x80})
ctrl.waitUntilIdle()
setLut(ctrl, opts.FullUpdate)
}
func configDisplayMode(ctrl controller, mode PartialUpdate, lut LUT) {
var vcom byte
var borderWaveformControlValue byte
switch mode {
case Full:
vcom = 0x55
borderWaveformControlValue = 0x03
case Partial:
vcom = 0x24
borderWaveformControlValue = 0x01
}
ctrl.sendCommand(writeVcomRegister)
ctrl.sendData([]byte{vcom})
ctrl.sendCommand(borderWaveformControl)
ctrl.sendData([]byte{borderWaveformControlValue})
ctrl.sendCommand(writeLutRegister)
ctrl.sendData(lut[:70])
ctrl.sendCommand(writeDisplayOptionRegister)
ctrl.sendData([]byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00})
// Start up the parts likely used by a draw operation soon.
ctrl.sendCommand(displayUpdateControl2)
ctrl.sendData([]byte{displayUpdateEnableClock | displayUpdateEnableAnalog})
ctrl.sendCommand(masterActivation)
ctrl.waitUntilIdle()
}
func updateDisplay(ctrl controller, mode PartialUpdate) {
var displayUpdateFlags byte
if mode == Partial {
// Make use of red buffer
displayUpdateFlags = 0b1000_0000
}
ctrl.sendCommand(displayUpdateControl1)
ctrl.sendData([]byte{displayUpdateFlags})
ctrl.sendCommand(displayUpdateControl2)
ctrl.sendData([]byte{
displayUpdateDisableClock |
displayUpdateDisableAnalog |
displayUpdateDisplay |
displayUpdateEnableClock |
displayUpdateEnableAnalog,
})
ctrl.sendCommand(masterActivation)
ctrl.waitUntilIdle()
}
// new
// turnOnDisplay turns on the display if mode = true it does a partial display
func turnOnDisplay(ctrl controller, mode PartialUpdate) {
var upMode byte = 0xC7
if mode {
upMode = 0x0f
}
ctrl.sendCommand(displayUpdateControl2)
ctrl.sendData([]byte{upMode})
ctrl.sendCommand(masterActivation)
ctrl.waitUntilIdle()
}
func lookUpTable(ctrl controller, lut LUT) {
ctrl.sendCommand(writeLutRegister)
ctrl.sendData(lut[:153])
ctrl.waitUntilIdle()
}
func setLut(ctrl controller, lut LUT) {
lookUpTable(ctrl, lut)
ctrl.sendCommand(endOptionEOPT)
ctrl.sendData([]byte{lut[153]})
ctrl.sendCommand(gateDrivingVoltageControl)
ctrl.sendData([]byte{lut[154]})
ctrl.sendCommand(sourceDrivingVoltageControl)
ctrl.sendData(lut[155:157])
ctrl.sendCommand(writeVcomRegister)
ctrl.sendData([]byte{lut[158]})
}
func setWindow(ctrl controller, x_start int, y_start int, x_end int, y_end int) {
ctrl.sendCommand(setRAMXAddressStartEndPosition)
ctrl.sendData([]byte{byte((x_start >> 3) & 0xFF), byte((x_end >> 3) & 0xFF)})
ctrl.sendCommand(setRAMYAddressStartEndPosition)
ctrl.sendData([]byte{byte(y_start & 0xFF), byte((y_start >> 8) & 0xFF), byte(y_end & 0xFF), byte((y_end >> 8) & 0xFF)})
}
func setCursor(ctrl controller, x int, y int) {
ctrl.sendCommand(setRAMXAddressCounter)
// x point must be the multiple of 8 or the last 3 bits will be ignored
ctrl.sendData([]byte{byte(x & 0xFF)})
ctrl.sendCommand(setRAMYAddressCounter)
ctrl.sendData([]byte{byte(y & 0xFF), byte((y >> 8) & 0xFF)})
}
func clear(ctrl controller, color byte, opts *Opts) {
var linewidth int
if opts.Width%8 == 0 {
linewidth = int(opts.Width / 8)
} else {
linewidth = int(opts.Width/8) + 1
}
var buff []byte
ctrl.sendCommand(writeRAMBW)
for j := 0; j < opts.Height; j++ {
for i := 0; i < linewidth; i++ {
buff = append(buff, color)
}
}
ctrl.sendData(buff)
turnOnDisplay(ctrl, false)
}