Project

General

Profile

Statistics
| Revision:

root / branches / rbom / code / projects / colonet / testing / dongle / robot_receiver / lights.c @ 1390

History | View | Annotate | Download (6.02 KB)

1 13 emarinel
/*
2
lights.c
3
Controls led_user (small green LED) and the ORB (big light)
4

5
author: CMU Robotics Club, Colony Project
6
*/
7
8
#include "lights.h"
9
#include "firefly+_lib.h"
10
11
// the below comment may not be correct
12
// Initializes timer2 to count every 0.5 us, overflowing every 16.32 ms (because we set the counter to start at 0x8000)
13
void orb_init()
14
{
15
#ifndef FFPP
16
        //enable the data direction register on the 3 orb LEDs
17
        DDRE |= _BV(REDLED) | _BV(GREENLED) | _BV(BLUELED);
18
19
        TCCR3A = 0xA9;  // COM## set to noninvert, WGM 1:0 set to 1
20
        TCCR3B = 0x0C;  // High bits to 0, WGM 3:2 set to 1, prescaler to 8
21
22
// clear Output Compare Registers
23
        OCR3AH=0x00;
24
        OCR3AL=0x00;
25
        OCR3BH=0x00;
26
        OCR3BL=0x00;
27
        OCR3CH=0x00;
28
        OCR3CL=0x00;
29
30
#else
31
        tlc5940init();
32
#endif
33
}
34
35
// Sets the red, green and blue elements of the LED with 8-bit resolution
36
void orb_set(unsigned int red_led, unsigned int green_led, unsigned int blue_led)
37
{
38
#ifdef FFPP
39
        orbs[28]=blue_led<<4;
40
        orbs[29]=green_led<<4;
41
        orbs[30]=red_led<<4;
42
        tlc_send();
43
#else
44
        OCR3AL = red_led;
45
        OCR3BL = green_led;
46
        OCR3CL = blue_led;
47
#endif
48
}
49
50
void orb_set_color(int col)
51
{
52
 int red, green, blue;
53
54
 red = ((col & 0xE0) >> 5) * 36;
55
 green = ((col & 0x1C) >> 2) * 36;
56
 blue = (col & 0x03) * 85;
57
58
 orb_set(red, green, blue);
59
}
60
61
// Disables the timer1 interrupt, disabling the Orb's color fading capabilities
62
// You can still turn the red, green, and blue leds on and off with set_orb_dio
63
void orb_disable()
64
{
65
#ifndef FFPP
66
        TCCR3A = 0x01;  // COM## disconnected, WGM 1:0 set to 1
67
#endif
68
}
69
70
// Enables the timer1 interrupt, enabling the Orb's color fading capabilities
71
void orb_enable()
72
{
73
#ifndef FFPP
74
        TCCR3A = 0xA9;  // COM## set to noninvert, WGM 1:0 set to 1
75
#else
76
        tlc5940init();
77
#endif
78
}
79
80
81
/*
82
This function turns each Orb element on or off
83
Useful for using the Orb for debugging purposes without
84
the overhead of the software PWM routine used for color fading.
85
*/
86
void orb_set_dio(int red, int green, int blue)
87
{
88
#ifdef FFPP
89
        orb_set(red*255, green*255, blue*255);
90
#else
91
        if(red == 0)
92
                PORTE &= (0xFF - _BV(REDLED));
93
        else
94
                PORTE |= _BV(REDLED);
95
96
97
        if(green == 0)
98
                PORTE &= (0xFF - _BV(GREENLED));
99
        else
100
                PORTE |= _BV(GREENLED);
101
102
103
        if(blue == 0)
104
                PORTE &= (0xFF - _BV(BLUELED));
105
        else
106
                PORTE |= _BV(BLUELED);
107
#endif
108
}
109
110
111
/////////////////////////////////////////
112
///////////    user LED   ///////////////
113
/////////////////////////////////////////
114
void led_init( void )
115
{
116
#ifdef FFPP
117
        tlc5940init();
118
#else
119
        DDRG |= _BV(USERLED);
120
#endif
121
}
122
123
void led_user(int value)
124
{
125
#ifdef FFPP
126
        orbs[USERLED]=value*4095;
127
        tlc_send();
128
#else
129
        if(value == 0)
130
                PORTG &= (0xFF - _BV(USERLED));
131
        else
132
                PORTG |= _BV(USERLED);
133
#endif
134
}
135
136
137
138
139
140
#ifdef FFPP
141
//no send
142
void orb_set_num_ns(unsigned char num, unsigned int red_led, unsigned int green_led, unsigned int blue_led)
143
{
144
        int high = (num>4);
145
        orbs[3*num+high]=blue_led<<4;
146
        orbs[3*num+1+high]=green_led<<4;
147
        orbs[3*num+2+high]=red_led<<4;
148
}
149
150
void orb_set_num(unsigned char num, unsigned int red_led, unsigned int green_led, unsigned int blue_led)
151
{
152
        orb_set_num_ns(num,red_led,green_led,blue_led);
153
        tlc_send();
154
}
155
156
157
void orb_send(){
158
        tlc_send();
159
}
160
161
void tlc_clock1(int data)
162
{
163
  PORTC &= ~0x02;
164
  PORTC |= (data << 1)&0x02;
165
  _delay_us(1);
166
  PORTC |= 0x04;
167
  _delay_us(1);
168
  PORTC &= ~0x04;
169
}
170
171
void tlc_clock2(int data)
172
{
173
  PORTC &= ~0x01;
174
  PORTC |= (data)&0x01;
175
 // _delay_us(1);
176
  PORTC |= 0x04;
177
 // _delay_us(1);
178
  PORTC &= ~0x04;
179
}
180
181
void tlc_send(void)
182
{
183
  int i,j;
184
  for(j = 15; j >= 0; j--)
185
  {
186
    for(i = 11; i >= 0; i--)
187
    {
188
      PORTC &= ~0x03;
189
      PORTC |= ((orbs[j]>>i)&0x01);
190
      PORTC |= ((orbs[j+16]>>i)<<1)&0x02;
191
      // _delay_us(1);
192
      PORTC |= 0x04;
193
      // _delay_us(1);
194
      PORTC &= ~0x04;
195
    }
196
  }
197
  PORTC |= 0x08;
198
  PORTC &= ~(0x08);
199
}
200
/*
201
void tlc_send2(int value)
202
{
203
  int i;
204

205
  for(i = 11; i >= 0; i--)
206
  {
207
    tlc_clock2(0x01 & (value >> i));
208
  }
209
}*/
210
211
void tlc_latch(void)
212
{
213
  PORTC |= 0x08;
214
//  _delay_us(1);
215
  PORTC &= ~(0x08);
216
}
217
218
void tlc5940init(void)
219
{
220
  int i;
221
222
  // set PC0...5 to outputs
223
  DDRC |= 0x3F;
224
  DDRE |= 0x08;
225
  DDRA |= 0x80;
226
  // unblank buffer
227
  PORTC &= ~0x10;
228
229
  // set DC mode so we start in known state
230
  PORTC |= 0x20;
231
  delay_ms(2);
232
233
  // set DC to all 1's?  needed?
234
/*  for(i = 0; i < 96; ++i)
235
  {
236
    tlc_clock1(1);
237
  }
238
  tlc_latch();
239
  */
240
  for(i=0;i<32;i++)
241
  {
242
    orbs[i]=4095;
243
  }
244
  tlc_send();
245
246
  delay_ms(2);
247
248
  // set GS mode
249
  PORTC &= ~0x20;
250
251
  // clock in 0s to do init case
252
/*  for(i = 0; i < 16; ++i)
253
  {
254
    tlc_send1(0);
255
  }
256
  tlc_latch();*/
257
  for(i=0;i<32;i++)
258
  {
259
    orbs[i]=4095;
260
  }
261
  tlc_send();
262
  // extra clock needed after DC -> GS transition
263
  tlc_clock1(0);
264
  tlc_clock2(0); //probably not needed
265
266
  TCCR3A |=_BV(COM3A0);
267
  TCCR3B |= _BV(CS30)|_BV(WGM32); //prescaler
268
  OCR3A = 1;
269
  TCNT3 = 0;
270
 // ETIMSK |=_BV(OCIE3A);//interrupt
271
272
273
  TCCR2 = 0x05; //prescaler
274
  TIMSK |= _BV(OCIE2);//interrupt
275
  OCR2 = 16;
276
  TCNT2 = 0;
277
  sei();
278
279
}
280
281
//int blankcounter = 0;
282
char status = 0;
283
284
ISR(TIMER2_COMP_vect){
285
//        int i = 0;
286
        //status=!status;
287
        //if(status){
288
                PORTC |= 0x10;
289
//                for(i=0;i<1;i++);
290
                PORTC &= ~0x10;
291
//        }
292
293
        TCNT2=0;
294
        //chirp(250, 150);
295
}
296
297
void silly_clock(void)
298
{
299
 /* int i;
300

301
  DDRA |= 0x80;
302

303
  PORTC |= 0x10;
304
  _delay_us(1);
305

306
  for(i = 0; i < 4095; ++i)
307
  {
308
    PORTA |= 0x80;
309
    _delay_us(1);
310
    PORTA &= ~(0x80);
311
        _delay_us(1);
312
  }
313
  */
314
//  delay_ms(1);
315
}
316
317
void tlc5940test()
318
{
319
  int j, k;
320
321
  tlc5940init();
322
323
        // fade up
324
        for(j = 0; j < 4096; ++j)
325
        {
326
327
          //tlc_send1(j);
328
329
          for(k = 0; k < 8; ++k)
330
          {
331
      orbs[2*k]=4096-j;
332
      orbs[2*k+1]=j;
333
      orbs[2*k+16]=0;
334
      orbs[2*k+17]=j;
335
          }
336
          tlc_send();
337
        }
338
339
        delay_ms(1000);
340
341
        // fade down
342
        for(j = 0; j < 4096; ++j)
343
        {
344
345
          //tlc_send(4095 - j);
346
347
          for(k = 0; k < 32; ++k)
348
          {
349
      orbs[k]=4096-j;
350
    }
351
          tlc_send();
352
        }
353
}
354
355
#endif