-
Notifications
You must be signed in to change notification settings - Fork 0
/
pomodoro.asm
408 lines (359 loc) · 9.38 KB
/
pomodoro.asm
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
;;;
;;; Pomodoro for AVR - ATtiny25/45/85
;;;
;;; Copyright 2016 Henrik Andersson <[email protected]>
;;;
;;; This program is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation, either version 3 of the License, or
;;; (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY ; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;;
;;;
;;
;; define I/O registers used in the program
;;
.equ PORTB , 0x18
.equ DDRB , 0x19
.equ TCCR0A , 0x2A ; Timer/Counter control register A
.equ TCCR0B , 0x33 ; Timer/Counter control register B
.equ OCR0A , 0x29 ; Output Compare Register A
.equ TIMSK , 0x39 ; Timer/Counter interrupt Mask Register
.equ MCUCR , 0x35 ; MCU Control Register
.equ GIMSK , 0x3b ; General Interrupt Mask Register
.equ PCMSK , 0x15 ; Pin Change Mask Register
.equ MCUSR , 0x34 ; MCU Status Register
.equ WDTCR , 0x21 ; Watchdog Timer Control Register
;;
;; general file registry
;;
.equ TMP , 0x10 ; r16 - temporary
.equ TMP2 , 0x11 ; r17 - temporary
.equ TICK_CNT , 0x12 ; r18 - tick counter
.equ DISPLAY , 0x13 ; r19 - display
.equ DISPLAY_BIT , 0x14 ; r20 - display bit
.equ STATE , 0x15 ; r21 - pomodoro state
.equ SECONDS , 0x16 ; r22 - seconds counter
.equ MINUTES , 0x17 ; r23 - minutes counter
.equ ANIM_FRAME , 0x18 ; r24 - current frame in anim
.equ ANIM_FRAME_CNT , 0x19 ; r25 - frame in current anim
.equ ANIM_TICK_CNT , 0x1a ; r26 - tick counter for animation frame
.equ CURRENT_ANIM , 0x1b ; r27 - current animation
.equ ZL , 0x1e ; r30 - low part of Z Register
.equ ZH , 0x1f ; r31 - high part of Z Register
;;
;; SRAM pointers for led animations
;;
.equ SRAM_ANIM_PAUSE , 0x60 ; address to pause animation
.equ SRAM_ANIM_START , 0x6a ; address to start animation
.equ SRAM_ANIM_DONE , 0x74 ; address to done animation
;;
;; pomodoro state enums
;;
.equ STATE_STARTUP , 0x00
.equ STATE_POMODOROS_1 , 0
.equ STATE_PAUSE_1 , 1
.equ STATE_POMODOROS_2 , 2
.equ STATE_PAUSE_2 , 3
.equ STATE_POMODOROS_3 , 4
.equ STATE_PAUSE_3 , 5
.equ STATE_POMODOROS_4 , 6
.equ STATE_DONE , 7
.text
;;;
;;; setup interrupt vectors trampolines
;;;
main: .org 0x0000
rjmp reset ; reset interrupt vector
reti
rjmp button ; pin change interrupt
reti
reti
reti
reti
reti
reti
reti
rjmp tick ; timer0 overflow interrupt vector
reti
reti
reti
reti
;;;
;;; button interrupt handler
;;;
button: cpi STATE, 0x00 ; do nothing if we are in startup state
brne . + 2 ; skip if not equal
reti
cpi STATE, (1 << STATE_DONE) ; soft reset program if we are in done state
breq soft_reset
mov TMP, STATE ; soft reset program if we are in a pomodoro state
andi TMP, 0b10101010
cpi TMP, 0x00
breq soft_reset
;;
;; take care of transition from PAUSE to next POMODOROS state
;;
clr SECONDS ; reset the pomodoro clock
clr MINUTES
clr ZL
clr ZH
;;
;; advance to next pomodoro state and set corresponding
;; display of leds
;;
lsl STATE ; advance state
sbrs STATE, STATE_POMODOROS_2 ; check if we are in second pomodoro state
brne . + 4 ; skip to next case if not equal
ldi DISPLAY, 0b00000011
reti
sbrs STATE, STATE_POMODOROS_3
brne . + 4
ldi DISPLAY, 0b00000111
reti
sbrs STATE, STATE_POMODOROS_4
brne . + 4
ldi DISPLAY, 0b00001111
reti
;;
;; unhandled state transition, shouldn't ever occur, just
;; a fench for following soft reset
;;
reti
;;
;; generate a soft reset of the program using watchdog
;;
soft_reset: ldi TMP, 0b00011000 ; soft reset the program using watchdog timeout
out WDTCR, TMP
reti
;;;
;;; render display and clock the pomodoro process
;;;
;;; this is called for each 5ms of time passed eg. 200 fps,
;;; each led is lit for 5ms at 200fps for lower current draw.
;;;
;;; for each 200 frames (1 second) clock the pomodoro process
;;;
tick: mov TMP, DISPLAY ; get which led to display and its on/off state
and TMP, DISPLAY_BIT
ori TMP, 0b00010000 ; important to set other bits due to out instruction
out PORTB, TMP
lsl DISPLAY_BIT ; advance display of next led
cpi DISPLAY_BIT, (1 << 4) ; check if we reached end of cylce
brne . + 2 ; skip if not equal
ldi DISPLAY_BIT, 0b00000001 ; reset cycle
cpi ZL, 0x00 ; skip animation if not loaded into Z registry
breq fin
inc ANIM_TICK_CNT ; increase anim tick counter
cpi ANIM_TICK_CNT, 25
brne fin
clr ANIM_TICK_CNT
ld DISPLAY, Z+ ; read anim frame into display
inc ANIM_FRAME ; increase current frame
cp ANIM_FRAME, ANIM_FRAME_CNT ; reset current frame if end is reached
brne fin
clr ANIM_FRAME
mov ZL, CURRENT_ANIM ; setup pause anim
clr ZH
ld ANIM_FRAME_CNT, Z+ ; get frame count and advance to first frame in anim
fin: inc TICK_CNT ; increase clock tick counter
cpi TICK_CNT, 200 ; check if counter reached 200, clock pomodoro timer
breq clock
reti
;;;
;;; clock the pomodoro process.
;;;
;;; this is called for each second passed
;;;
clock: clr TICK_CNT ; reset TICK_CNT
inc SECONDS ; increase pomodoro clock with one second
cpi SECONDS, 60 ; if we reached 60 secs, increase MINUTES counter
brne states
inc MINUTES
clr SECONDS
;; check which is our current state and call thee
;; appropiated handler for each state available
states: cpi STATE, 0x00 ; check if in statup state
breq startup
cpi STATE, (1 << STATE_DONE) ; check if in done state
breq done
mov TMP, STATE ; check if in a pomodoro state
andi TMP, 0b01010101
cpi TMP, 0x00
brne pomodoro
mov TMP, STATE ; check if in a pause state
andi TMP, 0b10101010
cpi TMP, 0x00
brne pause
;;
;; Unhandled states does nothing
;;
reti
;;
;; process the clock for startup state and handle transition
;; to next state if time has been reached
;;
startup:
cpi SECONDS, 2 ; check if we have reached end of startup state
breq . + 2 ; skip if equal
reti
clr SECONDS ; reset clock and advance to next state
clr MINUTES
ldi STATE, (1 << STATE_POMODOROS_1) ; setup next state, first pomodoro cycle
ldi DISPLAY, 0b00000001
clr ZH
clr ZL
reti
;;
;; process the clock for a pomodoros state and handle transition
;; to next pause state if time has been reached
;;
pomodoro:
cpi MINUTES, 25 ; check if we have reached end of pomodoro cycle
breq . + 2 ; skip if equal
reti
clr SECONDS ; reset clock and advance to next state
clr MINUTES
lsl STATE ; advance to next pause state
clr ZH ; setup pause led animation
ldi CURRENT_ANIM, SRAM_ANIM_PAUSE
cpi STATE, (1 << STATE_DONE) ; set done anim if last pomodoro
brne . + 2 ; skip if equal
ldi CURRENT_ANIM, SRAM_ANIM_DONE
mov ZL, CURRENT_ANIM
ld ANIM_FRAME_CNT, Z+
clr ANIM_FRAME
clr ANIM_TICK_CNT
reti
;;
;; external button is used to advance from pause state to next
;;
pause: reti
;;
;; when done is reached, a soft reset is requires to restart a pomodoro cycle using button
;;
done: reti
;;;
;;; reset and main loop
;;;
;;; initialization code, called upon program start and through reset
;;; switch and then enters the program main loop
;;;
reset: wdr ; disable the watch dog reset flag
clr TMP
out MCUSR, TMP
ldi TMP, 0b00011000
out WDTCR, TMP
ldi TMP, 0b00010000
out WDTCR, TMP
cli ; disable interrupts
;;
;; setup timer and interrupt
;;
ldi TMP, 0b00000010 ; clear on compare match
out TCCR0A, TMP
ldi TMP, 0b00000100 ; set /256 prescaler
out TCCR0B, TMP
ldi TMP, 19 ; (F_CPU / prescaler) / 200fps
out OCR0A, TMP
ldi TMP, 0b00010000 ; enable output compare match A interrupt
out TIMSK, TMP
;;
;; setup io ports
;;
ldi TMP, 0b00001111
out DDRB, TMP
ldi TMP, 0b00010000
out PORTB, TMP
;;
;; setup PCINT4 interrupt
;;
ldi TMP, 0b00100000 ; enable pin change interrupt
out GIMSK, TMP
ldi TMP, 0b00010000 ; enable PCINT4
out PCMSK, TMP
;;
;; setup sleep mode
;;
ldi TMP, 0b00100000
out MCUCR, TMP
;;
;; intialize program registers
;;
clr DISPLAY
ldi DISPLAY_BIT, 0b00000001
clr TICK_CNT
clr SECONDS
clr MINUTES
clr STATE
;;
;; store pause animation in SRAM
;;
clr ZH
ldi ZL, SRAM_ANIM_PAUSE
ldi TMP , 0x06 ; frame count
st Z+ , TMP
ldi TMP , 0b00000001
st Z+ , TMP
ldi TMP , 0b00000010
st Z+ , TMP
ldi TMP , 0b00000100
st Z+ , TMP
ldi TMP , 0b00001000
st Z+ , TMP
ldi TMP , 0b00000100
st Z+ , TMP
ldi TMP , 0b00000010
st Z+ , TMP
;;
;; store start anim in SRAM
;;
clr ZH
ldi ZL, SRAM_ANIM_START
ldi TMP, 0x2 ; frame count
st Z+ , TMP
ldi TMP , 0b00001111
st Z+ , TMP
ldi TMP , 0b00000000
st Z+ , TMP
;;
;; store done animation in SRAM
;;
clr ZH
ldi ZL, SRAM_ANIM_DONE
ldi TMP , 0x06 ; frame count
st Z+ , TMP
ldi TMP , 0b00001110
st Z+ , TMP
ldi TMP , 0b00001101
st Z+ , TMP
ldi TMP , 0b00001011
st Z+ , TMP
ldi TMP , 0b00000111
st Z+ , TMP
ldi TMP , 0b00001011
st Z+ , TMP
ldi TMP , 0b00001101
st Z+ , TMP
;;
;; setup animation for inital start state
;;
clr ZH
ldi CURRENT_ANIM, SRAM_ANIM_START
mov ZL, CURRENT_ANIM
ld ANIM_FRAME_CNT, Z+
clr ANIM_FRAME
clr ANIM_TICK_CNT
sei ; enable interrupts
;;;
;;; main loop
;;;
loop: sleep ; enter sleep
rjmp loop