Trammell Hudson avatar Trammell Hudson committed ed58309

led strip works with parallel strips

Comments (0)

Files changed (4)

 
 #include <avr/io.h>
 #include <avr/pgmspace.h>
+#include <avr/interrupt.h>
 #include <stdint.h>
 #include <util/delay.h>
 #include "usb_serial.h"
 uint8_t recv_str(char *buf, uint8_t size);
 void parse_and_execute_command(const char *buf, uint8_t num);
 
-#if 0
-// Very simple character echo test
+#if 1
+// Serial to parallel SPI driver
+static
+void send_parallel_byte(
+	const uint8_t c
+)
+{
+	PORTC &= ~(1 << 7);
+
+	PORTB = c;
+
+	PORTC |= 1 << 7;
+}
+
+
+static void
+send_color(
+	const uint8_t color
+)
+{
+	uint8_t c = color | 0x80;
+	uint8_t mask = 0x80;
+
+	while (mask)
+	{
+		if (c & mask)
+			send_parallel_byte(0xFF);
+		else
+			send_parallel_byte(0x00);
+		mask >>= 1;
+	}
+}
+
+
+
 int main(void)
 {
 	CPU_PRESCALE(0);
 	usb_init();
-	while (1) {
-		int n = usb_serial_getchar();
-		if (n >= 0) usb_serial_putchar(n);
+
+	DDRB = 0xFF;
+	DDRC = 1 << 7;
+
+#if 0
+	uint8_t r = 0x01;
+	uint8_t g = 0x30;
+	uint8_t b = 0x01;
+
+	while (1)
+	{
+		uint16_t i;
+		r = (r + 1) & 0x3F;
+
+		for (i = 0 ; i < (32 * 5) ; i++)
+		{
+			send_color(g);
+			send_color(r);
+			send_color(b);
+		}
+
+		for (i = 0 ; i < 64 ; i++)
+		{
+			send_parallel_byte(0x00);
+		}
+
+		for (i = 0 ; i < 65530 ; i++)
+		{
+			asm("nop");
+			asm("nop");
+			asm("nop");
+			asm("nop");
+			asm("nop");
+			asm("nop");
+		}
+	}
+#endif
+	
+
+	while (1)
+	{
+		const int8_t n = usb_serial_available();
+		if (n <= 0)
+			continue;
+
+		const uint8_t irq_flags = SREG;
+		cli();
+
+		int8_t i;
+		for (i = 0 ; i < n ; i++)
+		{
+#define CDC_RX_ENDPOINT		3
+			UENUM = CDC_RX_ENDPOINT;
+			const uint8_t c = UEDATX;
+			send_parallel_byte(c);
+		}
+
+		// Release the USB buffer
+		UEINTX = 0x6B;
+
+		// Re-enabled interrupts
+		SREG = irq_flags;
 	}
 }
 
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Data::Dumper;
+use Device::SerialPort;
+
+my $devfile = "/dev/tty.usbmodem12341";
+my $dev = Device::SerialPort->new($devfile)
+	or die "$devfile: Unable to open $!\n";
+
+my $num_leds = 32 * 5;
+my @pixels = map { [0,0,0] } (1..$num_leds);
+my $sprite = 0;
+
+# Pad the latch command out to 64-bytes
+my $latch = chr(0x00) x 64;
+#my $latch = chr(0x00) x (8 * 3 * int(($num_leds + 63) / 64));
+#$latch .= chr(0x00) x (64 - length($latch) % 64);
+
+
+sub translate_pixel
+{
+	my $c = shift;
+	$c |= 0x80;
+	my $mask = 0x80;
+	my $p = '';
+
+	while ($mask)
+	{
+		if ($c & $mask)
+		{
+			$p .= chr(0xFF);
+		} else {
+			$p .= chr(0x00);
+		}
+
+		$mask >>= 1;
+	}
+
+	return $p;
+}
+
+
+while (1)
+{
+	$pixels[$sprite] = [0,0,0];
+	$sprite = ($sprite - 1 + $num_leds) % $num_leds;
+	$pixels[$sprite] = [0,0x3f,0];
+
+	# Translate the colors array into a merged version per string
+	my $s = '';
+	for my $p (@pixels)
+	{
+		my ($r,$g,$b) = @$p;
+
+		$s .= translate_pixel($g);
+		$s .= translate_pixel($r);
+		$s .= translate_pixel($b);
+	}
+
+	for my $i (0..59)
+	{
+		my $t = substr($s, 64 * $i, 64);
+		$dev->write($t);
+		#sleep(0.001);
+	}
+
+	$dev->write($latch);
+
+	sleep 1.0 / 30;
+}
 	uint8_t  bInterfaceProtocol;
 	uint8_t  iInterface;
 
-	struct usb_endpoint_descriptor *endpoint;
+	struct usb_endpoint_descriptor endpoint;
 
 	unsigned char *extra;	/* Extra descriptors */
 	int extralen;
 	uint8_t  bmAttributes;
 	uint8_t  MaxPower;
 
-	struct usb_interface *interface;
+	struct usb_interface interfaces[];
 
+#if 0
 	unsigned char *extra;	/* Extra descriptors */
 	int extralen;
+#endif
 };
 
 /* Device descriptor */
 
 
 #define CONFIG1_DESC_SIZE (9+9+5+5+4+5+7+9+7+7)
