Parcourir la 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 il y a 12 ans
Parent
révision
57d88f75de
3 fichiers modifiés avec 62 ajouts et 48 suppressions
  1. 25
    33
      CubeFirmware/cube.c
  2. 32
    12
      CubeFirmware/main.c
  3. 5
    3
      CubeFirmware/strings.c

+ 25
- 33
CubeFirmware/cube.c Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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
 

Chargement…
Annuler
Enregistrer