2
* ----------------------------------------------------------------------------
3
* "THE BEER-WARE LICENSE" (Revision 42):
4
* Joerg Wunsch wrote this file. As long as you retain this notice you
5
* can do whatever you want with this stuff. If we meet some day, and you think
6
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
7
* ----------------------------------------------------------------------------
9
* Demo combining C and assembly source files.
11
* $Id: isrs.S 1124 2006-08-29 19:45:06Z joerg_wunsch $
14
* This file contains the interrupt service routine implementations
15
* when compiling the project for the ATtiny13 target.
22
#if defined(__AVR_ATtiny13__)
25
* Timer 0 hit TOP (0xff), i.e. it turns from up-counting
26
* into down-counting direction.
28
.global TIM0_COMPA_vect
30
in sreg_save, _SFR_IO_ADDR(SREG)
33
out _SFR_IO_ADDR(SREG), sreg_save
37
* Timer 0 hit BOTTOM (0x00), i.e. it turns from down-counting
38
* into up-counting direction.
42
in sreg_save, _SFR_IO_ADDR(SREG)
45
out _SFR_IO_ADDR(SREG), sreg_save
48
;;; one 16-bit word to store our rising edge's timestamp
56
in sreg_save, _SFR_IO_ADDR(SREG)
58
;; save our working registers
64
;; Now that we are ready to fetch the current
65
;; value of TCNT0, allow interrupts for a
66
;; moment. As the effect of the SEI will be
67
;; deferred by one instruction, any possible
68
;; rollover of TCNT0 (hitting BOTTOM when
69
;; counting down, or MAX when counting up) will
70
;; allow the above ISRs to trigger right here,
71
;; and update their status, so our combined
72
;; 16-bit time from [counter_hi, TCNT0] will
75
in r20, _SFR_IO_ADDR(TCNT0)
77
;; Now, make our working copy of the status,
78
;; so we can re-enable interrupts again.
83
;; what direction were we counting?
85
;; we are down-counting, invert TCNT0
87
;; at this point, r21:20 has our current
90
;; now, look which of the edges triggered
91
;; our pin-change interrupt
92
sbis _SFR_IO_ADDR(PINB), 4
94
;; rising edge detected, just record starttime
95
sts (starttime.0) + 1, r21
97
rjmp 99f ; we are done here
99
;; Falling edge: compute pulse width, store it
100
;; into pwm_incoming, disable pin-change
101
;; interrupt until the upper layers had a chance
102
;; to fetch the result.
104
10: in r18, _SFR_IO_ADDR(GIMSK)
105
andi r18, ~(1 << PCIE)
106
out _SFR_IO_ADDR(GIMSK), r18
108
;; pwm_incoming = current_time - starttime
109
lds r19, (starttime.0) + 1
113
sts (pwm_incoming) + 1, r21
114
sts pwm_incoming, r20
116
;; signal upper layer
126
out _SFR_IO_ADDR(SREG), sreg_save
128
#endif /* ATtiny13 */