+#if 1
 static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
 	// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
 	9, 					// bLength;
 	CDC_TX_SIZE, 0,				// wMaxPacketSize
 	0					// bInterval
 };
+#else
+static struct usb_config_descriptor PROGMEM config1_descriptor = {
+	.bLength		= USB_DT_CONFIG_SIZE,
+	.bDescriptorType	= USB_DT_CONFIG,
+	.wTotalLength		= CONFIG1_DESC_SIZE, // \todo compute
+	.bNumInterfaces		= 2,
+	.bConfigurationValue	= 1, // \todo ?
+	.iConfiguration		= 0, // \todo ?
+	.bmAttributes		= 0xC0, // \todo ?
+	.bMaxPower		= 50, // mA?
+	.interfaces		= {
+		{
+			.bLength		= USB_DT_INTERFACE_SIZE,
+			.bDescriptorType	= USB_DT_INTERFACE,
+			.bInterfaceNumber	= 0,
+			.bAlternateSetting	= 0,
+			.bNumEndPoints		= 0,
+			.bInterfaceClass	= USB_CLASS_COMM,
+			.bInterfaceSubClass	= USB_CLASS_COMM,
+			.bInterfaceProtocol	= 1, // \todo ?
+			.iInterface		= 0,
+			.endpoint		= {
+				.bLength		= USB_
+		},
+		{
+		},
+	},
+};
+#endif
 
 // If you're desperate for a little extra code memory, these strings
 // can be completely removed if iManufacturer, iProduct, iSerialNumber
 	}
 }
 
+
+#if 0
+/**
+ * Copy the receive buffer into a user space array, of at least 64 bytes.
+ *
+ * \return Number of bytes copied in this packet, 0 if none, -1 on error.
+ */
+int8_t
+usb_serial_recv(
+	uint8_t * buf
+)
+{
+	// interrupts are disabled so these functions can be
+	// used from the main program or interrupt context,
+	// even both in the same program!
+	const uint8_t intr_state = SREG;
+	cli();
+	if (!usb_configuration)
+	{
+		SREG = intr_state;
+		return -1;
+	}
+
+	int offset = 0;
+
+	UENUM = CDC_RX_ENDPOINT;
+	while (1)
+	{
+		if (bit_is_clear(UEINTX, RWAL))
+		{
+			// No data in the buffer .
+			if (bit_is_clear(UEINTX, RXOUTI))
+			{
+				UEINTX = 0x6B;
+				goto retry;
+			}	
+			SREG = intr_state;
+			return -1;
+		}
+
+		// take one byte out of the buffer
+		c = UEDATX;
+		// if buffer completely used, release it
+	if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B;
+	SREG = intr_state;
+	return c;
+}
+#endif
+
 // transmit a character.  0 returned on success, -1 on error
 int8_t usb_serial_putchar(uint8_t c)
 {
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.