Subversion Repositories HomeAutomation

Rev

Rev 546 | Rev 584 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 546 Rev 563
1
/**
1
/**
2
 * CAN RGB LED. This application is used to control a RGB LED.
2
 * CAN RGB LED. This application is used to control a RGB LED.
3
 * Still under heavy development
3
 * Still under heavy development
4
 *
4
 *
5
 * @date    2007-02-10
5
 * @date    2007-02-10
6
 * @author  Martin Nordén
6
 * @author  Martin Nordén
7
 *
7
 *
8
 * TODO: Better CAN Integration, Failsafe mode, Tempsensors etc.
8
 * TODO: Better CAN Integration, Failsafe mode, Tempsensors etc.
9
 * Also, check current/destination intensity better when in a program?
9
 * Also, check current/destination intensity better when in a program?
10
 *
10
 *
11
 * A little comment here :)
11
 * A little comment here :)
12
 */
12
 */
13
 
13
 
14
 
14
 
15
/*-----------------------------------------------------------------------------
15
/*-----------------------------------------------------------------------------
16
 * Includes
16
 * Includes
17
 *---------------------------------------------------------------------------*/
17
 *---------------------------------------------------------------------------*/
18
/* system files */
18
/* system files */
19
#include <avr/interrupt.h>
19
#include <avr/interrupt.h>
20
#include <inttypes.h>
20
#include <inttypes.h>
21
#include <stdio.h>
21
#include <stdio.h>
22
#include <avr/pgmspace.h> //To allow read/write from flash
22
#include <avr/pgmspace.h> //To allow read/write from flash
23
 
23
 
24
 
24
 
25
#include <drivers/timer/timebase.h>
25
#include <drivers/timer/timebase.h>
26
 
26
 
27
#include <config.h> // All configuration parameters
27
#include <config.h> // All configuration parameters
28
#include <bios.h>   // BIOS interface declarations, including CAN structure and ID defines.
28
#include <bios.h>   // BIOS interface declarations, including CAN structure and ID defines.
29
 
29
 
30
#include <string.h> //for memcpy
30
#include <string.h> //for memcpy
31
/* lib files */
31
/* lib files */
32
#include <bios.h>
32
#include <bios.h>
33
//#include <funcdefs/funcdefs.h>
33
//#include <funcdefs/funcdefs.h>
34
 
34
 
35
#include <settings.h>
35
//#include <settings.h> //Migrated to config.inc
36
 
36
 
37
/*----------------------------------------------------------------------------
37
/*----------------------------------------------------------------------------
38
 * Defines
38
 * Defines
39
 * -------------------------------------------------------------------------*/
39
 * -------------------------------------------------------------------------*/
40
 
40
 
41
//Working on implementing all of these...
41
//Working on implementing all of these...
42
 
42
 
43
#define RGBLED_CMD_STATUS           0x00    /* Get status */
43
#define RGBLED_CMD_STATUS           0x00    /* Get status */
44
#define RGBLED_CMD_SETRGB           0x01    /* Set RGB Triplet */
44
#define RGBLED_CMD_SETRGB           0x01    /* Set RGB Triplet */
45
#define RGBLED_CMD_CHANGERGB        0x02    /* Change RGB +/- */
45
#define RGBLED_CMD_CHANGERGB        0x02    /* Change RGB +/- */
46
#define RGBLED_CMD_SETPROGRAM       0x03  /* Set program */
46
#define RGBLED_CMD_SETPROGRAM       0x03  /* Set program */
47
#define RGBLED_CMD_SETFADESPEED     0x04  /* Set fadespeed */
47
#define RGBLED_CMD_SETFADESPEED     0x04  /* Set fadespeed */
48
#define RGBLED_CMD_SETDIMSPEED      0x05  /* Set dimspeed */
48
#define RGBLED_CMD_SETDIMSPEED      0x05  /* Set dimspeed */
49
#define RGBLED_CMD_SETINTENS        0x10  /* Set intensity */
49
#define RGBLED_CMD_SETINTENS        0x10  /* Set intensity */
50
 
