Revision 583
finished my lights driver, but it doesn't work; it turns the lights on to one color, and they stay that way, no matter what.
lights.c | ||
---|---|---|
26 | 26 |
|
27 | 27 |
// an orb node |
28 | 28 |
struct ORB_NODE { |
29 |
int is_changed; |
|
30 |
uint16_t new_angle; |
|
29 | 31 |
uint8_t num; |
30 | 32 |
uint16_t angle; |
31 | 33 |
uint16_t port_val; |
32 |
int time_split; // this will store the amount of time the timer needs to be set to from previous pin |
|
33 | 34 |
} ORB_NODE; |
34 | 35 |
|
36 |
struct ORB_SMALL { |
|
37 |
int number; |
|
38 |
int split; |
|
39 |
} ORB_SMALL; |
|
40 |
|
|
41 |
struct ORB_SORT { |
|
42 |
struct ORB_SMALL orbs[ORB_COUNT]; |
|
43 |
} ORB_SORT; |
|
44 |
|
|
35 | 45 |
// the status of the orbs |
36 | 46 |
struct ORB_STATUS_STRUCT { |
37 | 47 |
struct ORB_NODE orbs[ORB_COUNT]; |
38 |
int changes[ORB_COUNT]; // when an orb changes, its number will go from 0 to 1 |
|
39 |
uint8_t change_count; |
|
40 | 48 |
uint8_t new_angles; |
41 | 49 |
uint8_t current_orb; |
42 | 50 |
} ORB_STATUS; |
43 | 51 |
|
44 |
struct ORB_CHANGED_ORBS { |
|
45 |
int orb_number; |
|
46 |
uint16_t new_angle; |
|
47 |
} ORB_CHANGED_ORBS; |
|
48 |
|
|
49 |
struct ORB_CHANGED_ORBS_STRUCT { |
|
50 |
struct ORB_CHANGED_ORBS changed_orbs[ORB_COUNT]; |
|
51 |
} ORB_CHANGED_ORBS_STRUCT; |
|
52 |
|
|
53 |
struct ORB_ORDER { // 0 will store number of first orb to turn off, 1 of second, etc. |
|
54 |
int order[ORB_COUNT]; |
|
55 |
} ORB_ORDER; |
|
56 |
|
|
57 | 52 |
void sort_orbs(void); // this function will copy new values into angle values |
58 |
void calc_split_times(void); // this function will calculate split times and place them in the appropriate orbs |
|
53 |
//void calc_split_times(void); // this function will calculate split times and place them in the appropriate orbs
|
|
59 | 54 |
|
60 | 55 |
// use compare C to reset every pulse + check new times |
61 |
SIGNAL (SIG_OUTPUT_COMPARE3C){
|
|
56 |
SIGNAL (TIMER3_COMPC_vect){
|
|
62 | 57 |
|
63 | 58 |
ORB_STATUS.current_orb=0; // reset the orb we're looking at |
64 | 59 |
|
65 |
if(ORB_STATUS.change_count>0)
|
|
60 |
if(ORB_STATUS.new_angles>0)
|
|
66 | 61 |
{ |
62 |
uint8_t mysreg; |
|
63 |
mysreg=SREG; |
|
64 |
cli(); |
|
67 | 65 |
sort_orbs(); |
68 |
calc_split_times(); |
|
66 |
SREG = mysreg; |
|
67 |
ORB_STATUS.new_angles=0; |
|
68 |
//calc_split_times(); |
|
69 | 69 |
} |
70 | 70 |
|
71 | 71 |
// now that we've done everything, turn on all the lights |
72 | 72 |
ORB_PORT |= ORBMASK; |
73 | 73 |
// reset the time |
74 | 74 |
OCR3C = TCNT3+ORB_RESET; |
75 |
// turn ocr3a back on and set the time for the lights off counter
|
|
76 |
ETIMSK |= _BV(OCIE3A); //turn on oc3a interrupt
|
|
77 |
OCR3A = TCNT3+ORB_STATUS.orbs[0].time_split; //set time
|
|
75 |
// turn ocr3b back on and set the time for the lights off counter
|
|
76 |
ETIMSK |= _BV(OCIE3B); //turn on oc3b interrupt
|
|
77 |
OCR3B = TCNT3+ORB_SORT.orbs[0].split; //set time
|
|
78 | 78 |
|
79 | 79 |
} |
80 | 80 |
|
81 | 81 |
// use compare A for turning lights off |
82 |
SIGNAL (SIG_OUTPUT_COMPARE3A){
|
|
82 |
SIGNAL (TIMER3_COMPB_vect){
|
|
83 | 83 |
//pull the correct ones down |
84 |
ORBPORT &= ~(ORB_STATUS.orbs[ORB_ORDER.order[ORB_STATUS.current_orb]].port_val); |
|
84 |
int i; |
|
85 |
|
|
86 |
ORBPORT &= ~(ORB_STATUS.orbs[ORB_SORT.orbs[ORB_STATUS.current_orb].number].port_val); |
|
85 | 87 |
|
86 | 88 |
int num_updated_orbs = 1; |
87 |
// HERE, YOU ALSO NEED TO CHECK IF ANY OTHER ORBS HAVE THE SAME TIME!!!!!!!!!!!!!!!!@#!#!@#!@#!@#, update num updated |
|
89 |
// check if any of the others have the same time |
|
90 |
for(i=ORB_STATUS.current_orb+1;i<ORB_COUNT;i++) |
|
91 |
{ |
|
92 |
if(ORB_SORT.orbs[i].split==ORB_SORT.orbs[i-1].split) |
|
93 |
{ |
|
94 |
ORBPORT &= ~(ORB_STATUS.orbs[ORB_SORT.orbs[i].number].port_val); |
|
95 |
num_updated_orbs++; |
|
96 |
} |
|
97 |
else |
|
98 |
{ |
|
99 |
break; |
|
100 |
} |
|
101 |
} |
|
88 | 102 |
|
89 | 103 |
ORB_STATUS.current_orb+=num_updated_orbs; //now look at next orb transition |
90 | 104 |
|
91 | 105 |
if (ORB_STATUS.current_orb < ORB_COUNT) { //if it isnt the end... |
92 | 106 |
//setup timer for next pull down |
93 |
OCR3C = TCNT3+ORB_STATUS.orbs[ORB_STATUS.current_orb].time_split;
|
|
107 |
OCR3B = TCNT3+(ORB_SORT.orbs[ORB_STATUS.current_orb].split - ORB_SORT.orbs[ORB_STATUS.current_orb-1].split);
|
|
94 | 108 |
|
95 | 109 |
} |
96 | 110 |
else { //we are done with these pulses |
97 | 111 |
//turn off this timer until it is reset |
98 |
ETIMSK &= ~(_BV(OCIE3A));
|
|
112 |
ETIMSK &= ~(_BV(OCIE3B));
|
|
99 | 113 |
} |
100 | 114 |
|
101 | 115 |
} |
102 | 116 |
|
117 |
void sort_orbs(void) |
|
118 |
{ |
|
119 |
int i; |
|
120 |
int j; |
|
121 |
// first, we copy in new values |
|
122 |
for(i=0;i<ORB_COUNT; i++) |
|
123 |
{ |
|
124 |
if(ORB_STATUS.orbs[i].is_changed==1) |
|
125 |
{ |
|
126 |
ORB_STATUS.orbs[i].is_changed=0; |
|
127 |
ORB_STATUS.orbs[i].angle=ORB_STATUS.orbs[i].new_angle; |
|
128 |
} |
|
129 |
} |
|
130 |
|
|
131 |
// next, we fill in ORB_SORT |
|
132 |
for(i=0;i<ORB_COUNT;i++) |
|
133 |
{ |
|
134 |
ORB_SORT.orbs[i].number=i; |
|
135 |
ORB_SORT.orbs[i].split=ORB_STATUS.orbs[i].angle; |
|
136 |
} |
|
137 |
|
|
138 |
// and now we sort it |
|
139 |
for(i=0;i<ORB_COUNT;i++) |
|
140 |
{ |
|
141 |
int min = ORB_SORT.orbs[i].split; |
|
142 |
int index = i; |
|
143 |
for(j=i+1;j<ORB_COUNT;i++) |
|
144 |
{ |
|
145 |
if(ORB_SORT.orbs[j].split < min) |
|
146 |
{ |
|
147 |
min=ORB_SORT.orbs[j].split; |
|
148 |
index=j; |
|
149 |
} |
|
150 |
} |
|
151 |
struct ORB_SMALL tmporb=ORB_SORT.orbs[i]; |
|
152 |
ORB_SORT.orbs[i]=ORB_SORT.orbs[index]; |
|
153 |
ORB_SORT.orbs[index]=tmporb; |
|
154 |
} |
|
155 |
|
|
156 |
// now, calculate split times; up till now, the time is stored as 0-255, now convert it to clock cycles |
|
157 |
for(i=0;i<ORB_COUNT;i++) |
|
158 |
{ |
|
159 |
ORB_SORT.orbs[i].split=ORB_RESET/255*ORB_SORT.orbs[i].split; |
|
160 |
} |
|
161 |
} |
|
162 |
|
|
103 | 163 |
void orb_init() |
104 | 164 |
{ |
105 | 165 |
uint8_t mysreg; |
... | ... | |
110 | 170 |
mysreg=SREG; |
111 | 171 |
cli(); //turn off interrupts for now |
112 | 172 |
|
173 |
ORB_STATUS.new_angles=0; |
|
174 |
|
|
113 | 175 |
//we're looking at the 1st orb |
114 | 176 |
ORB_STATUS.current_orb=0; |
115 | 177 |
//store values |
... | ... | |
117 | 179 |
ORB_STATUS.orbs[i].num = i; |
118 | 180 |
//i'm not sure why he starts at 1023, so i'm making it 0 for now |
119 | 181 |
ORB_STATUS.orbs[i].angle = 0; //1023; //127 is a pretty stupid start angle, but oh well |
120 |
ORB_STATUS.changes[i]=1; // each orb has been "changed" |
|
182 |
ORB_STATUS.orbs[i].is_changed=1; // each orb has been "changed" |
|
183 |
ORB_STATUS.orbs[i].new_angle = 0; |
|
184 |
ORB_SORT.orbs[i].split=0; |
|
185 |
ORB_SORT.orbs[i].number=i; |
|
121 | 186 |
} |
187 |
ORB_STATUS.new_angles=1; |
|
122 | 188 |
ORB_STATUS.orbs[0].port_val=ORB1_RED; |
123 | 189 |
ORB_STATUS.orbs[1].port_val=ORB1_GREEN; |
124 | 190 |
ORB_STATUS.orbs[2].port_val=ORB1_BLUE; |
... | ... | |
131 | 197 |
TCCR3B = _BV(CS31); //set a prescale of 8 |
132 | 198 |
TCCR3C = 0; // sets normal operation |
133 | 199 |
ETIMSK |= _BV(OCIE3C); //turn on oc3c interrupt |
134 |
ETIMSK |= _BV(OCIE3A); //turn on oc3a interrupt
|
|
200 |
ETIMSK |= _BV(OCIE3B); //turn on oc3b interrupt
|
|
135 | 201 |
OCR3C = TCNT3+ORB_RESET; // WHAT HAPPENS IF THE TIMER IS ON FOR A VERY LONG TIME; OVERFLOW? |
136 |
OCR3A = TCNT3+ORB_RESET;
|
|
202 |
OCR3B = TCNT3+ORB_RESET/2;
|
|
137 | 203 |
|
138 | 204 |
SREG=mysreg; |
139 | 205 |
} |
... | ... | |
144 | 210 |
|
145 | 211 |
orb=orb&0x07; //only have 8 |
146 | 212 |
angle=angle&0xff; //only accept 0-255 |
147 |
angle=255-angle; //inverse intensity |
|
148 | 213 |
|
149 |
/* |
|
150 |
angle=angle<<2; //scale up so that we dont run it too often |
|
151 |
angle+=3; //0 values dont really work |
|
152 |
*/ |
|
153 |
|
|
154 | 214 |
// check if the angle is different, if it is, update our status |
155 | 215 |
if(angle!=ORB_STATUS.orbs[orb].angle) |
156 | 216 |
{ |
157 |
ORB_STATUS.new_angles++; |
|
158 |
ORB_STATUS.changes[orb]=1; |
|
217 |
mysreg=SREG; |
|
218 |
cli(); |
|
219 |
ORB_STATUS.new_angles=1; |
|
220 |
ORB_STATUS.orbs[orb].is_changed=1; |
|
221 |
ORB_STATUS.orbs[orb].new_angle = angle; |
|
222 |
SREG = mysreg; |
|
159 | 223 |
} |
160 |
|
|
161 |
mysreg=SREG; |
|
162 |
cli(); |
|
163 |
ORB_CHANGED_ORBS_STRUCT.changed_orbs[orb].new_angle=angle; |
|
164 |
// ORB_STATUS.orbs[orb].angle = angle; //update angle |
|
165 |
SREG = mysreg; |
|
166 |
|
|
167 |
// dont see why you need to track changes, so might as well just change it |
|
168 |
/* |
|
169 |
mysreg=SREG; |
|
170 |
cli(); |
|
171 |
ORB_STATUS.orb_angles[orb] = angle; //update angle |
|
172 |
SREG = mysreg; |
|
173 |
*/ |
|
174 |
/* |
|
175 |
if (ORB_STATUS.orb_angles[orb] != angle) { //if the angle has changed |
|
176 |
mysreg=SREG; |
|
177 |
cli(); //disable interrupts |
|
178 |
ORB_STATUS.orb_angles[orb] = angle; //update angle |
|
179 |
ORB_STATUS.new_angles = 1; |
|
180 |
SREG=mysreg; //put interrupt status back |
|
181 |
} |
|
182 |
*/ |
|
183 | 224 |
} |
184 | 225 |
|
185 | 226 |
void orb1_set(unsigned char red, unsigned char green, unsigned char blue) |
Also available in: Unified diff