diff options
Diffstat (limited to 'clockDisplay.go')
-rw-r--r-- | clockDisplay.go | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/clockDisplay.go b/clockDisplay.go new file mode 100644 index 0000000..cc20de3 --- /dev/null +++ b/clockDisplay.go @@ -0,0 +1,308 @@ +// 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 main + +import ( + "fmt" + "time" + + "benjamin.barenblat.name/audiotrond/cfa635" +) + +const ( + lowerHalfSprite = iota + upperHalfSprite + lowerHalfEdgeSprite + upperHalfEdgeSprite + fullBlockSprite + fullBlockEdgeSprite + lowerRightSprite + rightLowerEdgeSprite +) + +func initializeClockDisplay(lcd *cfa635.Module) error { + // Load sprites. + + if err := lcd.SetCharacter(lowerHalfSprite, &[...]byte{ + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_111111, + 0b00_111111, + 0b00_111111, + }); err != nil { + return err + } + + if err := lcd.SetCharacter(upperHalfSprite, &[...]byte{ + 0b00_111111, + 0b00_111111, + 0b00_111111, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + }); err != nil { + return err + } + + if err := lcd.SetCharacter(lowerHalfEdgeSprite, &[...]byte{ + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_001111, + 0b00_001111, + 0b00_001111, + }); err != nil { + return err + } + + if err := lcd.SetCharacter(upperHalfEdgeSprite, &[...]byte{ + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + 0b00_000000, + }); err != nil { + return err + } + + if err := lcd.SetCharacter(fullBlockSprite, &[...]byte{ + 0b00_111111, + 0b00_111111, + 0b00_111111, + 0b00_111111, + 0b00_111111, + 0b00_111111, + 0b00_111111, + 0b00_111111, + }); err != nil { + return err + } + + if err := lcd.SetCharacter(fullBlockEdgeSprite, &[...]byte{ + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + }); err != nil { + return err + } + + if err := lcd.SetCharacter(lowerRightSprite, &[...]byte{ + 0b00_000001, + 0b00_000011, + 0b00_000111, + 0b00_001111, + 0b00_011111, + 0b00_111111, + 0b00_111111, + 0b00_111111, + }); err != nil { + return err + } + + if err := lcd.SetCharacter(rightLowerEdgeSprite, &[...]byte{ + 0b00_000001, + 0b00_000011, + 0b00_000111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + 0b00_001111, + }); err != nil { + return err + } + + return nil +} + +func blitClockDigit(n int, lcd *cfa635.LCDState, x int) { + switch n { + case 0: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = fullBlockEdgeSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x] = fullBlockEdgeSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x] = fullBlockEdgeSprite + lcd[3][x+1] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 1: + lcd[0][x+2] = lowerRightSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 2: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = lowerHalfEdgeSprite + lcd[1][x+1] = lowerHalfSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x] = fullBlockEdgeSprite + lcd[2][x+1] = upperHalfSprite + lcd[2][x+2] = upperHalfSprite + lcd[3][x] = fullBlockEdgeSprite + lcd[3][x+1] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 3: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = lowerHalfEdgeSprite + lcd[1][x+1] = lowerHalfSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x] = upperHalfEdgeSprite + lcd[2][x+1] = upperHalfSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x] = fullBlockEdgeSprite + lcd[3][x+1] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 4: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = fullBlockEdgeSprite + lcd[1][x+1] = lowerHalfSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x] = upperHalfEdgeSprite + lcd[2][x+1] = upperHalfSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 5: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = fullBlockEdgeSprite + lcd[1][x+1] = lowerHalfSprite + lcd[1][x+2] = lowerHalfSprite + lcd[2][x] = upperHalfEdgeSprite + lcd[2][x+1] = upperHalfSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x] = fullBlockEdgeSprite + lcd[3][x+1] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 6: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = fullBlockEdgeSprite + lcd[1][x+1] = lowerHalfSprite + lcd[1][x+2] = lowerHalfSprite + lcd[2][x] = fullBlockEdgeSprite + lcd[2][x+1] = upperHalfSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x] = fullBlockEdgeSprite + lcd[3][x+1] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 7: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 8: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = fullBlockEdgeSprite + lcd[1][x+1] = lowerHalfSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x] = fullBlockEdgeSprite + lcd[2][x+1] = upperHalfSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x] = fullBlockEdgeSprite + lcd[3][x+1] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + case 9: + lcd[0][x] = rightLowerEdgeSprite + lcd[0][x+1] = fullBlockSprite + lcd[0][x+2] = fullBlockSprite + lcd[1][x] = fullBlockEdgeSprite + lcd[1][x+1] = lowerHalfSprite + lcd[1][x+2] = fullBlockSprite + lcd[2][x] = upperHalfEdgeSprite + lcd[2][x+1] = upperHalfSprite + lcd[2][x+2] = fullBlockSprite + lcd[3][x+2] = fullBlockSprite + + default: + panic(fmt.Sprint("unknown digit ", n)) + } +} + +func clockView(now time.Time) *view { + var new view + new.LCD = cfa635.ClearedLCDState() + + now = now.Local() + h := now.Hour() % 12 + if h == 0 { + h = 12 + } + if h >= 10 { + blitClockDigit(1, new.LCD, -2) + h -= 10 + } + blitClockDigit(h, new.LCD, 1) + + new.LCD[1][4] = 0xbb + new.LCD[2][4] = 0xbb + + m := now.Minute() + blitClockDigit(m/10, new.LCD, 5) + blitClockDigit(m%10, new.LCD, 8) + + new.LCD[1][11] = 0xbb + new.LCD[2][11] = 0xbb + + s := now.Second() + blitClockDigit(s/10, new.LCD, 12) + blitClockDigit(s%10, new.LCD, 15) + + if now.Hour() < 12 { + new.LCD[2][19] = 'a' + } else { + new.LCD[2][19] = 'p' + } + new.LCD[3][19] = 'm' + + return &new +} |