Project

General

Profile

Statistics
| Revision:

root / branches / rbom / code / projects / colonet / utilities / robot_wireless_relay / lights.c @ 1390

History | View | Annotate | Download (6.06 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
#ifdef FFPP
137
//no send
138
void orb_set_num_ns(unsigned char num, unsigned int red_led,
139
                    unsigned int green_led, unsigned int blue_led)
140
{
141
        int high = (num>4);
142
        orbs[3*num+high]=blue_led<<4;
143
        orbs[3*num+1+high]=green_led<<4;
144
        orbs[3*num+2+high]=red_led<<4;
145
}
146
147
void orb_set_num(unsigned char num, unsigned int red_led,
148
                 unsigned int green_led, unsigned int blue_led)
149
{
150
        orb_set_num_ns(num,red_led,green_led,blue_led);
151
        tlc_send();
152
}
153
154
void orb_send(){
155
        tlc_send();
156
}
157
652879
158
void tlc_clock1(int data)
159
{
160
  PORTC &= ~0x02;
161
  PORTC |= (data << 1)&0x02;
162
  _delay_us(1);
163
  PORTC |= 0x04;
164
  _delay_us(1);
165
  PORTC &= ~0x04;
166
}
167
168
void tlc_clock2(int data)
169
{
170
  PORTC &= ~0x01;
171
  PORTC |= (data)&0x01;
172
 // _delay_us(1);
173
  PORTC |= 0x04;
174
 // _delay_us(1);
175
  PORTC &= ~0x04;
176
}
177
178
void tlc_send(void)
179
{
180
  int i,j;
181
  for(j = 15; j >= 0; j--)
182
  {
183
    for(i = 11; i >= 0; i--)
184
    {
185
      PORTC &= ~0x03;
186
      PORTC |= ((orbs[j]>>i)&0x01);
187
      PORTC |= ((orbs[j+16]>>i)<<1)&0x02;
188
      // _delay_us(1);
189
      PORTC |= 0x04;
190
      // _delay_us(1);
191
      PORTC &= ~0x04;
192
    }
193
  }
194
  PORTC |= 0x08;
195
  PORTC &= ~(0x08);
196
}
197
/*
198
void tlc_send2(int value)
199
{
200
  int i;
201

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

298
  DDRA |= 0x80;
299

300
  PORTC |= 0x10;
301
  _delay_us(1);
302

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