50
 
51
#define APP_TYPE    CAN_APPTYPES_RGBLED
51
#define APP_TYPE    CAN_APPTYPES_RGBLED
52
#define APP_VERSION 0x0001
52
#define APP_VERSION 0x0001
53
 
53
 
54
#define GROUP_ID    0x01L // FIXME
54
#define GROUP_ID    0x01L // FIXME
55
#define TRUE 1
55
#define TRUE 1
56
#define FALSE !TRUE
56
#define FALSE !TRUE
57
 
57
 
58
 
58
 
59
/*----------------------------------------------------------------------------
59
/*----------------------------------------------------------------------------
60
 * Ehm, struct?
60
 * Ehm, struct?
61
 * -------------------------------------------------------------------------*/
61
 * -------------------------------------------------------------------------*/
62
typedef struct
62
typedef struct
63
{
63
{
64
    uint8_t R;
64
    uint8_t R;
65
    uint8_t G;
65
    uint8_t G;
66
    uint8_t B;
66
    uint8_t B;
67
    uint8_t Intens;
67
    uint8_t Intens;
68
} Color;
68
} Color;
69
 
69
 
70
/*-----------------------------------------------------------------------------
70
/*-----------------------------------------------------------------------------
71
 * Programs! There will be a better way to add programs here.. some day.
71
 * Programs! There will be a better way to add programs here.. some day.
72
 *---------------------------------------------------------------------------*/
72
 *---------------------------------------------------------------------------*/
73
 
73
 
74
//Special combinations that means something special
74
//Special combinations that means something special
75
//The combinations are useless for lighting anyway
75
//The combinations are useless for lighting anyway
76
//So we might as well use them!
76
//So we might as well use them!
77
//0x00, 0x00, 0x00, 0x00 means end of program, keep looping it
77
//0x00, 0x00, 0x00, 0x00 means end of program, keep looping it
78
//0x00, 0x00, 0x00, 0x01 means end of program, halt 
78
//0x00, 0x00, 0x00, 0x01 means end of program, halt 
79
 
79
 
80
Color pgm1[] PROGMEM = {
80
Color pgm1[] PROGMEM = {
81
{0xff,0x00,0x00,0x64},
81
{0xff,0x00,0x00,0x64},
82
{0xff,0xff,0x00,0x10},
82
{0xff,0xff,0x00,0x10},
83
{0x00,0xff,0x00,0xa0},
83
{0x00,0xff,0x00,0xa0},
84
{0x00,0xff,0xff,0x7f},
84
{0x00,0xff,0xff,0x7f},
85
{0x00,0x00,0xff,0x7f},
85
{0x00,0x00,0xff,0x7f},
86
{0xff,0x00,0xff,0x40},
86
{0xff,0x00,0xff,0x40},
87
{0x00,0x00,0x00,0x00}
87
{0x00,0x00,0x00,0x00}
88
};
88
};
89
 
89
 
90
Color pgm2[] PROGMEM = {
90
Color pgm2[] PROGMEM = {
91
{0xff,0x00,0x00,0x00},
91
{0xff,0x00,0x00,0x00},
92
{0xff,0xff,0x00,0x00},
92
{0xff,0xff,0x00,0x00},
93
{0xff,0xff,0xff,0x00},
93
{0xff,0xff,0xff,0x00},
94
{0xa0,0x00,0xa0,0x00},
94
{0xa0,0x00,0xa0,0x00},
95
{0x00,0x00,0xff,0x00},
95
{0x00,0x00,0xff,0x00},
96
{0x00,0x00,0x00,0x00}
96
{0x00,0x00,0x00,0x00}
97
};
97
};
98
 
98
 
99
Color pgm3[] PROGMEM = {
99
Color pgm3[] PROGMEM = {
100
{0xff,0xff,0xff,0x00},
100
{0xff,0xff,0xff,0x00},
101
{0x00,0x00,0x00,0x01}
101
{0x00,0x00,0x00,0x01}
102
};
102
};
103
 
103
 
