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,36 +36,44 @@
36 36
 #define F_CPU 16000000L
37 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 56
 volatile uint8_t imgBuffer[8][8];
60 57
 volatile uint8_t changedFlag = 0;
61 58
 volatile uint8_t imgFlag = 0;
62 59
 volatile uint8_t layer = 0;
60
+volatile uint8_t toggleFlag = 0;
63 61
 
64 62
 inline void isrCall(void);
65 63
 
66 64
 volatile uint32_t timesTriggered = 0;
67 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 77
 uint32_t getTriggerCount(void) {
70 78
 	return timesTriggered;
71 79
 }
@@ -97,7 +105,7 @@ void fillBuffer(uint8_t val) {
97 105
 }
98 106
 
99 107
 uint8_t isFinished(void) {
100
-	return imgFlag;
108
+	return (imgFlag / 2);
101 109
 }
102 110
 
103 111
 void initCube(void) {
@@ -110,22 +118,6 @@ void close(void) {
110 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 121
 // Data is sent to 8 Fet bits...
130 122
 inline void setFet(uint8_t data) {
131 123
 	PORTD = (data & ~(3)); // Doesn't interfere with serial communication...

+ 32
- 12
CubeFirmware/main.c View File

@@ -54,6 +54,9 @@
54 54
 // x = errorcode, e = error definition, not NOERROR
55 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 60
 void serialHandler(char c);
58 61
 void sendAudioData(void);
59 62
 void recieveAnimations(void);
@@ -83,13 +86,16 @@ uint8_t defaultImage[64] = 	{	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
83 86
 								0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
84 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 92
 int main(void) {
87 93
 	uint8_t *audioData = NULL;
88 94
 	uint8_t *imageData = NULL;
89 95
 	uint8_t i, length = 0, lastMode;
90 96
 	uint16_t count;
91 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 100
 	initCube();
95 101
 	serialInit(25, 8, NONE, 1);
@@ -172,14 +178,16 @@ int main(void) {
172 178
 					free(imageData);
173 179
 				}
174 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,9 +198,11 @@ int main(void) {
190 198
 		}
191 199
 
192 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 206
 			DebugDone |= 1;
197 207
 		}
198 208
 
@@ -275,9 +285,15 @@ void serialHandler(char c) {
275 285
 
276 286
 	case 'd': case 'D':
277 287
 		clearMem();
288
+#ifndef DEBUG
278 289
 		serialWrite(OK);
290
+#endif
291
+#ifdef DEBUG
292
+		serialWriteString(getString(29));
293
+#endif
279 294
 		break;
280 295
 
296
+#ifndef DEBUG
281 297
 	case 'g': case 'G':
282 298
 		transmitAnimations();
283 299
 		break;
@@ -285,6 +301,7 @@ void serialHandler(char c) {
285 301
 	case 's': case 'S':
286 302
 		recieveAnimations();
287 303
 		break;
304
+#endif
288 305
 
289 306
 	case 'v': case 'V':
290 307
 		serialWriteString(getString(0));
@@ -336,6 +353,7 @@ void serialHandler(char c) {
336 353
 		setAnimationCount(0);
337 354
 		refreshAnimationCount = 1;
338 355
 		serialWriteString(getString(20));
356
+		DebugDone |= 4;
339 357
 		break;
340 358
 
341 359
 	case '1':
@@ -343,9 +361,11 @@ void serialHandler(char c) {
343 361
 		setAnimationCount(0);
344 362
 		refreshAnimationCount = 1;
345 363
 		serialWriteString(getString(20));
364
+		DebugDone |= 4;
346 365
 		break;
347 366
 
348 367
 	case '2':
368
+		DebugDone |= 4;
349 369
 		fillBuffer(0);
350 370
 		for (i = 0; i < 64; i++) {
351 371
 			defaultImage[i] = 0;

+ 5
- 3
CubeFirmware/strings.c View File

@@ -56,10 +56,12 @@ char stringSnakeControl[] PROGMEM = "Controls: W A S D Q E, x to quit\n"; // 23
56 56
 char stringNoMoreHeap[] PROGMEM = "Ran out of Heap... Bye\n"; // 24
57 57
 char stringKilledAnimation[] PROGMEM = "Animation aborted!\n"; // 25
58 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 63
 // Last index + 1
62
-#define STRINGNUM 28
64
+#define STRINGNUM 30
63 65
 
64 66
 PGM_P stringTable[STRINGNUM] PROGMEM = { stringVersion, stringSelfTestError, stringInit,
65 67
 								stringAudioError, stringMemError, stringMemWriteError,
@@ -68,7 +70,7 @@ PGM_P stringTable[STRINGNUM] PROGMEM = { stringVersion, stringSelfTestError, str
68 70
 								stringByte, stringWritten, stringCount, stringSelfTest,
69 71
 								stringKillCount, stringAccessError, stringAudioData,
70 72
 								stringSnakeControl, stringNoMoreHeap, stringKilledAnimation,
71
-								stringHelp9, stringTimerOverflow };
73
+								stringHelp9, stringInterrupts, stringFrames2, stringDeleted };
72 74
 
73 75
 char stringNotFoundError[] PROGMEM = "String not found!\n";
74 76
 

Loading…
Cancel
Save