aboutsummaryrefslogtreecommitdiffstats
path: root/inkplate.scm
blob: d068455896e18f200640b30780d3ff649025d02e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
(define-module (inkplate)
  #:use-module ((ice-9 format) #:select (format))
  #:use-module ((srfi srfi-9) #:select (define-record-type))

  #:export (<inkplate>
            make-inkplate
            inkplate?
            inkplate-input-port
            inkplate-output-port

            convert-string-to-hex

            open
            close
            echo
            draw-pixel
            draw-line
            draw-fast-vertical-line
            draw-fast-horizontal-line
            draw-rectangle
            draw-circle
            draw-triangle
            draw-rounded-rectangle
            fill-rectangle
            fill-circle
            fill-triangle
            fill-rounded-rectangle
            print
            set-text-size
            set-cursor
            set-text-wrap
            set-rotation
            draw-bitmap
            set-display-mode
            get-display-mode
            clear-screen
            update
            partial-update
            read-temperature
            read-touchpad
            read-battery
            panel-supply
            get-panel-state
            draw-image
            draw-thick-line
            draw-ellipse
            fill-ellipse
            send))

(define-record-type <inkplate>
  (make-inkplate input-port output-port)
  inkplate?
  (input-port inkplate-input-port)
  (output-port inkplate-output-port))

