; baudrate = clock freq / etu
; std smartcard etu: 372
; other smartcards: 625
-.define clock 8000000
-.define clk_h 4000000
-.define etu 625
-.define etu_h 312
-.define baudrate 5 ; UBRR value for 76800 bits/s (8mhz clock)
+.equ etu = 625
+.equ etu_h = 312
+.equ baudrate = 8 ; UBRR value for 57600 bits/s (8mhz clock)
; sizes
-.define uart_data_len 4
+.equ uart_data_len = 4
; names for registers
.def tmp = r16
.def mode = r26
.def counter_l_tmp = r27
.def counter_h_tmp = r28
-.def address_h = r31
-.def address_l = r30
.def one = r1
.def zero = r0
; state
-.define LOW (1<<0)
-.define LOW_F 1
-.define HIGH (1<<1)
-.define HIGH_F 2
+.equ LOW = (1<<0)
+.equ LOW_F = 1
+.equ HIGH = (1<<1)
+.equ HIGH_F = 2
; mode
-.define STUPID (1<<0) ; forward cam <-> card communication
-.define STUPID_F 1
-.define COOL (1<<1) ; send time (clocks) & state via uart
-.define COOL_F 2
-.define ELITE (1<<2) ; create bytes, maybe even whole command arrays
-.define ELITE_F 3
-.define GODLIKE (1<<3) ; filter and mask for commands to card - send rejected via uart only
-.define GODLIKE_F 4
-.define INCREDIBLE_HACK (1<<4) ; destroy all your hardware
-.define INCREDIBLE_HACK_F 5
+.equ STUPID = (1<<0) ; forward cam <-> card communication
+.equ STUPID_F = 1
+.equ COOL = (1<<1) ; send time (clocks) & state via uart
+.equ COOL_F = 2
+.equ ELITE = (1<<2) ; create bytes, maybe even whole command arrays
+.equ ELITE_F = 3
+.equ GODLIKE = (1<<3) ; filter and mask for commands to card - send rejected via uart only
+.equ GODLIKE_F = 4
+.equ INCREDIBLE_HACK = (1<<4) ; destroy all your hardware
+.equ INCREDIBLE_HACK_F = 5
+; leds
+.equ LED_CARD = PB0
+.equ LED_CAM = PB1
+.equ LED_FWD_TO_CAM = PB2
+.equ LED_FWD_TO_CARD = PB3
+.equ LED_OVERFLOW = PB4
; but there is only stupid and cool mode right now %)
ldi tmp,low(RAMEND)
out SPL,tmp
-; enable interrupts int0,int1
+; enable interrupts int0,int1,sleep
ldi tmp,((1<<INT0)|(1<<INT1))
out GIMSK,tmp
; int0/1 setup
-ldi tmp,((1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10))
+ldi tmp,((1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10)|(1<<SE))
out MCUCR,tmp
; enable t/c overflow interrupt and icp
ldi tmp,baudrate
out UBRR,tmp
sbi UCR,TXEN
+; debug
+.ifdef DEBUG
+ldi tmp,0x49
+out UDR,tmp
+.endif
; enable pullups on int0, int1, clk, icp io ports
ldi tmp,((1<<PD2)|(1<<PD3)|(1<<PD5)|(1<<PD6))
+; pb 0-4 output high
+ldi tmp,((1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4))
+out DDRB,tmp
+out PORTB,tmp
+
; init registers
ldi bitcount,0
ldi byte,0
ldi state,HIGH ; .. as waiting for falling edge of start bit
ldi state_m,0x03
ldi mode,(STUPID|COOL)
-ldi address_h,0
+ldi ZH,0
ldi tmp,1
mov one,tmp
ldi tmp,0
MAIN:
-; loop and wait for interrupts
+; debug
+.ifdef DEBUG
+ldi tmp,0x4d
+out UDR,tmp
+.endif
+
+; sleep/wait for next interrupt
+sleep
+
+; go to sleep again
rjmp MAIN
; ----------------
REC_CARD:
+.ifdef DEBUG
+ldi tmp,0x52
+out UDR,tmp
+.endif
+
; input & pullup
cbi DDRD,DDD6
sbi PORTD,PD6
+; activate led
+sbi PORTB,LED_CAM
+cbi PORTB,LED_CARD
+
; toggle state
eor state,state_m
CALC_DELTA_CLOCK:
+.ifdef DEBUG
+ldi tmp,0x63
+out UDR,tmp
+.endif
+
; store counters
mov counter_l_tmp,counter_l
mov counter_h_tmp,counter_h
TOGGLE_ICP_SENSE:
+.ifdef DEBUG
+ldi tmp,0x54
+out UDR,tmp
+.endif
+
; toggle according to state
in tmp,TCCR1B
cbr tmp,ICES1
FWD_TO_CAM:
+.ifdef DEBUG
+ldi tmp,0x66
+out UDR,tmp
+.endif
+
+; activate led
+sbi PORTB,LED_FWD_TO_CARD
+cbi PORTB,LED_FWD_TO_CAM
+
; disable external interrupt 1 while toggling edge
in tmp,GIMSK
cbr tmp,INT1
PREPARE_UART:
+.ifdef DEBUG
+ldi tmp,0x50
+out UDR,tmp
+.endif
+
; write transfer data to sram
-ldi address_l,0x60
-st address_l+,counter_l
-st address_l+,counter_h
-st address_l+,overflow_counter
-st address_l+,state
+ldi ZL,0x60
+st Z+,counter_l
+st Z+,counter_h
+st Z+,overflow_counter
+st Z+,state
; enable uart data register empty interrupt
sbi UCR,UDRIE
REC_CAM:
+.ifdef DEBUG
+ldi tmp,0x72
+out UDR,tmp
+.endif
+
; first thing - pullup on
cbi DDRD,DDD3
sbi DDRD,PD3
+; activate led
+sbi PORTB,LED_CARD
+cbi PORTB,LED_CAM
+
; toggle state
eor state,state_m
TOGGLE_INT_SENSE:
+.ifdef DEBUG
+ldi tmp,0x73
+out UDR,tmp
+.endif
+
in tmp,MCUCR
cbr tmp,ISC10
sbrs state,HIGH_F
FWD_TO_CARD:
+.ifdef DEBUG
+ldi tmp,0x46
+out UDR,tmp
+.endif
+
+; activate led
+sbi PORTB,LED_FWD_TO_CAM
+cbi PORTB,LED_FWD_TO_CARD
+
; disable icp interrupt while toggling edge
in tmp,TIMSK
cbr tmp,TICIE
T1_OVERFLOW:
+.ifdef DEBUG
+ldi tmp,0x74
+out UDR,tmp
+.endif
+
; increment counter overflow
add overflow_counter,one
+; toggle led status
+mov tmp,overflow_counter
+and tmp,one
+sbi PORTB,LED_OVERFLOW
+sbrs tmp,1
+cbi PORTB,LED_OVERFLOW
+
; return
reti
RST_CAM:
+.ifdef DEBUG
+ldi tmp,0x69
+out UDR,tmp
+.endif
+
; by now just jump to init
rjmp INIT
cbi UCR,UDRIE
; init counter(s)
-mov address_l,zero
mov tmp,zero
; send the data
;
; read byte from memory and write via uart
-ld tmp1,address_l+
+ld tmp1,Z+
out UDR,tmp1
; increment counter (maybe needed later)