Browse Source

Cube now flicker free.

The display now gets updated with 48fps or 384 layers per second, while
the animations still play with 24fps.
Thomas Buck 12 years ago
parent
commit
57d88f75de
3 changed files with 62 additions and 48 deletions
  1. 25
    33
      CubeFirmware/cube.c
  2. 32
    12
      CubeFirmware/main.c
  3. 5
    3
      CubeFirmware/strings.c

+ 25
- 33
CubeFirmware/cube.c View File

36
 #define F_CPU 16000000L
36
 #define F_CPU 16000000L
37
 #endif
37
 #endif
38
 
38
 
39
-// Should be 41666
40
-#define COUNT 41666
41
-
42
 /*
39
 /*
43
- * We have:
44
- * Fosc / prescaler / fps / interruptsPerFrame = interruptCount
45
- * 16000000 / 1 / 24 / 8 = 83333 (round-a-bout)
46
- * That means, 192 Interrupts per second, 1920 after 10 secs!
47
- *
48
- * Small Study: Interrupt count after 10 seconds
40
+ * 24 fps, 8 layers => 192 Interrupts per second
41
+ * We are at 16MHz, so we count to:
42
+ * 16000000 / 192 = 83333,33...
43
+ * We can only count to 2^16, therefore we have a second counter
44
+ * COUNT * (COUNT2 + 1) = Realcount
45
+ * 41666 * 2 = 83332
46
+ * This is flickering really hard.
49
  *
47
  *
50
- * |-------------------------------|
51
- * |  COUNT   |  1   | 41666 |     |
52
- * |----------|------|-------|-----|
53
- * | intcount | 2451 | 2451  |     |
54
- * |-------------------------------|
55
- *
56
- * Haha, what's up with that?
48
+ * COUNT2 set to 0 on the other hand, thus producing 48fps,
49
+ * works flicker-free. Now we just return imgFlag / 2 as isFinished(),
50
+ * so we still fake 24fps for the main program...
57
  */
51
  */
58
 
52
 
53
+#define COUNT 41666
54
+#define COUNT2 0
55
+
59
 volatile uint8_t imgBuffer[8][8];
56
 volatile uint8_t imgBuffer[8][8];
60
 volatile uint8_t changedFlag = 0;
57
 volatile uint8_t changedFlag = 0;
61
 volatile uint8_t imgFlag = 0;
58
 volatile uint8_t imgFlag = 0;
62
 volatile uint8_t layer = 0;
59
 volatile uint8_t layer = 0;
60
+volatile uint8_t toggleFlag = 0;
63
 
61
 
64
 inline void isrCall(void);
62
 inline void isrCall(void);
65
 
63
 
66
 volatile uint32_t timesTriggered = 0;
64
 volatile uint32_t timesTriggered = 0;
67
 volatile uint8_t warningDisplayed = 0;
65
 volatile uint8_t warningDisplayed = 0;
68
 
66
 
67
+ISR(TIMER1_COMPA_vect) {
68
+	if (toggleFlag >= COUNT2) {
69
+		isrCall();
70
+		toggleFlag = 0;
71
+		timesTriggered++;
72
+	} else {
73
+		toggleFlag++;
74
+	}
75
+}
76
+
69
 uint32_t getTriggerCount(void) {
77
 uint32_t getTriggerCount(void) {
70
 	return timesTriggered;
78
 	return timesTriggered;
71
 }
79
 }
97
 }
105
 }
98
 
106
 
99
 uint8_t isFinished(void) {
107
 uint8_t isFinished(void) {
100
-	return imgFlag;
108
+	return (imgFlag / 2);
101
 }
109
 }
102
 
110
 
103
 void initCube(void) {
111
 void initCube(void) {
110
 	TIMSK &= ~(1 << OCIE1A); // Disable interrupt
118
 	TIMSK &= ~(1 << OCIE1A); // Disable interrupt
111
 }
119
 }
112
 
120
 
113
-ISR(TIMER1_COMPA_vect) {
114
-	isrCall();
115
-	timesTriggered++;
116
-#ifdef DEBUG
117
-	if (TIFR & TOV1) {
118
-		if (warningDisplayed) {
119
-			serialWrite('!');
120
-		} else {
121
-			serialWriteString(getString(27));
122
-			warningDisplayed++;
123
-		}
124
-		TIFR |= (1 << TOV1); // Clear flag
125
-	}
126
-#endif
127
-}
128
-
129
 // Data is sent to 8 Fet bits...