104
Color* programs[] PROGMEM = {
104
Color* programs[] PROGMEM = {
105
(Color*)pgm1,
105
(Color*)pgm1,
106
(Color*)pgm2,
106
(Color*)pgm2,
107
(Color*)pgm3
107
(Color*)pgm3
108
};
108
};
109
 
109
 
110
 
110
 
111
 
111
 
112
/*-----------------------------------------------------------------------------
112
/*-----------------------------------------------------------------------------
113
 * Global variables
113
 * Global variables
114
 *---------------------------------------------------------------------------*/
114
 *---------------------------------------------------------------------------*/
115
uint32_t timeStamp; //TimeStamp to keep track of time
115
uint32_t timeStamp; //TimeStamp to keep track of time
116
uint32_t dimStamp;  //Timestamp to keep track of dimmer changes
116
uint32_t dimStamp;  //Timestamp to keep track of dimmer changes
117
 
117
 
118
Color currColor;    //Current color
118
Color currColor;    //Current color
119
Color destColor;    //Destination color
119
Color destColor;    //Destination color
120
 
120
 
121
uint16_t fadeSpeed; //Fadingspeed. 16bit for reaaaally slow fading. Sets the speed of colorchange.
121
uint16_t fadeSpeed; //Fadingspeed. 16bit for reaaaally slow fading. Sets the speed of colorchange.
122
uint8_t dimSpeed;       //Dimmer speed. Sets the speed of intensitychange.
122
uint8_t dimSpeed;       //Dimmer speed. Sets the speed of intensitychange.
123
 
123
 
124
uint8_t currProgram;    //This variable keeps track of what program is currently running. 
124
uint8_t currProgram;    //This variable keeps track of what program is currently running. 
125
uint8_t programMode;    //This keeps track of what mode we are currently using. 0: the program obeyes the current brightness, 1: the program is allowed to set it's own brightness
125
uint8_t programMode;    //This keeps track of what mode we are currently using. 0: the program obeyes the current brightness, 1: the program is allowed to set it's own brightness
126
 
126
 
127
Can_Message_t txMsg;    //Transmit message storage
127
Can_Message_t txMsg;    //Transmit message storage
128
 
128
 
129
volatile Can_Message_t rxMsg; // Message storage
129
volatile Can_Message_t rxMsg; // Message storage
130
volatile uint8_t rxMsgFull;   // Synchronization flag
130
volatile uint8_t rxMsgFull;   // Synchronization flag
131
 
131
 
132
/*----------------------------------------------------------------------------
132
/*----------------------------------------------------------------------------
133
 * Functions
133
 * Functions
134
 * -------------------------------------------------------------------------*/
134
 * -------------------------------------------------------------------------*/
135
void updateLED(void);
135
void updateLED(void);
136
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright);
136
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright);
137
void changeColor(int8_t amount, uint8_t* color);
137
void changeColor(int8_t amount, uint8_t* color);
138
void fade(uint8_t* current, uint8_t* destination);
138
void fade(uint8_t* current, uint8_t* destination);
139
 
139
 
140
 
140
 
141
/* Takes care of incoming messages and parses them if this node is adressed */
141
/* Takes care of incoming messages and parses them if this node is adressed */
142
void can_receive(Can_Message_t *msg)
142
void can_receive(Can_Message_t *msg)
143
{ // CAN callback function
143
{ // CAN callback function
144
    if (!rxMsgFull) {
144
    if (!rxMsgFull) {
145
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
145
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
146
        rxMsgFull = 1;
146
        rxMsgFull = 1;
147
    }
147
    }
148
}
148
}
149
 
149
 
150
 
150
 
151
/*-----------------------------------------------------------------------------
151
/*-----------------------------------------------------------------------------
152
 * Main Program
152
 * Main Program
153
 *---------------------------------------------------------------------------*/
153
 *---------------------------------------------------------------------------*/
