Commits

Trammell Hudson committed 7425d39 Merge

merged back to head

  • Participants
  • Parent commits fef4502, e1a4a21

Comments (0)

Files changed (1)

 #include "usb_debug_only.h"
 #include "print.h"
 
+#include "font-small.c"
+
 
 // Teensy 2.0: LED is active high
 #if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__)
 	latch();
 }
 
-static void fade_pixels(void)
+
+static void fade_pixels(
+	uint8_t r,
+	uint8_t g,
+	uint8_t b
+)
 {
 	uint16_t i;
 	for (i = 0 ; i < NUM_LEDS ; i++)
 	{
 		uint8_t * const p = pixels[i];
-		uint8_t j;
-		for (j = 0 ; j < 3 ; j++)
+
+		p[0] = (p[0] * (uint16_t) 31 + r) / 32;
+		p[1] = (p[1] * (uint16_t) 31 + g) / 32;
+		p[2] = (p[2] * (uint16_t) 31 + b) / 32;
+	}
+}
+
+
+/******************************
+ * Smooth fading between colors.
+ */
+
+static const uint8_t colors[][3] =
+{
+	{ 0x00, 0x00, 0xFF },	// blue
+	{ 0xFF, 0xFF, 0xFF },	// white
+	{ 0xFF, 0xFF, 0x00 },   // yellow
+	{ 0xFF, 0x00, 0x00 },	// red
+	{ 0x00, 0x80, 0xFF },	// cyan
+	{ 0x00, 0xFF, 0x00 },	// green
+	{ 0xFF, 0xFF, 0xFF },	// white
+};
+
+static const uint8_t num_colors = sizeof(colors) / sizeof(*colors);
+
+
+static void pattern_fade(void)
+{
+	uint8_t cycle = 0;
+	const uint16_t iter_count = 256;
+
+	// total duration: 32 * 256 * 500 ms == 
+
+	for (cycle = 0 ; cycle < 32 ; cycle++)
+	{
+		const uint8_t * const c0 = colors[(cycle + 0) % num_colors];
+		const uint8_t * const c1 = colors[(cycle + 1) % num_colors];
+		//const uint8_t * const c2 = colors[(cycle + 2) % num_colors];
+
+		for (uint16_t iter = 0 ; iter < iter_count ; iter++)
 		{
-			uint16_t v = (p[j] * (uint16_t) 31) / 32;
-			if (v > 0xFF)
-				v = 0xFF;
-			p[j] = v;
+			uint16_t i;
+			for (i = 0 ; i < NUM_LEDS ; i++)
+			{
+				uint8_t * const p = pixels[i];
+				const uint16_t s0 = iter_count - iter;
+				const uint16_t s1 = iter;
+				p[0] = (c0[0] * s0 + c1[0] * s1) / iter_count;
+				p[1] = (c0[1] * s0 + c1[1] * s1) / iter_count;
+				p[2] = (c0[2] * s0 + c1[2] * s1) / iter_count;
+			}
+
+			send_pixels();
+			_delay_ms(500);
 		}
 	}
 }
 
+
+
+/***************************
+ * Chase pattern.
+ */
 struct sprite
 {
 	int16_t pos;
 	uint8_t g;
 };
 
