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/ht16k33/alphanum.go

168 lines
3.0 KiB
Go

// Copyright 2018 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 ht16k33
import (
"periph.io/x/conn/v3/i2c"
)
var digitValues = map[rune]uint16{
' ': 0x0,
'!': 0x6,
'"': 0x220,
'#': 0x12ce,
'$': 0x12ed,
'%': 0xc24,
'&': 0x235d,
'\'': 0x400,
'(': 0x2400,
')': 0x900,
'*': 0x3fc0,
'+': 0x12c0,
',': 0x800,
'-': 0xc0,
'.': 0x4000,
'/': 0xc00,
'0': 0xc3f,
'1': 0x6,
'2': 0xdb,
'3': 0x8f,
'4': 0xe6,
'5': 0x2069,
'6': 0xfd,
'7': 0x7,
'8': 0xff,
'9': 0xef,
':': 0x1200,
';': 0xa00,
'<': 0x2400,
'=': 0xc8,
'>': 0x900,
'?': 0x1083,
'@': 0x2bb,
'A': 0xf7,
'B': 0x128f,
'C': 0x39,
'D': 0x120f,
'E': 0xf9,
'F': 0x71,
'G': 0xbd,
'H': 0xf6,
'I': 0x1200,
'J': 0x1e,
'K': 0x2470,
'L': 0x38,
'M': 0x536,
'N': 0x2136,
'O': 0x3f,
'P': 0xf3,
'Q': 0x203f,
'R': 0x20f3,
'S': 0xed,
'T': 0x1201,
'U': 0x3e,
'V': 0xc30,
'W': 0x2836,
'X': 0x2d00,
'Y': 0x1500,
'Z': 0xc09,
'[': 0x39,
'\\': 0x2100,
']': 0xf,
'^': 0xc03,
'_': 0x8,
'`': 0x100,
'a': 0x1058,
'b': 0x2078,
'c': 0xd8,
'd': 0x88e,
'e': 0x858,
'f': 0x71,
'g': 0x48e,
'h': 0x1070,
'i': 0x1000,
'j': 0xe,
'k': 0x3600,
'l': 0x30,
'm': 0x10d4,
'n': 0x1050,
'o': 0xdc,
'p': 0x170,
'q': 0x486,
'r': 0x50,
's': 0x2088,
't': 0x78,
'u': 0x1c,
'v': 0x2004,
'w': 0x2814,
'x': 0x28c0,
'y': 0x200c,
'z': 0x848,
'{': 0x949,
'|': 0x1200,
'}': 0x2489,
'~': 0x520,
}
// Display is a handler to control an alphanumeric display based on ht16k33.
type Display struct {
dev *Dev
}
// NewAlphaNumericDisplay returns a Display object that communicates over I2C to ht16k33.
//
// To use on the default address, ht16k33.I2CAddr must be passed as argument.
func NewAlphaNumericDisplay(bus i2c.Bus, address uint16) (*Display, error) {
dev, err := NewI2C(bus, address)
if err != nil {
return nil, err
}
return &Display{dev: dev}, nil
}
// SetDigit at position to provided value.
func (d *Display) SetDigit(pos int, digit rune, decimal bool) error {
val := digitValues[digit]
if decimal {
val |= digitValues['.']
}
return d.dev.WriteColumn(pos, val)
}
// WriteString print string of values to the display.
//
// Characters in the string should be any ASCII value 32 to 127 (printable ASCII).
func (d *Display) WriteString(s string) (int, error) {
if err := d.dev.Halt(); err != nil {
return 0, err
}
pos := (4 - len(s))
if pos < 0 {
pos = 0
}
// Go through each character and print it on the display.
for _, ch := range s {
if ch == '.' {
// Print decimal points on the previous digit.
c := rune(s[pos-1])
if err := d.SetDigit(pos-1, c, true); err != nil {
return pos, err
}
} else {
if err := d.SetDigit(pos, ch, false); err != nil {
return pos, err
}
pos++
}
}
return pos, nil
}
// Halt clear all the display.
func (d *Display) Halt() error {
return d.dev.Halt()
}