154
int main(void) {
154
int main(void) {
155
 
155
 
156
//Setting up OC1A, 16 bit counter used as 8 bit.
156
//Setting up OC1A, 16 bit counter used as 8 bit.
157
    TCCR1A |= (1<<COM1A1) | (1<<WGM11); /* Set OC1A at TOP, mode 14 */
157
    TCCR1A |= (1<<COM1A1) | (1<<WGM11); /* Set OC1A at TOP, mode 14 */
158
    TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS12); /* Timer uses main system clock with ? prescale */
158
    TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS12); /* Timer uses main system clock with ? prescale */
159
    ICR1 = 256; //8 bit precision to match the other two counters.
159
    ICR1 = 256; //8 bit precision to match the other two counters.
160
    OCR1A = 0;  //0% as standard
160
    OCR1A = 0;  //0% as standard
161
    DDRB |= (1<<PB1); /* Enable pin as output */
161
    DDRB |= (1<<PB1); /* Enable pin as output */
162
//Setting up OC0A
162
//Setting up OC0A
163
    TCCR0A |= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00); /* Set OC0A at TOP, Mode 7 */
163
    TCCR0A |= (1<<COM0A1)|(1<<WGM01)|(1<<WGM00); /* Set OC0A at TOP, Mode 7 */
164
    TCCR0B |= (1<<CS02); /* Prescaler updating now */
164
    TCCR0B |= (1<<CS02); /* Prescaler updating now */
165
    OCR0A = 0;  //0% standard
165
    OCR0A = 0;  //0% standard
166
    DDRD |= (1<<PD6);
166
    DDRD |= (1<<PD6);
167
//Setting up OC0B
167
//Setting up OC0B
168
    TCCR0A |= (1<<COM0B1);
168
    TCCR0A |= (1<<COM0B1);
169
    OCR0B = 0;
169
    OCR0B = 0;
170
    DDRD |= (1<<PD5);
170
    DDRD |= (1<<PD5);
171
 
171
 
172
//Initialize variables
172
//Initialize variables
173
    fadeSpeed = 10;
173
    fadeSpeed = 10;
174
    dimSpeed = 10;
174
    dimSpeed = 10;
175
    timeStamp = 0;
175
    timeStamp = 0;
176
    dimStamp = 0;
176
    dimStamp = 0;
177
 
177
 
178
    reformatRGB(0x00,0x00,0x00,1);
178
    reformatRGB(0x00,0x00,0x00,1);
179
    destColor.Intens = 50;
179
    destColor.Intens = 50;
180
    currColor = destColor;
180
    currColor = destColor;
181
 
181
 
182
//Just temporary for now, they keep track of some kind of demo-program.
182
//Just temporary for now, they keep track of some kind of demo-program.
183
    currProgram = 1;
183
    currProgram = 1;
184
    programMode = 0;
184
    programMode = 0;
185
    uint16_t temp_adress = pgm_read_word(&programs[currProgram-1]); //Get adress for program 0
185
    uint16_t temp_adress = pgm_read_word(&programs[currProgram-1]); //Get adress for program 0
186
 
186
 
187
    sei();
187
    sei();
188
 
188
 
189
    BIOS_CanCallback = &can_receive;
189
    BIOS_CanCallback = &can_receive;
190
 
190
 
191
//Send a message that we are alive!
191
//Send a message that we are alive!
192
    txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
192
    txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
193
    txMsg.DataLength = 4;
193
    txMsg.DataLength = 4;
194
    txMsg.RemoteFlag = 0;
194
    txMsg.RemoteFlag = 0;
195
    txMsg.ExtendedFlag = 1;
195
    txMsg.ExtendedFlag = 1;
196
    txMsg.Data.words[0] = APP_TYPE;
196
    txMsg.Data.words[0] = APP_TYPE;
197
    txMsg.Data.words[1] = APP_VERSION;
197
    txMsg.Data.words[1] = APP_VERSION;
198
    BIOS_CanSend(&txMsg);
198
    BIOS_CanSend(&txMsg);
199
 
199
 
200
//Lets get timebase up and running
200
//Lets get timebase up and running
201
    Timebase_Init();
201
    Timebase_Init();
202
 
202
 
203
 
203
 
204
    /* main loop */
204
    /* main loop */
