--- /dev/null
+#include <avr/io.h>
+#include <util/delay.h>
+#include <avr/interrupt.h>
+
+#include "rgbstring.h"
+
+void init_serial()
+{
+ PORTB &= ~(_BV(PB2) | _BV(PB1));
+ DDRB |= _BV(PB2) | _BV(PB1);
+
+#if 0
+ TCCR0A = _BV(WGM01) | _BV(WGM00);
+ TCCR0B = _BV(WGM02) | _BV(CS00);
+ OCR0A = 2;
+#endif
+
+ zero_frame();
+}
+
+static void send_byte(unsigned char b)
+{
+ unsigned char i, mask;
+
+#if 0
+ USIDR = b;
+ USISR = _BV(USIOIF);
+ USICR = _BV(USIWM0) | _BV(USICS0);
+
+ while (!(USISR & _BV(USIOIF)))
+ ;
+#endif
+
+#if 1
+ USIDR = b;
+ USISR = _BV(USIOIF);
+
+ while ( (USISR & _BV(USIOIF)) == 0 ) {
+ USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK);
+ USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC);
+ }
+#endif
+
+#if 0
+ for (i = 0; i < 8; i++) {
+ USICR = _BV(USIWM0) | _BV(USITC);
+ USICR = _BV(USIWM0) | _BV(USITC) | _BV(USICLK);
+ }
+#endif
+
+#if 0
+ for (i = 0; i < 8; i++) {
+ PORTB &= ~_BV(PB2); // clock low
+ if (b & 0x80) // data bit on or off
+ PORTB |= _BV(PB1);
+ else
+ PORTB &= ~_BV(PB1);
+ b <<= 1;
+ PORTB |= _BV(PB2); // clock high
+ }
+#endif
+}
+
+void end_frame()
+{
+ PORTB &= ~_BV(PB2); // clock low
+ _delay_us(1000);
+}
+
+void send_rgb(unsigned char r, unsigned char g, unsigned char b)
+{
+ send_byte(r);
+ send_byte(g);
+ send_byte(b);
+}
+
+
+void zero_frame()
+{
+ unsigned char i;
+
+ for (i = 0; i < STRIP_SIZE; i++) {
+ send_rgb(0, 0, 0);
+ }
+
+ end_frame();
+}
+