~ubuntu-branches/ubuntu/vivid/avr-libc/vivid

« back to all changes in this revision

Viewing changes to doc/examples/asmdemo/isrs.S

  • Committer: Package Import Robot
  • Author(s): Hakan Ardo
  • Date: 2014-06-03 14:25:22 UTC
  • mfrom: (1.2.6)
  • Revision ID: package-import@ubuntu.com-20140603142522-76ia7366969f7jc2
Tags: 1:1.8.0+Atmel3.4.4-1
* New upstream release from Atmel-AVR-GNU-Toolchain v3.4.4
  (http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-
  Toolchain/3.4.4/) (closes: #740391, #739953, #695514, #719635)
* Moved manpages to the 3avr section of /usr/share/man
* Added avr-man manpage (closes: #733939)
* Added build-arch and build-indep targets
* Moved build to binary-indep target
* Increased standards version to 3.9.5
* Added ${misc:Depends} dependency
* Applied upstream fix to make pgmspace.h ansi compatible (closes:
  #675759)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
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
 
 * ----------------------------------------------------------------------------
8
 
 *
9
 
 * Demo combining C and assembly source files.
10
 
 *
11
 
 * $Id: isrs.S 1124 2006-08-29 19:45:06Z joerg_wunsch $
12
 
 */
13
 
/*
14
 
 * This file contains the interrupt service routine implementations
15
 
 * when compiling the project for the ATtiny13 target.
16
 
 */
17
 
 
18
 
#include <avr/io.h>
19
 
 
20
 
#include "project.h"
21
 
 
22
 
#if defined(__AVR_ATtiny13__)
23
 
 
24
 
/*
25
 
 * Timer 0 hit TOP (0xff), i.e. it turns from up-counting
26
 
 * into down-counting direction.
27
 
 */
28
 
.global TIM0_COMPA_vect
29
 
TIM0_COMPA_vect:
30
 
        in      sreg_save, _SFR_IO_ADDR(SREG)
31
 
        inc     counter_hi
32
 
        clr     flags
33
 
        out     _SFR_IO_ADDR(SREG), sreg_save
34
 
        reti
35
 
 
36
 
/*
37
 
 * Timer 0 hit BOTTOM (0x00), i.e. it turns from down-counting
38
 
 * into up-counting direction.
39
 
 */
40
 
.global TIM0_OVF_vect
41
 
TIM0_OVF_vect:
42
 
        in      sreg_save, _SFR_IO_ADDR(SREG)
43
 
        inc     counter_hi
44
 
        ser     flags
45
 
        out     _SFR_IO_ADDR(SREG), sreg_save
46
 
        reti
47
 
 
48
 
;;; one 16-bit word to store our rising edge's timestamp
49
 
.lcomm  starttime.0, 2
50
 
 
51
 
.extern pwm_incoming
52
 
.extern intbits
53
 
 
54
 
.global PCINT0_vect
55
 
PCINT0_vect:
56
 
        in      sreg_save, _SFR_IO_ADDR(SREG)
57
 
 
58
 
        ;; save our working registers
59
 
        push    r18
60
 
        push    r19
61
 
        push    r20
62
 
        push    r21
63
 
 
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
73
 
        ;; be correct.
74
 
        sei
75
 
        in      r20, _SFR_IO_ADDR(TCNT0)
76
 
        cli
77
 
        ;; Now, make our working copy of the status,
78
 
        ;; so we can re-enable interrupts again.
79
 
        mov     r21, counter_hi
80
 
        mov     r19, flags
81
 
        sei
82
 
 
83
 
        ;; what direction were we counting?
84
 
        sbrs    r19, 0
85
 
        ;; we are down-counting, invert TCNT0
86
 
        com     r20
87
 
        ;; at this point, r21:20 has our current
88
 
        ;; 16-bit time
89
 
 
90
 
        ;; now, look which of the edges triggered
91
 
        ;; our pin-change interrupt
92
 
        sbis    _SFR_IO_ADDR(PINB), 4
93
 
        rjmp    10f
94
 
        ;; rising edge detected, just record starttime
95
 
        sts     (starttime.0) + 1, r21
96
 
        sts     starttime.0, r20
97
 
        rjmp    99f             ; we are done here
98
 
 
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.
103
 
 
104
 
10:     in      r18, _SFR_IO_ADDR(GIMSK)
105
 
        andi    r18, ~(1 << PCIE)
106
 
        out     _SFR_IO_ADDR(GIMSK), r18
107
 
 
108
 
        ;; pwm_incoming = current_time - starttime
109
 
        lds     r19, (starttime.0) + 1
110
 
        lds     r18, starttime.0
111
 
        sub     r20, r18
112
 
        sbc     r21, r19
113
 
        sts     (pwm_incoming) + 1, r21
114
 
        sts     pwm_incoming, r20
115
 
 
116
 
        ;; signal upper layer
117
 
        lds     r18, intbits
118
 
        ori     r18, 1
119
 
        sts     intbits, r18
120
 
99:
121
 
        pop     r21
122
 
        pop     r20
123
 
        pop     r19
124
 
        pop     r18
125
 
 
126
 
        out     _SFR_IO_ADDR(SREG), sreg_save
127
 
        reti
128
 
#endif  /* ATtiny13 */