1package main
2
3import (
4 "fmt"
5 "log"
6 "syscall"
7 "time"
8
9 "pihonclient/appdata"
10 "pihonclient/extras"
11 "pihonclient/phnparser"
12 "pihonclient/renderer"
13 "pihonclient/screendriver"
14 "pihonclient/ui"
15
16 "github.com/warthog618/gpiod"
17 "github.com/warthog618/gpiod/device/rpi"
18)
19
20func checkError(error error) {
21 if error != nil {
22 log.Fatal(error)
23 }
24}
25
26func checkGPIOInitError(error error) {
27 if error != nil {
28 log.Fatal(fmt.Sprintf("RequestLine returned error: %s\n", error))
29 if error == syscall.Errno(22) {
30 log.Fatal("Note that the WithPullUp option requires kernel V5.5 or later - check your kernel version.")
31 }
32 }
33}
34
35func selectBook() {
36 // Read book
37 phnparser.LoadBook(ui.UISelectionIndex)
38 ui.UIDisplayedMenu = 2
39 ui.UISelectionIndex = appdata.ReadBookData(phnparser.LoadedBookHash)
40 ui.RenderUI()
41}
42
43func checkIfBothButtonsArePressed(currentButton string) bool {
44 if extras.LeftButtonState == true {
45 if extras.RightButtonState == true {
46 fmt.Println("Both buttons pressed!")
47 ui.UISelectionIndex = ui.UISelectionIndexBuffer
48 if ui.UIDisplayedMenu == 1 {
49 selectBook()
50 fmt.Println("Loaded a book!")
51 return true
52 } else if ui.UIDisplayedMenu == 2 {
53 appdata.SaveBookData(phnparser.LoadedBookHash, ui.UISelectionIndex)
54 ui.RenderUI()
55 fmt.Println("Saved the position!")
56 return true
57 }
58 }
59 }
60 return false
61}
62
63func leftEventHandler(evt gpiod.LineEvent) {
64 edge := "rising"
65 extras.LeftButtonState = false
66 if evt.Type == gpiod.LineEventFallingEdge {
67 edge = "falling"
68 extras.LeftButtonState = true
69 extras.LeftButtonPressedTime = time.Now()
70 }
71 if edge == "rising" {
72 if time.Now().Sub(extras.LeftButtonPressedTime).Seconds() >= extras.NavigationHoldDuration {
73 if ui.UIDisplayedMenu == 2 {
74 ui.UITopBarTitle = extras.FitWithinCharacterLimits(phnparser.MaxLengthOfLine-2, extras.GetCWD()+phnparser.LibraryPath)
75 ui.UIDisplayedMenu = 1
76 ui.UISelectionIndex = 0
77 ui.UISelectionIndexBuffer = ui.UISelectionIndex
78 ui.RenderUI()
79 }
80 }
81 }
82 if edge == "falling" {
83 if checkIfBothButtonsArePressed("left") {
84 return
85 }
86 fmt.Println("Left button pressed!")
87 if ui.UIDisplayedMenu == 1 {
88 if ui.UISelectionIndex > 0 {
89 ui.UISelectionIndexBuffer = ui.UISelectionIndex
90 ui.UISelectionIndex--
91 }
92 ui.RenderUI()
93 } else if ui.UIDisplayedMenu == 2 {
94 if ui.UISelectionIndex > 0 {
95 ui.UISelectionIndexBuffer = ui.UISelectionIndex
96 ui.UISelectionIndex--
97 }
98 ui.RenderUI()
99 }
100 }
101}
102
103func rightEventHandler(evt gpiod.LineEvent) {
104 edge := "rising"
105 extras.RightButtonState = false
106 if evt.Type == gpiod.LineEventFallingEdge {
107 edge = "falling"
108 extras.RightButtonState = true
109 }
110 if edge == "falling" {
111 if checkIfBothButtonsArePressed("right") {
112 return
113 }
114 fmt.Println("Right button pressed!")
115 if ui.UIDisplayedMenu == 0 {
116 fmt.Println("Displaying library!")
117 // Library show
118 phnparser.ScanLibraryFolder()
119 ui.UITopBarTitle = extras.FitWithinCharacterLimits(phnparser.MaxLengthOfLine-2, extras.GetCWD()+phnparser.LibraryPath)
120 ui.UIDisplayedMenu = 1
121 ui.RenderUI()
122 } else if ui.UIDisplayedMenu == 1 {
123 if ui.UISelectionIndex < len(phnparser.LibraryHashes)-1 {
124 ui.UISelectionIndexBuffer = ui.UISelectionIndex
125 ui.UISelectionIndex++
126 }
127 ui.RenderUI()
128 } else if ui.UIDisplayedMenu == 2 {
129 if ui.UISelectionIndex*ui.UIMaxBookLines < len(phnparser.LoadedBookLines)-1 {
130 ui.UISelectionIndexBuffer = ui.UISelectionIndex
131 ui.UISelectionIndex++
132 }
133 ui.RenderUI()
134 }
135
136 }
137}
138
139func main() {
140 // Config
141 // Input
142 leftButtonPinRef := rpi.J8p11
143 rightButtonPinRef := rpi.J8p13
144 debouncingPeriod := 10 * time.Millisecond
145 extras.NavigationHoldDuration = 3
146 // Screen
147 renderer.ScreenCount = 2
148 renderer.ScreenWidth = 128
149 renderer.ScreenHeight = 64
150 // UI
151 ui.BuildVersion = "V2022.05.05"
152 ui.UIMargin = 1
153 ui.UITopBarHeight = 10
154 ui.UILineHeight = 8
155 ui.UIFontHorizontalSpacing = 9
156 ui.UIMaxBookLines = 6
157 // Display Driver
158 screendriver.I2CBuses = []string{"1", "4"}
159 // .phn Parser
160 phnparser.LibraryPath = "library/"
161 phnparser.MaxLengthOfLine = 28
162 // Appdata
163 appdata.DataPath = "data/"
164 // Extras
165 extras.CloudflareIP = "1.1.1.1"
166 // Code
167 // GPIO init
168 l, err := gpiod.RequestLine("gpiochip0", leftButtonPinRef, gpiod.WithPullUp, gpiod.WithBothEdges, gpiod.WithEventHandler(leftEventHandler), gpiod.WithDebounce(debouncingPeriod))
169 checkGPIOInitError(err)
170 defer l.Close()
171 r, err := gpiod.RequestLine("gpiochip0", rightButtonPinRef, gpiod.WithPullUp, gpiod.WithBothEdges, gpiod.WithEventHandler(rightEventHandler), gpiod.WithDebounce(debouncingPeriod))
172 checkGPIOInitError(err)
173 defer r.Close()
174 // Displays init
175 screendriver.InitializeDisplays()
176 // Renderer init
177 renderer.InitFrameBuffers()
178 // Boot screen show
179 ui.UIDisplayedMenu = 0
180 ui.RenderUI()
181 ui.UIConnectedToInternet = extras.PingCloudflare()
182 // Ping every 60s
183 for true {
184 time.Sleep(time.Minute)
185 ui.UIConnectedToInternet = extras.PingCloudflare()
186 }
187}