summaryrefslogtreecommitdiff
path: root/cfa635/report.go
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbarenblat@gmail.com>2022-09-08 14:40:10 -0400
committerGravatar Benjamin Barenblat <bbarenblat@gmail.com>2022-09-08 14:40:10 -0400
commit64f73905537e4b1d083afe4c446279a78f9808c0 (patch)
treef7f22289cb0613dc7a29ac5ee5e87ca5ef61ec8c /cfa635/report.go
parentd48c52c1298777cba68b6e78dc5cd83dda4f12de (diff)
Basic, read-only audiotrondHEADmain
Audiotrond exists and properly displays music being played through MPD. The display includes title, artist, album, and progress bar, and text scrolls if too long to fit on the screen. Backlight support exists; the display backlight fades smoothly on and off when the music starts and stops. After being stopped for a little while, audiotrond switches to a clock. Currently, audiotrond lacks user interaction support, so it keeps the keypad backlight off.
Diffstat (limited to 'cfa635/report.go')
-rw-r--r--cfa635/report.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/cfa635/report.go b/cfa635/report.go
new file mode 100644
index 0000000..84541bc
--- /dev/null
+++ b/cfa635/report.go
@@ -0,0 +1,109 @@
+// Copyright 2022 Benjamin Barenblat
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+package cfa635
+
+import (
+ "encoding/binary"
+ "errors"
+)
+
+var (
+ errUnknownReportType = errors.New("failed to read report: unknown type")
+ errUnknownKey = errors.New("failed to read key activity report: unknown key")
+ errFBSCAB = errors.New("failed to read fan speed report: FBSCAB module disconnected")
+ errDOW = errors.New("failed to read temperature report: DOW sensor error")
+)
+
+// KeyActivity is a report that a key has been pressed or released.
+type KeyActivity struct {
+ K Key
+ Pressed bool
+}
+
+// Key represents a button on the CFA635.
+type Key int
+
+const (
+ _ Key = iota
+ UpButton
+ DownButton
+ LeftButton
+ RightButton
+ EnterButton
+ ExitButton
+)
+
+// FanSpeed is a report on the speed of a system fan.
+type FanSpeed struct {
+ N int
+ TachCycles int
+ TimerTicks int
+}
+
+// Temperature is a report on the system temperature.
+type Temperature struct {
+ N int // Sensor number.
+ Celsius float64
+}
+
+// decodeReport converts a packet into either a *KeyActivity, a *FanSpeed, or a
+// *Temperature, depending on the packet's type tag.
+func decodeReport(p []byte) (any, error) {
+ switch p[0] {
+ case 0x80:
+ return decodeKeyActivity(p[2])
+ case 0x81:
+ return decodeFanSpeed(p[2:6])
+ case 0x82:
+ return decodeTemperature(p[2:6])
+ default:
+ return nil, errUnknownReportType
+ }
+}
+
+// decodeKeyActivity converts the data byte from a key activity report to a
+// KeyActivity.
+func decodeKeyActivity(b byte) (*KeyActivity, error) {
+ if b == 0 || b > 12 {
+ return nil, errUnknownKey
+ }
+
+ var a KeyActivity
+ if b < 7 {
+ a.Pressed = true
+ } else {
+ b -= 6
+ }
+ a.K = Key(b)
+ return &a, nil
+}
+
+// decodeFanSpeed converts the data part of a fan speed report packet to a
+// FanSpeed.
+func decodeFanSpeed(b []byte) (*FanSpeed, error) {
+ if b[1] == 0 && b[2] == 0 && b[3] == 0 {
+ return nil, errFBSCAB
+ }
+ return &FanSpeed{int(b[0]), int(b[1]), int(binary.BigEndian.Uint16(b[2:4]))}, nil
+}
+
+// decodeTemperature converts the data part of a temperature report packet to a
+// Temperature.
+func decodeTemperature(b []byte) (*Temperature, error) {
+ if b[3] == 0 {
+ return nil, errDOW
+ }
+ return &Temperature{int(b[0]), float64(binary.BigEndian.Uint16(b[1:3])) / 16}, nil
+}