Project

General

Profile

Revision 583

Added by ibrin about 16 years ago

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.

View differences:

branches/lights/projects/template/main.c
2 2

  
3 3
int main(void) {
4 4
	dragonfly_init(ALL_ON);
5
	orb1_set(200,0,0);
6
	orb2_set(0,0,200);
7
	while(1) 
8
	{
9

  
10
	}
5 11
	return 0;
6 12
}
branches/lights/projects/template/Makefile
116 116
endif
117 117

  
118 118
# Place -I, -L options here
119
CINCS = -I$(COLONYROOT)/code/lib/include/libdragonfly
120
CINCS += -L$(COLONYROOT)/code/lib/bin
119
CINCS = -I../libdragonfly
120
CINCS += -L../libdragonfly
121 121
ifdef USE_WIRELESS
122
	CINCS += -I$(COLONYROOT)/code/lib/include/libwireless
122
	#CINCS += -I$(COLONYROOT)/code/lib/include/libwireless
123 123
endif
124 124

  
125 125
#---------------- Compiler Options ----------------
branches/lights/projects/libdragonfly/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