1. Trammell Hudson
  2. led-strip

Source

led-strip / blinky.c

/* LED Blink Example with USB Debug Channel for Teensy USB Development Board
 * http://www.pjrc.com/teensy/
 * Copyright (c) 2008, 2010 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 <util/delay.h>
#include "usb_debug_only.h"
#include "print.h"


// Teensy 2.0: LED is active high
#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__)
#define LED_ON		(PORTD |= (1<<6))
#define LED_OFF		(PORTD &= ~(1<<6))

// Teensy 1.0: LED is active low
#else
#define LED_ON	(PORTD &= ~(1<<6))
#define LED_OFF	(PORTD |= (1<<6))
#endif

#define LED_CONFIG	(DDRD |= (1<<6))
#define CPU_PRESCALE(n)	(CLKPR = 0x80, CLKPR = (n))
#define DIT 10		/* unit time for morse code */

void morse_character(char c);
void morse_P(const char *s);
const unsigned char morse_code_table[];

void
put_hexchar(
	unsigned c
)
{
	c &= 0xF;
	pchar(c <= 9 ? c + '0' : c + 'A' - 0xA);
}


int main(void)
{
	// set for 16 MHz clock, and make sure the LED is off
	CPU_PRESCALE(0);
	LED_CONFIG;
	LED_OFF;

	// initialize the USB, but don't want for the host to
	// configure.  The first several messages sent will be
	// lost because the PC hasn't configured the USB yet,
	// but we care more about blinking than debug messages!
	usb_init();

	LED_ON;

	// Set the port to 31.25 K-baud, 1 start, 8 data, 1 parity
	UBRR1H = 0;
	UBRR1L = 28;
	UCSR1B = 1 << RXEN1;
	UCSR1C = (0 << UCSZ12) | (1 << UCSZ11) | (1 << UCSZ10);

	print("waiting for data\n");

	while (1)
	{
		if (!(UCSR1A & (1 << RXC1)))
			continue;
		LED_ON;
		unsigned c = UDR1;
		put_hexchar(c >> 4);
		put_hexchar(c >> 0);
		pchar('\n');
		LED_OFF;
	}
}


// blink a single character in Morse code
void morse_character(char c)
{
	unsigned char code, count;

	if (c == ' ') {
		print("Space\n");
		_delay_ms(DIT * 7);
		return;
	}
	if (c < 'A' || c > 'Z') {
		print("Opps, unsupported character: ");
		pchar(c);
		print("\n");
		return;	
	}
	print("Char ");
	pchar(c);
	pchar(':');
	code = pgm_read_byte(morse_code_table + (c - 'A'));
	for (count = code & 0x07; count > 0; count--) {
		LED_ON;
		if (code & 0x80) {
			print(" dah");
			_delay_ms(DIT * 3);
		} else {
			print(" dit");
			_delay_ms(DIT);
		}
		LED_OFF;
		_delay_ms(DIT);
		code = code << 1;
	}
	print("\n");
	_delay_ms(DIT * 2);
}

// blink an entire message in Morse code
// the string must be in flash memory (using PSTR macro)
void morse_P(const char *s)
{
	char c;
	
	while (1) {
		c = pgm_read_byte(s++);
		if (!c) break;
		morse_character(c);
	}
	print("\n");
}

// lookup table for all 26 letters.  Upper 5 bits are the pulses
// to send (MSB first), and the lower 3 bits are the number of
// bits to send for this letter.
const unsigned char PROGMEM morse_code_table[] = {
	0x40 + 2,	// A: .-
	0x80 + 4,	// B: -...
	0xA0 + 4,	// C: -.-.
	0x80 + 3,	// D: -..
	0x00 + 1,	// E: .
	0x20 + 4,	// F: ..-.
	0xC0 + 3,	// G: --.
	0x00 + 4,	// H: ....
	0x00 + 2,	// I: ..
	0x70 + 4,	// J: .---
	0xA0 + 3,	// K: -.-
	0x40 + 4,	// L: .-..
	0xC0 + 2,	// M: --
	0x80 + 2,	// N: -.
	0xE0 + 3,	// O: ---
	0x60 + 4,	// P: .--.
	0xD0 + 4,	// Q: --.-
	0x40 + 3,	// R: .-.
	0x00 + 3,	// S: ...
	0x80 + 1,	// T: -
	0x20 + 3,	// U: ..-
	0x10 + 4,	// V: ...-
	0x60 + 3,	// W: .--
	0x90 + 4,	// X: -..-
	0xB0 + 4,	// Y: -.--
	0xC0 + 4	// Z: --..
};