fixed st and ld to sram - theoretically working now :)
[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 = 5 ; UBRR value for 76800 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
72 ; but there is only stupid and cool mode right now %)
73
74
75 ; #############
76 ; programm code
77 ; #############
78
79 ; ------------------
80 ; interrupt vectors:
81 ; ------------------
82
83 ; reset
84 rjmp INIT
85
86 ; int0
87 rjmp RST_CAM
88
89 ; int1
90 rjmp REC_CAM
91
92 ; timer/counter capt 1
93 rjmp REC_CARD
94
95 ; timer/counter compare
96 reti
97
98 ; timer/counter overflow 1
99 rjmp T1_OVERFLOW
100
101 ; timer/counter overflow 0
102 reti
103
104 ; uart rx complete
105 reti
106
107 ; uart data register empty
108 rjmp UART_OUT
109
110 ; uart tx complete
111 reti
112
113 ; analog comparator
114 reti
115
116 ; ------------
117 ; init routine
118 ; ------------
119
120 INIT:
121
122 ; output low on rst to card while init
123 sbi DDRD,DDD4
124 cbi PORTD,PD4
125
126 ; set stackpointer
127 ldi tmp,low(RAMEND)
128 out SPL,tmp
129
130 ; enable interrupts int0,int1
131 ldi tmp,((1<<INT0)|(1<<INT1))
132 out GIMSK,tmp
133 ; int0/1 setup
134 ldi tmp,((1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10))
135 out MCUCR,tmp
136
137 ; enable t/c overflow interrupt and icp
138 ldi tmp,((1<<TOIE1)|(1<<TICIE))
139 out TIMSK,tmp
140 ; setup t/c and icp
141 ldi tmp,((1<<CS12)|(1<<CS11)|(1<<CS10)|(1<<ICNC1)|(0<<ICES1))
142 out TCCR1B,tmp
143
144 ; configure uart - interrupt enabled when i/o
145 ldi tmp,baudrate
146 out UBRR,tmp
147 sbi UCR,TXEN
148
149 ; enable pullups on int0, int1, clk, icp io ports
150 ldi tmp,((1<<PD2)|(1<<PD3)|(1<<PD5)|(1<<PD6))
151
152 ; init registers
153 ldi bitcount,0 
154 ldi byte,0
155 ldi overflow_counter,0
156 ldi counter_l,0
157 ldi counter_h,0
158 ldi state,HIGH ; .. as waiting for falling edge of start bit
159 ldi state_m,0x03
160 ldi mode,(STUPID|COOL)
161 ldi ZH,0
162 ldi tmp,1
163 mov one,tmp
164 ldi tmp,0
165 mov zero,tmp
166
167 ; enable interrupts (global)
168 sei
169
170 ; output high on rst to card
171 sbi PORTD,PD4
172
173 ; jump to mainloop
174 rjmp MAIN
175
176 ; ------------
177 ; main routine
178 ; ------------
179
180 MAIN:
181
182 ; loop and wait for interrupts
183 rjmp MAIN
184
185 ; ----------------
186 ; rec_card routine
187 ; ----------------
188
189 REC_CARD:
190
191 ; input & pullup
192 cbi DDRD,DDD6
193 sbi PORTD,PD6
194
195 ; toggle state
196 eor state,state_m
197
198 ; toggle icp sense
199 rcall TOGGLE_ICP_SENSE
200
201 ; fwd to cam if in stupid mode
202 sbrc mode,STUPID_F
203 rcall FWD_TO_CAM
204
205 ; calculate delta clocks if in cool mode
206 sbrc mode,COOL_F
207 rcall CALC_DELTA_CLOCK
208
209 ; send time and state via uart
210 sbrc mode,COOL_F
211 rcall PREPARE_UART
212
213 ; return
214 reti
215
216 ; ------------------------
217 ; calc_delta_clock routine
218 ; ------------------------
219
220 CALC_DELTA_CLOCK:
221
222 ; store counters
223 mov counter_l_tmp,counter_l
224 mov counter_h_tmp,counter_h
225
226 ; get new ones
227 in counter_l,ICR1L
228 in counter_h,ICR1H
229
230 ; delta calc on host software by now
231
232 ; return
233 ret
234
235 ; ------------------------
236 ; toggle_icp_sense routine
237 ; ------------------------
238
239 TOGGLE_ICP_SENSE:
240
241 ; toggle according to state
242 in tmp,TCCR1B
243 cbr tmp,ICES1
244 sbrs state,HIGH ; maybe toggle according to TCCR1B?
245 sbr tmp,ICES1
246 out TCCR1B,tmp
247
248 ; return 
249 ret
250
251 ; ------------------
252 ; fwd_to_cam routine
253 ; ------------------
254
255 FWD_TO_CAM:
256
257 ; disable external interrupt 1 while toggling edge
258 in tmp,GIMSK
259 cbr tmp,INT1
260 out GIMSK,tmp
261
262 ; output state on port to cam
263 in tmp1,PORTD
264 sbr tmp1,PD3
265 sbrs state,HIGH_F
266 cbr tmp1,PD3
267
268 ; configure as output and push-pull low/high
269 sbi DDRD,DDD3
270 out PORTD,tmp1;
271
272 ; reenable external interrupt 1
273 sbr tmp,INT1
274 out GIMSK,tmp
275
276 ; return
277 ret
278
279 ; --------------------
280 ; prepare_uart routine
281 ; --------------------
282
283 PREPARE_UART:
284
285 ; write transfer data to sram
286 ldi ZL,0x60
287 st Z+,counter_l
288 st Z+,counter_h
289 st Z+,overflow_counter
290 st Z+,state
291
292 ; enable uart data register empty interrupt
293 sbi UCR,UDRIE
294
295 ; return
296 ret
297
298
299 ; ---------------
300 ; rec_cam routine
301 ; ---------------
302
303 REC_CAM:
304
305 ; first thing - pullup on
306 cbi DDRD,DDD3
307 sbi DDRD,PD3
308
309 ; toggle state
310 eor state,state_m
311
312 ; toggle int sense
313 rcall TOGGLE_INT_SENSE
314
315 ; fwd to card if in stupid mode
316 sbrc mode,STUPID_F
317 rcall FWD_TO_CARD
318
319 ; calculate delta clocks if in cool mode
320 sbrc mode,COOL_F
321 rcall CALC_DELTA_CLOCK
322
323 ; return
324 reti
325
326 ; ------------------------
327 ; toggle_int_sense routine
328 ; ------------------------
329
330 TOGGLE_INT_SENSE:
331
332 in tmp,MCUCR
333 cbr tmp,ISC10
334 sbrs state,HIGH_F
335 sbr tmp,ISC10
336 out MCUCR,tmp
337
338 ; return
339 ret
340
341 ; -------------------
342 ; fwd_to_card routine
343 ; -------------------
344
345 FWD_TO_CARD:
346
347 ; disable icp interrupt while toggling edge
348 in tmp,TIMSK
349 cbr tmp,TICIE
350 out TIMSK,tmp
351
352 ; output state on port to card
353 in tmp1,PORTD
354 sbr tmp1,PD6
355 sbrs state,HIGH_F
356 cbr tmp1,PD6
357
358 ; configure as output and push-pull low/high
359 sbi DDRD,DDD6
360 out PORTD,tmp1;
361
362 ; reenable icp interrupt
363 sbr tmp,TICIE
364 out TIMSK,tmp
365
366 ; return
367 ret
368
369 ; -------------------
370 ; t1_overflow routine
371 ; -------------------
372
373 T1_OVERFLOW:
374
375 ; increment counter overflow
376 add overflow_counter,one
377
378 ; return
379 reti
380
381 ; ---------------
382 ; rst_cam routine
383 ; ---------------
384
385 RST_CAM:
386
387 ; by now just jump to init
388 rjmp INIT
389
390 ; ----------------
391 ; uart_out routine
392 ; ----------------
393
394 UART_OUT:
395
396 ; disable uart data register empty interrupt
397 cbi UCR,UDRIE
398
399 ; init counter(s)
400 mov tmp,zero
401
402 ; send the data
403 rcall UART_SEND
404
405 ; return
406 reti
407
408 ; -----------------
409 ; uart_send routine
410 ; -----------------
411
412 UART_SEND:
413
414 ; read next byte from memmory and transfer via uart
415 sbic USR,UDRE
416 rcall UART_GS
417
418 ; return if everything was sent
419 cpi tmp,uart_data_len
420 brne UART_SEND
421 ret
422
423 ; ---------------
424 ; uart_gs routine
425 ; ---------------
426
427 UART_GS:
428
429
430 ; wie macht man load mit autoinc richtig?
431 ;
432
433 ; read byte from memory and write via uart
434 ld tmp1,Z+
435 out UDR,tmp1
436
437 ; increment counter (maybe needed later)
438 add tmp,one
439
440 ; return
441 ret