1 | /*
|
2 | * main.c
|
3 | *
|
4 | * Created on: 14.10.2010
|
5 | * (C) 2010 D.Goersch
|
6 | */
|
7 |
|
8 |
|
9 | #include <avr/io.h>
|
10 | #include <avr/pgmspace.h>
|
11 | #include <avr/interrupt.h>
|
12 | #include <util/delay.h>
|
13 | #include <stdint.h>
|
14 | #include "soft-pwm.h"
|
15 |
|
16 | #define DELAY_FADE 11 // wait XX ms between each fade step
|
17 | #define DELAY_LED 20 // wait XX ms between each LED
|
18 | #define DURATION_SHORT 15 // autofade off after XX sec if jumper is open (high)
|
19 | #define DURATION_LONG 25 // autofade off after XX sec if jumper is closed (low)
|
20 | #define LTR 0 // Fade fom PortA0 forwards
|
21 | #define RTL 1 // Fade from the last (amount) to PortA0 backwards
|
22 | #define OFF 0 // State of
|
23 | #define ON 1 // the LEDs
|
24 |
|
25 | uint8_t amount=0; // Amount of LEDs
|
26 | uint8_t time; // Fade-Off time
|
27 | uint8_t direction; // 0 - LTR 1 - RTL
|
28 | uint8_t state=OFF; // 0 - OFF 1 - ON
|
29 | volatile uint8_t int0=0, int1=0;// flags for interrupts
|
30 | volatile uint8_t tenms=0; // +1 each 10ms
|
31 | volatile uint8_t running=0; // +1 each second
|
32 |
|
33 | // dimming steps
|
34 | uint8_t pwmtable[32] PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11,
|
35 | 13, 16, 19, 23, 27, 32, 38, 45, 54, 64, 76,
|
36 | 91, 108, 128, 152, 181, 215, 255};
|
37 |
|
38 |
|
39 | // patchtable for outputs
|
40 | // uint8_t patchtable[24] PROGMEM = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
41 | // 10, 11, 12, 13, 14, 15, 16,
|
42 | // 17, 18, 19, 20, 21, 22, 23};
|
43 |
|
44 | // patchtable for outputs (u.wehner)
|
45 | uint8_t patchtable[24] PROGMEM = {0, 1, 2, 3, 4, 5, 6, 7, 23, 22,
|
46 | 21, 20, 19, 18, 17, 16, 8, 9,
|
47 | 10, 11, 12, 13, 14, 15};
|
48 |
|
49 |
|
50 | void init(void);
|
51 | void fade_on(uint8_t direction);
|
52 | void fade_off(uint8_t direction);
|
53 |
|
54 | int main(void)
|
55 | {
|
56 | init();
|
57 |
|
58 | for(;;)
|
59 | {
|
60 |
|
61 | if(state==OFF)
|
62 | {
|
63 | if(int0 || int1) amount = ~((PIND & 0x03) | ((PIND >>2) & 0x1C)) & 0x1f; // read PD0,1,4,5,6 as a dec. number
|
64 | if(int0) // if LEDs off, turn on LTR
|
65 | {
|
66 | state = ON;
|
67 | direction = LTR;
|
68 | fade_on(direction);
|
69 | int0 = 0;
|
70 |
|
71 | TCNT0 = 100; // Preload
|
72 | TCCR0 |= (1<<CS00) | (1<<CS02); // Timer0 prescaler 1024
|
73 | }
|
74 | else if(int1) // LEDs off, turn on RTL
|
75 | {
|
76 | state = ON;
|
77 | direction = RTL;
|
78 | fade_on(direction);
|
79 | int1 = 0;
|
80 |
|
81 | TCNT0 = 100; // Preload
|
82 | TCCR0 |= (1<<CS00) | (1<<CS02); // Timer0 prescaler 1024
|
83 | }
|
84 | }
|
85 | else if(state==ON)
|
86 | {
|
87 | if((!time & (running >= DURATION_SHORT)) | (time & (running >= DURATION_LONG))) { // turn of automaticly
|
88 | TCCR0 = 0; // disable timer0
|
89 | tenms = 0; running = 0; // reset turnoff-timer
|
90 | fade_off(direction);
|
91 | state = OFF;
|
92 |
|
93 | }
|
94 | if(int0 & (direction==LTR)) int0=0; // LEDs LTR on, left switch ignored
|
95 | else if(int1 & (direction==RTL)) int1=0; // LEDS RTL on, right switch ignored
|
96 | else if(int0 & (direction==RTL)) // LEDs RTL on, fade off on left switch
|
97 | {
|
98 | TCCR0 = 0; // disable timer0
|
99 | tenms = 0; running = 0; // reset turnoff-timer
|
100 | fade_off(direction);
|
101 | state = OFF;
|
102 | int0 = 0;
|
103 | }
|
104 | else if(int1 & (direction==LTR)) // LEDs LTR on, fade off on right switch
|
105 | {
|
106 | TCCR0 = 0; // disable timer0
|
107 | tenms = 0; running = 0; // reset turnoff-timer
|
108 | fade_off(direction);
|
109 | state = OFF;
|
110 | int1 = 0;
|
111 | }
|
112 | }
|
113 | }
|
114 | }
|
115 |
|
116 | // do basic initialisation
|
117 | void init(void)
|
118 | {
|
119 | DDRA = 0xff; // PortA
|
120 | DDRB = 0xff; // PortB
|
121 | DDRC = 0xff; // PortC as Output
|
122 | DDRD = 0x00; // PortD as Input
|
123 | PORTD = 0xff; // PullUps on PortD
|
124 |
|
125 | // moved to mainloop
|
126 | // amount = ~((PIND & 0x03) | ((PIND >>2) & 0x1C)) & 0x1f; // read PD0,1,4,5,6 as a dec. number
|
127 | time = PIND & 0x20; // read PinD5 as fadeout mode
|
128 |
|
129 | // activated in mainloop after LEDs on
|
130 | // TCCR0 |= (1<<CS00) | (1<<CS02); // Timer0 prescaler 1024
|
131 | TCNT0 = 100; // Preload
|
132 | TIMSK |= (1<<OCIE0); // enable Timer0
|
133 |
|
134 | TCCR1B = 1; // Timer1 runs full system clock
|
135 | TIMSK |= (1<<OCIE1A); // enable Timer1
|
136 |
|
137 | MCUCR |= (1<<ISC01); // INT0 on falling edge
|
138 | MCUCR |= (1<<ISC11); // INT1 on falling edge
|
139 | GICR |= (1<<INT0); // enable INT0
|
140 | GICR |= (1<<INT1); // enable INT1
|
141 |
|
142 | sei();
|
143 | }
|
144 |
|
145 | // fade the LEDs on
|
146 | void fade_on(uint8_t direction)
|
147 | {
|
148 | if (direction == LTR)
|
149 | {
|
150 | for(uint8_t led=0;led<amount;led++)
|
151 | {
|
152 | for(uint8_t bri=0;bri<32;bri++)
|
153 | {
|
154 | pwm_setting[pgm_read_byte(patchtable+led)] = pgm_read_byte(pwmtable+bri);
|
155 | // pwm_setting[patchtable[led]] = pwmtable[bri];
|
156 | _delay_ms(DELAY_FADE);
|
157 | }
|
158 | _delay_ms(DELAY_LED);
|
159 | }
|
160 | }
|
161 | else
|
162 | {
|
163 | for(uint8_t led=amount;led>0;led--)
|
164 | {
|
165 | for(uint8_t bri=0;bri<32;bri++)
|
166 | {
|
167 | pwm_setting[pgm_read_byte(patchtable+(led-1))] = pgm_read_byte(pwmtable+bri);
|
168 | _delay_ms(DELAY_FADE);
|
169 | }
|
170 | _delay_ms(DELAY_LED);
|
171 | }
|
172 | }
|
173 | }
|
174 |
|
175 | // fade the LEDs off
|
176 | void fade_off(uint8_t direction)
|
177 | {
|
178 | if (direction == LTR)
|
179 | {
|
180 | for(uint8_t led=0;led<amount;led++)
|
181 | {
|
182 | for(uint8_t bri=32;bri>0;bri--)
|
183 | {
|
184 | pwm_setting[pgm_read_byte(patchtable+led)] = pgm_read_byte(pwmtable+bri-1);
|
185 | _delay_ms(DELAY_FADE);
|
186 | }
|
187 | _delay_ms(DELAY_LED);
|
188 | }
|
189 | }
|
190 | else
|
191 | {
|
192 | for(uint8_t led=amount;led>0;led--)
|
193 | {
|
194 | for(uint8_t bri=32;bri>0;bri--)
|
195 | {
|
196 | pwm_setting[pgm_read_byte(patchtable+(led-1))] = pgm_read_byte(pwmtable+bri-1);
|
197 | _delay_ms(DELAY_FADE);
|
198 | }
|
199 | _delay_ms(DELAY_LED);
|
200 | }
|
201 | }
|
202 | }
|
203 |
|
204 | // set flags on interrupts
|
205 | ISR(INT0_vect) { int0 = 1; }
|
206 | ISR(INT1_vect) { int1 = 1; }
|
207 |
|
208 | // timer for auto-off
|
209 | ISR(TIMER0_COMP_vect)
|
210 | {
|
211 | tenms++;
|
212 | if (tenms >= 100)
|
213 | {
|
214 | running++;
|
215 | tenms = 0;
|
216 | }
|
217 | }
|