midi / iambic.c

Diff from to
 	return bit_is_clear(value, 5);
 }
 
+static uint16_t dah_count;
+static uint16_t dit_count;
 
-static uint8_t
+
+static void
 busy_wait(
 	uint16_t delay_ticks
 )
 {
-	uint8_t port = 0xFF;
-
 	OCR1A = TCNT1 + delay_ticks;
 	TIFR1 |= (1 << OCF1A);
 
 	while (bit_is_clear(TIFR1, OCF1A))
-		port &= PINB;
-
-	return port;
+	{
+		const uint8_t port = PINB;
+		if (is_dah(port))
+			dah_count++;
+		if (is_dit(port))
+			dit_count++;
+	}
 }
 
 
-static uint8_t
+static void
 wait(
 	uint16_t on_ticks,
 	uint16_t off_ticks
 )
 {
-	uint8_t port = 0xFF;
+	dit_count = dah_count = 0;
 
 	led_on();
-	//busy_wait(on_ticks/4); // ignore any pulses in the first half?
-	//port &= busy_wait(3*on_ticks/4);
-	port &= busy_wait(on_ticks);
+	busy_wait(on_ticks);
 
 	led_off();
-	port &= busy_wait(off_ticks);
+	busy_wait(off_ticks);
+}
 
-	return port;
+
+static void
+bad_input(void)
+{
+	uint8_t tccr0b = TCCR0B;
+	TCCR0B = 0x04; // Clk/256
+	led_on();
+	print("!!!\n");
+	_delay_ms(20);
+	led_off();
+
+	// Restore the old timer
+	TCCR0B = tccr0b;
 }
 
 
 	TCCR1B = 5; // clk/1024
 	const uint8_t cpm = 10;
 	const uint16_t dit_time = (1600 / cpm) * 16;
+	const uint16_t button_threshold = dit_time / 2;
 
 	// TCNT0 is configured for a 500 Hz tone on OC0A
-	// At CLK/512, this is turns on and off each time
-	// a full counter is made
+	// At CLK/64, this is turns on and off each time
+	// a full counter is made, which creates a 488 Hz
+	// square wave.
 	TCCR0A = (1 << COM0A0); // toggle OC0A on match
 	TCCR0B = 0x03; // CLK/64
 	OCR0A = 0xFF; // every roll over
 		if (bits > 7)
 		{
 			// Too many symbols.  Ignore it
-			print("?\n");
+			bad_input();
 			goto reset;
 		} else
 		if (is_dit(PINB))
 			value <<= 1;
 			print(".");
 
-			const uint8_t port = wait(dit_time, dit_time);
-			if (is_dah(port))
+			wait(dit_time, dit_time);
+			if (dah_count > button_threshold)
 				goto start_dah_bit;
 
 			continue;
 			value = (value << 1) | 1;
 			print("-");
 
-			const uint8_t port = wait(3*dit_time, dit_time);
-			if (is_dit(port))
+			wait(3*dit_time, dit_time);
+			if (dit_count > button_threshold)
 				goto start_dit_bit;
 
 			continue;
 		// has elapsed (since wait_delay is blocking).
 
 		// \todo Delay one more cycle to be sure
-		const uint8_t port = busy_wait(dit_time);
-		if (is_dah(port))
+		dit_count = dah_count = 0;
+		busy_wait(dit_time);
+		if (dah_count > button_threshold)
 			goto start_dah_bit;
-		if (is_dit(port))
+		if (dit_count > button_threshold)
 			goto start_dit_bit;
 
 		// Timeout has passed; check to see if the
 
 		if (!c)
 		{
-			print("!!!\n");
+			bad_input();
 			goto reset;
 		}
 
-		//print(" ");
-		//pchar(c);
 		pchar('\n');
 		
 		const uint8_t modbit = c & 0x80 ? KEY_SHIFT : 0;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.