86873a6ec55a500bf82e8fe44364354c13aa90e8
[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
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))
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
155 ; enable pullups on int0, int1, clk, icp io ports
156 ldi tmp,((1<<PD2)|(1<<PD3)|(1<<PD5)|(1<<PD6))
157
158 ; pb 0-4 output high
159 ldi tmp,((1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4))
160 out DDRB,tmp
161 out PORTB,tmp
162
163 ; init registers
164 ldi bitcount,0 
165 ldi byte,0
166 ldi overflow_counter,0
167 ldi counter_l,0
168 ldi counter_h,0
169 ldi state,HIGH ; .. as waiting for falling edge of start bit
170 ldi state_m,0x03
171 ldi mode,(STUPID|COOL)
172 ldi ZH,0
173 ldi tmp,1
174 mov one,tmp
175 ldi tmp,0
176 mov zero,tmp
177
178 ; enable interrupts (global)
179 sei
180
181 ; output high on rst to card
182 sbi PORTD,PD4
183
184 ; jump to mainloop
185 rjmp MAIN
186
187 ; ------------
188 ; main routine
189 ; ------------
190
191 MAIN:
192
193 ; loop and wait for interrupts
194 rjmp MAIN
195
196 ; ----------------
197 ; rec_card routine
198 ; ----------------
199
200 REC_CARD:
201
202 ; input & pullup
203 cbi DDRD,DDD6
204 sbi PORTD,PD6
205
206 ; activate led
207 sbi PORTB,LED_CAM
208 cbi PORTB,LED_CARD
209
210 ; toggle state
211 eor state,state_m
212
213 ; toggle icp sense
214 rcall TOGGLE_ICP_SENSE
215
216 ; fwd to cam if in stupid mode
217 sbrc mode,STUPID_F
218 rcall FWD_TO_CAM
219
220 ; calculate delta clocks if in cool mode
221 sbrc mode,COOL_F
222 rcall CALC_DELTA_CLOCK
223
224 ; send time and state via uart
225 sbrc mode,COOL_F
226 rcall PREPARE_UART
227
228 ; return
229 reti
230
231 ; ------------------------
232 ; calc_delta_clock routine
233 ; ------------------------
234
235 CALC_DELTA_CLOCK:
236
237 ; store counters
238 mov counter_l_tmp,counter_l
239 mov counter_h_tmp,counter_h
240
241 ; get new ones
242 in counter_l,ICR1L
243 in counter_h,ICR1H
244
245 ; delta calc on host software by now
246
247 ; return
248 ret
249
250 ; ------------------------
251 ; toggle_icp_sense routine
252 ; ------------------------
253
254 TOGGLE_ICP_SENSE:
255
256 ; toggle according to state
257 in tmp,TCCR1B
258 cbr tmp,ICES1
259 sbrs state,HIGH ; maybe toggle according to TCCR1B?
260 sbr tmp,ICES1
261 out TCCR1B,tmp
262
263 ; return 
264 ret
265
266 ; ------------------
267 ; fwd_to_cam routine
268 ; ------------------
269
270 FWD_TO_CAM:
271
272 ; activate led
273 sbi PORTB,LED_FWD_TO_CARD
274 cbi PORTB,LED_FWD_TO_CAM
275
276 ; disable external interrupt 1 while toggling edge
277 in tmp,GIMSK
278 cbr tmp,INT1
279 out GIMSK,tmp
280
281 ; output state on port to cam
282 in tmp1,PORTD
283 sbr tmp1,PD3
284 sbrs state,HIGH_F
285 cbr tmp1,PD3
286
287 ; configure as output and push-pull low/high
288 sbi DDRD,DDD3
289 out PORTD,tmp1;
290
291 ; reenable external interrupt 1
292 sbr tmp,INT1
293 out GIMSK,tmp
294
295 ; return
296 ret
297
298 ; --------------------
299 ; prepare_uart routine
300 ; --------------------
301
302 PREPARE_UART:
303
304 ; write transfer data to sram
305 ldi ZL,0x60
306 st Z+,counter_l
307 st Z+,counter_h
308 st Z+,overflow_counter
309 st Z+,state
310
311 ; enable uart data register empty interrupt
312 sbi UCR,UDRIE
313
314 ; return
315 ret
316
317
318 ; ---------------
319 ; rec_cam routine
320 ; ---------------
321
322 REC_CAM:
323
324 ; first thing - pullup on
325 cbi DDRD,DDD3
326 sbi DDRD,PD3
327
328 ; activate led
329 sbi PORTB,LED_CARD
330 cbi PORTB,LED_CAM
331
332 ; toggle state
333 eor state,state_m
334
335 ; toggle int sense
336 rcall TOGGLE_INT_SENSE
337
338 ; fwd to card if in stupid mode
339 sbrc mode,STUPID_F
340 rcall FWD_TO_CARD
341
342 ; calculate delta clocks if in cool mode
343 sbrc mode,COOL_F
344 rcall CALC_DELTA_CLOCK
345
346 ; return
347 reti
348
349 ; ------------------------
350 ; toggle_int_sense routine
351 ; ------------------------
352
353 TOGGLE_INT_SENSE:
354
355 in tmp,MCUCR
356 cbr tmp,ISC10
357 sbrs state,HIGH_F
358 sbr tmp,ISC10
359 out MCUCR,tmp
360
361 ; return
362 ret
363
364 ; -------------------
365 ; fwd_to_card routine
366 ; -------------------
367
368 FWD_TO_CARD:
369
370 ; activate led
371 sbi PORTB,LED_FWD_TO_CAM
372 cbi PORTB,LED_FWD_TO_CARD
373
374 ; disable icp interrupt while toggling edge
375 in tmp,TIMSK
376 cbr tmp,TICIE
377 out TIMSK,tmp
378
379 ; output state on port to card
380 in tmp1,PORTD
381 sbr tmp1,PD6
382 sbrs state,HIGH_F
383 cbr tmp1,PD6
384
385 ; configure as output and push-pull low/high
386 sbi DDRD,DDD6
387 out PORTD,tmp1;
388
389 ; reenable icp interrupt
390 sbr tmp,TICIE
391 out TIMSK,tmp
392
393 ; return
394 ret
395
396 ; -------------------
397 ; t1_overflow routine
398 ; -------------------
399
400 T1_OVERFLOW:
401
402 ; increment counter overflow
403 add overflow_counter,one
404
405 ; toggle led status
406 mov tmp,overflow_counter
407 and tmp,one
408 sbi PORTB,LED_OVERFLOW
409 sbrs tmp,1
410 cbi PORTB,LED_OVERFLOW
411
412 ; return
413 reti
414
415 ; ---------------
416 ; rst_cam routine
417 ; ---------------
418
419 RST_CAM:
420
421 ; by now just jump to init
422 rjmp INIT
423
424 ; ----------------
425 ; uart_out routine
426 ; ----------------
427
428 UART_OUT:
429
430 ; disable uart data register empty interrupt
431 cbi UCR,UDRIE
432
433 ; init counter(s)
434 mov tmp,zero
435
436 ; send the data
437 rcall UART_SEND
438
439 ; return
440 reti
441
442 ; -----------------
443 ; uart_send routine
444 ; -----------------
445
446 UART_SEND:
447
448 ; read next byte from memmory and transfer via uart
449 sbic USR,UDRE
450 rcall UART_GS
451
452 ; return if everything was sent
453 cpi tmp,uart_data_len
454 brne UART_SEND
455 ret
456
457 ; ---------------
458 ; uart_gs routine
459 ; ---------------
460
461 UART_GS:
462
463
464 ; wie macht man load mit autoinc richtig?
465 ;
466
467 ; read byte from memory and write via uart
468 ld tmp1,Z+
469 out UDR,tmp1
470
471 ; increment counter (maybe needed later)
472 add tmp,one
473
474 ; return
475 ret