205
    while (1) {
205
    while (1) {
206
       
206
       
207
        /* Time to fade color? */
207
        /* Time to fade color? */
208
        if ((Timebase_CurrentTime() - timeStamp) >= fadeSpeed) {
208
        if ((Timebase_CurrentTime() - timeStamp) >= fadeSpeed) {
209
            fade(&currColor.R, &destColor.R);          
209
            fade(&currColor.R, &destColor.R);          
210
            fade(&currColor.G, &destColor.G);
210
            fade(&currColor.G, &destColor.G);
211
            fade(&currColor.B, &destColor.B);
211
            fade(&currColor.B, &destColor.B);
212
 
212
 
213
            timeStamp = Timebase_CurrentTime();
213
            timeStamp = Timebase_CurrentTime();
214
            updateLED();
214
            updateLED();
215
        }
215
        }
216
 
216
 
217
 
217
 
218
        /* Time to fade intensity? */
218
        /* Time to fade intensity? */
219
        if (Timebase_CurrentTime() - dimStamp >= dimSpeed) {
219
        if (Timebase_CurrentTime() - dimStamp >= dimSpeed) {
220
            fade(&currColor.Intens, &destColor.Intens);
220
            fade(&currColor.Intens, &destColor.Intens);
221
            dimStamp = Timebase_CurrentTime();
221
            dimStamp = Timebase_CurrentTime();
222
            updateLED();
222
            updateLED();
223
        }
223
        }
224
 
224
 
225
 
225
 
226
        /* Program management */
226
        /* Program management */
227
        if (currProgram != 0) { //Check if a program is currently running
227
        if (currProgram != 0) { //Check if a program is currently running
228
            if ((currColor.R == destColor.R)&(currColor.G == destColor.G)&(currColor.B == destColor.B)&(currColor.Intens == destColor.Intens)){//Is the current sequence finished?
228
            if ((currColor.R == destColor.R)&(currColor.G == destColor.G)&(currColor.B == destColor.B)&(currColor.Intens == destColor.Intens)){//Is the current sequence finished?
229
                //Now we have to check if the program is finished and if we should loop
229
                //Now we have to check if the program is finished and if we should loop
230
                if ((pgm_read_byte(temp_adress)==0)&(pgm_read_byte(temp_adress+1)==0)&(pgm_read_byte(temp_adress+2)==0)){
230
                if ((pgm_read_byte(temp_adress)==0)&(pgm_read_byte(temp_adress+1)==0)&(pgm_read_byte(temp_adress+2)==0)){
231
                    //The program has ended! Shall we loop it?
231
                    //The program has ended! Shall we loop it?
232
                    if (pgm_read_byte(temp_adress+3)==0){
232
                    if (pgm_read_byte(temp_adress+3)==0){
233
                        //Yes, let's loop it
233
                        //Yes, let's loop it
234
                        temp_adress = pgm_read_word(&programs[currProgram-1]);
234
                        temp_adress = pgm_read_word(&programs[currProgram-1]);
235
                    } else {
235
                    } else {
236
                        //No, halt!
236
                        //No, halt!
237
                        currProgram = 0;
237
                        currProgram = 0;
238
                    }
238
                    }
239
                } else {
239
                } else {
240
                    //The program has not ended, let's get the next RGB-triplet!
240
                    //The program has not ended, let's get the next RGB-triplet!
241
                    destColor.R = pgm_read_byte(temp_adress);
241
                    destColor.R = pgm_read_byte(temp_adress);
242
                    destColor.G = pgm_read_byte(temp_adress + 1);
242
                    destColor.G = pgm_read_byte(temp_adress + 1);
243
                    destColor.B = pgm_read_byte(temp_adress + 2);
243
                    destColor.B = pgm_read_byte(temp_adress + 2);
244
                    if (programMode == 1){
244
                    if (programMode == 1){
245
                        destColor.Intens = pgm_read_byte(temp_adress + 3);
245
                        destColor.Intens = pgm_read_byte(temp_adress + 3);
246
                    }
246
                    }
247
 
247
 
248
                    temp_adress = temp_adress + 4;             
248
                    temp_adress = temp_adress + 4;             
249
                }
249
                }
250
 
250
 
251
            }
251
            }
252
 
252
 
253
        }
253
        }
254
 
254
 
255
 
255
 
256
        /* Check if any messages has been recieved */
256
        /* Check if any messages has been recieved */
257
        if (rxMsgFull) {
257
        if (rxMsgFull) {
258
            uint16_t acttype;
258
            uint16_t acttype;
259
            uint8_t rgbledid;
259
            uint8_t rgbledid;
260
       
260
       
261
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
261
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
262
                // Actuator package
262
                // Actuator package
263
                acttype =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
263
                acttype =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
264
                rgbledid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
264
                rgbledid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
265
               
265
               
266
                if ((acttype == ACT_TYPE_RGBLED) && (rgbledid == THISRGBLEDID)) {
266
                if ((acttype == ACT_TYPE_RGBLED) && (rgbledid == THISRGBLEDID)) {
267
                    // This is a message for this rgbled
267
                    // This is a message for this rgbled
268
                    if( rxMsg.Data.bytes[0] == RGBLED_CMD_SETPROGRAM ){
268
                    if( rxMsg.Data.bytes[0] == RGBLED_CMD_SETPROGRAM ){
269
                        /* Set a program! */
269
                        /* Set a program! */
270
                        currProgram = rxMsg.Data.bytes[1];
270
                        currProgram = rxMsg.Data.bytes[1];
271
                        temp_adress = pgm_read_word(&programs[currProgram-1]);             
271
                        temp_adress = pgm_read_word(&programs[currProgram-1]);             
272
                    } else if ( rxMsg.Data.bytes[0] == RGBLED_CMD_SETINTENS ){
272
                    } else if ( rxMsg.Data.bytes[0] == RGBLED_CMD_SETINTENS ){
273
                        /* Set intensity! */
273
                        /* Set intensity! */
274
                        if (rxMsg.Data.bytes[1] == TRUE){
274
                        if (rxMsg.Data.bytes[1] == TRUE){
275
                            currColor.Intens = rxMsg.Data.bytes[2];                
275
                            currColor.Intens = rxMsg.Data.bytes[2];                
276
                        }
276
                        }
277
                        destColor.Intens = rxMsg.Data.bytes[2];
277
                        destColor.Intens = rxMsg.Data.bytes[2];
278
                        if (rxMsg.Data.bytes[3] != 0){
278
                        if (rxMsg.Data.bytes[3] != 0){
279
                            dimSpeed = rxMsg.Data.bytes[3];
279
                            dimSpeed = rxMsg.Data.bytes[3];
280
                        }
280
                        }
281
                        currProgram = rxMsg.Data.bytes[1];
281
                        currProgram = rxMsg.Data.bytes[1];
282
                        temp_adress = pgm_read_word(&programs[currProgram-1]);
282
                        temp_adress = pgm_read_word(&programs[currProgram-1]);
283
                    } else if( rxMsg.Data.bytes[0] == RGBLED_CMD_SETRGB) {
283
                    } else if( rxMsg.Data.bytes[0] == RGBLED_CMD_SETRGB) {
284
                        /* Set RGB-triplet! */
284
                        /* Set RGB-triplet! */
285
                        reformatRGB(rxMsg.Data.bytes[2],rxMsg.Data.bytes[3],rxMsg.Data.bytes[4],0);
285
                        reformatRGB(rxMsg.Data.bytes[2],rxMsg.Data.bytes[3],rxMsg.Data.bytes[4],0);
286
                        if (rxMsg.Data.bytes[5] != 0){
286
                        if (rxMsg.Data.bytes[5] != 0){
287
                            destColor.Intens = rxMsg.Data.bytes[5];
287
                            destColor.Intens = rxMsg.Data.bytes[5];
288
                        }
288
                        }
289
                        if (rxMsg.Data.bytes[1] == TRUE){
289
                        if (rxMsg.Data.bytes[1] == TRUE){
290
                            currColor = destColor;
290
                            currColor = destColor;
291
                        }
291
                        }
292
 
292
 
293
                        if (rxMsg.Data.bytes[7] != 0){
293
                        if (rxMsg.Data.bytes[7] != 0){
294
                            fadeSpeed = rxMsg.Data.bytes[6] * 255 + rxMsg.Data.bytes[7];
294
                            fadeSpeed = rxMsg.Data.bytes[6] * 255 + rxMsg.Data.bytes[7];
295
                        }
295
                        }
296
                        currProgram = 0;               
296
                        currProgram = 0;               
297
                    }
297
                    }
298
                   
298
                   
299
                }
299
                }
300
            }
300
            }
301
            rxMsgFull = 0; //  
301
            rxMsgFull = 0; //  
302
 
302
 
303
        }
303
        }
