mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-16 12:53:23 +00:00
clean commit, added smoke tests
This commit is contained in:
committed by
Ron Evans
parent
de22b8839e
commit
35a7590c2d
@@ -0,0 +1,150 @@
|
||||
// Package pcd8544 implements a driver for the PCD8544 48x84 pixels matrix LCD, used in Nokia's 5110 and 3310 phones.
|
||||
//
|
||||
// Datasheet: http://eia.udg.edu/~forest/PCD8544_1.pdf
|
||||
package pcd8544
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image/color"
|
||||
"machine"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Device wraps an SPI connection.
|
||||
type Device struct {
|
||||
bus machine.SPI
|
||||
dcPin machine.GPIO
|
||||
rstPin machine.GPIO
|
||||
scePin machine.GPIO
|
||||
buffer []byte
|
||||
width int16
|
||||
height int16
|
||||
bufferSize int16
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Width int16
|
||||
Height int16
|
||||
}
|
||||
|
||||
// New creates a new PCD8544 connection. The SPI bus must already be configured.
|
||||
func New(bus machine.SPI, dcPin machine.GPIO, rstPin machine.GPIO, scePin machine.GPIO) *Device {
|
||||
return &Device{
|
||||
bus: bus,
|
||||
dcPin: dcPin,
|
||||
rstPin: rstPin,
|
||||
scePin: scePin,
|
||||
}
|
||||
}
|
||||
|
||||
// Configure initializes the display with default configuration
|
||||
func (d *Device) Configure(cfg Config) {
|
||||
if cfg.Width != 0 {
|
||||
d.width = cfg.Width
|
||||
} else {
|
||||
d.width = 84
|
||||
}
|
||||
if cfg.Height != 0 {
|
||||
d.height = cfg.Height
|
||||
} else {
|
||||
d.height = 48
|
||||
}
|
||||
d.bufferSize = d.width * d.height / 8
|
||||
d.buffer = make([]byte, d.bufferSize)
|
||||
|
||||
d.rstPin.Low()
|
||||
time.Sleep(100 * time.Nanosecond)
|
||||
d.rstPin.High()
|
||||
d.SendCommand(FUNCTIONSET | EXTENDEDINSTRUCTION) // H = 1
|
||||
d.SendCommand(SETVOP | 0x3f) // 0x3f : Vop6 = 0, Vop5 to Vop0 = 1
|
||||
d.SendCommand(SETTEMP | 0x03) // Experimentally determined
|
||||
d.SendCommand(SETBIAS | 0x03) // Experimentally determined
|
||||
d.SendCommand(FUNCTIONSET) // H = 0
|
||||
d.SendCommand(DISPLAYCONTROL | DISPLAYNORMAL)
|
||||
}
|
||||
|
||||
// ClearBuffer clears the image buffer
|
||||
func (d *Device) ClearBuffer() {
|
||||
d.buffer = make([]byte, d.bufferSize)
|
||||
}
|
||||
|
||||
// ClearDisplay clears the image buffer and clear the display
|
||||
func (d *Device) ClearDisplay() {
|
||||
d.ClearBuffer()
|
||||
d.Display()
|
||||
}
|
||||
|
||||
// Display sends the whole buffer to the screen
|
||||
func (d *Device) Display() error {
|
||||
d.SendCommand(FUNCTIONSET) // H = 0
|
||||
d.SendCommand(SETXADDR)
|
||||
d.SendCommand(SETYADDR)
|
||||
|
||||
for i := int16(0); i < d.bufferSize; i++ {
|
||||
d.SendData(d.buffer[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendDataCommand sends image data or a command to the screen
|
||||
func (d *Device) sendDataCommand(isCommand bool, data uint8) {
|
||||
if isCommand {
|
||||
d.dcPin.Low()
|
||||
} else {
|
||||
d.dcPin.High()
|
||||
}
|
||||
d.scePin.Low()
|
||||
d.bus.Transfer(data)
|
||||
d.scePin.High()
|
||||
}
|
||||
|
||||
// SetPixel enables or disables a pixel in the buffer
|
||||
// color.RGBA{0, 0, 0, 255} is consider transparent, anything else
|
||||
// with enable a pixel on the screen
|
||||
func (d *Device) SetPixel(x int16, y int16, c color.RGBA) {
|
||||
if x < 0 || x >= d.width || y < 0 || y >= d.height {
|
||||
return
|
||||
}
|
||||
byteIndex := x + (y/8)*d.width
|
||||
if c.R != 0 || c.G != 0 || c.B != 0 {
|
||||
d.buffer[byteIndex] |= 1 << uint8(y%8)
|
||||
} else {
|
||||
d.buffer[byteIndex] &^= 1 << uint8(y%8)
|
||||
}
|
||||
}
|
||||
|
||||
// GetPixel returns if the specified pixel is on (true) or off (false)
|
||||
func (d *Device) GetPixel(x int16, y int16) bool {
|
||||
if x < 0 || x >= d.width || y < 0 || y >= d.height {
|
||||
return false
|
||||
}
|
||||
byteIndex := x + (y/8)*d.width
|
||||
return (d.buffer[byteIndex] >> uint8(y%8) & 0x1) == 1
|
||||
}
|
||||
|
||||
// SetBuffer changes the whole buffer at once
|
||||
func (d *Device) SetBuffer(buffer []byte) error {
|
||||
if int16(len(buffer)) != d.bufferSize {
|
||||
//return ErrBuffer
|
||||
return errors.New("Wrong size buffer")
|
||||
}
|
||||
for i := int16(0); i < d.bufferSize; i++ {
|
||||
d.buffer[i] = buffer[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendCommand sends a command to the display
|
||||
func (d *Device) SendCommand(command uint8) {
|
||||
d.sendDataCommand(true, command)
|
||||
}
|
||||
|
||||
// SendData sends a data byte to the display
|
||||
func (d *Device) SendData(data uint8) {
|
||||
d.sendDataCommand(false, data)
|
||||
}
|
||||
|
||||
// Size returns the current size of the display.
|
||||
func (d *Device) Size() (w, h int16) {
|
||||
return d.width, d.height
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package pcd8544
|
||||
|
||||
// Registers
|
||||
const (
|
||||
POWERDOWN = 0x04
|
||||
ENTRYMODE = 0x02
|
||||
EXTENDEDINSTRUCTION = 0x01
|
||||
FUNCTIONSET = 0x20
|
||||
|
||||
DISPLAYCONTROL = 0x08
|
||||
DISPLAYBLANK = 0x0
|
||||
DISPLAYNORMAL = 0x04
|
||||
DISPLAYALLON = 0x01
|
||||
DISPLAYINVERTED = 0x05
|
||||
|
||||
SETYADDR = 0x40
|
||||
SETXADDR = 0x80
|
||||
SETTEMP = 0x04
|
||||
SETBIAS = 0x10
|
||||
SETVOP = 0x80
|
||||
)
|
||||
Reference in New Issue
Block a user