121
 // Data is sent to 8 Fet bits...
130
 inline void setFet(uint8_t data) {
122
 inline void setFet(uint8_t data) {
131
 	PORTD = (data & ~(3)); // Doesn't interfere with serial communication...
123
 	PORTD = (data & ~(3)); // Doesn't interfere with serial communication...

+ 32
- 12
CubeFirmware/main.c View File

54
 // x = errorcode, e = error definition, not NOERROR
54
 // x = errorcode, e = error definition, not NOERROR
55
 #define ISERROR(x, e) ((x) & (e))
55
 #define ISERROR(x, e) ((x) & (e))
56
 
56
 
57
+// Length of an idle animation frame, 24 -> 1 second
58
+#define IDLELENGTH 24
59
+
57
 void serialHandler(char c);
60
 void serialHandler(char c);
58
 void sendAudioData(void);
61
 void sendAudioData(void);
59
 void recieveAnimations(void);
62
 void recieveAnimations(void);
83
 								0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
86
 								0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
84
 								0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
87
 								0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
85
 
88
 
89
+uint8_t DebugDone = 0; // Bit 0: 10s int. count, Bit 1: switch idle display
90
+					   // Bit 2: state changed, disable idle
91
+
86
 int main(void) {
92
 int main(void) {
87
 	uint8_t *audioData = NULL;
93
 	uint8_t *audioData = NULL;
88
 	uint8_t *imageData = NULL;
94
 	uint8_t *imageData = NULL;
89
 	uint8_t i, length = 0, lastMode;
95
 	uint8_t i, length = 0, lastMode;
90
 	uint16_t count;
96
 	uint16_t count;
91
 	uint64_t lastChecked;
97
 	uint64_t lastChecked;
92
-	uint8_t DebugDone = 0; // Bit 0: 10s int. count, Bit 1: switch idle display
98
+	uint32_t temp;
93
 
99
 
94
 	initCube();
100
 	initCube();
95
 	serialInit(25, 8, NONE, 1);
101
 	serialInit(25, 8, NONE, 1);
172
 					free(imageData);
178
 					free(imageData);
173
 				}
179
 				}
174
 			} else {
180
 			} else {
175
-				if (isFinished() >= 12) {
176
-					// Should happen every half second
177
-					if (DebugDone & 2) {
178
-						fillBuffer(0);
179
-						DebugDone &= ~(2);
180
-					} else {
181
-						fillBuffer(0xFF);
182
-						DebugDone |= 2;
181
+				if (!(DebugDone & 4)) {
182
+					if (isFinished() >= IDLELENGTH) {
183
+						// Should happen every half second
184
+						if (DebugDone & 2) {
185
+							fillBuffer(0);
186
+							DebugDone &= ~(2);
187
+						} else {
188
+							fillBuffer(0xFF);
189
+							DebugDone |= 2;
190
+						}
183
 					}
191
 					}
184
 				}
192
 				}
185
 			}
193
 			}
190
 		}
198
 		}
191
 
199
 
192
 		if ((getSystemTime() >= 1000) && ((DebugDone & 1) == 0)) {
200
 		if ((getSystemTime() >= 1000) && ((DebugDone & 1) == 0)) {
193
-			printTime();
194
-			serialWriteString(ltoa(getTriggerCount(), buffer, 10));
195
-			serialWrite('\n');
201
+			temp = getTriggerCount();
202
+			serialWriteString(ltoa(temp, buffer, 10));
203
+			serialWriteString(getString(27));
204
+			serialWriteString(ltoa((temp / 8), buffer, 10));
205
+			serialWriteString(getString(28));
196
 			DebugDone |= 1;
206
 			DebugDone |= 1;
197
 		}
207
 		}
198
 
208
 
275
 
285
 
276
 	case 'd': case 'D':
286
 	case 'd': case 'D':
277
 		clearMem();
287
 		clearMem();
288
+#ifndef DEBUG
278
 		serialWrite(OK);
289
 		serialWrite(OK);