304
        /* Done checking incoming packages */
304
        /* Done checking incoming packages */
305
 
305
 
306
    }
306
    }
307
   
307
   
308
    return 0;
308
    return 0;
309
}
309
}
310
 
310
 
311
 
311
 
312
 
312
 
313
 
313
 
314
/************************************************************************************************
314
/************************************************************************************************
315
 *     updateLED updates the PWM counter values and thus changes the color of the RGBLED.       *
315
 *     updateLED updates the PWM counter values and thus changes the color of the RGBLED.       *
316
 *     It doesn't reculculate anything, except the values to write to the PWM registers.        *
316
 *     It doesn't reculculate anything, except the values to write to the PWM registers.        *
317
 *     TODO: Get rid of the tempcontainer!                                                      *
317
 *     TODO: Get rid of the tempcontainer!                                                      *
318
 ************************************************************************************************/
318
 ************************************************************************************************/
319
void updateLED(){
319
void updateLED(){
320
    uint8_t tempcontainer;
320
    uint8_t tempcontainer;
321
 
321
 
322
    tempcontainer = currColor.R * currColor.Intens / 255;   //I really want to skip this, don't know how yet though.
322
    tempcontainer = currColor.R * currColor.Intens / 255;   //I really want to skip this, don't know how yet though.
323
    OCR1A = tempcontainer; 
323
    OCR1A = tempcontainer; 
324
      OCR0A = currColor.G * currColor.Intens / 255;
324
      OCR0A = currColor.G * currColor.Intens / 255;
325
    OCR0B = currColor.B * currColor.Intens / 255;      
325
    OCR0B = currColor.B * currColor.Intens / 255;      
326
 
326
 
327
       
327
       
328
    //Bara för debugcrap
328
    //Bara för debugcrap
329
    Can_Message_t txMsg;
329
    Can_Message_t txMsg;
330
    txMsg.Id = 0x55;
330
    txMsg.Id = 0x55;
331
    txMsg.RemoteFlag = 0;
331
    txMsg.RemoteFlag = 0;
332
    txMsg.ExtendedFlag = 1;
332
    txMsg.ExtendedFlag = 1;
333
    txMsg.DataLength = 4;
333
    txMsg.DataLength = 4;
334
    txMsg.Data.bytes[0] = currColor.R;
334
    txMsg.Data.bytes[0] = currColor.R;
335
    txMsg.Data.bytes[1] = currColor.G;
335
    txMsg.Data.bytes[1] = currColor.G;
336
    txMsg.Data.bytes[2] = currColor.B;
336
    txMsg.Data.bytes[2] = currColor.B;
337
    txMsg.Data.bytes[3] = currColor.Intens;
337
    txMsg.Data.bytes[3] = currColor.Intens;
338
 
338
 
339
    BIOS_CanSend(&txMsg);
339
    BIOS_CanSend(&txMsg);
340
 
340
 
341
}
341
}
342
 
