File: tc5.cpp

package info (click to toggle)
simulavr 1.0.0%2Bgit20160221.e53413b-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 5,748 kB
  • sloc: cpp: 35,491; python: 6,991; ansic: 3,567; makefile: 1,072; sh: 653; asm: 414; tcl: 320
file content (175 lines) | stat: -rw-r--r-- 2,827 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>

uint8_t vector[100];
unsigned int index=0;

extern "C"
{
    void stopsim();
}

void Record()
{
    vector[index++]=PORTC;
}

void FireINT0()
{
    PORTD|= ( 1 << 2 ); // INT0
}

void FireINT1()
{
    PORTD|= ( 1 << 3 ); // INT1 
}

void FireINT2()
{
    PORTB|= ( 1 << 2 ); // INT2 
}

void ResetINT0()
{
    PORTD&= 0xff - ( 1 << 2 ); // INT0
}

void ResetINT1()
{
    PORTD&= 0xff- ( 1 << 3 ); // INT1
}

void ResetINT2()
{
    PORTB&= 0xff-( 1 << 2 ); // INT2
}

void stopsim()
{
    while(1);
}

int main()
{
    // set PORTS to 0
    DDRB = 0xff;
    PORTB = 0x00;

    DDRD = 0xff;
    PORTD = 0x00;

    // use PORT C for LEDS
    DDRC = 0xff;
    // switch them off ( invers )
    PORTC = 0x0f;


    //Setup INT1 + INT0 to rising edge
    MCUCR = (1 << ISC11 ) | ( 1 << ISC10 )| // INT1
        ( 1 << ISC01 ) | ( 1 << ISC00 ) ;   // INT0

    MCUCSR = (1 << ISC2 ); // INT2 auf rising edge

    GICR = ( 1<< INT1 )| ( 1 << INT0 ) | ( 1 << INT2 ); // INT0..3 active


    // fire the interrupts
    FireINT0();
    FireINT1();
    FireINT2();

    _NOP();
    sei();
    cli();  // expect no irq
    Record();   // index[0] -> 0x0f;

    // now we only want to see the first interrupt
    sei(); 
    _NOP(); // exactly the first irq should fire
    cli(); // and nothing more
    Record(); // index[1] -> 0x0e;

    // now again lets fire the next pending irq
    sei();
    _NOP();
    cli();
    Record();   // index[2] -> 0x0c;

    // and now we get the last irq
    sei();
    _NOP();
    cli();
    Record();   // index[3] -> 0x08;

    cli();

    // now reset the ports
    ResetINT0();
    ResetINT1();
    ResetINT2();

    // CLear LED Port
    PORTC = 0x0f;

    // now checking for correct ordering
    FireINT2(); // lowest order
    sei(); 
    cli(); // nothing should happen
    Record();   // index[4] -> 0x0f;

    // now fire another irq with higher prio 
    FireINT1(); // mid prio
    sei();
    _NOP();
    cli(); 
    Record(); // index[5] -> 0x0d;

    FireINT0();
    sei();
    _NOP();
    cli();
    Record();   //index[6] -> 0x0c;

    // now the pending INT2 should run
    sei();
    _NOP();
    cli();
    Record();   // index[7] -> 0x08;

    // now reset the ports
    ResetINT0();
    ResetINT1();
    ResetINT2();

    // CLear LED Port
    PORTC = 0x0f;

    // now we do it faster...
    PORTB|= ( 1 << 2 ); // INT2
    sei(); 
    PORTD|= ( 1 << 2 ); // INT0
    cli();
    Record(); // index[8] -> 0x0b   // actual not checked WRONG ORDER TODO
    sei();
    _NOP();
    cli();

    Record(); // index[9] -> 0x0a;  // actual not checked WRONG ORDER TODO

    //stopsim();
}

ISR( INT0_vect )
{
    PORTC &= 0xff-1;
}
ISR( INT1_vect )
{
    PORTC &= 0xff-2;
}
ISR( INT2_vect )
{
    PORTC &= 0xff-4;
}