+static struct sprite sprites[] = {
+	{ .v = +1, .r = 0xFF, .b = 0x00, .g = 0x00 },
+	{ .v = +2, .r = 0x00, .b = 0xFF, .g = 0x00, .pos = NUM_LEDS*LED_SCALE/2 },
+	{ .v = +3, .r = 0xFF, .b = 0xFF, .g = 0xFF },
+	{ .v = +5, .r = 0x00, .b = 0xFF, .g = 0xFF },
+	{ .v = +7, .r = 0x80, .b = 0x80, .g = 0x10 },
+	{ .v = +11, .r = 0x00, .b = 0x00, .g = 0xFF },
+	{ .v = +13, .r = 0xFF, .b = 0x00, .g = 0xFF },
+};
+
+static const int num_sprites = sizeof(sprites) / sizeof(*sprites);
+
+
+static void pattern_chase(void)
+{
+	uint16_t cycle;
+	for (cycle = 0 ; cycle < 512 ; cycle++)
+	{
+		// Compute the next position
+		for (int i = 0 ; i < num_sprites ; i++)
+		{
+			struct sprite * const s = &sprites[i];
+			int16_t pos = s->pos + s->v;
+
+			if (pos >= NUM_LEDS * LED_SCALE)
+			{
+				pos = NUM_LEDS * LED_SCALE - 1;
+				s->v = -s->v;
+			} else
+			if (pos < 0) {
+				pos = 0;
+				s->v = -s->v;
+			}
+				
+			s->pos = pos;
+
+			uint8_t * const p = pixels[pos / LED_SCALE];
+			p[0] = (s->r * (uint16_t) 3 + p[0]) / 4;
+			p[1] = (s->g * (uint16_t) 3 + p[1]) / 4;
+			p[2] = (s->b * (uint16_t) 3 + p[2]) / 4;
+		}
+
+		send_pixels();
+		fade_pixels(0, 0, 0);
+		_delay_ms(30);
+	}
+}
+
+
+/***********************
+ * Decay to blue
+ */
+static void pattern_decay(void)
+{
+	uint8_t cycle;
+	const uint8_t * const c = colors[0];
+
+	for (cycle = 0 ; cycle < 32 ; cycle++)
+	{
+		fade_pixels(c[0], c[1], c[2]);
+		send_pixels();
+		_delay_ms(30);
+	}
+}
 
 
 int main(void)
 	for (i = 0 ; i < NUM_LEDS ; i++)
 		pixels[i][0] = pixels[i][1] = pixels[i][2] = 0xFF;
 	send_pixels();
-	//while(1);
-
-	struct sprite sprites[] = {
-		{ .v = +1, .r = 0xFF, .b = 0x00, .g = 0x00 },
-		{ .v = +2, .r = 0x00, .b = 0xFF, .g = 0x00, .pos = NUM_LEDS*LED_SCALE/2 },
-		{ .v = +3, .r = 0xFF, .b = 0xFF, .g = 0xFF },
-		{ .v = +5, .r = 0x00, .b = 0xFF, .g = 0xFF },
-		{ .v = +7, .r = 0x80, .b = 0x80, .g = 0x10 },
-		{ .v = +11, .r = 0x00, .b = 0x00, .g = 0xFF, .pos = NUM_LEDS*LED_SCALE/2 },
-		{ .v = +13, .r = 0xFF, .b = 0x00, .g = 0xFF, .pos = NUM_LEDS*LED_SCALE/2 },
-	};
-	const int num_sprites = sizeof(sprites) / sizeof(*sprites);
 
 	while (1)
 	{
-		send_pixels();
-		fade_pixels();
-
-		// Compute the next position
-		for (int i = 0 ; i < num_sprites ; i++)
-		{
-			struct sprite * const s = &sprites[i];
-			int16_t pos = s->pos + s->v;
-
-			if (pos >= NUM_LEDS * LED_SCALE)
-			{
-				pos = NUM_LEDS * LED_SCALE - 1;
-				s->v = -s->v;
-			} else
-			if (pos < 0) {
-				pos = 0;
-				s->v = -s->v;
-			}
-				
-			s->pos = pos;
-
-			uint8_t * const p = pixels[pos / LED_SCALE];
-			p[0] = (s->r * (uint16_t) 3 + p[0]) / 4;
-			p[1] = (s->g * (uint16_t) 3 + p[1]) / 4;
-			p[2] = (s->b * (uint16_t) 3 + p[2]) / 4;
-		}
-
-		_delay_ms(30);
+		pattern_chase();
+		pattern_decay();
+		pattern_fade();
 	}
 }