342
 
343
 
343
 
344
 
344
 
345
/************************************************************************************************
345
/************************************************************************************************
346
 *     reformatRGB sets a new target RGB triplet to fade to. It reformats it so that            *
346
 *     reformatRGB sets a new target RGB triplet to fade to. It reformats it so that            *
347
 *     the highest color always gets 0xff. Brightness is recalculated.                          *
347
 *     the highest color always gets 0xff. Brightness is recalculated.                          *
348
 *     if setBright is set to 0, the brightness will not be updated.                            *
348
 *     if setBright is set to 0, the brightness will not be updated.                            *
349
 *     TODO: Smarter 16-bit arithmetics would be nice.                                          *
349
 *     TODO: Smarter 16-bit arithmetics would be nice.                                          *
350
 ************************************************************************************************/
350
 ************************************************************************************************/
351
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright){
351
void reformatRGB(uint8_t R, uint8_t G, uint8_t B, uint8_t setBright){
352
    uint8_t maxvalue;
352
    uint8_t maxvalue;
353
    uint16_t tempcontainer;
353
    uint16_t tempcontainer;
354
 
354
 
355
    if ((R>=G)&(R>=B)){
355
    if ((R>=G)&(R>=B)){
356
        maxvalue = R;
356
        maxvalue = R;
357
    } else if ((G>=R)&(G>=B)){
357
    } else if ((G>=R)&(G>=B)){
358
        maxvalue = G;
358
        maxvalue = G;
359
    } else {
359
    } else {
360
        maxvalue = B;
360
        maxvalue = B;
361
    }
361
    }
362
 
362
 
363
    tempcontainer = R * 255;
363
    tempcontainer = R * 255;
364
    destColor.R = tempcontainer/maxvalue;
364
    destColor.R = tempcontainer/maxvalue;
365
    tempcontainer = G * 255;
365
    tempcontainer = G * 255;
366
    destColor.G = tempcontainer/maxvalue;
366
    destColor.G = tempcontainer/maxvalue;
367
    tempcontainer = B * 255;
367
    tempcontainer = B * 255;
368
    destColor.B = tempcontainer/maxvalue;
368
    destColor.B = tempcontainer/maxvalue;
369
 
369
 
370
    if (setBright){
370
    if (setBright){
371
        destColor.Intens = maxvalue;
371
        destColor.Intens = maxvalue;
372
    }
372
    }
373
}
373
}
374
 
