133 |
133 |
// ** Initialization **
|
134 |
134 |
// ********************
|
135 |
135 |
|
|
136 |
static void dset(uint8_t num)
|
|
137 |
{
|
|
138 |
PORTF|=1<<num;
|
|
139 |
}
|
|
140 |
|
|
141 |
static void dclear(uint8_t num)
|
|
142 |
{
|
|
143 |
PORTF&=~(1<<num);
|
|
144 |
}
|
|
145 |
|
136 |
146 |
/**
|
137 |
147 |
* Initializes the PWM for Orb control. This must be called before
|
138 |
148 |
* the orbs are used for them to function.
|
139 |
149 |
**/
|
140 |
150 |
void orb_init ()
|
141 |
151 |
{
|
|
152 |
// Timer mode:
|
|
153 |
// OCRnx update "immediate" is required. This leaves "Normal" mode and the
|
|
154 |
// "CTC" modes. "Normal" doesn't allow setting a reload value, and the
|
|
155 |
// prescaler is too limited. So CTC is used. CTC can match to OCRnA and
|
|
156 |
// ICRn. For the motor, OCRnA is already in use for the compare match
|
|
157 |
// output unit. So ICRn is used.
|
|
158 |
// This leaves: WGMn3:0=1100.
|
|
159 |
// This mode does not provide an overflow interrupt, so Output Compare
|
|
160 |
// has to be used instead.
|
|
161 |
|
142 |
162 |
// Enable the output ports and turn off the LEDs
|
143 |
163 |
ORBDDR |= all_orbs_mask;
|
144 |
164 |
ORBPORT &= ~all_orbs_mask;
|
... | ... | |
148 |
168 |
|
149 |
169 |
// Set up the timer
|
150 |
170 |
// Prescaler 8 is 66 ms or 15 Hz (8 MHz/prescaler 8/2^16)
|
151 |
|
TCCR3A=0;
|
|
171 |
|
|
172 |
|
|
173 |
|
|
174 |
TCCR3A=0;
|
152 |
175 |
TCCR3B=_BV(CS31); // Prescaler 8
|
153 |
|
TCCR3B=_BV(CS31) | _BV(CS30); // Prescaler 64
|
|
176 |
//TCCR3B=_BV(CS31) | _BV(CS30); // Prescaler 64
|
154 |
177 |
TCCR3C=0;
|
155 |
178 |
ETIMSK |= _BV(TOIE3) | _BV(OCIE3C); // Enable Overflow Interrupt and Output compare 3 interrupt
|
156 |
179 |
|
157 |
180 |
// Clear Timer on Compare match:
|
158 |
181 |
// Either from OCR3A (WGM3 3:0=4) or from ICR3 (WGM3 3:0=12
|
|
182 |
|
|
183 |
// DOING: Select a good reload so
|
|
184 |
// - there are 256 values (not so important)
|
|
185 |
// - the refresh rate is around 20..25 Hz
|
|
186 |
// Then, check if it can be co-used w/ the compare match output unit.
|
|
187 |
|
|
188 |
ICR3=10000; // Refresh rate (period): 10ms
|
|
189 |
OCR3C=0;
|
159 |
190 |
|
160 |
|
TCCR3B |= _BV(WGM33);
|
161 |
|
ICR3=511;
|
|
191 |
//TCCR3A |= _BV(WGM31);
|
|
192 |
TCCR3B |= _BV(WGM33) | _BV(WGM32);
|
|
193 |
|
|
194 |
// TOP is 6, counter counts 0 1 2 3 4 5 6 (7 intervals) => 8 possibilities
|
|
195 |
// OCR=0 => 1/8, OCR=7 => 8/8
|
162 |
196 |
|
163 |
|
OCR3C=127;
|
|
197 |
//OCR3C=1; // Compare after (?) 1
|
164 |
198 |
|
165 |
199 |
// Debug
|
166 |
|
DDRF=2;
|
|
200 |
DDRF=6;
|
167 |
201 |
|
168 |
|
// uint16_t i;
|
169 |
|
// uint8_t mysreg;
|
170 |
|
//
|
171 |
|
// mysreg=SREG;
|
172 |
|
// cli(); //turn off interrupts for now
|
173 |
|
//
|
174 |
|
// //init everything
|
175 |
|
//
|
176 |
|
// for (i = 0; i < ORB_COUNT; ++i) {
|
177 |
|
// ORB_STATUS.orbs[i].num = i;
|
178 |
|
// ORB_STATUS.orbs[i].angle = 1023; //127 is a pretty stupid start angle, but oh well
|
179 |
|
// ORB_STATUS.orb_angles[i] = 1023;
|
180 |
|
// }
|
181 |
|
//
|
182 |
|
// ORB_STATUS.new_angles = 1;
|
183 |
|
// ORB_STATUS.change_count = 0;
|
184 |
|
//
|
|
202 |
// In PWM mode, the OCR is double buffered (updated at TOP or BOTTOM)
|
|
203 |
|
185 |
204 |
// //init timer3
|
186 |
205 |
// TCCR3A = 0;
|
187 |
206 |
// TCCR3B = _BV(CS31); //prescale = 8
|
188 |
207 |
// TCCR3C = 0;
|
189 |
208 |
// ETIMSK |= _BV(OCIE3C); //turn on oc3c interrupt
|
190 |
209 |
// OCR3C = TCNT3+ORB_RESET;
|
191 |
|
//
|
192 |
|
// SREG=mysreg;
|
193 |
210 |
}
|
194 |
211 |
//
|
195 |
212 |
|
... | ... | |
199 |
216 |
// ****************
|
200 |
217 |
|
201 |
218 |
volatile uint8_t x;
|
|
219 |
volatile uint8_t i;
|
202 |
220 |
|
|
221 |
void orb_tick (uint8_t t)
|
|
222 |
{
|
|
223 |
x++;
|
|
224 |
}
|
|
225 |
|
203 |
226 |
SIGNAL (SIG_OVERFLOW3)
|
204 |
227 |
{
|
205 |
|
// Overflow: set debug pin
|
206 |
|
PORTF=2;
|
207 |
|
|
208 |
|
orb1_set (1,0,0);
|
209 |
|
orb2_set (1,0,0);
|
210 |
|
x=0;
|
211 |
|
OCR3C=64<<1;
|
212 |
228 |
}
|
213 |
229 |
|
|
230 |
// Timer values: 0 1 2 3 4 5 6 7 8 9
|
|
231 |
|
|
232 |
|
|
233 |
|
214 |
234 |
SIGNAL (SIG_OUTPUT_COMPARE3C)
|
215 |
235 |
{
|
216 |
|
// First match: clear debug pin
|
217 |
|
// Second match: spike on debug pin
|
218 |
|
if (x==0)
|
219 |
|
{
|
220 |
|
PORTF=0;
|
221 |
|
|
222 |
|
x=1;
|
223 |
|
orb1_set (0,0,0);
|
224 |
|
OCR3C=192<<1;
|
225 |
|
}
|
226 |
|
else if (x==1)
|
227 |
|
{
|
228 |
|
PORTF=2; PORTF=0;
|
229 |
|
PORTF=2; PORTF=0;
|
230 |
|
PORTF=2; PORTF=0;
|
231 |
|
PORTF=2; PORTF=0;
|
232 |
|
PORTF=2; PORTF=0;
|
233 |
|
PORTF=2; PORTF=0;
|
234 |
|
PORTF=2; PORTF=0;
|
235 |
|
PORTF=2; PORTF=0;
|
236 |
|
x=2;
|
237 |
|
orb2_set (0,0,0);
|
238 |
|
}
|
|
236 |
if (i==0)
|
|
237 |
{
|
|
238 |
dset (1);
|
|
239 |
dset (2);
|
|
240 |
|
|
241 |
i=1;
|
|
242 |
OCR3C=1000;
|
|
243 |
}
|
|
244 |
else if (i==1)
|
|
245 |
{
|
|
246 |
dclear (1);
|
|
247 |
|
|
248 |
OCR3C=2000;
|
|
249 |
i=2;
|
|
250 |
}
|
|
251 |
else if (i==2)
|
|
252 |
{
|
|
253 |
dclear (2);
|
|
254 |
|
|
255 |
OCR3C=0;
|
|
256 |
i=0;
|
|
257 |
}
|
239 |
258 |
}
|
240 |
259 |
|
241 |
260 |
|