(define (convert-string-to-hex string)
  "Convert STRING to a hexadecimal representation of the text."
  (string-join
   (map (lambda (x) (format #f "~2,'0x" (char->integer x)))
        (string->list string))
   ""))

(define (open device-path)
  "Open a connection to an Inkplate on the named DEVICE-PATH."
  (let ((port (open-file device-path "r+")))
   (make-inkplate port port)))

(define (close device)
  "Close a connection to an Inkplate in DEVICE."
  (close-port (inkplate-output-port device))
  (close-port (inkplate-input-port device)))

(define (echo device)
  "Send a command to check if the DEVICE is receiving commands."
  (display "#?*" (inkplate-output-port device)))

(define (draw-pixel device x y color)
  "Draw a pixel on DEVICE at coordinates X and Y in COLOR."
  (format (inkplate-output-port device) "#0(~3,'0d,~3,'0d,~2,'0d)*" x y color))

(define (draw-line device x1 y1 x2 y2 color)
  "Draw a line on DEVICE from coordinates X1,Y1 to X2,Y2 in COLOR."
  (format (inkplate-output-port device)
          "#1(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x1 y1 x2 y2 color))

(define (draw-fast-vertical-line device x y length color)
  "Draw a vertical line on DEVICE from X,Y for LENGTH pixels in COLOR."
  (format (inkplate-output-port device)
          "#2(~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y length color))

(define (draw-fast-horizontal-line device x y length color)
  "Draw a horizontal line on DEVICE from X,Y for LENGTH pixels in COLOR."
  (format (inkplate-output-port device)
          "#3(~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y length color))

(define (draw-rectangle device x y width height color)
  "Draw a rectangle on DEVICE at X,Y WIDTH wide by HEIGHT high in COLOR.
This function draws an outline of a rectangle whereas ‘fill-rectangle’ fills the
rectangle with the specified color."
  (format (inkplate-output-port device)
          "#4(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y width height color))

(define (draw-circle device x y radius color)
  "Draw a circle on DEVICE at X,Y with RADIUS in COLOR.
This function draws an outline of a circle whereas ‘fill-circle’ fills the
circle with the specified color."
  (format (inkplate-output-port device)
          "#5(~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y radius color))

(define (draw-triangle device x1 y1 x2 y2 x3 y3 color)
  "Draw a triangle on DEVICE at points X1,Y1, X2,Y2, and X3,Y3 in COLOR.
This function draws an outline of a triangle whereas ‘fill-triangle’ fills the
triangle with the specified color."
  (format (inkplate-output-port device)
          "#6(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*"
          x1 y1 x2 y2 x3 y3 color))

(define (draw-rounded-rectangle device x y width height radius color)
  "Draw a rounded rectangle on DEVICE at X,Y WIDTH wide by HEIGHT high.
RADIUS is the radius of the rounded corners. Draw the rectangle in COLOR."
  (format (inkplate-output-port device)
          "#7(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*"
          x y width height radius color))

(define (fill-rectangle device x y width height color)
  "Draw a rectangle on DEVICE at X,Y WIDTH wide by HEIGHT high in COLOR.
This function fills the entire rectangle with COLOR while ‘draw-rectangle’ only
draws an outline."
  (format (inkplate-output-port device)
          "#8(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y width height color))

(define (fill-circle device x y radius color)
  "Draw a circle on DEVICE at X,Y with RADIUS.
This function fills the entire circle with COLOR while ‘draw-circle’ only draws
an outline."
  (format (inkplate-output-port device)
          "#9(~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y radius color))

(define (fill-triangle device x1 y1 x2 y2 x3 y3 color)
  "Draw a triangle on DEVICE at points X1,Y1, X2,Y2, and X3,Y3 in COLOR.
This function fills the entire triangle with COLOR while ‘draw-triangle’ only
draws an outline."
  (format (inkplate-output-port device)
          "#A(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*"
          x1 y1 x2 y2 x3 y3 color))

(define (fill-rounded-rectangle device x y width height radius color)
  "Draw a rounded rectangle on DEVICE at X,Y WIDTH wide by HEIGHT high.
CORNER-RADIUS is the radius of the rounded corners. Fill the rectangle with
COLOR."
  (format (inkplate-output-port device)
          "#B(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*"
          x y width height radius color))

(define (print device text)
  "Print the TEXT onto the screen of DEVICE.
TEXT should be a hex string as produced by ‘convert-string-to-hex’."
  (format (inkplate-output-port device) "#C(~s)*" text))

(define (set-text-size device size)
  "Set the text size for the next print command to SIZE for DEVICE."
  (format (inkplate-output-port device) "#D(~2,'0d)*" size))

(define (set-cursor device x y)
  "Move the cursor on DEVICE to the X and Y coordinates."
  (format (inkplate-output-port device) "#E(~3,'0d,~3,'0d)*" x y))

(define (set-text-wrap device enable)
  "Enable or disable text wrapping on DEVICE depending on the value of ENABLE.
If ENABLE is #t, enable text wrapping. Otherwise disable it."
  (format (inkplate-output-port device) "#F(~a)*" (if enable "T" "F")))

(define (set-rotation device rotation)
  "Set the screen rotation on DEVICE.
ROTATION can be one of:
- 0: 0 degrees rotation
- 1: 90 degrees rotation
- 2: 180 degrees rotation
- 3: 270 degrees rotation"
  (format (inkplate-output-port device) "#G(~3,'0d)*" rotation))

(define (draw-bitmap device x y path)
  "Draw a bitmap on DEVICE at coordinates X,Y.
PATH should be a path on the SD card and should be a hex string
as produced by ‘inkplate--convert-string-to-hex’. This command
puts a response in the output buffer. It should be one of:

- #H(0)*: Image load failed
- #H(1)*: Image loaded successfully
- #H(-1)*: SD Card Init Error"
  (format (inkplate-output-port device) "#H(~3,'0d,~3,'0d,~s)*" x y path))

(define (set-display-mode device mode)
  "Set the display mode for DEVICE to MODE.
Mode can be one of:
- 1: 1-bit mode
- 3: 3-bit mode"
  (format (inkplate-output-port device) "#I(~d)*" mode))

(define (get-display-mode device)
  "Query the DEVICE for which display mode is active.

This puts one of the following responses into the output buffer:
- #J(0): 1-bit mode
- #J(1): 3-bit mode"
  (display "#J(?)*" (inkplate-output-port device)))

(define (clear-screen device)
  "Send the command to clear the screen to DEVICE."
  (display "#K(1)*" (inkplate-output-port device)))

(define (update device)
  "Send the command to update the display to DEVICE."
  (display "#L(1)*" (inkplate-output-port device)))

(define (partial-update device yy1 xx2 yy2)
  "Send the command to update the display to DEVICE.
Tell it to only do a partial update."
  ;; I guess that xx1 is implicitly 0? It's not mentioned in the documentation.
  (format (inkplate-output-port device) "#M(~3,'0d,~3,'0d,~3,'0d)*" yy1 xx2 yy2))

(define (read-temperature device)
  "Query DEVICE for its current temperature.
This will produce a response in the output buffer in the form or #N(22)* which
means its temperature is 22 degrees Celsius."
  (display "#N(?)*" (inkplate-output-port device)))

(define (read-touchpad device touchpad)
  "Query DEVICE for the state of TOUCHPAD.
TOUCHPAD can be 1, 2, or 3. This will produce a response in the
output buffer which can be read with ‘inkplate-read-output’.
Possible responses are:
- #O(1)*: The touch pad is in the high state
- #O(0)*: The touch pad is in the low state"
  (format (inkplate-output-port device) "#O(~d)*" touchpad))

(define (read-battery device)
  "Query DEVICE for the current voltage on the battery.
This produces a response in the output buffer which can be read using
‘read-output’. The response is in the form of #P(3.65)* meaning the measured
voltage on the battery is 3.65VDC."
  (display "#P(?)*" (inkplate-output-port device)))

(define (panel-supply device enable)
  "Turn DEVICE on or off depending on the value of ENABLE.
If ENABLE is #t turn DEVICE on, otherwise turn it off."
  (format (inkplate-output-port device) "#Q(~d)*" (if enable 1 0)))

(define (get-panel-state device)
  "Query DEVICE for the state of the panel.
This command produces a response in the output buffer which can be read using
‘read-output’. The response can be one of:

- #R(1)*: Panel has power
- #R(0)*: Panel has no power"
  (display "#R(?)*" (inkplate-output-port device)))

(define (draw-image device x y path)
  "Draw an image on DEVICE at coordinates X,Y.
PATH should be a path on the SD card and a hex string as produced by
‘convert-string-to-hex’."
  (format (inkplate-output-port device) "#S(~3,'0d,~3,'0d,~s)*" x y path))

(define (draw-thick-line device x1 y1 x2 y2 thickness color)
  "Draw a line on DEVICE from X1,Y1 to X2,Y2 in THICKNESS and COLOR."
  (format (inkplate-output-port device)
          "#T(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d,~2,'0d)*"
          x1 y1 x2 y2 thickness color))

(define (draw-ellipse device x y x-radius y-radius color)
  "Draw an ellipse on DEVICE at coordinates X,Y.
X-RADIUS and Y-RADIUS specify the x and y radius of the ellipse. Draw it in
COLOR."
  (format (inkplate-output-port device)
          "#U(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y x-radius y-radius color))

(define (fill-ellipse device x y x-radius y-radius color)
  "Draw and fill an ellipse on DEVICE at coordinates X,Y.
X-RADIUS and Y-RADIUS specify the x and y radius of the ellipse. Draw it in
COLOR."
  (format (inkplate-output-port device)
          "#V(~3,'0d,~3,'0d,~3,'0d,~3,'0d,~2,'0d)*" x y x-radius y-radius color))

(define (send device)
  "Send the accumulated commands to DEVICE."
  (force-output (inkplate-output-port device)))