debug messages + slee
[my-code/atmel.git] / beginners / season_junior.asm
1 ; season - junior
2 ;
3 ; author: hackbard@hackdaworld.dyndns.org
4 ;
5
6
7 ; at90s2313
8 ; setup:
9 ;
10 ; vcc card --- atmel vcc
11 ; vcc cam  --- 
12 ; rst cam  --- atmel int0 (pd2)
13 ; rst card --- atmel (pd4)
14 ; clk card -\ 
15 ;            -  atmel t1 (pd5)
16 ; clk cam  -/
17 ; gnd card --- gnd cam --- atmel gnd
18 ; i/o card --- atmel icp (pd6)
19 ; i/o cam  --- atmel int1 (pd3)
20
21 .include "../include/2313def.inc"
22
23
24 ; #######
25 ; defines
26 ; #######
27
28 ; baudrate = clock freq / etu
29 ; std smartcard etu: 372
30 ; other smartcards: 625
31 .equ etu = 625
32 .equ etu_h = 312
33 .equ baudrate = 8 ; UBRR value for 57600 bits/s (8mhz clock)
34
35 ; sizes
36 .equ uart_data_len = 4
37
38 ; names for registers
39 .def tmp = r16
40 .def bitcount = r17
41 .def tmp1 = r18
42 .def tmp2 = r19
43 .def byte = r20
44 .def overflow_counter = r21
45 .def counter_l = r22
46 .def counter_h = r23
47 .def state = r24
48 .def state_m = r25
49 .def mode = r26
50 .def counter_l_tmp = r27
51 .def counter_h_tmp = r28
52 .def one = r1
53 .def zero = r0
54
55 ; state
56 .equ LOW = (1<<0)
57 .equ LOW_F = 1
58 .equ HIGH = (1<<1)
59 .equ HIGH_F = 2
60 ; mode
61 .equ STUPID = (1<<0) ; forward cam <-> card communication
62 .equ STUPID_F = 1
63 .equ COOL = (1<<1) ; send time (clocks) & state via uart
64 .equ COOL_F = 2
65 .equ ELITE = (1<<2) ; create bytes, maybe even whole command arrays
66 .equ ELITE_F = 3
67 .equ GODLIKE = (1<<3) ; filter and mask for commands to card - send rejected via uart only
68 .equ GODLIKE_F = 4
69 .equ INCREDIBLE_HACK = (1<<4) ; destroy all your hardware
70 .equ INCREDIBLE_HACK_F = 5 
71 ; leds
72 .equ LED_CARD = PB0
73 .equ LED_CAM = PB1
74 .equ LED_FWD_TO_CAM = PB2
75 .equ LED_FWD_TO_CARD = PB3
76 .equ LED_OVERFLOW = PB4
77
78 ; but there is only stupid and cool mode right now %)
79
80
81 ; #############
82 ; programm code
83 ; #############
84
85 ; ------------------
86 ; interrupt vectors:
87 ; ------------------
88
89 ; reset
90 rjmp INIT
91
92 ; int0
93 rjmp RST_CAM
94
95 ; int1
96 rjmp REC_CAM
97
98 ; timer/counter capt 1
99 rjmp REC_CARD
100
101 ; timer/counter compare
102 reti
103
104 ; timer/counter overflow 1
105 rjmp T1_OVERFLOW
106
107 ; timer/counter overflow 0
108 reti
109
110 ; uart rx complete
111 reti
112
113 ; uart data register empty
114 rjmp UART_OUT
115
116 ; uart tx complete
117 reti
118
119 ; analog comparator
120 reti
121
122 ; ------------
123 ; init routine
124 ; ------------
125
126 INIT:
127
128 ; output low on rst to card while init
129 sbi DDRD,DDD4
130 cbi PORTD,PD4
131
132 ; set stackpointer
133 ldi tmp,low(RAMEND)
134 out SPL,tmp
135
136 ; enable interrupts int0,int1,sleep
137 ldi tmp,((1<<INT0)|(1<<INT1))
138 out GIMSK,tmp
139 ; int0/1 setup
140 ldi tmp,((1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10)|(1<<SE))
141 out MCUCR,tmp
142
143 ; enable t/c overflow interrupt and icp
144 ldi tmp,((1<<TOIE1)|(1<<TICIE))
145 out TIMSK,tmp
146 ; setup t/c and icp
147 ldi tmp,((1<<CS12)|(1<<CS11)|(1<<CS10)|(1<<ICNC1)|(0<<ICES1))
148 out TCCR1B,tmp
149
150 ; configure uart - interrupt enabled when i/o
151 ldi tmp,baudrate
152 out UBRR,tmp
153 sbi UCR,TXEN
154 ; debug
155 .ifdef DEBUG
156 ldi tmp,0x49
157 out UDR,tmp
158 .endif
159
160 ; enable pullups on int0, int1, clk, icp io ports
161 ldi tmp,((1<<PD2)|(1<<PD3)|(1<<PD5)|(1<<PD6))
162
163 ; pb 0-4 output high
164 ldi tmp,((1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4))
165 out DDRB,tmp
166 out PORTB,tmp
167
168 ; init registers
169 ldi bitcount,0 
170 ldi byte,0
171 ldi overflow_counter,0
172 ldi counter_l,0
173 ldi counter_h,0
174 ldi state,HIGH ; .. as waiting for falling edge of start bit
175 ldi state_m,0x03
176 ldi mode,(STUPID|COOL)
177 ldi ZH,0
178 ldi tmp,1
179 mov one,tmp
180 ldi tmp,0
181 mov zero,tmp
182
183 ; enable interrupts (global)
184 sei
185
186 ; output high on rst to card
187 sbi PORTD,PD4
188
189 ; jump to mainloop
190 rjmp MAIN
191
192 ; ------------
193 ; main routine
194 ; ------------
195
196 MAIN:
197
198 ; debug
199 .ifdef DEBUG
200 ldi tmp,0x4d
201 out UDR,tmp
202 .endif
203
204 ; sleep/wait for next interrupt
205 sleep
206
207 ; go to sleep again
208 rjmp MAIN
209
210 ; ----------------
211 ; rec_card routine
212 ; ----------------
213
214 REC_CARD:
215
216 .ifdef DEBUG
217 ldi tmp,0x52
218 out UDR,tmp
219 .endif
220
221 ; input & pullup
222 cbi DDRD,DDD6
223 sbi PORTD,PD6
224
225 ; activate led
226 sbi PORTB,LED_CAM
227 cbi PORTB,LED_CARD
228
229 ; toggle state
230 eor state,state_m
231
232 ; toggle icp sense
233 rcall TOGGLE_ICP_SENSE
234
235 ; fwd to cam if in stupid mode
236 sbrc mode,STUPID_F
237 rcall FWD_TO_CAM
238
239 ; calculate delta clocks if in cool mode
240 sbrc mode,COOL_F
241 rcall CALC_DELTA_CLOCK
242
243 ; send time and state via uart
244 sbrc mode,COOL_F
245 rcall PREPARE_UART
246
247 ; return
248 reti
249
250 ; ------------------------
251 ; calc_delta_clock routine
252 ; ------------------------
253
254 CALC_DELTA_CLOCK:
255
256 .ifdef DEBUG
257 ldi tmp,0x63
258 out UDR,tmp
259 .endif
260
261 ; store counters
262 mov counter_l_tmp,counter_l
263 mov counter_h_tmp,counter_h
264
265 ; get new ones
266 in counter_l,ICR1L
267 in counter_h,ICR1H
268
269 ; delta calc on host software by now
270
271 ; return
272 ret
273
274 ; ------------------------
275 ; toggle_icp_sense routine
276 ; ------------------------
277
278 TOGGLE_ICP_SENSE:
279
280 .ifdef DEBUG
281 ldi tmp,0x54
282 out UDR,tmp
283 .endif
284
285 ; toggle according to state
286 in tmp,TCCR1B
287 cbr tmp,ICES1
288 sbrs state,HIGH ; maybe toggle according to TCCR1B?
289 sbr tmp,ICES1
290 out TCCR1B,tmp
291
292 ; return 
293 ret
294
295 ; ------------------
296 ; fwd_to_cam routine
297 ; ------------------
298
299 FWD_TO_CAM:
300
301 .ifdef DEBUG
302 ldi tmp,0x66
303 out UDR,tmp
304 .endif
305
306 ; activate led
307 sbi PORTB,LED_FWD_TO_CARD
308 cbi PORTB,LED_FWD_TO_CAM
309
310 ; disable external interrupt 1 while toggling edge
311 in tmp,GIMSK
312 cbr tmp,INT1
313 out GIMSK,tmp
314
315 ; output state on port to cam
316 in tmp1,PORTD
317 sbr tmp1,PD3
318 sbrs state,HIGH_F
319 cbr tmp1,PD3
320
321 ; configure as output and push-pull low/high
322 sbi DDRD,DDD3
323 out PORTD,tmp1;
324
325 ; reenable external interrupt 1
326 sbr tmp,INT1
327 out GIMSK,tmp
328
329 ; return
330 ret
331
332 ; --------------------
333 ; prepare_uart routine
334 ; --------------------
335
336 PREPARE_UART:
337
338 .ifdef DEBUG
339 ldi tmp,0x50
340 out UDR,tmp
341 .endif
342
343 ; write transfer data to sram
344 ldi ZL,0x60
345 st Z+,counter_l
346 st Z+,counter_h
347 st Z+,overflow_counter
348 st Z+,state
349
350 ; enable uart data register empty interrupt
351 sbi UCR,UDRIE
352
353 ; return
354 ret
355
356
357 ; ---------------
358 ; rec_cam routine
359 ; ---------------
360
361 REC_CAM:
362
363 .ifdef DEBUG
364 ldi tmp,0x72
365 out UDR,tmp
366 .endif
367
368 ; first thing - pullup on
369 cbi DDRD,DDD3
370 sbi DDRD,PD3
371
372 ; activate led
373 sbi PORTB,LED_CARD
374 cbi PORTB,LED_CAM
375
376 ; toggle state
377 eor state,state_m
378
379 ; toggle int sense
380 rcall TOGGLE_INT_SENSE
381
382 ; fwd to card if in stupid mode
383 sbrc mode,STUPID_F
384 rcall FWD_TO_CARD
385
386 ; calculate delta clocks if in cool mode
387 sbrc mode,COOL_F
388 rcall CALC_DELTA_CLOCK
389
390 ; return
391 reti
392
393 ; ------------------------
394 ; toggle_int_sense routine
395 ; ------------------------
396
397 TOGGLE_INT_SENSE:
398
399 .ifdef DEBUG
400 ldi tmp,0x73
401 out UDR,tmp
402 .endif
403
404 in tmp,MCUCR
405 cbr tmp,ISC10
406 sbrs state,HIGH_F
407 sbr tmp,ISC10
408 out MCUCR,tmp
409
410 ; return
411 ret
412
413 ; -------------------
414 ; fwd_to_card routine
415 ; -------------------
416
417 FWD_TO_CARD:
418
419 .ifdef DEBUG
420 ldi tmp,0x46
421 out UDR,tmp
422 .endif
423
424 ; activate led
425 sbi PORTB,LED_FWD_TO_CAM
426 cbi PORTB,LED_FWD_TO_CARD
427
428 ; disable icp interrupt while toggling edge
429 in tmp,TIMSK
430 cbr tmp,TICIE
431 out TIMSK,tmp
432
433 ; output state on port to card
434 in tmp1,PORTD
435 sbr tmp1,PD6
436 sbrs state,HIGH_F
437 cbr tmp1,PD6
438
439 ; configure as output and push-pull low/high
440 sbi DDRD,DDD6
441 out PORTD,tmp1;
442
443 ; reenable icp interrupt
444 sbr tmp,TICIE
445 out TIMSK,tmp
446
447 ; return
448 ret
449
450 ; -------------------
451 ; t1_overflow routine
452 ; -------------------
453
454 T1_OVERFLOW:
455
456 .ifdef DEBUG
457 ldi tmp,0x74
458 out UDR,tmp
459 .endif
460
461 ; increment counter overflow
462 add overflow_counter,one
463
464 ; toggle led status
465 mov tmp,overflow_counter
466 and tmp,one
467 sbi PORTB,LED_OVERFLOW
468 sbrs tmp,1
469 cbi PORTB,LED_OVERFLOW
470
471 ; return
472 reti
473
474 ; ---------------
475 ; rst_cam routine
476 ; ---------------
477
478 RST_CAM:
479
480 .ifdef DEBUG
481 ldi tmp,0x69
482 out UDR,tmp
483 .endif
484
485 ; by now just jump to init
486 rjmp INIT
487
488 ; ----------------
489 ; uart_out routine
490 ; ----------------
491
492 UART_OUT:
493
494 ; disable uart data register empty interrupt
495 cbi UCR,UDRIE
496
497 ; init counter(s)
498 mov tmp,zero
499
500 ; send the data
501 rcall UART_SEND
502
503 ; return
504 reti
505
506 ; -----------------
507 ; uart_send routine
508 ; -----------------
509
510 UART_SEND:
511
512 ; read next byte from memmory and transfer via uart
513 sbic USR,UDRE
514 rcall UART_GS
515
516 ; return if everything was sent
517 cpi tmp,uart_data_len
518 brne UART_SEND
519 ret
520
521 ; ---------------
522 ; uart_gs routine
523 ; ---------------
524
525 UART_GS:
526
527
528 ; wie macht man load mit autoinc richtig?
529 ;
530
531 ; read byte from memory and write via uart
532 ld tmp1,Z+
533 out UDR,tmp1
534
535 ; increment counter (maybe needed later)
536 add tmp,one
537
538 ; return
539 ret