Commits

Trammell Hudson committed e65fbed Draft

renamed example to iambic

  • Participants
  • Parent commits 236087d

Comments (0)

Files changed (3)

 
 
 # Target file name (without extension).
-TARGET = example
+TARGET = iambic
 
 
 # List C source files here. (C dependencies are automatically generated.)

example.c

-/** \file
- * Iambic USB keyer.
- *
- * Read an iambic keyer on port D and generate key press events
- * based on the Morse code input.
- *
- * (c) 2012 Trammell Hudson <hudson@osresearch.net>
- *
- * Based on the
- * Keyboard example with debug channel, for Teensy USB Development Board
- * http://www.pjrc.com/teensy/usb_keyboard.html
- * Copyright (c) 2008 PJRC.COM, LLC
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "usb_keyboard_debug.h"
-#include "print.h"
-
-#define CPU_PRESCALE(n)	(CLKPR = 0x80, CLKPR = (n))
-
-#define LED_PIN (1 << 6)
-
-static inline void
-led_on(void)
-{
-	PORTD |= LED_PIN;
-}
-
-static inline void
-led_off(void)
-{
-	PORTD &= ~LED_PIN;
-}
-
-static inline void
-led_config(void)
-{
-	DDRD |= LED_PIN;
-}
-
-uint8_t number_keys[10]=
-	{KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9};
-
-uint16_t idle_count=0;
-
-
-static inline int
-is_dah(
-	const uint8_t value
-)
-{
-	return bit_is_clear(value, 5);
-}
-
-
-static inline int
-is_dit(
-	const uint8_t value
-)
-{
-	return bit_is_clear(value, 4);
-}
-
-
-static uint8_t
-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;
-}
-
-
-static uint8_t
-wait(
-	uint16_t on_ticks,
-	uint16_t off_ticks
-)
-{
-	uint8_t port = 0xFF;
-
-	led_on();
-	port &= busy_wait(on_ticks);
-
-	led_off();
-	port &= busy_wait(off_ticks);
-
-	return port;
-}
-
-
-int main(void)
-{
-	uint8_t b, d, mask, i, reset_idle;
-	uint8_t b_prev=0xFF, d_prev=0xFF;
-
-	// set for 16 MHz clock
-	CPU_PRESCALE(0);
-	led_config();
-
-	// Configure all port B and port D pins as inputs with pullup resistors.
-	// See the "Using I/O Pins" page for details.
-	// http://www.pjrc.com/teensy/pins.html
-	DDRD = 0x00;
-	DDRB = 0x00;
-	PORTB = 0xFF;
-	PORTD = 0xFF;
-
-	// Initialize the USB, and then wait for the host to set configuration.
-	// If the Teensy is powered without a PC connected to the USB port,
-	// this will wait forever.
-	usb_init();
-	while (!usb_configured())
-	{
-		/* busy wait */
-	}
-
-	// Wait an extra second for the PC's operating system to load drivers
-	// and do whatever it does to actually be ready for input
-	_delay_ms(1000);
-
-/*
-* http://en.wikipedia.org/wiki/Morse_code#Representation.2C_timing_and_speeds
-*
-* International Morse code is composed of five elements:
-*
-* short mark, dot or 'dit' (·) — 'dot duration' is one unit long
-* longer mark, dash or 'dah' (–) — three units long
-* inter-element gap between the dots and dashes within a character
-*   - one dot duration or one unit long
-* short gap (between letters) — three units long
-* medium gap (between words) — seven units long[19]
-*
-* Based upon a 50 dot duration standard word such as PARIS, the time
-* for one dot duration or one unit can be computed by the formula:
-* T = 1200 / W
-* or
-* T = 6000 / C
-* Where: T is the unit time, or dot duration, in milliseconds,
-* W is the speed in wpm, and C is the speed in cpm.
-*/
-
-#include "morse.h"
-
-	// 
-	// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
-	// This demonstrates how to use interrupts to implement a simple
-	// inactivity timeout.
-	TCCR0A = 0x00;
-	TCCR0B = 0x05;
-	//TIMSK0 = (1<<TOIE0);
-
-	// TCNT1 runs at CLK/1024, which is 0.064 ms per tick
-	// This is pretty close to 16 ticks/ms.  The output compare
-	// sets OCF flag on match
-	TCCR1B = 5; // clk/1024
-	const uint8_t cpm = 10;
-	const uint16_t dit_time = (1600 / cpm) * 16;
-
-	uint8_t value = 1;
-	uint8_t bits = 0;
-	uint8_t last_bit = 0;
-
-	while (1)
-	{
-		// Read PINB, which has both input pins
-		// since there is a pull-up, the pins will be pulled
-		// to ground when the switch is hit.
-
-		if (bits > 7)
-		{
-			// Too many symbols.  Ignore it
-			print("?\n");
-			goto reset;
-		} else
-		if (is_dit(PINB))
-		{
-			// The dit key is held down and
-			// If the last bit sent was also a dit and the
-			// dah switch is enabled, send a dah instead.
-start_dit_bit:
-			bits++;
-			value <<= 1;
-			print(".");
-
-			const uint8_t port = wait(dit_time, dit_time);
-			if (is_dah(port))
-				goto start_dah_bit;
-			//if (is_dit(port))
-				//goto start_dit_bit;
-
-			continue;
-		} else
-		if (is_dah(PINB))
-		{
-start_dah_bit:
-			bits++;
-			value = (value << 1) | 1;
-			print("-");
-
-			const uint8_t port = wait(3*dit_time, dit_time);
-			if (is_dit(port))
-				goto start_dit_bit;
-			//if (is_dah(port))
-				//goto start_dah_bit;
-
-			continue;
-		} else
-		if (bits == 0)
-		{
-#if 0
-			if (last_send_time && now() > last_send_time)
-				usb_keyboard_press(KEY_SPACE, 0);
-			last_send_time = 0;
-#endif
-			continue;
-		}
-
-		// Neither key is held down and the single space time
-		// has elapsed (since wait_delay is blocking).
-
-		// Timeout has passed; check to see if the
-		// value exist in the map
-		uint8_t c = pgm_read_byte(&morse[value]);
-
-		//last_send_time = now();
-		print(" = ");
-		phex(value);
-
-		if (!c)
-		{
-			print("!!!\n");
-			goto reset;
-		}
-
-		print(" ");
-		pchar(c);
-		pchar('\n');
-		
-		//usb_keyboard_press(KEY_SPACE, 0);
-
-reset:
-		bits = 0;
-		value = 1;
-	}
-}
-
-// This interrupt routine is run approx 61 times per second.
-// A very simple inactivity timeout is implemented, where we
-// will send a space character and print a message to the
-// hid_listen debug message window.
-ISR(TIMER0_OVF_vect)
-{
-	idle_count++;
-	if (idle_count > 61 * 8) {
-		idle_count = 0;
-		print("Timer Event :)\n");
-		usb_keyboard_press(KEY_SPACE, 0);
-	}
-}
-
-
+/** \file
+ * Iambic USB keyer.
+ *
+ * Read an iambic keyer on port D and generate key press events
+ * based on the Morse code input.
+ *
+ * (c) 2012 Trammell Hudson <hudson@osresearch.net>
+ *
+ * Based on the
+ * Keyboard example with debug channel, for Teensy USB Development Board
+ * http://www.pjrc.com/teensy/usb_keyboard.html
+ * Copyright (c) 2008 PJRC.COM, LLC
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "usb_keyboard_debug.h"
+#include "print.h"
+
+#define CPU_PRESCALE(n)	(CLKPR = 0x80, CLKPR = (n))
+
+#define LED_PIN (1 << 6)
+
+static inline void
+led_on(void)
+{
+	PORTD |= LED_PIN;
+}
+
+static inline void
+led_off(void)
+{
+	PORTD &= ~LED_PIN;
+}
+
+static inline void
+led_config(void)
+{
+	DDRD |= LED_PIN;
+}
+
+uint8_t number_keys[10]=
+	{KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9};
+
+uint16_t idle_count=0;
+
+
+static inline int
+is_dah(
+	const uint8_t value
+)
+{
+	return bit_is_clear(value, 5);
+}
+
+
+static inline int
+is_dit(
+	const uint8_t value
+)
+{
+	return bit_is_clear(value, 4);
+}
+
+
+static uint8_t
+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;
+}
+
+
+static uint8_t
+wait(
+	uint16_t on_ticks,
+	uint16_t off_ticks
+)
+{
+	uint8_t port = 0xFF;
+
+	led_on();
+	port &= busy_wait(on_ticks);
+
+	led_off();
+	port &= busy_wait(off_ticks);
+
+	return port;
+}
+
+
+int main(void)
+{
+	uint8_t b, d, mask, i, reset_idle;
+	uint8_t b_prev=0xFF, d_prev=0xFF;
+
+	// set for 16 MHz clock
+	CPU_PRESCALE(0);
+	led_config();
+
+	// Configure all port B and port D pins as inputs with pullup resistors.
+	// See the "Using I/O Pins" page for details.
+	// http://www.pjrc.com/teensy/pins.html
+	DDRD = 0x00;
+	DDRB = 0x00;
+	PORTB = 0xFF;
+	PORTD = 0xFF;
+
+	// Initialize the USB, and then wait for the host to set configuration.
+	// If the Teensy is powered without a PC connected to the USB port,
+	// this will wait forever.
+	usb_init();
+	while (!usb_configured())
+	{
+		/* busy wait */
+	}
+
+	// Wait an extra second for the PC's operating system to load drivers
+	// and do whatever it does to actually be ready for input
+	_delay_ms(1000);
+
+/*
+* http://en.wikipedia.org/wiki/Morse_code#Representation.2C_timing_and_speeds
+*
+* International Morse code is composed of five elements:
+*
+* short mark, dot or 'dit' (·) — 'dot duration' is one unit long
+* longer mark, dash or 'dah' (–) — three units long
+* inter-element gap between the dots and dashes within a character
+*   - one dot duration or one unit long
+* short gap (between letters) — three units long
+* medium gap (between words) — seven units long[19]
+*
+* Based upon a 50 dot duration standard word such as PARIS, the time
+* for one dot duration or one unit can be computed by the formula:
+* T = 1200 / W
+* or
+* T = 6000 / C
+* Where: T is the unit time, or dot duration, in milliseconds,
+* W is the speed in wpm, and C is the speed in cpm.
+*/
+
+#include "morse.h"
+
+	// 
+	// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
+	// This demonstrates how to use interrupts to implement a simple
+	// inactivity timeout.
+	TCCR0A = 0x00;
+	TCCR0B = 0x05;
+	//TIMSK0 = (1<<TOIE0);
+
+	// TCNT1 runs at CLK/1024, which is 0.064 ms per tick
+	// This is pretty close to 16 ticks/ms.  The output compare
+	// sets OCF flag on match
+	TCCR1B = 5; // clk/1024
+	const uint8_t cpm = 10;
+	const uint16_t dit_time = (1600 / cpm) * 16;
+
+	uint8_t value = 1;
+	uint8_t bits = 0;
+	uint8_t last_bit = 0;
+
+	while (1)
+	{
+		// Read PINB, which has both input pins
+		// since there is a pull-up, the pins will be pulled
+		// to ground when the switch is hit.
+
+		if (bits > 7)
+		{
+			// Too many symbols.  Ignore it
+			print("?\n");
+			goto reset;
+		} else
+		if (is_dit(PINB))
+		{
+			// The dit key is held down and
+			// If the last bit sent was also a dit and the
+			// dah switch is enabled, send a dah instead.
+start_dit_bit:
+			bits++;
+			value <<= 1;
+			print(".");
+
+			const uint8_t port = wait(dit_time, dit_time);
+			if (is_dah(port))
+				goto start_dah_bit;
+			//if (is_dit(port))
+				//goto start_dit_bit;
+
+			continue;
+		} else
+		if (is_dah(PINB))
+		{
+start_dah_bit:
+			bits++;
+			value = (value << 1) | 1;
+			print("-");
+
+			const uint8_t port = wait(3*dit_time, dit_time);
+			if (is_dit(port))
+				goto start_dit_bit;
+			//if (is_dah(port))
+				//goto start_dah_bit;
+
+			continue;
+		} else
+		if (bits == 0)
+		{
+#if 0
+			if (last_send_time && now() > last_send_time)
+				usb_keyboard_press(KEY_SPACE, 0);
+			last_send_time = 0;
+#endif
+			continue;
+		}
+
+		// Neither key is held down and the single space time
+		// has elapsed (since wait_delay is blocking).
+
+		// Timeout has passed; check to see if the
+		// value exist in the map
+		uint8_t c = pgm_read_byte(&morse[value]);
+
+		//last_send_time = now();
+		print(" = ");
+		phex(value);
+
+		if (!c)
+		{
+			print("!!!\n");
+			goto reset;
+		}
+
+		print(" ");
+		pchar(c);
+		pchar('\n');
+		
+		//usb_keyboard_press(KEY_SPACE, 0);
+
+reset:
+		bits = 0;
+		value = 1;
+	}
+}
+
+// This interrupt routine is run approx 61 times per second.
+// A very simple inactivity timeout is implemented, where we
+// will send a space character and print a message to the
+// hid_listen debug message window.
+ISR(TIMER0_OVF_vect)
+{
+	idle_count++;
+	if (idle_count > 61 * 8) {
+		idle_count = 0;
+		print("Timer Event :)\n");
+		usb_keyboard_press(KEY_SPACE, 0);
+	}
+}
+
+