374
 
375
 
375
 
376
/************************************************************************************************
376
/************************************************************************************************
377
 *     fade takes two pointers, current and destination and fades current                       *
377
 *     fade takes two pointers, current and destination and fades current                       *
378
 *     one tick closer to destination.                                                          *
378
 *     one tick closer to destination.                                                          *
379
 ************************************************************************************************/
379
 ************************************************************************************************/
380
void fade(uint8_t* current, uint8_t* destination){
380
void fade(uint8_t* current, uint8_t* destination){
381
    if (*current > *destination){
381
    if (*current > *destination){
382
        *current = *current - 1;
382
        *current = *current - 1;
383
    } else if (*current < *destination){
383
    } else if (*current < *destination){
384
        *current = *current + 1;
384
        *current = *current + 1;
385
    }
385
    }
386
}
386
}
387
 
387
 
388
 
388
 
389
/************************************************************************************************
389
/************************************************************************************************
390
 *     changeColor changes a color accord to amount. -127>127.                                  *
390
 *     changeColor changes a color accord to amount. -127>127.                                  *
391
 *     color is either dest och curr R,G,B.                                                     *
391
 *     color is either dest och curr R,G,B.                                                     *
392
 *     Maybe TODO: If red is already 255 and we want to increase it, decrease the other ones.   *
392
 *     Maybe TODO: If red is already 255 and we want to increase it, decrease the other ones.   *
393
 ************************************************************************************************/
393
 ************************************************************************************************/
394
void changeColor(int8_t amount, uint8_t* color){
394
void changeColor(int8_t amount, uint8_t* color){
395
    if ( ((amount > 0)&(*color < 255)) || ((amount < 0)&(*color > 0)) ) //Se till att vi inte slår över *color
395
    if ( ((amount > 0)&(*color < 255)) || ((amount < 0)&(*color > 0)) ) //Se till att vi inte slår över *color
396
    *color = *color + amount;
396
    *color = *color + amount;
397
}
397
}
398
 
398
 
399
 
399