290
+#endif
291
+#ifdef DEBUG
292
+		serialWriteString(getString(29));
293
+#endif
279
 		break;
294
 		break;
280
 
295
 
296
+#ifndef DEBUG
281
 	case 'g': case 'G':
297
 	case 'g': case 'G':
282
 		transmitAnimations();
298
 		transmitAnimations();
283
 		break;
299
 		break;
285
 	case 's': case 'S':
301
 	case 's': case 'S':
286
 		recieveAnimations();
302
 		recieveAnimations();
287
 		break;
303
 		break;
304
+#endif
288
 
305
 
289
 	case 'v': case 'V':
306
 	case 'v': case 'V':
290
 		serialWriteString(getString(0));
307
 		serialWriteString(getString(0));
336
 		setAnimationCount(0);
353
 		setAnimationCount(0);
337
 		refreshAnimationCount = 1;
354
 		refreshAnimationCount = 1;
338
 		serialWriteString(getString(20));
355
 		serialWriteString(getString(20));
356
+		DebugDone |= 4;
339
 		break;
357
 		break;
340
 
358
 
341
 	case '1':
359
 	case '1':
343
 		setAnimationCount(0);
361
 		setAnimationCount(0);
344
 		refreshAnimationCount = 1;
362
 		refreshAnimationCount = 1;
345
 		serialWriteString(getString(20));
363
 		serialWriteString(getString(20));
364
+		DebugDone |= 4;
346
 		break;
365
 		break;
347
 
366
 
348
 	case '2':
367
 	case '2':
368
+		DebugDone |= 4;
349
 		fillBuffer(0);
369
 		fillBuffer(0);
350
 		for (i = 0; i < 64; i++) {
370
 		for (i = 0; i < 64; i++) {
351
 			defaultImage[i] = 0;
371
 			defaultImage[i] = 0;

+ 5
- 3
CubeFirmware/strings.c View File

56
 char stringNoMoreHeap[] PROGMEM = "Ran out of Heap... Bye\n"; // 24
56
 char stringNoMoreHeap[] PROGMEM = "Ran out of Heap... Bye\n"; // 24
57
 char stringKilledAnimation[] PROGMEM = "Animation aborted!\n"; // 25
57
 char stringKilledAnimation[] PROGMEM = "Animation aborted!\n"; // 25
58
 char stringHelp9[] PROGMEM = "(i)nterrupt count\n"; // 26
58
 char stringHelp9[] PROGMEM = "(i)nterrupt count\n"; // 26
59
-char stringTimerOverflow[] PROGMEM = "Cube Timer Overflowed (now !)\n"; // 27
59
+char stringInterrupts[] PROGMEM = " Interrupts after 1000msec\n"; // 27
60
+char stringFrames2[] PROGMEM = " Frames per Second\n"; // 28
61
+char stringDeleted[] PROGMEM = "Memory deleted!\n"; // 29
60
 
62
 
61
 // Last index + 1
63
 // Last index + 1
62
-#define STRINGNUM 28
64
+#define STRINGNUM 30
63
 
65
 
64
 PGM_P stringTable[STRINGNUM] PROGMEM = { stringVersion, stringSelfTestError, stringInit,
66
 PGM_P stringTable[STRINGNUM] PROGMEM = { stringVersion, stringSelfTestError, stringInit,
65
 								stringAudioError, stringMemError, stringMemWriteError,
67
 								stringAudioError, stringMemError, stringMemWriteError,
68
 								stringByte, stringWritten, stringCount, stringSelfTest,
70
 								stringByte, stringWritten, stringCount, stringSelfTest,
69
 								stringKillCount, stringAccessError, stringAudioData,
71
 								stringKillCount, stringAccessError, stringAudioData,
70
 								stringSnakeControl, stringNoMoreHeap, stringKilledAnimation,
72
 								stringSnakeControl, stringNoMoreHeap, stringKilledAnimation,
71
-								stringHelp9, stringTimerOverflow };
73
+								stringHelp9, stringInterrupts, stringFrames2, stringDeleted };
72
 
74
 
73
 char stringNotFoundError[] PROGMEM = "String not found!\n";
75
 char stringNotFoundError[] PROGMEM = "String not found!\n";
74
 
76
 

Loading…
Cancel
Save